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

时间:2015-02-20 05:08:01

标签: c++ elf

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

printf("String Literal: %p\n", "Hello World");   

objdump -s -j .rodata test1显示

部分内容.rodata:

400670 01000200 48 656c6c 6f20576f 726c6400 .... H ello World。

...

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

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

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

1 个答案:

答案 0 :(得分:2)

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

首先,允许(但不要求)在同一翻译单元中同时看到"abcd""cd"个文字字符串的编译器共享其存储空间并使用"abcd"+2作为第二个存储库。请参阅this answer

然后,在ELF个文件中,字符串只是初始化的只读数据(通常位于text segment.rodata.text部分),它们可能会发生与一些非字符串常量相同。 ELF文件在使用-g编译时不保留任何键入信息(调试DWARF信息除外)。换句话说,以下

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

"hello"文字字符串完全相同,但不是源字符串。更糟糕的是,机器代码的某些部分可能看起来像字符串。

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

另请参阅dladdr(3)this question

请记住,processes中有两个不同的address spaces(根据定义!)不同virtual memory。另请阅读ASLR。字符串文字也可能出现在共享对象中(例如像libc.so这样的共享库),它们通常在不同的地址段中mmap(因此相同的文字字符串在不同的进程中会有不同的地址!)。 / p>

您可能会对libelfreadelf(1)bfd感兴趣,以阅读ELF文件。