我创建了一个程序,它从进程的加载dll(模块)中读取X字节并对它们进行哈希处理,以将它们与硬编码的干净哈希进行比较。该模块的基地址始终相同(在XP和7上由不同的人在几台不同的计算机上测试),并且哈希值也始终相同。
但是对于一个人来说,基地址总是不同的,并且哈希值也总是不同的(每次运行时都不同)。他正在使用Windows 7 Ultimate。
我的问题是:
为什么模块的基地址总是不同?我知道dll可以加载到不同的地址,但是什么触发了这种行为? (Is DLL always have the same Base Address?)基址始终是0x02XXXXXX类型,而其他人获得的永不改变的地址是0x6F000000。
为什么哈希不匹配?即使模块加载到不同的地址,我仍然从base + someoffset读取相同数量的字节。哈希不仅不同,每次运行程序时都不同。因此,我怀疑基地址实际上是错误的,并且有些可疑。我比较了我的dd和他的dll的md5,它们是相同的,因此加载的库是完全相同的。
代码中采取的步骤:
CreateToolhelp32Snapshot
,Process32Next
)EnumProcessModules
)GetModuleFileNameEx
)查找特定模块并获取句柄ReadProcessMemory(hProcess, base_of_module+some_additional_offset, dllBuffer_to_read_into, 0x100000, &numRead)
从模块中读取X字节,其中0x100000 不溢出模块大小这个程序正在做的是将内存中的dll内容与“干净”哈希进行比较,以发现对恶意软件/黑客/等的篡改。
答案 0 :(得分:6)
你的方法无法成功。 DLL的基地址只是加载程序的指南。加载程序可以选择在该地址加载DLL。如果它这样做,它不需要修复任何绝对引用。
但是,如果请求的地址不可用(进程中的其他内容已经保留了请求的地址范围)或者加载程序选择不使用请求的地址(例如ASLR),那么DLL将被加载到某些地址其他地址。然后重定位表将用于修改绝对引用。
为了使哈希计算更加健壮,您需要考虑重定位。原则上,您可以读取重定位表,并在执行哈希计算时考虑重定位。但是,要想做到这一点可能会非常棘手。
答案 1 :(得分:2)
在该系统上加载了一些其他DLL,配置为在每个进程中加载。这可以是例如如果您安装网络摄像头或鼠标软件,这些往往会强制他们的DLL在每个进程中加载。当然,如果将此DLL加载到阻止您使用首选基址的地址,则会重新定位您的DLL。
重定位。加载DLL时,加载程序会解析.reloc部分,并将对绝对地址的更正直接写入加载的DLL映像。为了创建正确的哈希,您还必须读取重定位目录并更正DLL的这些加载器修改。
答案 2 :(得分:0)
最可能的原因是EMET,即Microsoft的增强型缓解体验工具包。
EMET所做的一件事就是强制执行ASLR(地址空间布局随机化),即强制所有DLL在随机地址加载,即使它们没有配置为使用ASLR。这使攻击者更难以利用漏洞。