1

我可以手动插入 PE 文件的 ImageBase 值吗?

基本上.. DLL的ImageBase = 10000000 EXE的ImageBase = 00400000

如果可以,我想将 ImageBase 更改为随机地址。我想知道怎么做。

4

2 回答 2

3

您可以轻松更改基地址并防止 Windows 将可执行模块重定位到随机基址。我要强调的是,如果您可以访问构建环境,您应该更喜欢指定基地址并防止在构建时将 DYNAMICBASE 标志放在模块中,从而允许链接器进行适当的优化。要使用 MSVC 执行此操作,您需要指定链接器标志:

/BASE:400000
/DYNAMICBASE:NO

在可以完成之后更改图像库,并且适用于简单模块,但在某些情况下可能会导致崩溃,具体取决于代码的生成方式。有时,当一个人无法访问原始源代码时,别无选择。

代码和数据访问可能会基于与之链接的原始 ImageBase 对值进行硬编码。如果您想在构建模块后对其进行修改,请继续阅读。

虽然在 Windows Vista 中引入了地址空间布局随机化 (ASLR) 行为,但此处建议的修改将适用于任何版本的 Windows。

注意:前面的声明假设微软在未来不会开始随机化图像基地址而不考虑标头中的相关 PE 标志,或者完全拒绝加载这些模块。从当前版本的 Windows 10 开始,Windows 当前支持不包含 IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE 标志的图像,从而防止动态重定位。

使用十六进制编辑器、MSVC 的 editbin 之类的工具,甚至您自己的代码,应对所需模块的 PE 标头进行以下修改,以设置 FIXED 基本加载地址:

-set desired IMAGE_OPTIONAL_HEADER -> ImageBase (e.g. 0x400000)
    i.e. editbin.exe /rebase:base=0x400000 <YOUR_MODULE>

-remove the the 0x0040 (DYNAMIC_BASE) bit from the IMAGE_OPTIONAL_HEADER -> DllCharacteristics flags or use editbin:
    i.e.: editbin /dynamicbase:no <YOUR_MODULE>

-if not using editbin, you will need to recalculate the header checksum or just leave at zero for any non-driver or start-up Windows service; editbin updates the checksum automatically.

注意: - 手动更改模块的基地址可能需要您遍历 .reloc 部分条目并静态或在运行时为您的新基地址执行手动修复(模拟 Windows 加载程序所做的事情);不这样做可能会导致崩溃。为避免这种麻烦,只需删除 DYNAMIC_BASE 标志并保留与构建模块时相同的基地址。然后你仍然阻止 ASLR,即使原始基地址没有改变。

-editbin 版本必须来自 MSVC 2005 SP1 (8.0.50727.161) 以支持 /dynamicbase 参数;MSVC C++ 工具集的 editbin 的任何免费现代版本都将具有此功能;我的经验是 /rebase 选项可能会报告神秘的“LNK1175:rebase 失败;错误 487”,即使对于没有 .reloc 部分的模块也是如此 - 这最终会迫使您使用 PE 编辑器来更改 ImgBase。

- 上述更改可能会破坏嵌入式数字签名检查或验证原始文件完整性的任何内容,因为我们已对其进行了修改。

于 2018-07-29T21:24:43.970 回答
0

据我记得,Windows PE loader 决定基本加载地址(您的问题中的 ImageBase),除非您自己编写 PE loader,否则您无法手动选择它。

从 Windows Vista 开始,Windows 使用地址随机化器来选择随机的基本加载地址。所以它不再像 0x10000000 或 0x00400000 了,它在每次运行时都会发生变化,除非进程在调试模式等特殊情况下启动。

于 2018-07-21T19:20:59.493 回答