测试在Ubuntu 12.04,32位,gcc
4.6.3。
基本上我正在对ELF二进制文件进行一些二进制操作,现在我要做的就是组装一个汇编程序并保证我将libc符号加载到预定义的地址。
让我在一个简单的例子中详细说明。
假设在原始代码中使用了libc符号stdout@GLIBC_2.0
。
#include <stdio.h>
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
。 (我试图在stdout@@GLIBC_2.0
中写symbolfile
,但无法编译......)
似乎我没有成功,.bss
部分的起始地址也发生了变化,这使得stdout
符号的地址位于非剖面区域。在运行时期间,从0x804a024
加载时会引发分段错误。
有人可以帮我解决如何在预定义地址成功加载库符号的问题吗?谢谢!