c++ - Why am i getting wrong values when performing PE base relocation? -
i trying perform pe base relocation , whole concept, data structures, method , why doing not problem that. days have been trying code work whatever keep getting undefined/wrong relocation types in variable called relocationtype(obviously) , have feeling might getting wrong offsets aswell allthought when checked debugger few bytes off, regardless cause crash.
i should inform of relocation types correct, , either image_rel_absolute or image_rel_based_highlow 1 expect, after few loops finds wrong values. not have clue happening, suspect pbaserelocation might few bytes of reason after while.
here relocation function:
int fixrelocs(dword imagebase, pimage_nt_headers ntheaders, image_base_relocation *reloc, unsigned int size) { pimage_base_relocation pbaserelocation; image_data_directory datadir; pword list; dword delta; dword count; dword *patchaddr; unsigned char* dest; unsigned char* base = (unsigned char*)imagebase; bool ndelta = false; datadir = (image_data_directory)ntheaders->optionalheader.datadirectory[image_directory_entry_basereloc]; pbaserelocation = (pimage_base_relocation)(imagebase + datadir.size); if (imagebase > ntheaders->optionalheader.imagebase) { delta = imagebase - ntheaders->optionalheader.imagebase; } else if (imagebase < ntheaders->optionalheader.imagebase) { delta = ntheaders->optionalheader.imagebase - imagebase; ndelta = true; } else { return dll_no_reloc_required; } while (pbaserelocation->virtualaddress > 0) { count = (pbaserelocation->sizeofblock - sizeof(image_base_relocation)) / sizeof(word); list = (pword)(pbaserelocation + sizeof(image_base_relocation)); dest = base + pbaserelocation->virtualaddress; (int = 0; < count; i++) { int offset = *list & 0x0fff; int relocationtype = (*list >> 12) & 0x000f; switch (relocationtype) { case image_rel_based_absolute: break; case image_rel_based_highlow: patchaddr = (dword*)(dest + offset); if (!ndelta) { *patchaddr += (dword)delta; } else { *patchaddr = (dword)delta; } break; case image_rel_based_low: patchaddr = (dword*)(dest + offset); if (!ndelta) { *patchaddr += (word)((delta >> 16) & 0x0000ffff); } else { *patchaddr -= (word)((delta >> 16) & 0x0000ffff); } break; default: dbgprint("dll!fixrelocs+0x156 unknown relocation %d. address: 0x%02x\n", relocationtype, patchaddr); break; } list++; pbaserelocation = (pimage_base_relocation)((dword)pbaserelocation + pbaserelocation->sizeofblock); } } return 0; }
any appreciated, allthought know knowledge of topic limited.
regards paze.
Comments
Post a Comment