0

我需要在程序中找到指令的偏移量。假设我想在程序 cat 中找到 open *system_call* 的位置。

我使用 objdump 来查找 bin 文件中的位置。

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

不幸的是,分析 sible 表我无法检索该信息,因为 open 函数是动态链接的。open 函数在glibc中实现。

在 Glibc 库上使用相同的方法,我检索了 open 函数的偏移量,尽管这个偏移量是指内部的位置/lib/libc.so.6所以这对我没有用。

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

当 cat 程序调用 open 函数时,我需要偏移量来设置跟踪器。如果我在 Glibc 库上放置一个跟踪器,我将在每次调用它时跟踪该系统调用。

你能帮助我吗?我是否清楚地解释了我的问题?

谢谢

4

3 回答 3

3

好吧,cat它本身不包含open系统调用。它住在glibc.so. cat调用库以使用该函数。这就是为什么当你往里看的时候cat,里面没有open函数,它是“未定义的”并且指的是glibc.so.

你当然可以找到 wherecat调用open

如果您在符号表中搜索该符号open@plt,这就是它调用 open 的地方。例如objdump -dwhich cat |grep open@pltshows 0000000000401910 <open@plt>:,这是跳转到 glibc 函数的地方。

我希望这有帮助。

于 2012-12-26T21:41:58.080 回答
1

具有不错的动态链接器集成的调试器应该为您处理此问题,解析您希望设置断点的符号名称。当您尝试设置断点时库尚未加载时,它甚至可以执行此操作。

但是,请注意,您可以使用用户模式调试器跟踪的系统调用并不多。您可以跟踪小 libc 存根,它可能会做一些事情,例如在平台的 C 调用约定与其通常不同的系统调用约定之间重新排序参数,或者实现一个已弃用的系统调用作为新系统调用的包装器,但实际的内核模式实现只能使用内核调试器进行跟踪。

您可能还对 strace 程序感兴趣,它打印出所有系统调用的参数和返回值。在某些情况下有用的另一件事是动态库拦截,例如使用 LD_PRELOAD。

于 2012-12-26T23:16:29.067 回答
1

用于/proc/$PID/maps查看共享对象库的段在进程内存中的加载位置。例如:

# 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

-- 所以有4段libc.so加载到进程的地址空间,我们需要一个可执行的,标记为r-xp(“Read, no write, eXecute, Private”),它的开始是在*0x7f3243879000。您已经知道如何获取符号的相对偏移量,例如freopen,您的示例是000000000000035d从可执行段的开头开始,因此在我的示例中,可以在进程内存中的7f3243879000 + 35d=处找到符号。*0x7f324387935d

于 2012-12-26T21:49:12.950 回答