赞
踩
- #include <stdio.h>
- #include <unistd.h>
-
- int main(){
- printf("the pid is %d\n",getpid());
- return 0;
- }
gcc -o gotTest main.c
readelf -a gotTest
可以得到如下结果:
- ELF 头:
- Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
- 类别: ELF64
- 数据: 2 补码,小端序 (little endian)
- Version: 1 (current)
- OS/ABI: UNIX - System V
- ABI 版本: 0
- 类型: DYN (共享目标文件)
- 系统架构: Advanced Micro Devices X86-64
- 版本: 0x1
- 入口点地址: 0x1080
- 程序头起点: 64 (bytes into file)
- Start of section headers: 14760 (bytes into file)
- 标志: 0x0
- Size of this header: 64 (bytes)
- Size of program headers: 56 (bytes)
- Number of program headers: 13
- Size of section headers: 64 (bytes)
- Number of section headers: 31
- Section header string table index: 30
-
- 节头:
- [号] 名称 类型 地址 偏移量
- 大小 全体大小 旗标 链接 信息 对齐
- [ 0] NULL 0000000000000000 00000000
- 0000000000000000 0000000000000000 0 0 0
- [ 1] .interp PROGBITS 0000000000000318 00000318
- 000000000000001c 0000000000000000 A 0 0 1
- [ 2] .note.gnu.propert NOTE 0000000000000338 00000338
- 0000000000000020 0000000000000000 A 0 0 8
- [ 3] .note.gnu.build-i NOTE 0000000000000358 00000358
- 0000000000000024 0000000000000000 A 0 0 4
- [ 4] .note.ABI-tag NOTE 000000000000037c 0000037c
- 0000000000000020 0000000000000000 A 0 0 4
- [ 5] .gnu.hash GNU_HASH 00000000000003a0 000003a0
- 0000000000000024 0000000000000000 A 6 0 8
- [ 6] .dynsym DYNSYM 00000000000003c8 000003c8
- 00000000000000c0 0000000000000018 A 7 1 8
- [ 7] .dynstr STRTAB 0000000000000488 00000488
- 000000000000008b 0000000000000000 A 0 0 1
- [ 8] .gnu.version VERSYM 0000000000000514 00000514
- 0000000000000010 0000000000000002 A 6 0 2
- [ 9] .gnu.version_r VERNEED 0000000000000528 00000528
- 0000000000000020 0000000000000000 A 7 1 8
- [10] .rela.dyn RELA 0000000000000548 00000548
- 00000000000000c0 0000000000000018 A 6 0 8
- [11] .rela.plt RELA 0000000000000608 00000608
- 0000000000000030 0000000000000018 AI 6 24 8
- [12] .init PROGBITS 0000000000001000 00001000
- 000000000000001b 0000000000000000 AX 0 0 4
- [13] .plt PROGBITS 0000000000001020 00001020
- 0000000000000030 0000000000000010 AX 0 0 16
- [14] .plt.got PROGBITS 0000000000001050 00001050
- 0000000000000010 0000000000000010 AX 0 0 16
- [15] .plt.sec PROGBITS 0000000000001060 00001060
- 0000000000000020 0000000000000010 AX 0 0 16
- [16] .text PROGBITS 0000000000001080 00001080
- 0000000000000185 0000000000000000 AX 0 0 16
- [17] .fini PROGBITS 0000000000001208 00001208
- 000000000000000d 0000000000000000 AX 0 0 4
- [18] .rodata PROGBITS 0000000000002000 00002000
- 0000000000000013 0000000000000000 A 0 0 4
- [19] .eh_frame_hdr PROGBITS 0000000000002014 00002014
- 0000000000000044 0000000000000000 A 0 0 4
- [20] .eh_frame PROGBITS 0000000000002058 00002058
- 0000000000000108 0000000000000000 A 0 0 8
- [21] .init_array INIT_ARRAY 0000000000003db0 00002db0
- 0000000000000008 0000000000000008 WA 0 0 8
- [22] .fini_array FINI_ARRAY 0000000000003db8 00002db8
- 0000000000000008 0000000000000008 WA 0 0 8
- [23] .dynamic DYNAMIC 0000000000003dc0 00002dc0
- 00000000000001f0 0000000000000010 WA 7 0 8
- [24] .got PROGBITS 0000000000003fb0 00002fb0
- 0000000000000050 0000000000000008 WA 0 0 8
- [25] .data PROGBITS 0000000000004000 00003000
- 0000000000000010 0000000000000000 WA 0 0 8
- [26] .bss NOBITS 0000000000004010 00003010
- 0000000000000008 0000000000000000 WA 0 0 1
- [27] .comment PROGBITS 0000000000000000 00003010
- 000000000000002b 0000000000000001 MS 0 0 1
- [28] .symtab SYMTAB 0000000000000000 00003040
- 0000000000000630 0000000000000018 29 46 8
- [29] .strtab STRTAB 0000000000000000 00003670
- 0000000000000218 0000000000000000 0 0 1
- [30] .shstrtab STRTAB 0000000000000000 00003888
- 000000000000011a 0000000000000000 0 0 1
- Key to Flags:
- W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
- L (link order), O (extra OS processing required), G (group), T (TLS),
- C (compressed), x (unknown), o (OS specific), E (exclude),
- l (large), p (processor specific)
-
- There are no section groups in this file.
-
- 程序头:
- Type Offset VirtAddr PhysAddr
- FileSiz MemSiz Flags Align
- PHDR 0x0000000000000040 0x0000000000000040 0x0000000000000040
- 0x00000000000002d8 0x00000000000002d8 R 0x8
- INTERP 0x0000000000000318 0x0000000000000318 0x0000000000000318
- 0x000000000000001c 0x000000000000001c R 0x1
- [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
- LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000
- 0x0000000000000638 0x0000000000000638 R 0x1000
- LOAD 0x0000000000001000 0x0000000000001000 0x0000000000001000
- 0x0000000000000215 0x0000000000000215 R E 0x1000
- LOAD 0x0000000000002000 0x0000000000002000 0x0000000000002000
- 0x0000000000000160 0x0000000000000160 R 0x1000
- LOAD 0x0000000000002db0 0x0000000000003db0 0x0000000000003db0
- 0x0000000000000260 0x0000000000000268 RW 0x1000
- DYNAMIC 0x0000000000002dc0 0x0000000000003dc0 0x0000000000003dc0
- 0x00000000000001f0 0x00000000000001f0 RW 0x8
- NOTE 0x0000000000000338 0x0000000000000338 0x0000000000000338
- 0x0000000000000020 0x0000000000000020 R 0x8
- NOTE 0x0000000000000358 0x0000000000000358 0x0000000000000358
- 0x0000000000000044 0x0000000000000044 R 0x4
- GNU_PROPERTY 0x0000000000000338 0x0000000000000338 0x0000000000000338
- 0x0000000000000020 0x0000000000000020 R 0x8
- GNU_EH_FRAME 0x0000000000002014 0x0000000000002014 0x0000000000002014
- 0x0000000000000044 0x0000000000000044 R 0x4
- GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
- 0x0000000000000000 0x0000000000000000 RW 0x10
- GNU_RELRO 0x0000000000002db0 0x0000000000003db0 0x0000000000003db0
- 0x0000000000000250 0x0000000000000250 R 0x1
-
- Section to Segment mapping:
- 段节...
- 00
- 01 .interp
- 02 .interp .note.gnu.property .note.gnu.build-id .note.ABI-tag .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt
- 03 .init .plt .plt.got .plt.sec .text .fini
- 04 .rodata .eh_frame_hdr .eh_frame
- 05 .init_array .fini_array .dynamic .got .data .bss
- 06 .dynamic
- 07 .note.gnu.property
- 08 .note.gnu.build-id .note.ABI-tag
- 09 .note.gnu.property
- 10 .eh_frame_hdr
- 11
- 12 .init_array .fini_array .dynamic .got
-
- Dynamic section at offset 0x2dc0 contains 27 entries:
- 标记 类型 名称/值
- 0x0000000000000001 (NEEDED) 共享库:[libc.so.6]
- 0x000000000000000c (INIT) 0x1000
- 0x000000000000000d (FINI) 0x1208
- 0x0000000000000019 (INIT_ARRAY) 0x3db0
- 0x000000000000001b (INIT_ARRAYSZ) 8 (bytes)
- 0x000000000000001a (FINI_ARRAY) 0x3db8
- 0x000000000000001c (FINI_ARRAYSZ) 8 (bytes)
- 0x000000006ffffef5 (GNU_HASH) 0x3a0
- 0x0000000000000005 (STRTAB) 0x488
- 0x0000000000000006 (SYMTAB) 0x3c8
- 0x000000000000000a (STRSZ) 139 (bytes)
- 0x000000000000000b (SYMENT) 24 (bytes)
- 0x0000000000000015 (DEBUG) 0x0
- 0x0000000000000003 (PLTGOT) 0x3fb0
- 0x0000000000000002 (PLTRELSZ) 48 (bytes)
- 0x0000000000000014 (PLTREL) RELA
- 0x0000000000000017 (JMPREL) 0x608
- 0x0000000000000007 (RELA) 0x548
- 0x0000000000000008 (RELASZ) 192 (bytes)
- 0x0000000000000009 (RELAENT) 24 (bytes)
- 0x000000000000001e (FLAGS) BIND_NOW
- 0x000000006ffffffb (FLAGS_1) 标志: NOW PIE
- 0x000000006ffffffe (VERNEED) 0x528
- 0x000000006fffffff (VERNEEDNUM) 1
- 0x000000006ffffff0 (VERSYM) 0x514
- 0x000000006ffffff9 (RELACOUNT) 3
- 0x0000000000000000 (NULL) 0x0
-
- 重定位节 '.rela.dyn' at offset 0x548 contains 8 entries:
- 偏移量 信息 类型 符号值 符号名称 + 加数
- 000000003db0 000000000008 R_X86_64_RELATIVE 1160
- 000000003db8 000000000008 R_X86_64_RELATIVE 1120
- 000000004008 000000000008 R_X86_64_RELATIVE 4008
- 000000003fd8 000100000006 R_X86_64_GLOB_DAT 0000000000000000 _ITM_deregisterTMClone + 0
- 000000003fe0 000400000006 R_X86_64_GLOB_DAT 0000000000000000 __libc_start_main@GLIBC_2.2.5 + 0
- 000000003fe8 000500000006 R_X86_64_GLOB_DAT 0000000000000000 __gmon_start__ + 0
- 000000003ff0 000600000006 R_X86_64_GLOB_DAT 0000000000000000 _ITM_registerTMCloneTa + 0
- 000000003ff8 000700000006 R_X86_64_GLOB_DAT 0000000000000000 __cxa_finalize@GLIBC_2.2.5 + 0
-
- 重定位节 '.rela.plt' at offset 0x608 contains 2 entries:
- 偏移量 信息 类型 符号值 符号名称 + 加数
- 000000003fc8 000200000007 R_X86_64_JUMP_SLO 0000000000000000 getpid@GLIBC_2.2.5 + 0
- 000000003fd0 000300000007 R_X86_64_JUMP_SLO 0000000000000000 printf@GLIBC_2.2.5 + 0
-
- The decoding of unwind sections for machine type Advanced Micro Devices X86-64 is not currently supported.
-
- Symbol table '.dynsym' contains 8 entries:
- Num: Value Size Type Bind Vis Ndx Name
- 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
- 1: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterTMCloneTab
- 2: 0000000000000000 0 FUNC GLOBAL DEFAULT UND getpid@GLIBC_2.2.5 (2)
- 3: 0000000000000000 0 FUNC GLOBAL DEFAULT UND printf@GLIBC_2.2.5 (2)
- 4: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.2.5 (2)
- 5: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
- 6: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_registerTMCloneTable
- 7: 0000000000000000 0 FUNC WEAK DEFAULT UND __cxa_finalize@GLIBC_2.2.5 (2)
-
- Symbol table '.symtab' contains 66 entries:
- Num: Value Size Type Bind Vis Ndx Name
- 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
- 1: 0000000000000318 0 SECTION LOCAL DEFAULT 1
- 2: 0000000000000338 0 SECTION LOCAL DEFAULT 2
- 3: 0000000000000358 0 SECTION LOCAL DEFAULT 3
- 4: 000000000000037c 0 SECTION LOCAL DEFAULT 4
- 5: 00000000000003a0 0 SECTION LOCAL DEFAULT 5
- 6: 00000000000003c8 0 SECTION LOCAL DEFAULT 6
- 7: 0000000000000488 0 SECTION LOCAL DEFAULT 7
- 8: 0000000000000514 0 SECTION LOCAL DEFAULT 8
- 9: 0000000000000528 0 SECTION LOCAL DEFAULT 9
- 10: 0000000000000548 0 SECTION LOCAL DEFAULT 10
- 11: 0000000000000608 0 SECTION LOCAL DEFAULT 11
- 12: 0000000000001000 0 SECTION LOCAL DEFAULT 12
- 13: 0000000000001020 0 SECTION LOCAL DEFAULT 13
- 14: 0000000000001050 0 SECTION LOCAL DEFAULT 14
- 15: 0000000000001060 0 SECTION LOCAL DEFAULT 15
- 16: 0000000000001080 0 SECTION LOCAL DEFAULT 16
- 17: 0000000000001208 0 SECTION LOCAL DEFAULT 17
- 18: 0000000000002000 0 SECTION LOCAL DEFAULT 18
- 19: 0000000000002014 0 SECTION LOCAL DEFAULT 19
- 20: 0000000000002058 0 SECTION LOCAL DEFAULT 20
- 21: 0000000000003db0 0 SECTION LOCAL DEFAULT 21
- 22: 0000000000003db8 0 SECTION LOCAL DEFAULT 22
- 23: 0000000000003dc0 0 SECTION LOCAL DEFAULT 23
- 24: 0000000000003fb0 0 SECTION LOCAL DEFAULT 24
- 25: 0000000000004000 0 SECTION LOCAL DEFAULT 25
- 26: 0000000000004010 0 SECTION LOCAL DEFAULT 26
- 27: 0000000000000000 0 SECTION LOCAL DEFAULT 27
- 28: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
- 29: 00000000000010b0 0 FUNC LOCAL DEFAULT 16 deregister_tm_clones
- 30: 00000000000010e0 0 FUNC LOCAL DEFAULT 16 register_tm_clones
- 31: 0000000000001120 0 FUNC LOCAL DEFAULT 16 __do_global_dtors_aux
- 32: 0000000000004010 1 OBJECT LOCAL DEFAULT 26 completed.8061
- 33: 0000000000003db8 0 OBJECT LOCAL DEFAULT 22 __do_global_dtors_aux_fin
- 34: 0000000000001160 0 FUNC LOCAL DEFAULT 16 frame_dummy
- 35: 0000000000003db0 0 OBJECT LOCAL DEFAULT 21 __frame_dummy_init_array_
- 36: 0000000000000000 0 FILE LOCAL DEFAULT ABS main.c
- 37: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
- 38: 000000000000215c 0 OBJECT LOCAL DEFAULT 20 __FRAME_END__
- 39: 0000000000000000 0 FILE LOCAL DEFAULT ABS
- 40: 0000000000003db8 0 NOTYPE LOCAL DEFAULT 21 __init_array_end
- 41: 0000000000003dc0 0 OBJECT LOCAL DEFAULT 23 _DYNAMIC
- 42: 0000000000003db0 0 NOTYPE LOCAL DEFAULT 21 __init_array_start
- 43: 0000000000002014 0 NOTYPE LOCAL DEFAULT 19 __GNU_EH_FRAME_HDR
- 44: 0000000000003fb0 0 OBJECT LOCAL DEFAULT 24 _GLOBAL_OFFSET_TABLE_
- 45: 0000000000001000 0 FUNC LOCAL DEFAULT 12 _init
- 46: 0000000000001200 5 FUNC GLOBAL DEFAULT 16 __libc_csu_fini
- 47: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterTMCloneTab
- 48: 0000000000004000 0 NOTYPE WEAK DEFAULT 25 data_start
- 49: 0000000000000000 0 FUNC GLOBAL DEFAULT UND getpid@@GLIBC_2.2.5
- 50: 0000000000004010 0 NOTYPE GLOBAL DEFAULT 25 _edata
- 51: 0000000000001208 0 FUNC GLOBAL HIDDEN 17 _fini
- 52: 0000000000000000 0 FUNC GLOBAL DEFAULT UND printf@@GLIBC_2.2.5
- 53: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@@GLIBC_
- 54: 0000000000004000 0 NOTYPE GLOBAL DEFAULT 25 __data_start
- 55: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
- 56: 0000000000004008 0 OBJECT GLOBAL HIDDEN 25 __dso_handle
- 57: 0000000000002000 4 OBJECT GLOBAL DEFAULT 18 _IO_stdin_used
- 58: 0000000000001190 101 FUNC GLOBAL DEFAULT 16 __libc_csu_init
- 59: 0000000000004018 0 NOTYPE GLOBAL DEFAULT 26 _end
- 60: 0000000000001080 47 FUNC GLOBAL DEFAULT 16 _start
- 61: 0000000000004010 0 NOTYPE GLOBAL DEFAULT 26 __bss_start
- 62: 0000000000001169 39 FUNC GLOBAL DEFAULT 16 main
- 63: 0000000000004010 0 OBJECT GLOBAL HIDDEN 25 __TMC_END__
- 64: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_registerTMCloneTable
- 65: 0000000000000000 0 FUNC WEAK DEFAULT UND __cxa_finalize@@GLIBC_2.2
-
- Histogram for `.gnu.hash' bucket list length (total of 2 buckets):
- Length Number % of total Coverage
- 0 1 ( 50.0%)
- 1 1 ( 50.0%) 100.0%
- Version symbols section '.gnu.version' contains 8 entries:
- 地址:0x0000000000000514 Offset: 0x000514 Link: 6 (.dynsym)
- 000: 0 (*本地*) 0 (*本地*) 2 (GLIBC_2.2.5) 2 (GLIBC_2.2.5)
- 004: 2 (GLIBC_2.2.5) 0 (*本地*) 0 (*本地*) 2 (GLIBC_2.2.5)
- Version needs section '.gnu.version_r' contains 1 entry:
- 地址:0x0000000000000528 Offset: 0x000528 Link: 7 (.dynstr)
- 000000: Version: 1 文件:libc.so.6 计数:1
- 0x0010: Name: GLIBC_2.2.5 标志:无 版本:2
- Displaying notes found in: .note.gnu.property
- 所有者 Data size Description
- GNU 0x00000010 NT_GNU_PROPERTY_TYPE_0
- Properties: x86 feature: IBT, SHSTK
- Displaying notes found in: .note.gnu.build-id
- 所有者 Data size Description
- GNU 0x00000014 NT_GNU_BUILD_ID (unique build ID bitstring)
- Build ID: c72301e0c49b0cd407f0056210312787d9224273
- Displaying notes found in: .note.ABI-tag
- 所有者 Data size Description
- GNU 0x00000010 NT_GNU_ABI_TAG (ABI version tag)
- OS: Linux, ABI: 3.2.0
重点关注节头以下信息:
- [13] .plt PROGBITS 0000000000001020 00001020
- 0000000000000030 0000000000000010 AX 0 0 16
- [14] .plt.got PROGBITS 0000000000001050 00001050
- 0000000000000010 0000000000000010 AX 0 0 16
- [15] .plt.sec PROGBITS 0000000000001060 00001060
- 0000000000000020 0000000000000010 AX 0 0 16
- [24] .got PROGBITS 0000000000003fb0 00002fb0
- 0000000000000050 0000000000000008 WA 0 0 8
从以上表可以看出:
其中:
0X1020 是.plt表在程序中的偏移位置。
0X1050 是.plt.got表在程序中的偏移位置。
0X1060 是.plt.sec表在程序中的偏移位置。
0X3fb0 是.got表在程序中的偏移位置。
我们可以看到,getpid和printf函数都在这个.got表中,其中偏移量是他们在表中的地址,信息是他们实际的地址,由于程序未启动,地址还没加载,所以显示的并不是程序的实际地址。
那么这个got表和got.plt表到底是怎么运作的呢?
首先,当一个程序第一次调用一个外部函数时,就会跳转到.plt表(注意,不是.got.plt),而这个表中包含有一些代码,这些代码总共有两个作用:
(1)调用链接器来解析某个外部函数的地址, 并填充到.got.plt中, 然后跳转到该函数。
(2)在.got.plt中查找并跳转到对应外部函数(如果已经填充过)。
相对的,.got.plt也同样具有两个功能:
1)如果在之前查找过该符号,内容为外部函数的具体地址。
2)如果没查找过, 则内容为跳转回.plt的代码。
所以当你首次调用某个外部函数时,其流程为code → .plt → .got.plt → .plt→.got.plt→target function
结合上图可更好的理解整个过程。
接下来要hook函数就很简单了,只需要将运行中的got.plt表中对应的地址覆盖为我们自己的函数地址,当调用时,自然就调用到我们自己的函数了。
接下来我们来实现一下hook的过程
首先,将测试代码改造一下,改造后测试代码如下:
- #include <stdio.h>
- #include <unistd.h>
- #include <stdbool>
- int mygetpid(){
- return 12306;
- }
-
- int main(){
-
- while(true){
- printf("the pid is %d\n",getpid());
- sleep(1);
- }
- return 0;
- }
改造后的代码,每隔一段时间就会打印一下pid,然后我们还新增了一个函数,用于到时候替换用,我们再用readelf -a 来查看一下编译成的执行文件的elf情况如下:
首先是.got.plt表
接下来是.symtab,.symtab是c程序的符号表,其中包含有各种程序的符号,其内容如下:
我们可以看到,getpid函数和我们自己编写的mygetpid函数在这个表中都可以看到,由于getpid是外部引用函数,其地址是使用时动态加载,所以此时为0,接下来的内容就很明确了,我们只需要把.got.plt表中,位置为0X3fc0的值,覆写成我们自己的mygetpid函数的地址,就可以hook住getpid函数了。
那么我们应该怎么才能修改程序运行时候的内存地址呢,我们都知道,linux秉承的是万物皆文件的原则,程序在运行时候,其内存会映射为一个/proc/$pid/mem文件,修改这个文件,等于修改程序内存(其实这样说不够严谨,差不多是这个意思)。
于是我们可以编写个程序用来修改程序运行时候的内存,代码如下:
- vim inject.c
- --------------------------------------------
- #include <stdio.h>
- #include <unistd.h>
- #include <fcntl.h>
- int main(int argc,char* argv[]) {
- int pid = atoi(argv[1]);
- unsigned long offset = 0x601018;
- unsigned long myfunctionaddr = 0x4005b6;
- char filename[32];
- snprintf(filename, sizeof(filename),"/proc/%d/mem",pid);
- int fd = open(filename, O_RDWR|O_SYNC);
- lseek(fd,offset,SEEK_SET);
- write(fd,&myfunctionaddr, sizeof(unsigned long));
- return 0;
- }
- -----------------------------------
- gcc -o inect inject.c
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。