在项目中,遇到一个问题,就是去除了某个DLL库的 ASLR后,其动态加载的基址仍然会发生变化。
在此记录一下自己的解决思路。
0x1
去除一个程序或者 DLL的 ASLR的方法,根据他人所述和自己的亲自实践。
发现只有 去除 程序和 DLL 库的 PE 文件中 OptionalHeader 头中的 DllCharacteristic 数据中的 0x004 标志位 即可。
网上其余所说的 方法:修改注册表,修改Windows Exploit Protection 等方法,经过尝试都无法去除 ASLR。
0x2
问题就在去除 ASLR之后,某些库的 加载基址仍然 不等于其 PE 文件中的 ImageBase 的值。
后来,经过分析是由于 一个程序在动态加载链接库时,如果动态链接库的加载基址发生了冲突,操作系统就会自动修改 后来的加载库的基址到一个 空闲地址区域中。
也就是 即使我们去除了一个 DLL 的 ASLR之后,该 DLL加载到内存中时 由于其加载基址 已经被其他库文件占用,所以操作系统就会自动为其分配一个空闲空间。这就导致了 这个 DLL 在以后加载时,其加载基址仍然会发生改变,且是任意的。
为了解决这个问题,我们有两种思路:一是将该 DLL 在其基址区域被占用前 加载进内存,这样该文件就可以分配到基址处的内存区域;二是 修改文件的 ImageBase,将文件的加载基址 修改为其他不会被占用的区域。
第一种方法 涉及到 库的链接加载机制,我们无法直接更改。
第二种,我们就可以直接通过修改 PE 文件来实现。
0x3
PE文件中与 加载 基址相关的有数据有 OptionalHeader中的 ImageBase 以及 重定位表中的数据。
所以,我们要修改的地方就是 ImageBase 和 重定位表偏移地址。
相关修改原理 及 方法,就不做具体讲解,网上有详细教程。
放上一篇 参考性很高的教程。
https://github.com/276793422/ReparePE
https://bbs.pediy.com/thread-219232-1.htm