查看共享库中是否调用了函数

find out if a function is called in a shared library

我一直在使用 Anthony Shoumikhin's elfhook utility 重定向共享库中的某些函数调用。

作为概念证明,我创建了一个共享库,它从 posix 套接字 api.

调用各种函数
void TestAPI::work()
{
    int fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    char buf[1024];
    recv(fd, buf, sizeof(buf), 0);

    listen(fd, 1);
}

然后我连接了这些函数:

elf_hook(filename, base_address, "socket", hook_socket);
elf_hook(filename, base_address, "listen", hook_listen);
elf_hook(filename, base_address, "recv", hook_recv);

挂钩函数调用原始 api 函数,但也记录正在发生的事情,例如:

int hook_socket(int domain, int type, int protocol)
{
    int fd = socket(domain, type, protocol);

    printf("fd=%d domain=%d type=%d protocol=%d\n", fd, domain, type, protocol);

    return fd;
}

一切正常,直到我尝试挂钩一个未在我的 TestAPI 共享库中调用的函数

elf_hook(filename, base_address, "bind", hook_bind);
elf_hook(filename, base_address, "connect", hook_connect);

我一这样做,就得到一个分段错误:

#0  elf_machine_fixup_plt (map=<optimized out>, t=<optimized out>, reloc=<optimized out>, value=139753823227104, reloc_addr=0x7f1afa15e188) at ../sysdeps/x86_64/dl-machine.h:235
#1  _dl_fixup (l=<optimized out>, reloc_arg=<optimized out>) at ../elf/dl-runtime.c:148
#2  0x00007f1afa176753 in _dl_runtime_resolve_avx () at ../sysdeps/x86_64/dl-trampoline.h:112
#3  0x0000000000561b20 in ?? ()
#4  0x00007f1afa16f8e0 in ?? () at dl-fini.c:105 from /lib64/ld-linux-x86-64.so.2
#5  0x00007f1afa16f5fb in call_init (env=0x7ffff0e3aae0, argv=0x4a7390 <_start>, argc=-253515440, l=<optimized out>) at dl-init.c:30
#6  _dl_init (main_map=0x0, argc=-253515440, argv=0x4a7390 <_start>, env=0x7ffff0e3aae0) at dl-init.c:120
#7  0x000000000000001c in ?? ()
#8  0x0000000000000001 in ?? ()
#9  0x00007ffff0e3c21f in ?? ()
#10 0x0000000000000000 in ?? ()

我已经通过挂钩函数测试了这个,运行 我的应用程序,看到它出现段错误,在我的共享库中调用该函数,再次 运行,并看到工作正常。

我对 libdlelf 的了解还不够全面,无法了解这里发生了什么或如何防止它/抓住一个事实,即我试图挂钩一个没有的函数' 接到电话。

如何防止这种情况发生?

编辑:

根据请求,这里是 readelf 的输出:

$ readelf -s -S --dyn-syms -r ./libtest_api.so
There are 36 section headers, starting at offset 0x14a208:

Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
  [ 0]                   NULL             0000000000000000  00000000
       0000000000000000  0000000000000000           0     0     0
  [ 1] .note.gnu.build-i NOTE             00000000000001c8  000001c8
       0000000000000024  0000000000000000   A       0     0     4
  [ 2] .gnu.hash         GNU_HASH         00000000000001f0  000001f0
       0000000000000044  0000000000000000   A       3     0     8
  [ 3] .dynsym           DYNSYM           0000000000000238  00000238
       0000000000000240  0000000000000018   A       4     2     8
  [ 4] .dynstr           STRTAB           0000000000000478  00000478
       00000000000001b4  0000000000000000   A       0     0     1
  [ 5] .gnu.version      VERSYM           000000000000062c  0000062c
       0000000000000030  0000000000000002   A       3     0     2
  [ 6] .gnu.version_r    VERNEED          0000000000000660  00000660
       0000000000000070  0000000000000000   A       4     3     8
  [ 7] .rela.dyn         RELA             00000000000006d0  000006d0
       00000000000000f0  0000000000000018   A       3     0     8
  [ 8] .rela.plt         RELA             00000000000007c0  000007c0
       00000000000000d8  0000000000000018  AI       3    22     8
  [ 9] .init             PROGBITS         0000000000000898  00000898
       000000000000001a  0000000000000000  AX       0     0     4
  [10] .plt              PROGBITS         00000000000008c0  000008c0
       00000000000000a0  0000000000000010  AX       0     0     16
  [11] .plt.got          PROGBITS         0000000000000960  00000960
       0000000000000010  0000000000000000  AX       0     0     8
  [12] .text             PROGBITS         0000000000000970  00000970
       0000000000000253  0000000000000000  AX       0     0     16
  [13] .fini             PROGBITS         0000000000000bc4  00000bc4
       0000000000000009  0000000000000000  AX       0     0     4
  [14] .rodata           PROGBITS         0000000000000bd0  00000bd0
       0000000000000105  0000000000000000   A       0     0     8
  [15] .eh_frame_hdr     PROGBITS         0000000000000cd8  00000cd8
       0000000000000034  0000000000000000   A       0     0     4
  [16] .eh_frame         PROGBITS         0000000000000d10  00000d10
       00000000000000cc  0000000000000000   A       0     0     8
  [17] .init_array       INIT_ARRAY       0000000000201dc0  00001dc0
       0000000000000010  0000000000000000  WA       0     0     8
  [18] .fini_array       FINI_ARRAY       0000000000201dd0  00001dd0
       0000000000000008  0000000000000000  WA       0     0     8
  [19] .jcr              PROGBITS         0000000000201dd8  00001dd8
       0000000000000008  0000000000000000  WA       0     0     8
  [20] .dynamic          DYNAMIC          0000000000201de0  00001de0
       00000000000001f0  0000000000000010  WA       4     0     8
  [21] .got              PROGBITS         0000000000201fd0  00001fd0
       0000000000000030  0000000000000008  WA       0     0     8
  [22] .got.plt          PROGBITS         0000000000202000  00002000
       0000000000000060  0000000000000008  WA       0     0     8
  [23] .data             PROGBITS         0000000000202060  00002060
       0000000000000008  0000000000000000  WA       0     0     8
  [24] .bss              NOBITS           0000000000202068  00002068
       0000000000000008  0000000000000000  WA       0     0     1
  [25] .comment          PROGBITS         0000000000000000  00002068
       0000000000000034  0000000000000001  MS       0     0     1
  [26] .debug_aranges    PROGBITS         0000000000000000  0000209c
       0000000000000040  0000000000000000           0     0     1
  [27] .debug_info       PROGBITS         0000000000000000  000020dc
       0000000000007a3b  0000000000000000           0     0     1
  [28] .debug_abbrev     PROGBITS         0000000000000000  00009b17
       00000000000009e1  0000000000000000           0     0     1
  [29] .debug_line       PROGBITS         0000000000000000  0000a4f8
       00000000000052dd  0000000000000000           0     0     1
  [30] .debug_str        PROGBITS         0000000000000000  0000f7d5
       000000000011cb84  0000000000000001  MS       0     0     1
  [31] .debug_ranges     PROGBITS         0000000000000000  0012c359
       0000000000000030  0000000000000000           0     0     1
  [32] .debug_macro      PROGBITS         0000000000000000  0012c389
       000000000001c8a8  0000000000000000           0     0     1
  [33] .shstrtab         STRTAB           0000000000000000  0014a0b4
       0000000000000151  0000000000000000           0     0     1
  [34] .symtab           SYMTAB           0000000000000000  00148c38
       0000000000000ba0  0000000000000018          35   102     8
  [35] .strtab           STRTAB           0000000000000000  001497d8
       00000000000008dc  0000000000000000           0     0     1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), l (large)
  I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)

Relocation section '.rela.dyn' at offset 0x6d0 contains 10 entries:
  Offset          Info           Type           Sym. Value    Sym. Name + Addend
000000201dc0  000000000008 R_X86_64_RELATIVE                    a40
000000201dc8  000000000008 R_X86_64_RELATIVE                    ba2
000000201dd0  000000000008 R_X86_64_RELATIVE                    a00
000000202060  000000000008 R_X86_64_RELATIVE                    202060
000000201fd0  000200000006 R_X86_64_GLOB_DAT 0000000000000000 __gmon_start__ + 0
000000201fd8  000300000006 R_X86_64_GLOB_DAT 0000000000000000 _Jv_RegisterClasses + 0
000000201fe0  000800000006 R_X86_64_GLOB_DAT 0000000000000000 _ZNSt8ios_base4InitD1E@GLIBCXX_3.4 + 0
000000201fe8  000900000006 R_X86_64_GLOB_DAT 0000000000000000 _ITM_deregisterTMClone + 0
000000201ff0  000a00000006 R_X86_64_GLOB_DAT 0000000000000000 _ITM_registerTMCloneTa + 0
000000201ff8  000c00000006 R_X86_64_GLOB_DAT 0000000000000000 __cxa_finalize@GLIBC_2.2.5 + 0

Relocation section '.rela.plt' at offset 0x7c0 contains 9 entries:
  Offset          Info           Type           Sym. Value    Sym. Name + Addend
000000202018  000400000007 R_X86_64_JUMP_SLO 0000000000000000 puts@GLIBC_2.2.5 + 0
000000202020  000500000007 R_X86_64_JUMP_SLO 0000000000000000 _ZNSt8ios_base4InitC1E@GLIBCXX_3.4 + 0
000000202028  001600000007 R_X86_64_JUMP_SLO 0000000000000bb8 _ZN5boost6none_tC1ENS0 + 0
000000202030  000600000007 R_X86_64_JUMP_SLO 0000000000000000 recv@GLIBC_2.2.5 + 0
000000202038  000700000007 R_X86_64_JUMP_SLO 0000000000000000 __cxa_atexit@GLIBC_2.2.5 + 0
000000202040  000b00000007 R_X86_64_JUMP_SLO 0000000000000000 listen@GLIBC_2.2.5 + 0
000000202048  000d00000007 R_X86_64_JUMP_SLO 0000000000000000 socket@GLIBC_2.2.5 + 0
000000202050  000e00000007 R_X86_64_JUMP_SLO 0000000000000000 __stack_chk_fail@GLIBC_2.4 + 0
000000202058  000f00000007 R_X86_64_JUMP_SLO 0000000000000000 send@GLIBC_2.2.5 + 0

Symbol table '.dynsym' contains 24 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000898     0 SECTION LOCAL  DEFAULT    9 
     2: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
     3: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _Jv_RegisterClasses
     4: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND puts@GLIBC_2.2.5 (2)
     5: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND _ZNSt8ios_base4InitC1Ev@GLIBCXX_3.4 (3)
     6: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND recv@GLIBC_2.2.5 (4)
     7: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __cxa_atexit@GLIBC_2.2.5 (2)
     8: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND _ZNSt8ios_base4InitD1Ev@GLIBCXX_3.4 (3)
     9: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_deregisterTMCloneTab
    10: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_registerTMCloneTable
    11: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND listen@GLIBC_2.2.5 (2)
    12: 0000000000000000     0 FUNC    WEAK   DEFAULT  UND __cxa_finalize@GLIBC_2.2.5 (2)
    13: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND socket@GLIBC_2.2.5 (2)
    14: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __stack_chk_fail@GLIBC_2.4 (5)
    15: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND send@GLIBC_2.2.5 (4)
    16: 0000000000202070     0 NOTYPE  GLOBAL DEFAULT   24 _end
    17: 0000000000202068     0 NOTYPE  GLOBAL DEFAULT   23 _edata
    18: 0000000000000a70   172 FUNC    GLOBAL DEFAULT   12 _ZN10ElfHookAPI4workEv
    19: 0000000000202068     0 NOTYPE  GLOBAL DEFAULT   24 __bss_start
    20: 0000000000000898     0 FUNC    GLOBAL DEFAULT    9 _init
    21: 0000000000000bc4     0 FUNC    GLOBAL DEFAULT   13 _fini
    22: 0000000000000bb8    11 FUNC    WEAK   DEFAULT   12 _ZN5boost6none_tC1ENS0_8i
    23: 0000000000000bb8    11 FUNC    WEAK   DEFAULT   12 _ZN5boost6none_tC2ENS0_8i

Symbol table '.symtab' contains 124 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 00000000000001c8     0 SECTION LOCAL  DEFAULT    1 
     2: 00000000000001f0     0 SECTION LOCAL  DEFAULT    2 
     3: 0000000000000238     0 SECTION LOCAL  DEFAULT    3 
     4: 0000000000000478     0 SECTION LOCAL  DEFAULT    4 
     5: 000000000000062c     0 SECTION LOCAL  DEFAULT    5 
     6: 0000000000000660     0 SECTION LOCAL  DEFAULT    6 
     7: 00000000000006d0     0 SECTION LOCAL  DEFAULT    7 
     8: 00000000000007c0     0 SECTION LOCAL  DEFAULT    8 
     9: 0000000000000898     0 SECTION LOCAL  DEFAULT    9 
    10: 00000000000008c0     0 SECTION LOCAL  DEFAULT   10 
    11: 0000000000000960     0 SECTION LOCAL  DEFAULT   11 
    12: 0000000000000970     0 SECTION LOCAL  DEFAULT   12 
    13: 0000000000000bc4     0 SECTION LOCAL  DEFAULT   13 
    14: 0000000000000bd0     0 SECTION LOCAL  DEFAULT   14 
    15: 0000000000000cd8     0 SECTION LOCAL  DEFAULT   15 
    16: 0000000000000d10     0 SECTION LOCAL  DEFAULT   16 
    17: 0000000000201dc0     0 SECTION LOCAL  DEFAULT   17 
    18: 0000000000201dd0     0 SECTION LOCAL  DEFAULT   18 
    19: 0000000000201dd8     0 SECTION LOCAL  DEFAULT   19 
    20: 0000000000201de0     0 SECTION LOCAL  DEFAULT   20 
    21: 0000000000201fd0     0 SECTION LOCAL  DEFAULT   21 
    22: 0000000000202000     0 SECTION LOCAL  DEFAULT   22 
    23: 0000000000202060     0 SECTION LOCAL  DEFAULT   23 
    24: 0000000000202068     0 SECTION LOCAL  DEFAULT   24 
    25: 0000000000000000     0 SECTION LOCAL  DEFAULT   25 
    26: 0000000000000000     0 SECTION LOCAL  DEFAULT   26 
    27: 0000000000000000     0 SECTION LOCAL  DEFAULT   27 
    28: 0000000000000000     0 SECTION LOCAL  DEFAULT   28 
    29: 0000000000000000     0 SECTION LOCAL  DEFAULT   29 
    30: 0000000000000000     0 SECTION LOCAL  DEFAULT   30 
    31: 0000000000000000     0 SECTION LOCAL  DEFAULT   31 
    32: 0000000000000000     0 SECTION LOCAL  DEFAULT   32 
    33: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c
    34: 0000000000201dd8     0 OBJECT  LOCAL  DEFAULT   19 __JCR_LIST__
    35: 0000000000000970     0 FUNC    LOCAL  DEFAULT   12 deregister_tm_clones
    36: 00000000000009b0     0 FUNC    LOCAL  DEFAULT   12 register_tm_clones
    37: 0000000000000a00     0 FUNC    LOCAL  DEFAULT   12 __do_global_dtors_aux
    38: 0000000000202068     1 OBJECT  LOCAL  DEFAULT   24 completed.7585
    39: 0000000000201dd0     0 OBJECT  LOCAL  DEFAULT   18 __do_global_dtors_aux_fin
    40: 0000000000000a40     0 FUNC    LOCAL  DEFAULT   12 frame_dummy
    41: 0000000000201dc0     0 OBJECT  LOCAL  DEFAULT   17 __frame_dummy_init_array_
    42: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS lib_elfhook.cpp
    43: 0000000000000bd0     1 OBJECT  LOCAL  DEFAULT   14 _ZStL19piecewise_construc
    44: 0000000000202069     1 OBJECT  LOCAL  DEFAULT   24 _ZStL8__ioinit
    45: 0000000000000bd1     1 OBJECT  LOCAL  DEFAULT   14 _ZStL13allocator_arg
    46: 0000000000000bd2     1 OBJECT  LOCAL  DEFAULT   14 _ZStL6ignore
    47: 0000000000000bd3     1 OBJECT  LOCAL  DEFAULT   14 _ZStL10defer_lock
    48: 0000000000000bd4     1 OBJECT  LOCAL  DEFAULT   14 _ZStL11try_to_lock
    49: 0000000000000bd5     1 OBJECT  LOCAL  DEFAULT   14 _ZStL10adopt_lock
    50: 0000000000000bd8     4 OBJECT  LOCAL  DEFAULT   14 _ZN9__gnu_cxxL21__default
    51: 0000000000000bdc     4 OBJECT  LOCAL  DEFAULT   14 _ZN6google8protobuf8inter
    52: 0000000000000be0     4 OBJECT  LOCAL  DEFAULT   14 _ZN6google8protobuf8inter
    53: 0000000000000be4     4 OBJECT  LOCAL  DEFAULT   14 _ZN6google8protobufL9kint
    54: 0000000000000be8     4 OBJECT  LOCAL  DEFAULT   14 _ZN6google8protobufL9kint
    55: 0000000000000bf0     8 OBJECT  LOCAL  DEFAULT   14 _ZN6google8protobufL9kint
    56: 0000000000000bf8     8 OBJECT  LOCAL  DEFAULT   14 _ZN6google8protobufL9kint
    57: 0000000000000c00     4 OBJECT  LOCAL  DEFAULT   14 _ZN6google8protobufL10kui
    58: 0000000000000c08     8 OBJECT  LOCAL  DEFAULT   14 _ZN6google8protobufL10kui
    59: 0000000000000c10     4 OBJECT  LOCAL  DEFAULT   14 _ZN6google8protobuf8inter
    60: 0000000000000c14     4 OBJECT  LOCAL  DEFAULT   14 _ZN3cay3logL9Level_MINE
    61: 0000000000000c18     4 OBJECT  LOCAL  DEFAULT   14 _ZN3cay3logL9Level_MAXE
    62: 0000000000000c1c     4 OBJECT  LOCAL  DEFAULT   14 _ZN3cay3logL15Level_ARRAY
    63: 0000000000000c20     4 OBJECT  LOCAL  DEFAULT   14 _ZN3cay3logL13DEFAULT_LEV
    64: 000000000020206a     1 OBJECT  LOCAL  DEFAULT   24 _ZN5boostL4noneE
    65: 0000000000000c24     4 OBJECT  LOCAL  DEFAULT   14 _ZN3cay6chronoL13days_per
    66: 0000000000000c28     4 OBJECT  LOCAL  DEFAULT   14 _ZN3cay6chronoL18days_per
    67: 0000000000000c2c     4 OBJECT  LOCAL  DEFAULT   14 _ZN3cay6chronoL16days_per
    68: 0000000000000c30     4 OBJECT  LOCAL  DEFAULT   14 _ZN3cay6chronoL18days_per
    69: 0000000000000c34     4 OBJECT  LOCAL  DEFAULT   14 _ZN3cay6chronoL18days_per
    70: 0000000000000c38     8 OBJECT  LOCAL  DEFAULT   14 _ZN3cay6chronoL12min_per_
    71: 0000000000000c40     8 OBJECT  LOCAL  DEFAULT   14 _ZN3cay6chronoL12sec_per_
    72: 0000000000000c48     8 OBJECT  LOCAL  DEFAULT   14 _ZN3cay6chronoL11ms_per_h
    73: 0000000000000c50     8 OBJECT  LOCAL  DEFAULT   14 _ZN3cay6chronoL11us_per_h
    74: 0000000000000c58     8 OBJECT  LOCAL  DEFAULT   14 _ZN3cay6chronoL11ns_per_h
    75: 0000000000000c60     8 OBJECT  LOCAL  DEFAULT   14 _ZN3cay6chronoL11sec_per_
    76: 0000000000000c68     8 OBJECT  LOCAL  DEFAULT   14 _ZN3cay6chronoL10ms_per_m
    77: 0000000000000c70     8 OBJECT  LOCAL  DEFAULT   14 _ZN3cay6chronoL10us_per_m
    78: 0000000000000c78     8 OBJECT  LOCAL  DEFAULT   14 _ZN3cay6chronoL10ns_per_m
    79: 0000000000000c80     4 OBJECT  LOCAL  DEFAULT   14 _ZN3cay6chronoL10ms_per_s
    80: 0000000000000c84     4 OBJECT  LOCAL  DEFAULT   14 _ZN3cay6chronoL10us_per_s
    81: 0000000000000c88     4 OBJECT  LOCAL  DEFAULT   14 _ZN3cay6chronoL10ns_per_s
    82: 0000000000000c90     8 OBJECT  LOCAL  DEFAULT   14 _ZN3cay6chronoL10sec_per_
    83: 0000000000000c98     4 OBJECT  LOCAL  DEFAULT   14 _ZN3cay6chronoL9us_per_ms
    84: 0000000000000c9c     4 OBJECT  LOCAL  DEFAULT   14 _ZN3cay6chronoL9ns_per_ms
    85: 0000000000000ca0     8 OBJECT  LOCAL  DEFAULT   14 _ZN3cay6chronoL10sec_per_
    86: 0000000000000ca8     8 OBJECT  LOCAL  DEFAULT   14 _ZN3cay6chronoL9ms_per_us
    87: 0000000000000cb0     4 OBJECT  LOCAL  DEFAULT   14 _ZN3cay6chronoL9ns_per_us
    88: 0000000000000cb8     8 OBJECT  LOCAL  DEFAULT   14 _ZN3cay6chronoL10sec_per_
    89: 0000000000000cc0     8 OBJECT  LOCAL  DEFAULT   14 _ZN3cay6chronoL9ms_per_ns
    90: 0000000000000cc8     8 OBJECT  LOCAL  DEFAULT   14 _ZN3cay6chronoL9us_per_ns
    91: 0000000000000b1c   134 FUNC    LOCAL  DEFAULT   12 _Z41__static_initializati
    92: 0000000000000ba2    21 FUNC    LOCAL  DEFAULT   12 _GLOBAL__sub_I_lib_elfhoo
    93: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c
    94: 0000000000000dd8     0 OBJECT  LOCAL  DEFAULT   16 __FRAME_END__
    95: 0000000000201dd8     0 OBJECT  LOCAL  DEFAULT   19 __JCR_END__
    96: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS 
    97: 0000000000000cd8     0 NOTYPE  LOCAL  DEFAULT   15 __GNU_EH_FRAME_HDR
    98: 0000000000202000     0 OBJECT  LOCAL  DEFAULT   22 _GLOBAL_OFFSET_TABLE_
    99: 0000000000202068     0 OBJECT  LOCAL  DEFAULT   23 __TMC_END__
   100: 0000000000202060     0 OBJECT  LOCAL  DEFAULT   23 __dso_handle
   101: 0000000000201de0     0 OBJECT  LOCAL  DEFAULT   20 _DYNAMIC
   102: 0000000000000a70   172 FUNC    GLOBAL DEFAULT   12 _ZN10ElfHookAPI4workEv
   103: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
   104: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _Jv_RegisterClasses
   105: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND puts@@GLIBC_2.2.5
   106: 0000000000000bc4     0 FUNC    GLOBAL DEFAULT   13 _fini
   107: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND _ZNSt8ios_base4InitC1Ev@@
   108: 0000000000000bb8    11 FUNC    WEAK   DEFAULT   12 _ZN5boost6none_tC1ENS0_8i
   109: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND recv@@GLIBC_2.2.5
   110: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __cxa_atexit@@GLIBC_2.2.5
   111: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND _ZNSt8ios_base4InitD1Ev@@
   112: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_deregisterTMCloneTab
   113: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_registerTMCloneTable
   114: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND listen@@GLIBC_2.2.5
   115: 0000000000000000     0 FUNC    WEAK   DEFAULT  UND __cxa_finalize@@GLIBC_2.2
   116: 0000000000000bb8    11 FUNC    WEAK   DEFAULT   12 _ZN5boost6none_tC2ENS0_8i
   117: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND socket@@GLIBC_2.2.5
   118: 0000000000202068     0 NOTYPE  GLOBAL DEFAULT   24 __bss_start
   119: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __stack_chk_fail@@GLIBC_2
   120: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND send@@GLIBC_2.2.5
   121: 0000000000202070     0 NOTYPE  GLOBAL DEFAULT   24 _end
   122: 0000000000202068     0 NOTYPE  GLOBAL DEFAULT   23 _edata
   123: 0000000000000898     0 FUNC    GLOBAL DEFAULT    9 _init

所以基本上他的代码所做的是,当您创建共享库 libtest.so 并在其中调用 libc.so 时,会在您的库中创建以下项目

  • 一个动态符号 table(包括您从 libc.so 调用的所有函数的数据)
  • 一个重定位 table(代码中的条目列表调用了 libc.so 中的函数,重定位 table 中的每个条目都表示属于 libc.solibtest.so 行 a、b、c...
  • 中被调用

他的代码解析你的共享库,从中提取 dynsymtable 和重定位 table 并通过调用 elf_hook() 将符号交换到你的请求(参见 elf_hook.c第 434 - 442 行)。

您从 libc.so API 中调用了三个函数,这是一个巨大的 API,因此 table 中的 dynsym 应该包含符号对于 socket() listen()recv()

我们可以看到 dyn-symbols 13 11 和 6 相应地 socket@GLIBC, listen@GLIBCrecv@GLIBC.

重定位 table 所做的基本上是说在您的实际代码中调用了那些函数,以及这些符号何时具有解析地址需要替换哪些地址以便您的代码调用实际函数,正如我们在 .rela.plt 中看到的那样,您已发布为 readelf 命令的输出,我们看到在 3 个不同的条目上您调用了这些符号。这些是我们需要更换的。

所以他的代码所做的是找到您要替换的符号的索引,检查所有重定位,然后查看它们是否与索引符号相关。如果是这样就意味着在这个重定位条目相关的地方,需要用你想要的代码替换它。

回到我们之前的例子,假设您想在 libtest.so 中用 y() 替换 socket()。他的代码找到 socket() 的符号索引,找到您在代码中调用 socket() 的位置,并将其替换为 y() 的地址。

试图挂钩不存在的符号

可能出错的事实是,当尝试挂钩未调用的符号时,只是没有该符号的重定位条目并且该符号不存在,您可以看到例如没有bind()dynsym table(readelf 输出)中的条目。

应该发生的是他找不到相应的符号并且不会挂钩任何东西。

老实说,我还没有检查他的整个代码,但我猜那里出了点问题,他没有处理试图挂钩一个不存在的符号的情况...

注:

我注意到的另一件事似乎是错误的,那就是 rel.dyn 的填充重定位。

他选择在他的示例中使用 RTLD_LAZY 加载库,这基本上意味着每次调用 DLL 函数都会跳转到某些 table 的偏移量,这指向您的动态链接器,当动态链接器被调用时,它会用函数的实际偏移量替换调用它的偏移量...这是 运行-时间重定位...

据我所知,rel.dyn 通常用于加载时重定位,当操作系统加载一个 executable 时,它会复制它的代码并查看所有重定位条目并替换它们在代码中....

在 运行 期间,rel.dyn table 条目指向的偏移量将在 executable 图像的 executable 部分内,这意味着它们应该只有读/执行权限,而不是写权限因此尝试写入它们应该会导致一些段错误....

总而言之,这可能是因为他的实用程序没有处理尝试挂钩符号 table 中不存在的 API 函数(未在您的代码中调用)的权利。 .. 希望我能帮助您更多地了解所发生的事情...

此外,尝试阅读这篇文章,它帮助我了解了很多关于 ELF 主题的知识:)

http://flint.cs.yale.edu/cs422/doc/ELF_Format.pdf