在elf二进制文件中,是否有任何简单的方法可从offset获取内存地址?

时间:2019-02-25 13:16:39

标签: linux binary hex elf

在elf二进制文件中,假设我知道二进制文件的偏移量。
在那种情况下,我怎么知道偏移量区域的虚拟地址?
更详细地,这里是二进制my_binary
...我发现数据"the_key_string"位于二进制文件0x204的偏移量中。
在这种情况下,0x204在加载到内存时会映射到0x0804204中。

问题:
0x0804204获取地址信息0x204最简单的方法是什么?
您能否向我推荐工具中的任何有用的快捷方式(010editorhxd ..)
...或者我可以结合objdump命令来做到这一点?

1 个答案:

答案 0 :(得分:0)

ELF程序具有程序头,该头列出了PT_LOAD段(struct Elf32_Phdrstruct Elf64_Phdr)。它们既具有文件偏移量和长度(p_offsetp_filesz成员)又具有虚拟地址和长度(p_vaddrp_memsz)。关键是,文件偏移量和长度所标识的区域将在运行时在指定的虚拟地址处变为可用。虚拟地址是相对于内存中对象的基址的。

您可以使用readelf -l查看程序标题:

Elf file type is DYN (Shared object file)
Entry point 0x1670
There are 9 program headers, starting at offset 64

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  PHDR           0x0000000000000040 0x0000000000000040 0x0000000000000040
                 0x00000000000001f8 0x00000000000001f8  R E    0x8
  INTERP         0x0000000000000238 0x0000000000000238 0x0000000000000238
                 0x000000000000001c 0x000000000000001c  R      0x1
      [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
  LOAD           0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x000000000000627c 0x000000000000627c  R E    0x200000
  LOAD           0x0000000000006d68 0x0000000000206d68 0x0000000000206d68
                 0x00000000000004b8 0x0000000000000658  RW     0x200000
…

在这种情况下,有两个负载段,一个可读和可执行(程序代码),一个可读和可写(数据和重定位)。

并非二进制文件的所有部分都被PT_LOAD段覆盖,因此加载程序在运行时将其映射。如果数据在未分配的节中,则它将仅不在内存中(除非您通过其他方式从磁盘读取数据)。

但是,如果分配了数据,则它将属于装入段之一,一旦有了基地址,就可以使用装入段中的信息来根据文件偏移量计算虚拟地址。