如何将库定义的符号加载到指定的位置?
测试在Ubuntu 12.04,32位, gcc
4.6.3。
基本上我正在对ELF二进制文件进行一些二进制操作工作,我现在要做的是组装一个汇编程序并保证libc符号被我加载到预定义的地址。
让我在一个简单的例子中详细说明。
假设在原始代码中使用了libc符号stdout@GLIBC_2.0
。
#include int main() { FILE* fout = stdout; fprintf( fout, "hello\n" ); }
当我编译它并使用以下命令检查符号地址时:
gcc main.c readelf -s a.out | grep stdout
我懂了:
0804a020 4 OBJECT GLOBAL DEFAULT 25 stdout@GLIBC_2.0 (2) 0804a020 4 OBJECT GLOBAL DEFAULT 25 stdout@@GLIBC_2.0
和.bss
部分是这样的:
readelf -S a.out | grep bss [25] .bss NOBITS 0804a020 001014 00000c 00 WA 0 0 32
现在我要做的是将stdout
符号加载到预定义的地址中,所以我这样做了:
echo "stdout = 0x804a024;" > symbolfile gcc -Wl,--just-symbols=symbolfile main.c
然后,当我检查.bss
部分和符号stdout
,我得到了这个:
[25] .bss NOBITS 0804a014 001014 000008 00 WA 0 0 4 4: 0804a024 0 NOTYPE GLOBAL DEFAULT ABS stdout 49: 0804a024 0 NOTYPE GLOBAL DEFAULT ABS stdout
-
似乎我没有成功加载符号
stdout@@GLIBC_2.0
,而只是一个有线stdout
。 (我试着在symbolfile
stdout@@GLIBC_2.0
中写入stdout@@GLIBC_2.0
symbolfile
,但它无法编译……) -
看来,正如我没有做到的那样,
.bss
部分的起始地址也发生了变化,这使得stdout
符号的地址在非截面区域中。 在运行时,从0x804a024
加载时会引发分段错误。
谁能帮助我如何在预定义的地址成功加载库符号? 谢谢!