我创建了一个程序,它从一个进程的加载的dll(模块)中读取X字节并对它们进行哈希处理,以便将它们与硬编码的干净哈希进行比较.模块的基地址始终相同(在XP和7上由不同的人在几台不同的计算机上测试),并且哈希值也始终相同.
但是对于一个人来说,基地址总是不同的,并且哈希值也总是不同的(每次运行时都不同).他正在使用Windows 7旗舰版.
我的问题是:
为什么模块的基地址总是不同?我知道dll可以加载到不同的地址,但是什么触发了这种行为?(DLL总是具有相同的基址吗?)基址始终是0x02XXXXXX类型,而其他人得到的永不改变的地址是0x6F000000.
为什么哈希不匹配?即使模块加载到不同的地址,我仍然从base + someoffset读取相同数量的字节.散列不仅不同,每次运行程序时都不同.因此,我怀疑基地址实际上是错误的,并且有些可疑.我比较了我的dll和他的dll的md5,它们是相同的,所以加载的库是完全相同的.
代码中采取的步骤:
获取进程句柄(CreateToolhelp32Snapshot
,Process32Next
)
枚举加载的模块(EnumProcessModules
)
按名称(GetModuleFileNameEx
)查找特定模块并获取句柄
向模块基址添加额外的偏移量(模块内的偏移量)
阅读X字节从与模块ReadProcessMemory(hProcess, base_of_module+some_additional_offset, dllBuffer_to_read_into, 0x100000, &numRead)
,其中的0x100000并没有溢出模块尺寸
该程序正在做的是将内存中的dll内容与"干净"哈希进行比较,以发现对恶意软件/黑客/等的篡改.
你的方法不可能成功.DLL的基地址只是加载程序的指南.加载程序可以选择在该地址加载DLL.如果它这样做,它不需要修复任何绝对引用.
但是,如果请求的地址不可用(进程中的其他内容已经保留了请求的地址范围)或者加载程序选择不使用请求的地址(例如ASLR),则DLL将被加载到某个其他地址.然后重定位表将用于修改绝对引用.
为了使哈希计算更加健壮,您需要考虑重定位.原则上,您可以读取重定位表,并在执行哈希计算时考虑重定位.但是,要想做到这一点,这可能会非常棘手.