在ELF中查找函数的起始偏移量

时间:2016-10-25 10:18:00

标签: function executable elf disassembly relocation

假设我在ELF64可执行文件的fn部分中的某个地方有函数.text。有没有办法知道fn函数所在的ELF文件开头的偏移量(以字节为单位)?请注意,我不需要知道它在链接时重新定位的VA,而是它在ELF文件中的位置。

3 个答案:

答案 0 :(得分:6)

通常是的,如果您可以直接解析ELF文件或组合来自objdump和readelf等工具的输出。

更具体:您可以使用'readelf -S 文件'获取.text部分的偏移量和虚拟地址 - 将其写下来。 此外,您可以使用'readelf -s 文件'列出符号,只要您的可执行文件未被删除,并且您的函数是可见的(不是静态的或在匿名命名空间中),那么您应该找到您的函数和它的虚拟地址。

因此,您可以通过

计算偏移量
  

fn symbol offset = fn symbol VA - .text VA + .text offset

多数民众赞成假设您希望使用常用工具“离线”。如果您无法访问未经剥离的ELF文件,并且由于只有部分ELF文件保留在内存中,如果不使用“离线”技巧添加一些信息,则可能无法实现。

答案 1 :(得分:1)

只需使用 objdump -F 选项

user@phoenix-amd64:~$ objdump -D -F /opt/phoenix/i486/heap-xxx -D | grep main
08048630 <__libc_start_main@plt> (File Offset: 0x630):
8048679:       e8 b2 ff ff ff          call   8048630 <__libc_start_main@plt> (File 
Offset: 0x630)
080487d5 <main> (File Offset: 0x7d5):

答案 2 :(得分:0)

answer by Norbert Lange适用于ELF文件的符号表中列出的功能。但是static函数不会在那里出现,即使例如GDB可以找到它们(通过使用DWARF调试信息),readelf -s找不到。

在这种情况下,您可以使用GDB。例如,让我们在xfce_displays_helper_normalize_crtc中找到/usr/bin/xfsettingsd的偏移量(这是我的实际用例,因此示例的这种晦涩的选择)。

$ gdb -q -ex 'p &xfce_displays_helper_normalize_crtc' -ex q xfsettingsd
Reading symbols from xfsettingsd...
Reading symbols from /usr/lib/debug/.build-id/b2/2ad9713642253d4d7a6f94acf0174ccfe3d487.debug...
$1 = (void (*)(XfceRRCrtc *, XfceDisplaysHelper *)) 0x11e80 <xfce_displays_helper_normalize_crtc>

请注意,此处我们仅使用GDB加载文件,请勿让其启动。然后使用p命令(完整格式print)获取地址。因此,就我而言,该函数的偏移量为0x11e80

在某些情况下,甚至在我们执行startstarti程序之前,GDB都会将偏移量解析为虚拟地址。这种情况尤其发生在x86-32上。在这种情况下,我们可以简单地减去readelf -l给出的文件映像的虚拟地址:

$ readelf -l /bin/sleep | grep ' VirtAddr \|\<LOAD *0x[0-9a-f]\+\>'
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x000000 0x08048000 0x08048000 0x05230 0x05230 R E 0x1000

在上面的示例中,文件映像的虚拟地址为0x8048000,如果GDB恰巧输出了该函数而不是偏移量,则必须从函数的虚拟地址中减去它。