查看共享库中是否调用了函数
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 ?? ()
我已经通过挂钩函数测试了这个,运行 我的应用程序,看到它出现段错误,在我的共享库中调用该函数,再次 运行,并看到工作正常。
我对 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
所以基本上他的代码所做的是,当您创建共享库 libtest.so
并在其中调用 libc.so
时,会在您的库中创建以下项目
- 一个动态符号 table(包括您从
libc.so
调用的所有函数的数据)
- 一个重定位 table(代码中的条目列表调用了
libc.so
中的函数,重定位 table 中的每个条目都表示属于 libc.so
在 libtest.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@GLIBC
和 recv@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 主题的知识:)
我一直在使用 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 ?? ()
我已经通过挂钩函数测试了这个,运行 我的应用程序,看到它出现段错误,在我的共享库中调用该函数,再次 运行,并看到工作正常。
我对 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
所以基本上他的代码所做的是,当您创建共享库 libtest.so
并在其中调用 libc.so
时,会在您的库中创建以下项目
- 一个动态符号 table(包括您从
libc.so
调用的所有函数的数据) - 一个重定位 table(代码中的条目列表调用了
libc.so
中的函数,重定位 table 中的每个条目都表示属于libc.so
在libtest.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@GLIBC
和 recv@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 主题的知识:)