winapi - 不在偏移量 0 处映射 Win32 可移植可执行镜像的可能原因是什么?

标签 winapi mapping executable portability offset

我最近一直在研究 Window 的 PE 格式,我注意到在大多数示例中, 人们倾向于将 optional header 中的 ImageBase 偏移值设置为不合理的值,例如 0x400000

什么会导致在偏移0x0处映射图像不利?

最佳答案

首先,这不是 Windows 或 PE 文件格式的默认设置,当您使用它来链接 EXE 时,它是链接器的/BASE 选项的默认设置。 DLL 的默认值为 0x10000000。

选择/BASE:0 将是一个糟糕的选择,任何程序都不能在该基地址运行。地址空间的前 64 KB 是保留的,永远不能映射。主要是为了捕获空指针取消引用错误。并扩展到 64KB 以捕获以 16 位开始并重新编译为 32 位的程序中的指针错误。

为什么 0x40000 而不是 0x10000 是默认值也是历史事故,并且至少可以追溯到 Windows 95。它为“16 位/MS-DOS 兼容性竞技场”保留了地址空间的前 4 兆字节。我不太记得了,Windows 9x 有一个与 NT 非常不同的 16 位 VM 实现。您可以在这个古老的 KB article 中阅读更多相关信息.现在它肯定不再相关了,64 位操作系统很容易在 0x010000 和 0x400000 之间的空间中分配堆内存。

更改 EXE 的/BASE 选项没有任何意义。但是,很多 有必要将其更改为 DLL。如果它们不重叠并且因此不必重新定位,它们将更加有效,它们不会占用页面文件中的任何空间并且可以在进程之间共享。它甚至有一个 SDK 工具,因此您可以在构建后更改它,rebase.exe

关于winapi - 不在偏移量 0 处映射 Win32 可移植可执行镜像的可能原因是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11833899/

相关文章:

winapi - 为什么 Chrome 在插件失败时不会挂起?

c++ - 内存池和 <Unable to read memory>

mapping - BizTalk 映射问题

ios - RestKit 0.20 忽略 putObject : mapping

c - 二进制文件的相对路径

c++ - 观看来自可执行文件的指令?

c++ - 获取当前目录下的所有文件

c# - 类映射错误 : 'T' must be a non-abstract type with a public parameterless constructor

java - 将我的java项目变成可执行文件

c++ - Directshow 返回错误的帧速率 FPS