检索.rodata和.rodata1中的偏移量,字符串和虚拟地址

时间:2018-08-19 16:52:09

标签: c linux elf

我正在尝试获取.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 ++代码来检索:

  1. 所有字符串文字的偏移量(例如,上面的10、14、23和“ \ 0 \ 0”缺少的字符串)

  2. 字符串文字(例如上面的“%p \ n”,“ hello wolrd”,“ \ 0 \ 0”)

  3. .rodata文件的偏移量(例如,上面的400600;是否保证是虚拟内存地址?至少我看到上面的测试代码中的所有字符串文字都是这种情况。)< / p>

因为我的最终目标是编写C / C ++代码以读取可执行文件并接受用户输入作为偏移量/虚拟内存地址,如果输入匹配任何字符串文字的偏移量/虚拟内存地址,则使用{ {1}}进行打印。否则,请忽略。 (感谢@Armali帮助我阐明问题)

我已阅读this article。我可以访问printf()中的整个字符串表,但不能访问“字符串表索引”。本文提到“字符串表索引”,但未指定如何检索索引。

提示?

我也不知道为什么会有一个叫做.rodata的部分。根据精灵手册:

  

.rodata1

     

此部分保留通常在过程映像中构成不可写段的只读数据。此部分的类型为SHT_PROGBITS。使用的属性是SHF_ALLOC。

它的描述与.rodata1完全相同。那么,为什么我们有.rodata

谢谢!

2 个答案:

答案 0 :(得分:1)

  

我正在尝试在.rodata和.rodata1部分中获取偏移量,字符串和虚拟地址。

     

我想编写一个C或C ++代码来检索:

     
      
  1. 所有字符串文字的偏移量(例如,上面的10、14、23和“ \ 0 \ 0”缺少的字符串)

  2.   
  3. 字符串文字(例如上面的“%p \ n”,“ hello wolrd”,“ \ 0 \ 0”)

  4.   

字符串文字是用双引号引起来的一系列字符。实际上,我们无法分辨ELF数据节中的字符串文字表示形式。考虑将这些行添加到您的main()

        static const int s = '\0fg\0';
        myprintf((char *)&s);

尽管没有字符串文字,readelf -p .rodata …可能会输出类似e的行。 g。

  [    21]  gf

因此,要真正识别数据节中字符串文字的表示形式,有必要将数据与源代码标记(困难)或汇编代码(可能更容易)相关联。

  

如果.rodata中不存在字符串文字,对我来说是个问题

这很容易发生。考虑:

        static char hello[] = "Hi";
        myprintf(hello);

由于字符串文字用于初始化字符数组(必须可修改),因此它可以进入.data而不是.rodata部分,如readelf -p .data …所示。

  

如果ELF部分包含所有有效的偏移量,为什么不使用它们呢?

有效偏移量不会在任何可方便访问的地方收集,因此出于实际目的,我们可以说 ELF节不包含字符串文字的偏移量/索引 >。


  

我能够访问.rodata中的整个字符串表,但不能访问“字符串表索引”。本文提到“字符串表索引”,但未指定如何检索索引。

字符串表索引.rodata无关,但与 字符串表部分 .strtab

  

此部分包含字符串,最常见的是代表相关名称的字符串   带有符号表条目。

答案 1 :(得分:1)

  

只是一个侧面但相关的问题,您知道.rodata中的前16个字节是什么吗?我注意到它有1 0x1和1 0x2,然后其余的是0x0。

并非总是如此;它仅取决于程序使用什么只读数据。例如,如果我编译示例程序,则字符串%p\n从偏移量4开始,在此之前,我还有1和2(作为16位字),但没有零。进一步查看在.rodata中以

开头的符号
> readelf -s … | grep 400738
    14: 0000000000400738     0 SECTION LOCAL  DEFAULT   14
    59: 0000000000400738     4 OBJECT  GLOBAL DEFAULT   14 _IO_stdin_used

({400738是这里的.rodata起始地址),我得到_IO_stdin_used,它是大小为4的全局对象,听起来像是标准库中的内容。