int pe_relocate(vm_offset_t imgbase) { image_section_header sect; image_base_reloc *relhdr; uint16_t rel, *sloc; uint32_t base, delta, *lloc; int i, count; vm_offset_t txt; base = pe_imagebase(imgbase); pe_get_section(imgbase, §, ".text"); txt = pe_translate_addr(imgbase, sect.ish_vaddr); delta = (uint32_t)(txt) - base - sect.ish_vaddr; pe_get_section(imgbase, §, ".reloc"); relhdr = (image_base_reloc *)(imgbase + sect.ish_rawdataaddr); do { count = (relhdr->ibr_blocksize - (sizeof(uint32_t) * 2)) / sizeof(uint16_t); for (i = 0; i < count; i++) { rel = relhdr->ibr_rel[i]; switch (IMR_RELTYPE(rel)) { case IMAGE_REL_BASED_ABSOLUTE: break; case IMAGE_REL_BASED_HIGHLOW: lloc = (uint32_t *)pe_translate_addr(imgbase, relhdr->ibr_vaddr + IMR_RELOFFSET(rel)); *lloc = pe_translate_addr(imgbase, (*lloc - base)); break; case IMAGE_REL_BASED_HIGH: sloc = (uint16_t *)pe_translate_addr(imgbase, relhdr->ibr_vaddr + IMR_RELOFFSET(rel)); *sloc += (delta & 0xFFFF0000) >> 16; break; case IMAGE_REL_BASED_LOW: sloc = (uint16_t *)pe_translate_addr(imgbase, relhdr->ibr_vaddr + IMR_RELOFFSET(rel)); *sloc += (delta & 0xFFFF); break; default: kprintf ("[%d]reloc type: %d\n",i, IMR_RELTYPE(rel)); break; } } relhdr = (image_base_reloc *)((vm_offset_t)relhdr + relhdr->ibr_blocksize); } while (relhdr->ibr_blocksize); return(0); }
BOOL CRemoteLoader::ProcessRelocation( INT ImageBaseDelta, WORD Data, PBYTE RelocationBase ) { BOOL bReturn = TRUE; switch( IMR_RELTYPE( Data ) ) { case IMAGE_REL_BASED_ABSOLUTE: { DebugShout( "[ProcessRelocation] IMAGE_REL_BASED_ABSOLUTE" ); break; } case IMAGE_REL_BASED_HIGH: { SHORT* Raw = reinterpret_cast< SHORT* >( RelocationBase + IMR_RELOFFSET( Data ) ); SHORT Backup = *Raw; *Raw += HIWORD( ImageBaseDelta ); DebugShout( "[ProcessRelocation] IMAGE_REL_BASED_HIGH (0x%X) -> (0x%X)", Backup, *Raw ); break; } case IMAGE_REL_BASED_LOW: { SHORT* Raw = reinterpret_cast< SHORT* >( RelocationBase + IMR_RELOFFSET( Data ) ); SHORT Backup = *Raw; *Raw += LOWORD( ImageBaseDelta ); DebugShout( "[ProcessRelocation] IMAGE_REL_BASED_LOW (0x%X) -> (0x%X)", Backup, *Raw ); break; } case IMAGE_REL_BASED_HIGHLOW: { DWORD32* Raw = reinterpret_cast< DWORD32* >( RelocationBase + IMR_RELOFFSET( Data ) ); DWORD32 Backup = *Raw; *Raw += ImageBaseDelta; DebugShout( "[ProcessRelocation] IMAGE_REL_BASED_HIGHLOW (0x%X) -> (0x%X)", Backup, *Raw ); break; } case IMAGE_REL_BASED_DIR64: { DWORD64* Raw = reinterpret_cast< DWORD64* >( RelocationBase + IMR_RELOFFSET( Data ) ); DWORD64 Backup = *Raw; *Raw += ImageBaseDelta; DebugShout( "[ProcessRelocation] IMAGE_REL_BASED_DIR64 (0x%X) -> (0x%X)", Backup, *Raw ); break; } case IMAGE_REL_BASED_HIGHADJ: { DebugShout( "[ProcessRelocation] IMAGE_REL_BASED_HIGHADJ" ); break; } default: { DebugShout( "[ProcessRelocation] UNKNOWN RELOCATION (0x%X)", IMR_RELTYPE( Data ) ); bReturn = FALSE; break; } } return bReturn; }