怎样摆脱固定代码地址

机器指令访问其他位置时,既可能直接嵌入绝对地址,也可能使用相对位置或间接读取地址。位置无关代码选择适合目标架构的寻址和引用方式,让代码整体搬到另一地址时,不必逐一改写其中所有引用。

外部对象的位置仍可能要到链接或加载时才知道。ELF共享对象可通过全局偏移表等结构间接访问地址,调用也可借助过程链接表。具体指令与表格布局由目标架构的ABI规定,不是所有平台都采用同一套机器序列。

参考:[1] [2]

共享库与可执行程序的构建选项

GCC的-fpic和-fPIC在受支持目标上生成适合共享对象的位置无关代码;二者在某些架构上涉及不同表格容量或代码模型。-fpie和-fPIE则面向位置无关可执行程序,通常还需在链接阶段配合-pie,不能把编译与链接两个步骤混为一谈。

位置无关也不必然意味着依赖动态链接器。GCC另有-static-pie选项,用于支持平台上的静态位置无关可执行文件,使其无需动态链接器便可在不同地址加载。是否支持、需要哪些选项以及怎样处理启动阶段,仍由具体工具链与平台决定。

参考:[1] [3]

仍有重定位,也不自动完成随机化

位置无关代码中的相对位移可以随整体位置保持有效,但数据中保存的指针、外部符号地址或其他引用仍可能需要重定位。把“位置无关”理解成文件里绝无修正项,会误判实际加载过程和文件结构。

地址空间布局随机化由加载策略选择地址;位置无关的表示为这种选择提供便利,却不等于系统一定进行了随机化。它也不是自动加速或自动安全的承诺,间接访问、代码模型、内存权限与程序缺陷仍需分别分析。

参考:[4] [1] [5]