Suppose I have function fn
somewhere within the .text
section of an ELF64 executable. Is there a way to know at which offset (in bytes) from the start of the ELF file the fn
function is located? Note that I don't need to know at which VA it was relocated at linking time, but its position within the ELF file.
simply use objdump -F option
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):
Generally yes, if you can parse the ELF file directly or combine output from tools like objdump and readelf.
More specific: You can get the offset and virtual address of your .text section with 'readelf -S file' - write those down. Further you can list symbols with 'readelf -s file', as long your executable is not stripped, and your function is visible (not static or in an anonymous namespace) then you should find your function and the virtual address of it.
Thus you can calculate the offset via
fn symbol offset = fn symbol VA - .text VA + .text offset
Thats assuming you want to do it "offline" with common tools. Its more difficult if you dont have access to the unstripped ELF file, and since only a part of the ELF File remains in memory, probably not possible without adding some information with "offline" tricks.
The answer by Norbert Lange works for the functions that are listed in the symbol table of the ELF file. But static
functions will not be present there, so even if e.g. GDB could find them (by using DWARF debug info), readelf -s
won't.
In this case, you can use GDB. For example, let's find the offset of xfce_displays_helper_normalize_crtc
in /usr/bin/xfsettingsd
(that was my actual use case, thus this obscure choice of an example).
$ 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>
Note that here we only load the file with GDB, don't let it start. And then use p
command (print
in full form) to get the address. So in my case, the function is at offset 0x11e80
.
In some cases GDB will resolve the offset to virtual address even before we start
or starti
the program. This happens, in particular, on x86-32. In this case we can simply subtract the virtual address of the file image, given by 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
In the example above, the virtual address of the file image is 0x8048000
, which would have to be subtracted from virtual address of the function if GDB happens to output it instead of the offset.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With