通过解析 ELF C++程序,将字符串文本的地址映射到字符串文本

map the address of string literal to string literal, by parsing ELF C++ program

本文关键字:文本 字符串 地址映射 程序 ELF C++      更新时间:2023-10-16

字符串文字的地址在编译时确定。此地址和字符串文字可以在构建的可执行程序(ELF 格式(中找到。例如,以下代码输出String Literal: 0x400674

printf("String Literal: %pn", "Hello World");   

objdump -s -j .rodata test1节目

.rodata部分的内容:

400670 01000200 48656c6c 6f20576f 726c6400 ....Hello World。

....

所以看起来我可以通过读取可执行程序本身来获取"Hello World"的虚拟地址。

问题:如何通过读取 ELF 格式在字符串文字的地址和字符串本身之间构建表/映射/字典?

我正在尝试编写一个独立的python脚本或c ++程序来读取elf程序并生成表。如果表中有额外的映射(不是字符串文字(,只要表包含字符串文字的整个映射,就可以了。

我不确定你的问题总是有意义的。详细信息特定于实现(特定于操作系统、编译器和编译标志(。

首先,允许(但不要求(在同一翻译单元中同时看到"abcd""cd"文字字符串的编译器共享其存储并使用"abcd"+2作为第二个。看到这个答案。

然后,在 ELF 文件中,字符串只是初始化的只读数据(通常在文本段的.rodata.text部分中(,它们可能恰好与某些非字符串常量相同。ELF文件不保留任何类型信息(除了用-g编译时作为调试DWARF信息(。换句话说,以下

const uint8_t constable[] = { 0x65, 0x68, 0x6c, 0x6c, 0x6f, 0 };

具有与文本字符串完全相同"hello"机器表示形式,但不是源字符串。更糟糕的是,机器代码的某些部分可能碰巧看起来像字符串。

顺便说一句,您可以使用 strings(1( 命令,或者研究它的源代码并根据您的需要进行调整。

另请参阅dladdr(3(和这个问题。

请记住,两个不同的进程在虚拟内存中具有(根据定义!(不同的地址空间。另请阅读有关 ASLR 的信息。此外,字符串文字也可能出现在共享对象中(例如像libc.so这样的共享库(,这些对象通常在不同的地址段中mmap -ed(因此相同的文字字符串在不同的进程中具有不同的地址!

您可能对 libelf 或 readelf(1( 或 bfd 来读取 ELF 文件感兴趣。