假设我在ELF64可执行文件的fn
部分中的某个地方有函数.text
。有没有办法知道fn
函数所在的ELF文件开头的偏移量(以字节为单位)?请注意,我不需要知道它在链接时重新定位的VA,而是它在ELF文件中的位置。
答案 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
。
在某些情况下,甚至在我们执行start
或starti
程序之前,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恰巧输出了该函数而不是偏移量,则必须从函数的虚拟地址中减去它。