简体   繁体   English

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

[英]Base dll address always different and hash mismatch

I made a program that reads X bytes from a loaded dll (module) of a process and hashes them to compare them to a clean hash which is hardcoded. 我编写了一个程序,该程序从进程的已加载dll(模块)中读取X个字节,并对其进行哈希处理以将它们与经过硬编码的干净哈希进行比较。 The base address of the module is always the same (tested at a few different computers by different people on XP and 7) and the hash is also always the same. 模块的基址始终是相同的(在XP和7上由不同的人在几台不同的计算机上进行了测试),哈希值也始终相同。

But for one person the base address is always different and the hash is also always different (different on every run). 但是对于一个人来说,基址总是不同的,并且哈希值也总是不同的(每次运行都不同)。 He is using Windows 7 Ultimate. 他正在使用Windows 7 Ultimate。

My questions are: 我的问题是:

  1. Why would the base address of the module always be different? 为什么模块的基址总是不同的? I know that dlls can be loaded at different addresses but what triggers this behavior? 我知道dll可以加载到不同的地址,但是什么触发了此行为? ( Is DLL always have the same Base Address? ) The base address is always of type 0x02XXXXXX while the never-changing address everyone else gets is 0x6F000000. DLL是否始终具有相同的基址? )基址始终为0x02XXXXXX类型,而其他所有人获得的永不变地址为0x6F000000。

  2. Why does the hash mismatch? 为什么哈希不匹配? Even if the module is loaded at different address, I still read the same number of bytes from base+someoffset. 即使模块加载到不同的地址,我仍然从base + someoffset读取相同数量的字节。 Not only is the hash different, it is different everytime you run the program . 哈希不仅有所不同, 而且每次运行该程序都不同 Because of this I suspect that the base address is actually wrong and something fishy is going on. 因此,我怀疑基址实际上是错误的,并且有些混乱。 I compared the md5 of my dll and his dll and they are the same so the library being loaded is defenetly identical. 我比较了我的dll和他的dll的md5,它们是相同的,因此要加载的库在外观上完全相同。

The steps taken in the code: 代码中采取的步骤:

  1. Get a process handle ( CreateToolhelp32Snapshot , Process32Next ) 获取流程句柄( CreateToolhelp32SnapshotProcess32Next
  2. Enumerate the loaded modules ( EnumProcessModules ) 枚举已加载的模块( EnumProcessModules
  3. Find the specific module by name ( GetModuleFileNameEx ) and get the handle 通过名称找到特定的模块( GetModuleFileNameEx )并获取句柄
  4. Add an additional offset to the module base address (offset within a module) 向模块基地址添加一个额外的偏移量(模块内的偏移量)
  5. Read X bytes from the module with ReadProcessMemory(hProcess, base_of_module+some_additional_offset, dllBuffer_to_read_into, 0x100000, &numRead) where 0x100000 does not overflow the module size 读X字节从与模块ReadProcessMemory(hProcess, base_of_module+some_additional_offset, dllBuffer_to_read_into, 0x100000, &numRead)其中的0x100000 溢出模块尺寸

What this program is doing is comparing the in-memory dll content against a "clean" hash to discover tampering from malware/hacks/etc. 该程序正在做的是将内存中的dll内容与“干净的”哈希进行比较,以发现恶意软件/黑客/等等的篡改。

Your approach cannot hope to succeed. 您的方法不能希望成功。 The base address of a DLL is only a guide to the loader. DLL的基地址仅是加载程序的指南。 The loader may choose to load the DLL at that address. 加载程序可以选择在该地址加载DLL。 And if it does so it does not need to fix up any absolute references. 如果这样做的话,就不需要修复任何绝对引用。

However, if the requested address is not available (something else in the process has already reserved the requested address range) or the loader chooses not to use the requested address (ASLR for instance), then the DLL will be loaded at some other address. 但是,如果请求的地址不可用(该进程中的其他内容已经保留了请求的地址范围),或者加载程序选择不使用请求的地址(例如ASLR),则DLL将在其他某个地址加载。 And then the relocation table will be used to modify absolute references. 然后,重定位表将用于修改绝对引用。

In order for your hash calculation to be robust, you would need to account for the relocations. 为了使哈希计算更可靠,您需要考虑重定位。 You could, in principle, read the relocation table, and account for the relocations when performing the hash calculation. 原则上,您可以读取重定位表,并在执行哈希计算时考虑重定位。 However, that is likely to be very tricky to get right. 但是,这可能很棘手。

  1. Some other DLL, configured to load in every process, is loaded on that system. 配置为在每个进程中加载​​的其他一些DLL被加载到该系统上。 This can eg happen if you install webcam or mouse software, these tend to force their DLLs to be loaded in every process. 例如,如果您安装了网络摄像头或鼠标软件,则会发生这种情况,这些趋向于迫使它们的DLL在每个进程中加载​​。 Of course, if this DLL is loaded at an address preventing your preferred base address from being used, your DLL will be relocated. 当然,如果将此DLL加载到阻止使用您首选的基地址的地址,则DLL将被重定位。

  2. Relocations. 搬迁。 When a DLL is loaded, the .reloc section is parsed by the loader, and corrections to absolute addresses are written directly to the loaded DLL image. 加载DLL时,加载程序将解析.reloc节,并将对绝对地址的更正直接写入到加载的DLL映像中。 In order to create a correct hash, you must also read the relocation directory and correct for these loader modifications of the DLL. 为了创建正确的哈希,还必须读取重定位目录并更正这些DLL的加载程序修改。

The most likely cause is EMET , the Enhanced Mitigation Experience Toolkit from Microsoft. 最可能的原因是EMET (Microsoft的增强缓解经验工具包)​​。

One of the things EMET does is to enforce ASLR (Address Space Layout Randomization), ie, it forces all DLLs to be loaded at random addresses, even if they aren't configured to use ASLR. EMET要做的一件事是强制执行A​​SLR(地址空间布局随机化),即,即使未将其配置为使用ASLR,它也会强制将所有DLL加载到随机地址。 This make it considerably more difficult for an attacker to exploit vulnerabilities. 这使攻击者利用漏洞变得更加困难。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM