ELF文件 - 获取字符串使用的函数

3

我有一个elf文件,想知道是否可能获取关于变量(字符串)在可执行文件中使用情况的一些信息。

如果我打印出.elf文件中的字符串,我会找到一个有趣的字符串,我想知道它在哪个函数中被使用了,这是否有可能?

谢谢!

1个回答

5

让我们考虑下面的示例:

test.c

#include <stdlib.h>
#include <stdio.h>

int
main(int argc, char *argv[])
{
    char *str_a = "a";
    char *str_abc = "abc";

    printf("%s\n", str_a);
    printf("%s\n", str_abc);

    exit(EXIT_SUCCESS);
}

让我们编译它:gcc -Wall -pedantic-errors -o ~/test ~/test.c

这将生成名为test的文件。

让我们检查.rodata部分:readelf -x .rodata ./test

输出如下:

Hex dump of section '.rodata':
  0x00400610 01000200 61006162 6300              ....a.abc.

起始地址为0x00400610。在第一个字符串常量之前显示了四个点,因此字符串a的地址将是0x00400614。跳过a和空字节(分隔符)跳过2字节,abc的地址将是0x00400616。 因此,现在已知这两个地址。
接下来,让我们执行objdump -M intel -d ./test
这是.text部分中main的清单:

    0000000000400546 <main>:
      400546:   55                      push   rbp
      400547:   48 89 e5                mov    rbp,rsp
      40054a:   48 83 ec 20             sub    rsp,0x20
      40054e:   89 7d ec                mov    DWORD PTR [rbp-0x14],edi
      400551:   48 89 75 e0             mov    QWORD PTR [rbp-0x20],rsi
      400555:   48 c7 45 f8 14 06 40    mov    QWORD PTR [rbp-0x8],<b>0x400614</b>
      40055c:   00 
      40055d:   48 c7 45 f0 16 06 40    mov    QWORD PTR [rbp-0x10],<b>0x400616</b>
      400564:   00 
      400565:   48 8b 45 f8             mov    rax,QWORD PTR [rbp-0x8]
      400569:   48 89 c7                mov    rdi,rax
      40056c:   e8 9f fe ff ff          call   400410 <puts@plt>
      400571:   48 8b 45 f0             mov    rax,QWORD PTR [rbp-0x10]
      400575:   48 89 c7                mov    rdi,rax
      400578:   e8 93 fe ff ff          call   400410 <puts@plt>
      40057d:   bf 00 00 00 00          mov    edi,0x0
      400582:   e8 b9 fe ff ff          call   400440 <exit@plt>
      400587:   66 0f 1f 84 00 00 00    nop    WORD PTR [rax+rax*1+0x0]
      40058e:   00 00

从列表中可以清楚地看出这两个字符串如何放在屏幕上。列表中提到了上面找到的两个地址 - 它们被突出显示。

因此,总的来说,您可以检查.rodata部分,找到特定字符串的位置地址,然后只需在.text部分中搜索找到的地址。


多好的答案! 我现在已经得到了我的字符串地址,这很好。 如果我尝试读取.text部分,似乎我没有对内存的绝对引用。例如输出:14045fc4: 40 1e 00 18 bne cr7,14045fdc <_init+0x19a4c> 所以我需要知道例如“_init”位于哪个地址。但是有成千上万的相对地址。即使有这个参考,是否有一种优雅的方法来找到它呢? - Manuel
这是不可能的吗?因为文件被剥夺得太多,所以无法深入挖掘?如果可能的话,我想要达到以下目标:找出函数的位置。获取函数的参数。读取从程序中调用的参数,并最终更改参数以使用不同的参数调用函数。这是否有可能实现,还是只是一个梦想呢? ;) - Manuel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接