You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

编译兼具PIC与PIE特性且含外部符号的代码问题求助

实现无GOT依赖的位置独立ARM二进制文件

需求回顾

要生成一个位置独立的ARM二进制文件,满足两个核心要求:

  1. 直接向固定绝对地址0x00001000写入函数指针
  2. 通过文本段内的相对偏移获取目标函数地址,完全不依赖GOT(全局偏移表)

原方案中使用外部符号指定绝对地址、常规编译选项导致函数地址依赖GOT或为绝对地址,无法满足位置独立性要求。

解决方案

1. 修改C代码:硬编码绝对地址+相对偏移计算函数地址

直接在代码中硬编码目标绝对地址,同时利用同一文本段内函数的固定相对偏移,计算出位置无关的函数地址:

// main.c
#include <stdint.h>

// 直接硬编码目标全局内存地址,避免外部符号依赖
#define TARGET_ADDR ((void**)0x00001000)

int some_function(void) {
    return 1;
}

int main(void) {
    // 利用main和some_function的固定相对偏移计算函数地址
    // 同一.text段内的函数相对偏移在编译后固定,不受加载地址影响
    int (*func_ptr)() = (int (*)())((char*)main + ((char*)&some_function - (char*)main));
    
    // 直接写入指定绝对地址
    *TARGET_ADDR = func_ptr;
    return 0;
}

2. 调整编译链接选项

使用以下命令编译,确保生成位置独立且无GOT依赖的二进制:

arm-linux-gnueabi-gcc main.c -Os -nostdlib -nolibc -nodefaultlibs -nostartfiles \
-march=armv5tej -mcpu=arm926ej-s -mthumb -o main \
-Wl,-e,main -Wl,--section-start=.text=0xffff0000 \
-fpie -fno-plt -fno-pic-data-is-text-relative

选项说明:

  • -fpie:生成位置独立的可执行代码,确保指令使用PC相对寻址
  • -fno-plt:禁止生成过程链接表,避免间接函数调用依赖
  • -fno-pic-data-is-text-relative:确保数据引用不强制依赖文本段相对寻址(这里我们直接硬编码绝对地址,不受影响)
  • 保留原有的-nostdlib等选项,避免引入标准库依赖

原理说明

  • 绝对地址写入:通过宏直接硬编码0x00001000,编译器会直接生成存储到该地址的指令,无需通过GOT间接访问
  • 位置无关的函数地址:main和some_function处于同一.text段,编译后两者的相对偏移固定。无论二进制加载到哪个内存地址,通过main的当前地址加上固定偏移,就能准确得到some_function的实际运行地址,完全不需要GOT或动态链接的介入

验证

编译完成后,使用arm-linux-gnueabi-objdump -d main反汇编查看main函数:

  • 会看到计算函数地址的指令使用PC相对偏移或基于main地址的加法操作
  • 写入0x00001000的指令为直接绝对地址访问,无GOT相关的间接引用

内容的提问来源于stack exchange,提问作者TJR

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 05:40:39