diff --git a/popnhax/omnimix_patch.cc b/popnhax/omnimix_patch.cc index d65dcc0..d9bb771 100644 --- a/popnhax/omnimix_patch.cc +++ b/popnhax/omnimix_patch.cc @@ -74,7 +74,7 @@ uint32_t *find_binary_xref(char *data, DWORD dllSize, const char *search_pattern } -uint32_t get_table_size_by_xref(char *data, DWORD dllSize, uint32_t *ea, uint32_t entry_size) +uint32_t get_table_size_by_xref(char *data, DWORD data_size, uint32_t *ea, uint32_t entry_size) { fprintf(stderr, "get table size by xref\n"); uint32_t *orig_ea = ea; @@ -86,27 +86,26 @@ uint32_t get_table_size_by_xref(char *data, DWORD dllSize, uint32_t *ea, uint32_ while (!found) { + uint32_t curr_limit = (((uint32_t)ea)-((uint32_t)orig_ea))/entry_size; + uint32_t *as_int = (uint32_t*)&ea; - //fprintf(stderr, "looking for xref to %0X\n", *as_int); + //fprintf(stderr, "limit candidate %u, looking for xref to %0X\n", curr_limit, *as_int); if ( bst_search(g_xref_bst, *as_int) != NULL ) { + //fprintf(stderr, "found .text XREF in BST\n"); found=true; - } -/* uint32_t *xref = find_binary(data, dllSize, as_hex, 4, 0, 0); - if ( xref != NULL ) - { - fprintf(stderr, "found at addr %p\n", xref); - if ( xref != (uint32_t*)0x10169236 ) + } else { + //look for Xref in data section + char *as_hex = (char*)&ea; + uint32_t *xref = find_binary(data, data_size, as_hex, 4, 0, 0); + if ( xref != NULL ) { - found = true; - } - else - { - fprintf(stderr, "bad offset\n"); + //fprintf(stderr, "found .data XREF at addr %p\n", xref); + found = true; } } -*/ + if (!found) ea = (uint32_t*)((uint32_t)ea+entry_size); } @@ -115,25 +114,6 @@ uint32_t get_table_size_by_xref(char *data, DWORD dllSize, uint32_t *ea, uint32_ return (((uint32_t)ea)-((uint32_t)orig_ea))/entry_size; } -/* -def get_table_size_by_xref(ea, entry_size): - # Skip 10 entries because why not. We're looking for the end anyway - orig_ea = ea - ea += entry_size * 10 - - found_end = False - while not found_end: - for xref_idx, xref in enumerate(idautils.XrefsTo(ea)): - found_end = True - break - - if not found_end: - ea += entry_size - - return (ea - orig_ea) // entry_size -*/ - - void print_cb(x86_insn_t *insn, void *arg) { char line[LINE_SIZE]; /* buffer of line to print */ @@ -146,7 +126,7 @@ static void add_xref_to_bst(uint32_t addr) if ( bst_search(g_xref_bst, addr) == NULL ) { //LOG("added addr %0X to BST\n", addr); - g_xref_bst = bst_insert(g_xref_bst, addr); + g_xref_bst = bst_insert(g_xref_bst, addr); } } @@ -200,16 +180,48 @@ bool make_omnimix_patch(const char *dllFilename){ DWORD dllSize = 0; char *buf = getDllData(dllFilename, &dllSize); -/* -const char *dummy_buf = "\x8b\x0c\x95\xfc\x28\x32\x10"; -DWORD dummy_size = 7; -*/ -/* build instruction table indexed by parameter */ - LOG("START DISASSEMBLY\n"); - x86_init(opt_none, NULL, NULL); + char *text = NULL; + DWORD text_size = 0; + + char *data = NULL; + DWORD data_size = 0; + + char *rdata = NULL; + DWORD rdata_size = 0; + +PIMAGE_NT_HEADERS headers = (PIMAGE_NT_HEADERS)(buf + ((PIMAGE_DOS_HEADER)buf)->e_lfanew); +PIMAGE_SECTION_HEADER section_header = IMAGE_FIRST_SECTION(headers); - unsigned int num_insn = x86_disasm_range( (unsigned char *)buf, (uint32_t) buf, 0, dllSize, &add_xref, NULL); +for (WORD SectionIndex = 0; SectionIndex < headers->FileHeader.NumberOfSections; SectionIndex++) +{ + PIMAGE_SECTION_HEADER curr_header = §ion_header[SectionIndex]; + + if ( strcmp( (const char*)curr_header->Name, ".text" ) == 0 || curr_header->Characteristics & IMAGE_SCN_CNT_CODE ) + { + text = (char*) ((int64_t)buf + curr_header->VirtualAddress); + text_size = curr_header->Misc.VirtualSize; + } + if ( strcmp( (const char*)curr_header->Name, ".data" ) == 0 ) + { + data = (char*) ((int64_t)buf + curr_header->VirtualAddress); + data_size = curr_header->Misc.VirtualSize; + } + if ( strcmp( (const char*)curr_header->Name, ".rdata" ) == 0 ) + { + rdata = (char*) ((int64_t)buf + curr_header->VirtualAddress); + rdata_size = curr_header->Misc.VirtualSize; + } +} + LOG("buf addr is %p\n", buf); + LOG("text section size %lX, addr %p, beginning %02X %02X %02X %02X\n", text_size, text, text[0], text[1], text[2], text[3]); + LOG("data section size %lX, addr %p, beginning %02X %02X %02X %02X\n", data_size, data, data[0], data[1], data[2], data[3]); + LOG("rdata section size %lX, addr %p, beginning %02X %02X %02X %02X\n", rdata_size, rdata, rdata[0], rdata[1], rdata[2], rdata[3]); + + // disassemble .text section and add all xrefs to our BST + LOG("START DISASSEMBLY\n"); + x86_init(opt_none, NULL, NULL); + unsigned int num_insn = x86_disasm_range( (unsigned char *)text, (uint32_t) buf, 0, text_size, &add_xref, NULL); LOG("parsed %u instructions\n", num_insn); LOG("END DISASSEMBLY\n"); @@ -243,11 +255,11 @@ g_tables[FLAVOR_IDX].size = 0x60; g_tables[CHARA_IDX].size = 0x4C; // buffer_addr + (buffer_entry_size * limit) should give you the very end of the array (after the last entry) -g_tables[MUSIC_IDX].limit = get_table_size_by_xref(buf, dllSize, g_tables[MUSIC_IDX].addr, g_tables[MUSIC_IDX].size); -g_tables[CHART_IDX].limit = get_table_size_by_xref(buf, dllSize, g_tables[CHART_IDX].addr, g_tables[CHART_IDX].size); -g_tables[STYLE_IDX].limit = get_table_size_by_xref(buf, dllSize, g_tables[STYLE_IDX].addr, g_tables[STYLE_IDX].size); -g_tables[FLAVOR_IDX].limit = get_table_size_by_xref(buf, dllSize, g_tables[FLAVOR_IDX].addr, g_tables[FLAVOR_IDX].size); -g_tables[CHARA_IDX].limit = get_table_size_by_xref(buf, dllSize, g_tables[CHARA_IDX].addr, g_tables[CHARA_IDX].size); +g_tables[MUSIC_IDX].limit = get_table_size_by_xref(data, data_size, g_tables[MUSIC_IDX].addr, g_tables[MUSIC_IDX].size); +g_tables[CHART_IDX].limit = get_table_size_by_xref(data, data_size, g_tables[CHART_IDX].addr, g_tables[CHART_IDX].size); +g_tables[STYLE_IDX].limit = get_table_size_by_xref(data, data_size, g_tables[STYLE_IDX].addr, g_tables[STYLE_IDX].size); +g_tables[FLAVOR_IDX].limit = get_table_size_by_xref(data, data_size, g_tables[FLAVOR_IDX].addr, g_tables[FLAVOR_IDX].size); +g_tables[CHARA_IDX].limit = get_table_size_by_xref(data, data_size, g_tables[CHARA_IDX].addr, g_tables[CHARA_IDX].size); /* # Modify the entry sizes as required