基本DLL地址始终不同并且哈希不匹配

cen*_*cen 1 c++ dll winapi

我创建了一个程序,它从一个进程的加载的dll(模块)中读取X字节并对它们进行哈希处理,以便将它们与硬编码的干净哈希进行比较.模块的基地址始终相同(在XP和7上由不同的人在几台不同的计算机上测试),并且哈希值也始终相同.

但是对于一个人来说,基地址总是不同的,并且哈希值也总是不同的(每次运行时都不同).他正在使用Windows 7旗舰版.

我的问题是:

  1. 为什么模块的基地址总是不同?我知道dll可以加载到不同的地址,但是什么触发了这种行为?(DLL总是具有相同的基址吗?)基址始终是0x02XXXXXX类型,而其他人得到的永不改变的地址是0x6F000000.

  2. 为什么哈希不匹配?即使模块加载到不同的地址,我仍然从base + someoffset读取相同数量的字节.散列不仅不同,每次运行程序时都不同.因此,我怀疑基地址实际上是错误的,并且有些可疑.我比较了我的dll和他的dll的md5,它们是相同的,所以加载的库是完全相同的.

代码中采取的步骤:

  1. 获取进程句柄(CreateToolhelp32Snapshot,Process32Next)
  2. 枚举加载的模块(EnumProcessModules)
  3. 按名称(GetModuleFileNameEx)查找特定模块并获取句柄
  4. 向模块基址添加额外的偏移量(模块内的偏移量)
  5. 阅读X字节从与模块ReadProcessMemory(hProcess, base_of_module+some_additional_offset, dllBuffer_to_read_into, 0x100000, &numRead),其中的0x100000并没有溢出模块尺寸

该程序正在做的是将内存中的dll内容与"干净"哈希进行比较,以发现对恶意软件/黑客/等的篡改.

Dav*_*nan 6

你的方法不可能成功.DLL的基地址只是加载程序的指南.加载程序可以选择在该地址加载DLL.如果它这样做,它不需要修复任何绝对引用.

但是,如果请求的地址不可用(进程中的其他内容已经保留了请求的地址范围)或者加载程序选择不使用请求的地址(例如ASLR),则DLL将被加载到某个其他地址.然后重定位表将用于修改绝对引用.

为了使哈希计算更加健壮,您需要考虑重定位.原则上,您可以读取重定位表,并在执行哈希计算时考虑重定位.但是,要想做到这一点,这可能会非常棘手.