能力值:
( LV3,RANK:30 )
|
-
-
26 楼
就当文件加载 是和文件在硬盘上的分布 一样?
|
能力值:
( LV12,RANK:400 )
|
-
-
27 楼
http://bbs.pediy.com/showthread.php?t=147059
本地文件必须存在或者存在内存拷贝否则没有对比的参考
|
能力值:
( LV9,RANK:190 )
|
-
-
28 楼
磁盘上的PE文件和加载到内存的PE是不完全一样的。这个需要你去仔细阅读PE文件格式。最好参考《PE权威指南》
|
能力值:
( LV4,RANK:50 )
|
-
-
29 楼
其实上面exediy等人都说了怎么去验证,只是你自己没动手过,不知道而已。自己RELOAD一份dll然后重定位修改好,crc或者暴力的memcmp都可以的。
重定位函数:
// 重定位
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;
}
|
|
|