//
重定位
BOOL RelocAddr(HMODULE hModule /*自己加载dll的基址*/, DWORD CheckDllModuleAddress /*要验证的函数加载基址*/)
{
if
(hModule == NULL)
{
return
false
;
}
PIMAGE_DOS_HEADER Header = (PIMAGE_DOS_HEADER)hModule;
PIMAGE_NT_HEADERS peheader =
(PIMAGE_NT_HEADERS)((DWORD)Header + Header->e_lfanew);
DWORD dwsizeOfImage = peheader->OptionalHeader.SizeOfImage;
//
如果之前用LoadLibrary加载的此dll的话,这里的dwAddress值为LoadLibrary返回的地址
//
如果直接从文件中读取的text段,那么dwAddress值如下
DWORD dwAddress = peheader->OptionalHeader.ImageBase;
if
(dwAddress == (DWORD)hModule)
{
//
加载到理想基址,不需要重定位
return
TRUE;
}
//
PE 头 offset 0x98
pRELOADTABLE reloadaddr = (pRELOADTABLE)
( (DWORD)hModule + peheader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress) ;
if
( (DWORD)reloadaddr < (DWORD)hModule ||
(DWORD)reloadaddr > (DWORD)hModule+dwsizeOfImage )
{
//
不落在这个文件内,重定位表错误
return
false
;
}
//
遍历重定位表
while
( reloadaddr->StartVirtualAddress != NULL )
{
for
(DWORD i=0; i<(reloadaddr->size-8)
/2
; i++)
{
if
( reloadaddr->Table[i].flags == 3 )
{
PDWORD OffsetAddress = (PDWORD)(reloadaddr->Table[i].addr + (DWORD)hModule + reloadaddr->StartVirtualAddress);
//
计算新的偏移量 = 原始值 - 原始加载地址 + 新的加载地址
*OffsetAddress = *OffsetAddress - (DWORD)dwAddress + (DWORD)CheckDllModuleAddress;
}
}
reloadaddr = (pRELOADTABLE) ((DWORD)reloadaddr + reloadaddr->size );
}
return
true
;
}