(Windows) 某个程序的基地址永远不会改变

(Windows) Base Address of a some program never changes

我启用了 aslr,当我玩一些叫做 assault cube 的游戏时,这个程序的基址总是相同的 (00400000) 我通过 GetModuleHandle(NULL) 得到它也试图用 windbg 得到它,它也说 00400000 我想知道为什么它永远不会改变,因为对于其他程序它总是改变?

即使您全局启用了 ASLR,Windows 也只会将其应用于明确表示支持它的应用程序。否则很容易使遗留应用程序意外崩溃,从而导致兼容性问题。所有可执行文件和支持 DLL 必须明确表明它们支持 ASLR。

表明您支持 ASLR 是您在通过指定 the /DYNAMICBASE option 链接 object 文件时所做的事情(至少如果您使用的是 Microsoft 的链接器)。现代版本的链接器默认启用它,但如果您的游戏是在默认动态地址重定位支持之前使用旧版本的工具集编译的(例如,VS 2008 和更早版本) 或来自不同供应商的链接器,它很可能没有与 ASLR 支持链接。

这在the relevant MSDN article中被调用(重点添加):

ASLR moves executable images into random locations when a system boots, making it harder for exploit code to operate predictably. For a component to support ASLR, all components that it loads must also support ASLR. For example, if A.exe consumes B.dll and C.dll, all three must support ASLR. By default, Windows Vista and later will randomize system DLLs and EXEs, but DLLs and EXEs created by ISVs must opt in to support ASLR using the /DYNAMICBASE linker option.

另请参阅:Vista ASLR is not on by default for image base addresses


请注意,您可以 修改 现有二进制文件的 PE header,强制其支持 ASLR,通过 运行 editbin SDK 提供的实用程序。与链接器一样,the /dynamicbase switch 将打开它。

或者,您可以通过编辑以下注册表项在全局范围内强制使用 ASLR:

HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management\MoveImages

当然,这些都不会真正改变代码,所以如果存在兼容性问题,应用程序就会崩溃。