Выяснить, вызывается ли функция в общей библиотеке

Я использовал утилиту elfhook Энтони Шоухихина для перенаправления некоторых вызовов функций в общей библиотеке.

В качестве подтверждения концепции я создал разделяемую библиотеку, которая вызывает различные функции из api сокета posix.

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 ?? ()

Я проверил это, перехватив функцию, запустив мое приложение, увидев его segfault, вызвав эту функцию в моей общей библиотеке, снова запустив и убедившись, что работа работает правильно.

Мои знания libdl а также elf не в силах узнать, что здесь происходит или как это предотвратить / поймать тот факт, что я пытался перехватить функцию, которая не вызывается.

Как я могу предотвратить это?

Редактировать:

По запросу, здесь вывод 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

1 ответ

Решение

Так что в основном его код делает, когда вы создаете общую библиотеку libtest.so что вызывает libc.so внутри него создаются следующие элементы в вашей библиотеке

  • динамическая таблица символов (которая включает в себя данные всех функций, из которых вы вызываете libc.so)
  • таблица перемещений (список записей в вашем коде, которые вызывали функции внутри libc.soкаждая запись в таблице перемещений говорит, что функция X, которая принадлежит libc.so был вызван в libtest.so в строках а, б, в...

Его код анализирует вашу общую библиотеку, тянет dynsymtable и таблицу перемещений из нее и меняет символы к вашему запросу, вызывая elf_hook() (увидеть elf_hook.c строки 434 - 442).

Вы вызвали три функции из libc.so API, который является ОГРОМНЫМ API, следовательно, dynsym в вашей таблице должны содержать символы для socket()listen() а также recv()

Мы можем увидеть dyn-symbols 13 11 и 6 соответственно socket@GLIBC, listen@GLIBC а также recv@GLIBC,

То, что делает таблица перемещения, в основном говорит, где в вашем АКТУАЛЬНОМ коде эти функции вызываются, и когда эти символы будут иметь разрешенный адрес, какие адреса необходимо будет заменить, чтобы ваш код вызывал реальные функции, как мы также можно увидеть на .rela.plt Вы отправили в качестве вывода из readelf По команде мы видим, что на 3 разных записях вы назвали эти символы. Это то, что нам нужно заменить.

Так что его код делает поиск индекса символа, который вы хотите заменить, проходит ВСЕ перемещения и проверяет, относятся ли они к индексу-символу. Если это так, это означает, что в месте, где эта запись о перемещении является релевантной, ее необходимо заменить на код, который вы хотите.

Вернемся к нашему предыдущему примеру. Допустим, вы хотите заменить socket() с y() в вашем libtest.so, Его код находит индекс символа socket(), находит, где в коде вы звонили socket() и заменяет это адресом y() вместо.

Попытка поймать символы, которые не существуют

Что может пойти не так, так это тот факт, что при попытке перехватить символы, которые не были вызваны, просто отсутствует запись о перемещении для этого символа И этот символ не существует, вы можете видеть, что, например, в записи нет dynsym Таблица (readelf выход) из bind(),

Что ДОЛЖНО случиться, так это то, что он не найдет соответствующий символ и ничего не зацепит.

Честно говоря, я не прошел весь его код, но думаю, что там что-то пошло не так, и он не справился со случаем попытки перехватить символ, который не существует правильно...

Замечания:

Еще одна вещь, которую я заметил, которая кажется ужасно неправильной, - это rel.dyn,

Он решил загрузить библиотеки в своем примере RTLD_LAZYЭто означает, что при каждом вызове функции DLL происходит переход к некоторой таблице смещений, которая указывает на ваш динамический компоновщик, и когда вызывается динамический компоновщик, он заменяет смещение, из которого он был вызван, фактическим смещением функция... это перемещение во время выполнения...

Насколько я знаю rel.dyn обычно предназначен для перемещения во время загрузки, когда операционная система загружает исполняемый файл, она копирует свой код и просматривает все записи перемещения и заменяет их в коде....

Во время выполнения смещения rel.dyn элементы таблицы, на которые указывают записи, будут находиться в пределах исполняемого раздела исполняемого образа, что означает, что они ДОЛЖНЫ иметь только разрешения ЧТЕНИЕ / ВЫПОЛНЕНИЕ, а не ЗАПИСАТЬ, поэтому попытка записи в них ДОЛЖНА вызвать некоторый segfault....

Подводя итог, это, вероятно, происходит потому, что его утилита не справилась с попыткой перехватить функцию API, которая не существует в таблице символов (не вызывается в вашем коде) правильно... надеюсь, я помог вам понять немного больше что случилось...

Кроме того, попробуйте прочитать это, это помогло мне узнать много нового о предмете ELF в прошлом:)

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

Другие вопросы по тегам