debugging 从中检索常量字符串值,elf二进制通过变量名使用命令行实用程序?

rlcwz9us  于 2023-04-30  发布在  其他
关注(0)|答案(1)|浏览(100)

考虑以下main.c

#include <stdio.h>

const char greeting[] = "hello world";

int main() {
    printf("%s!\n", greeting);
    return 0;
}

我在Ubuntu中编译了这个:

gcc -g main.c -o main.exe

我想检索变量greeting的值;考虑到它是const,它不会改变,所以应该可以从可执行文件中检索值“hello world”。
基本上,我可以看到二进制文件中的变量名:

$ readelf -p .rodata main.exe | grep hello
  [     8]  hello world

...我可以看到值使用:

$ readelf -s main.exe | grep greeting
    59: 0000000000002008    12 OBJECT  GLOBAL DEFAULT   18 greeting

我可以尝试解析readelf -sreadelf -p的输出以获得我想要的结果(检索名为greeting的变量的值),但我很确定我会搞砸它。
那么,是否存在一些bintools实用程序(或任何命令行程序)的开关组合,它们将执行与下面的伪代码等效的操作:

$ [tool] --get-value-of-variable-name greeting --program=main.exe
"hello world"

或者甚至:

$ [tool] --verbose --get-value-of-variable-name greeting --program=main.exe
The constant value of the variable "greeting" in `main.exe` is:
"hello world"
mccptt67

mccptt671#

是否存在一些bintools实用程序(或任何命令行程序)的开关组合,它们将执行与下面的伪代码等效的操作:
当然可以:

  • 您需要查找符号所在的部分、该部分中的地址以及数据的长度,以及
  • 你需要在文件中找到节本身开始的位置,并且
  • 你需要从文件的右偏移量转储长度字节。

把这些放在一起(我的文件与你的文件的数据略有不同):

readelf -Ws main.exe | grep greeting
    29: 0000000000002008    12 OBJECT  GLOBAL DEFAULT   17 greeting

readelf -WS main.exe | grep '\[17\]'
  [17] .rodata           PROGBITS        0000000000002000 002000 000019 00   A  0   0  8

这告诉我,我需要转储12字节(实际上是11个,因为我不希望终止\0),从偏移量0x2000 + (0x2008 (symbol address) - 0x2000 (section address))开始。

dd if=main.exe bs=1 skip=$((0x2008)) count=11 2>/dev/null
hello world

现在,从readelf输出中解析出这些数据的麻烦比它的价值要大得多--编写一个简单的C++程序来生成所需的输出要容易得多。使用ELFIO应该会使这变得非常容易。

相关问题