首页
社区
课程
招聘
[求助]如何校验内存中的dll是否被篡改?
发表于: 2013-7-10 09:40 16545

[求助]如何校验内存中的dll是否被篡改?

2013-7-10 09:40
16545
收藏
免费
支持
分享
最新回复 (28)
雪    币: 275
活跃值: (51)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
26
就当文件加载 是和文件在硬盘上的分布 一样?
2013-8-12 10:43
0
雪    币: 535
活跃值: (245)
能力值: ( LV12,RANK:400 )
在线值:
发帖
回帖
粉丝
27
http://bbs.pediy.com/showthread.php?t=147059
本地文件必须存在或者存在内存拷贝否则没有对比的参考
2013-8-12 11:39
0
雪    币: 267
活跃值: (438)
能力值: ( LV9,RANK:190 )
在线值:
发帖
回帖
粉丝
28
磁盘上的PE文件和加载到内存的PE是不完全一样的。这个需要你去仔细阅读PE文件格式。最好参考《PE权威指南》
2013-8-13 13:11
0
雪    币: 293
活跃值: (287)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
29
其实上面exediy等人都说了怎么去验证,只是你自己没动手过,不知道而已。自己RELOAD一份dll然后重定位修改好,crc或者暴力的memcmp都可以的。
重定位函数:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
// 重定位
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;
}
2013-8-13 15:08
0
游客
登录 | 注册 方可回帖
返回

账号登录
验证码登录

忘记密码?
没有账号?立即免费注册