基本dll地址总是不同且哈希值不匹配
Base dll address always different and hash mismatch
我编写了一个程序,从加载的进程的dll(模块)中读取X字节,并对它们进行哈希,以将它们与硬编码的干净哈希进行比较。模块的基址总是相同(由不同的人在XP和7上的几台不同的计算机上测试),哈希值也总是相同的。
但是对于一个人来说,基地地址总是不同的,哈希值也总是不同的(每次运行都不同)。他使用的是Windows 7 Ultimate。
我的问题是:
-
为什么模块的基址总是不同的?我知道dll可以在不同的地址加载,但是是什么触发了这种行为?(DLL总是有相同的基址吗?)基址总是0x02XXXXXX类型,而其他人得到的不变地址是0x6F000000。
-
为什么散列不匹配?即使模块在不同的地址加载,我仍然从base+someoffset读取相同数量的字节。不仅哈希值不同,每次运行程序时都不一样。因此,我怀疑基地地址实际上是错误的,一些可疑的事情正在发生。我比较了我的dll和他的dll的md5,它们是相同的,所以正在加载的库是完全相同的。
代码中的步骤:
- 获取进程句柄(
CreateToolhelp32Snapshot
,Process32Next
) - 枚举加载模块(
EnumProcessModules
) - 查找模块名称(
GetModuleFileNameEx
),获取句柄 - 为模块基址添加额外的偏移量(模块内的偏移量)
- 从
ReadProcessMemory(hProcess, base_of_module+some_additional_offset, dllBuffer_to_read_into, 0x100000, &numRead)
模块读取X字节,其中0x100000 不溢出模块大小
这个程序正在做的是将内存中的dll内容与"干净"哈希进行比较,以发现恶意软件/黑客等的篡改
你的方法不可能成功。DLL的基址只是加载程序的指南。加载程序可以选择在该地址加载DLL。如果它这样做,它不需要修复任何绝对引用。
然而,如果请求的地址不可用(进程中的其他东西已经保留了请求的地址范围)或者加载程序选择不使用请求的地址(例如ASLR),那么DLL将被加载到其他地址。然后,重定位表将用于修改绝对引用。
为了使您的哈希计算健壮,您需要考虑重定位。原则上,您可以读取重定位表,并在执行哈希计算时考虑重定位。然而,这可能是非常棘手的正确。
-
配置为在每个进程中加载的其他DLL被加载到该系统上。例如,如果你安装了网络摄像头或鼠标软件,就会发生这种情况,这些软件往往会在每个进程中加载它们的dll。当然,如果这个DLL被加载在一个阻止你的首选基址被使用的地址,你的DLL将被重新定位。
-
搬迁。当加载一个DLL时,加载程序解析.reloc段,并将对绝对地址的修正直接写入加载的DLL映像中。为了创建正确的散列,您还必须读取重定位目录并纠正这些加载器对DLL的修改。
最可能的原因是EMET,即微软的增强缓解体验工具包。
EMET所做的事情之一是强制ASLR(地址空间布局随机化),也就是说,它强制所有dll在随机地址加载,即使它们没有配置为使用ASLR。这大大增加了攻击者利用漏洞的难度。
- C++模板/别名 - 模板参数列表中参数 1 处的类型/值不匹配
- boost::包含提升单元的元组的哈希值
- 错误:"模板<类_Tp,类_Dp>类 std::unique_ptr"的模板参数列表中参数 1 的类型/值不匹配
- 模板参数列表中参数 3 处的类型/值不匹配
- 如何使用 STL 哈希容器中的哈希值检索元素?
- 哈希函数中同一键的不同值和良好的哈希值排序
- 字符串单词的唯一哈希值
- 模板-模板参数给出神秘的类型/值不匹配
- 是否可以将哈希值作为编译时常数
- C++公式与指定值不匹配的结果
- 类模板方法的专用化,类型名称是类模板 - 错误:参数处的类型/值不匹配
- C++ 可变参数模板和模板模板参数:错误:模板参数列表中参数 1 处的类型/值不匹配
- CMake检查下载文件的哈希值(MD5/SHA256)
- 正在将哈希值存储到int
- 如何计算没有标签信息的 mp3 文件的哈希值
- 如何定义函数序列的哈希值(C++)
- 杂音哈希 - 哈希值不一致
- 为什么不同程序执行之间的哈希值不一致
- 基本dll地址总是不同且哈希值不匹配
- HMAC-SHA1不返回期望的哈希值