字符串文字的地址在编译时确定。可以在构建的可执行程序(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程序并生成表格。只要表包含字符串文字的整个映射,如果表中有额外的映射(不是字符串文字),则没有问题。
答案 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>
您可能会对libelf或readelf(1)或bfd感兴趣,以阅读ELF文件。