从ELF二进制文件

时间:2016-03-19 17:00:41

标签: python reverse-engineering elf

我想写一个python脚本,它从elf二进制文件中提取一个函数操作码,知道它的地址,例如0x437310和size。如何将此地址映射到二进制文件中的相应偏移量以开始从中读取?

使用十六进制编辑器,我可以计算出0x437310处的函数从hexdump中的偏移量0x37310处开始。

如何以通用方式计算,因为二进制的图像库并不总是相同。

任何帮助将不胜感激

1 个答案:

答案 0 :(得分:0)

假设我想从maybe_make_export_env中提取bash的说明。

您要做的第一件事是在符号表中找到此符号:

$ readelf -s /bin/bash
   Num:    Value          Size Type    Bind   Vis      Ndx Name
[...]
   216: 000000000043ed80    18 FUNC    GLOBAL DEFAULT   14 maybe_make_export_env
[...]

这为我们提供了在内存中(0x43ed80)及其长度(18)的函数地址。

我们在(虚拟)内存中有地址(在过程映像中)。我们现在想在文件中找到相关地址。为此,我们需要查看程序头表:

$ readelf -l /bin/bash
Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  PHDR           0x0000000000000040 0x0000000000400040 0x0000000000400040
                 0x00000000000001f8 0x00000000000001f8  R E    8
  INTERP         0x0000000000000238 0x0000000000400238 0x0000000000400238
                 0x000000000000001c 0x000000000000001c  R      1
      [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
  LOAD           0x0000000000000000 0x0000000000400000 0x0000000000400000
                 0x00000000000f3ad4 0x00000000000f3ad4  R E    200000
  LOAD           0x00000000000f3de0 0x00000000006f3de0 0x00000000006f3de0
                 0x0000000000008ea8 0x000000000000ea78  RW     200000
  DYNAMIC        0x00000000000f3df8 0x00000000006f3df8 0x00000000006f3df8
                 0x0000000000000200 0x0000000000000200  RW     8
  NOTE           0x0000000000000254 0x0000000000400254 0x0000000000400254
                 0x0000000000000044 0x0000000000000044  R      4
  GNU_EH_FRAME   0x00000000000d8ab0 0x00000000004d8ab0 0x00000000004d8ab0
                 0x0000000000004094 0x0000000000004094  R      4
  GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x0000000000000000 0x0000000000000000  RW     10
  GNU_RELRO      0x00000000000f3de0 0x00000000006f3de0 0x00000000006f3de0
                 0x0000000000000220 0x0000000000000220  R      1

我们希望找到此地址所属的PT_LOAD条目(基于VirtAddrMemSize)。第一个PT_LOAD条目范围从0x4000000x400000 + 0xf3ad4 = 0x4f3ad4(已排除),因此该符号属于此PT_LOAD条目。

我们无法在文件中找到偏移symbol_value - VirtAddr + Offset = 0x3ed80

这是文件的相关部分:

0003ed80: 8b05 3260 2b00 85c0 7406 e911 feff ff90  ..2`+...t.......
0003ed90: f3c3 0f1f 4000 662e 0f1f 8400 0000 0000  ....@.f.........

我们确实具有与objdump -d /bin/bash给出的字节相同的字节:

000000000043ed80 <maybe_make_export_env@@Base>:
  43ed80:       8b 05 32 60 2b 00       mov    0x2b6032(%rip),%eax        # 6f4db8 <array_needs_making@@Base>
  43ed86:       85 c0                   test   %eax,%eax
  43ed88:       74 06                   je     43ed90 <maybe_make_export_env@@Base+0x10>
  43ed8a:       e9 11 fe ff ff          jmpq   43eba0 <bind_global_variable@@Base+0x60>
  43ed8f:       90                      nop
  43ed90:       f3 c3                   repz retq 
  43ed92:       0f 1f 40 00             nopl   0x0(%rax)
  43ed96:       66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)
  43ed9d:       00 00 00