如何将库定义的符号加载到指定位置?

逆向工程 部件 C 小精灵 动态链接
2021-07-09 00:54:59

测试在 Ubuntu 12.04、32 位、gcc4.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
  1. 似乎我没有成功加载符号stdout@@GLIBC_2.0,而只是一个有线的stdout. (我试着写stdout@@GLIBC_2.0进去symbolfile,但它不能编译...)

  2. 好像是我没弄到,.bsssection的起始地址也变了,这就使得stdoutsymbol的地址在一个非section区。在运行时,从0x804a024.

谁能帮助我如何在预定义的地址成功加载库符号?谢谢!

1个回答

在代码中(或在链接器命令文件中)创建一个内存名称(比如 .stdio)并给它一个特定的地址。然后写一段语句:'.stdio' 并列出 'stdio.text' 将是内存 .stdio 部分中的第一件事。链接器命令文件在 .stdio 部分也可以有一个全局名称,可以从程序中引用。