Reputation: 7912
I need to find the offset of an instruction inside a program. Let's say I wanna find the position of open *system_call* in the program cat.
I used objdump to find the position inside the bin file.
objdump -T /bin/cat | grep open :
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 fdopen
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 open
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 iconv_ope
Unfortunately, analyzing the sible table I cannot retrieve that information because the open function is linked dynamically. The open function is implemented in glibc.
Using the same approach on the Glibc library I retrieved the offset of the open function, though this offset refers to the position inside the /lib/libc.so.6
So this is not useful for me.
00000000000778d0 g DF .text 00000000000004e3 GLIBC_2.2.5 _IO_file_fopen
000000000006be50 g DF .text 000000000000000a GLIBC_2.2.5 fopen
0000000000073540 g DF .text 00000000000000f6 GLIBC_2.4 open_wmemstream
0000000000121cf0 w DF .text 0000000000000107 GLIBC_2.2.5 posix_openpt
000000000006d480 g DF .text 00000000000003bf GLIBC_2.2.5 _IO_proc_open
00000000000e38b0 g DF .text 0000000000000021 GLIBC_2.7 __open64_2
000000000006bfe0 g DF .text 00000000000000fa GLIBC_2.2.5 fopencookie
000000000006d840 g DF .text 0000000000000098 GLIBC_2.2.5 popen
00000000000ddd30 w DF .text 000000000000005e GLIBC_2.2.5 __open64
000000000006be50 g DF .text 000000000000000a GLIBC_2.2.5 _IO_fopen
00000000000de020 w DF .text 0000000000000020 GLIBC_2.7 __openat64_2
00000000000e84d0 g DF .text 0000000000000066 GLIBC_2.2.5 openlog
00000000000ddd30 w DF .text 000000000000005e GLIBC_2.2.5 open64
00000000003aa630 g DO .bss 0000000000000008 GLIBC_PRIVATE _dl_open_hook
00000000000ec840 g DF .text 000000000000005e GLIBC_2.14 open_by_handle_at
0000000000034250 g DF .text 0000000000000254 GLIBC_2.2.5 catopen
000000000006d840 g DF .text 0000000000000098 GLIBC_2.2.5 _IO_popen
0000000000075330 g DF .text 0000000000000355 GLIBC_2.2.5 freopen64
0000000000075eb0 g DF .text 00000000000001d8 GLIBC_2.2.5 fmemopen
00000000000b5b90 w DF .text 000000000000008b GLIBC_2.4 fdopendir
00000000000de020 g DF .text 0000000000000020 GLIBC_2.7 __openat_2
00000000000b5640 w DF .text 000000000000000d GLIBC_2.2.5 opendir
00000000000e3880 g DF .text 0000000000000021 GLIBC_2.7 __open_2
00000000000ddd30 w DF .text 000000000000005e GLIBC_2.2.5 __open
00000000000777f0 g DF .text 00000000000000d2 GLIBC_2.2.5 _IO_file_open
0000000000074370 g DF .text 00000000000000e6 GLIBC_2.2.5 open_memstream
0000000000073ab0 g DF .text 000000000000035d GLIBC_2.2.5 freopen
00000000000345a0 g DF .text 0000000000000837 GLIBC_PRIVATE __open_catalog
00000000000ddd30 w DF .text 000000000000005e GLIBC_2.2.5 open
000000000006b540 g DF .text 0000000000000249 GLIBC_2.2.5 fdopen
0000000000022b20 g DF .text 000000000000020a GLIBC_2.2.5 iconv_open
00000000000e2130 g DF .text 0000000000000373 GLIBC_2.2.5 fts_open
00000000000ddf80 w DF .text 0000000000000092 GLIBC_2.4 openat
000000000006be50 w DF .text 000000000000000a GLIBC_2.2.5 fopen64
00000000000ddf80 w DF .text 0000000000000092 GLIBC_2.4 openat64
0000000000122f30 g DF .text 0000000000000046 GLIBC_PRIVATE __libc_dlopen_mode
00000000000dc650 g DF .text 00000000000000b8 GLIBC_2.2.5 posix_spawn_file_actions_addopen
000000000006b540 g DF .text 0000000000000249 GLIBC_2.2.5 _IO_fdopen
I need the offset to set a tracer when the open function is called by the cat program. If I put a tracer on the Glibc lib I will trace that syscall each time it will be called.
Can you help me? Have I been clear explaining my problem?
Thanks
Upvotes: 0
Views: 662
Reputation: 40347
A debugger with decent dynamic linker integration should handle this for you, resolving the symbolic name at which you wish to set a breakpoint. It can even do this when the library hasn't yet been loaded at the time you attempt to set the breakpoint.
However, be aware that there's not much of a syscall you can trace with a user-mode debugger. You can trace through the little libc stub which might do something such as re-order paramaters between the platform's C calling convention and its often different syscall convention, or implement a deprecated syscall as a wrapper around a new one, but the actual kernel mode implementation can only be traced with a kernel debugger.
You might also be interested in the strace program, which prints out the paramaters and return values of all syscalls. Another thing usefull in some cases is dynamic library interception, for example using LD_PRELOAD.
Upvotes: 1
Reputation: 5083
Use /proc/$PID/maps
to see where a shared object library's segments are loaded in the process memory. E.g.:
# grep libc /proc/$$/maps
7f3243879000-7f3243a2e000 r-xp 00000000 08:01 270246 /lib/x86_64-linux-gnu/libc-2.15.so
7f3243a2e000-7f3243c2d000 ---p 001b5000 08:01 270246 /lib/x86_64-linux-gnu/libc-2.15.so
7f3243c2d000-7f3243c31000 r--p 001b4000 08:01 270246 /lib/x86_64-linux-gnu/libc-2.15.so
7f3243c31000-7f3243c33000 rw-p 001b8000 08:01 270246 /lib/x86_64-linux-gnu/libc-2.15.so
-- so there are 4 segments of libc.so
loaded into the address space of the process, we need an executable one, which is marked r-xp
("Read, no write, eXecute, Private"), its start is at *0x7f3243879000
. You already know how to get relative offset for a symbols, e.g. freopen
from your example is at 000000000000035d
from the start of the executable segment, so in my example the symbol can be found at 7f3243879000 + 35d
= *0x7f324387935d
in the process memory.
Upvotes: 1
Reputation: 129344
Well, cat
itself doesn't contain the open
system call. It lives in glibc.so
. cat
calls the library to make use of the function. That's why when you look inside cat
, there is no open
function in it, it's "undefined" and refers to glibc.so
.
You can of course find where cat
calls open
:
If you search for the symbol open@plt
in the symbol table, that's where it calls open. For example objdump -d
which cat|grep open@plt
shows 0000000000401910 <open@plt>:
, which is where the jump to the glibc function takes place.
I hope this helps.
Upvotes: 3