简体   繁体   中英

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. 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.

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.

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? ( 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.

  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. 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.

The steps taken in the code:

  1. Get a process handle ( CreateToolhelp32Snapshot , Process32Next )
  2. Enumerate the loaded modules ( EnumProcessModules )
  3. Find the specific module by name ( GetModuleFileNameEx ) and get the handle
  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

What this program is doing is comparing the in-memory dll content against a "clean" hash to discover tampering from malware/hacks/etc.

Your approach cannot hope to succeed. The base address of a DLL is only a guide to the loader. The loader may choose to load the DLL at that address. 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. 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. This can eg happen if you install webcam or mouse software, these tend to force their DLLs to be loaded in every process. Of course, if this DLL is loaded at an address preventing your preferred base address from being used, your DLL will be relocated.

  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. In order to create a correct hash, you must also read the relocation directory and correct for these loader modifications of the DLL.

The most likely cause is EMET , the Enhanced Mitigation Experience Toolkit from 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. This make it considerably more difficult for an attacker to exploit vulnerabilities.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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