【发布时间】:2018-08-19 16:52:08
【问题描述】:
我正在尝试获取偏移量/虚拟地址、.rodata 和 .rodata1 部分中的字符串。
例如:
#include <cstdio>
void myprintf(const char* ptr) {
printf("%p\n", ptr);
}
int main() {
myprintf("hello world");
myprintf("\0\0");
myprintf("ab\0cde");
}
上面的程序每个readelf -a的输出都有.rodata:
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[16] .rodata PROGBITS 0000000000400600 00000600
readelf -W -p .rodata 给了我偏移量和相关的 non 空字符串:
String dump of section '.rodata':
[ 10] %p^J
[ 14] hello world
[ 23] ab
[ 26] cde
我想写一段 C 或 C++ 代码来检索:
所有字符串字面量的偏移量(例如上面的 10、14、23 和 "\0\0" 缺少的一个)
字符串字面量(例如上面的“%p\n”、“hello wolrd”、“\0\0”)
.rodata 文件的偏移量(例如上面的 400600;它保证是虚拟内存地址吗?至少我看到上面测试代码中的所有字符串文字都是这种情况。)
因为我的最终目标是编写一个 C/C++ 代码来读取可执行文件并接受用户的输入作为偏移量/虚拟内存地址,如果输入与任何字符串文字的偏移量/虚拟内存地址匹配,则使用 @ 987654328@打印出来。否则,忽略。 (感谢@Armali 帮助我澄清)
我已阅读this article。我可以访问.rodata 中的整个字符串表,但不能访问“字符串表索引”。文章提到了“字符串表索引”,但没有具体说明如何检索索引。
提示?
另外,我想知道为什么会有一个名为.rodata1 的部分。根据精灵手册页:
.rodata1
此部分包含只读数据,这些数据通常构成过程映像中的不可写段。此部分的类型为 SHT_PROGBITS。使用的属性是 SHF_ALLOC。
它的描述与.rodata 完全相同。那么,为什么我们有.rodata1?
谢谢!
【问题讨论】:
-
解析
system("readelf -W -p .rodata")和system("readelf -a | grep .rodata | awk '{print $4}'");的输出还不够吗? -
@KamilCuk 我在网上遇到了来自 readelf -a 的不同输出。所以我认为通过elf.h基于ELF解析更安全。
-
@KamilCuk 我也刚刚发现
readelf -W -p .rodata不输出空字符串的偏移量(例如“\0\0”和“\0”)。因此,我不能使用 readelf。让我更新我的问题。谢谢你的建议! -
是的,
readelf -p的输出确实让我觉得偏移量存储在 elf 中。而readelf source code 相当复杂(见dump_section_as_strings()),这让我觉得我不能只使用\0作为分隔符来解析字符串表。 -
@Armali 你介意用“ELF 部分不包含字符串文字的偏移量/索引”来更新你的答案吗?那么,我会接受你的回答。谢谢。