Linux逆向实战—程序的诞生
Linux逆向实战—程序的诞生
C 编译的过程
二进制文件通过编译生成,编译是将人类可读的源代码(C/C++)转换为处理器可以执行的机器码的过程,编译分为4个阶段,分为预**处理**、**编译**、**汇编**及**链接**。

预处理阶段
- 源文件
#include <stdio.h>
#define FORMAT_STRING "%s"
#define MESSAGE "Hello, world!\n"
int
main(int argc, char *argv[]) {
printf(FORMAT_STRING, MESSAGE);
return 0;
}
- C预处理器输出
gcc -E -P compilation_example.c > 1.txt
- 输出结果
typedef long unsigned int size_t;
typedef unsigned char __u_char;
typedef unsigned short int __u_short;
typedef unsigned int __u_int;
typedef unsigned long int __u_long;
typedef signed char __int8_t;
typedef unsigned char __uint8_t;
typedef signed short int __int16_t;
typedef unsigned short int __uint16_t;
typedef signed int __int32_t;
typedef unsigned int __uint32_t;
typedef signed long int __int64_t;
typedef unsigned long int __uint64_t;
typedef long int __quad_t;
typedef unsigned long int __u_quad_t;
typedef unsigned long int __dev_t;
typedef unsigned int __uid_t;
typedef unsigned int __gid_t;
typedef unsigned long int __ino_t;
typedef unsigned long int __ino64_t;
typedef unsigned int __mode_t;
/* ... */
extern int __underflow (_IO_FILE *);
extern int __uflow (_IO_FILE *);
extern int __overflow (_IO_FILE *, int);
extern int _IO_getc (_IO_FILE *__fp);
extern int _IO_putc (int __c, _IO_FILE *__fp);
extern int _IO_feof (_IO_FILE *__fp) __attribute__ ((__nothrow__ , __leaf__));
extern int _IO_ferror (_IO_FILE *__fp) __attribute__ ((__nothrow__ , __leaf__));
extern int _IO_peekc_locked (_IO_FILE *__fp);
extern void _IO_flockfile (_IO_FILE *) __attribute__ ((__nothrow__ , __leaf__));
extern void _IO_funlockfile (_IO_FILE *) __attribute__ ((__nothrow__ , __leaf__));
extern int _IO_ftrylockfile (_IO_FILE *) __attribute__ ((__nothrow__ , __leaf__));
extern int _IO_vfscanf (_IO_FILE * __restrict, const char * __restrict,
__gnuc_va_list, int *__restrict);
extern int _IO_vfprintf (_IO_FILE *__restrict, const char *__restrict,
__gnuc_va_list);
extern __ssize_t _IO_padn (_IO_FILE *, int, __ssize_t);
extern size_t _IO_sgetn (_IO_FILE *, void *, size_t);
extern __off64_t _IO_seekoff (_IO_FILE *, __off64_t, int, int);
extern __off64_t _IO_seekpos (_IO_FILE *, __off64_t, int);
extern void _IO_free_backup_area (_IO_FILE *) __attribute__ ((__nothrow__ , __leaf__));
typedef __gnuc_va_list va_list;
typedef __off_t off_t;
typedef __ssize_t ssize_t;
typedef _G_fpos_t fpos_t;
/* ... */
extern int sys_nerr;
extern const char *const sys_errlist[];
extern int fileno (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ;
extern int fileno_unlocked (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ;
extern FILE *popen (const char *__command, const char *__modes) ;
extern int pclose (FILE *__stream);
extern char *ctermid (char *__s) __attribute__ ((__nothrow__ , __leaf__));
extern void flockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));
extern int ftrylockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ;
extern void funlockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));
int
main(int argc, char *argv[]) {
printf("%s", "Hello, world!\n");
return 0;
}
C的源文件中包含宏(#define)和 #includ 指令,在预处理中扩展了所有源文件中这两个指令,stdio.h头文件中其所有的类型定义、全局变量及函数原型都被复制到了源文件中。预处理器还完整扩展了#define定义的任何宏的所有用法,将宏代表的常量进行替换。
编译阶段
预处理阶段完成之后,可以编译成源代码了。编译阶段采用预处理代码并将代码转换为汇编语言,本篇主要涉及x86_64汇编,编译器会在这个阶段进行大量的优化,编译阶段的输出以人类可读的形式进行汇编,其中的符号信息完整无缺,在编译阶段查看已翻译的汇编需要告诉GCC在此阶段后停止,-S停止 -masm=intel使用Intel语法
gcc -S -masm=intel compilation_example.c
gcc -m32 -S -masm=intel compilation_example.c #生成32位汇编
- 生成的汇编代码
.file "compilation_example.c"
.intel_syntax noprefix
.section .rodata
.LC0:
.string "Hello, world!"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
push rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
mov rbp, rsp
.cfi_def_cfa_register 6
sub rsp, 16
mov DWORD PTR [rbp-4], edi
mov QWORD PTR [rbp-16], rsi
mov edi, OFFSET FLAT:.LC0
call puts
mov eax, 0
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.5) 5.4.0 20160609"
.section .note.GNU-stack,"",@progbits
汇编阶段
在汇编阶段可以得到真正的机器代码,输入编译阶段的汇编语言集输出一组对象文件,对象文件包含可由处理器执行的机器指令
gcc -m32 -c compilation_example.c

链接阶段
在链接阶段是编译的最后阶段,将所有对象文件链接到一个可执行的二进制文件中,链接有时会包含额外的优化过程(连接时优化 *Link-Time Optimization, LTO*),通常连接器与编译器相互独立,编译器实现所有的步骤。
链接器的工作是获取属于程序的所有对象文件,并将它们合并为一个连贯的可执行文件,然后加载到特定的内存地址。
静态库(在Linux操作系统上通常扩展名*.a)被合并到可执行文件中,允许完全解析对静态库的任何引用。动态库,在系统上运行的所有程序的内存中共享,在二进制文件实际加载到要执行的内存中之前,不会解析这些引用。
- GCC生成二进制可执行文件
gcc compilation_example.c

默认的可执行文件名为a.out,通过file实用程序知道这是一个ELF 64位的LSB可执行文件,而且文件是动态链接的,表明要使用的某些库未合并到可执行文件中,是在同一系统上运行的所有程序之间共享。
符号和剥离的二进制文件
高级源代码以有意义的、人类可读的函数和变量命名为中心,编译时编译器会翻译符号跟踪其名称,记录哪些二进制代码和数据对应哪些符号。
- 查看符号信息
$ readelf --syms a.out > a.txt
Symbol table '.dynsym' contains 7 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 puts@GLIBC_2.2.5 (2)
3: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.2.5 (2)
4: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
5: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_registerTMCloneTable
6: 0000000000000000 0 FUNC WEAK DEFAULT UND __cxa_finalize@GLIBC_2.2.5 (2)
Symbol table '.symtab' contains 63 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000238 0 SECTION LOCAL DEFAULT 1
2: 0000000000000254 0 SECTION LOCAL DEFAULT 2
3: 0000000000000274 0 SECTION LOCAL DEFAULT 3
4: 0000000000000298 0 SECTION LOCAL DEFAULT 4
5: 00000000000002b8 0 SECTION LOCAL DEFAULT 5
6: 0000000000000360 0 SECTION LOCAL DEFAULT 6
7: 00000000000003e2 0 SECTION LOCAL DEFAULT 7
8: 00000000000003f0 0 SECTION LOCAL DEFAULT 8
9: 0000000000000410 0 SECTION LOCAL DEFAULT 9
10: 00000000000004d0 0 SECTION LOCAL DEFAULT 10
11: 00000000000004e8 0 SECTION LOCAL DEFAULT 11
12: 0000000000000500 0 SECTION LOCAL DEFAULT 12
13: 0000000000000520 0 SECTION LOCAL DEFAULT 13
14: 0000000000000530 0 SECTION LOCAL DEFAULT 14
15: 00000000000006d4 0 SECTION LOCAL DEFAULT 15
16: 00000000000006e0 0 SECTION LOCAL DEFAULT 16
17: 00000000000006f4 0 SECTION LOCAL DEFAULT 17
18: 0000000000000730 0 SECTION LOCAL DEFAULT 18
19: 0000000000200db8 0 SECTION LOCAL DEFAULT 19
20: 0000000000200dc0 0 SECTION LOCAL DEFAULT 20
21: 0000000000200dc8 0 SECTION LOCAL DEFAULT 21
22: 0000000000200fb8 0 SECTION LOCAL DEFAULT 22
23: 0000000000201000 0 SECTION LOCAL DEFAULT 23
24: 0000000000201010 0 SECTION LOCAL DEFAULT 24
25: 0000000000000000 0 SECTION LOCAL DEFAULT 25
26: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
27: 0000000000000560 0 FUNC LOCAL DEFAULT 14 deregister_tm_clones
28: 00000000000005a0 0 FUNC LOCAL DEFAULT 14 register_tm_clones
29: 00000000000005f0 0 FUNC LOCAL DEFAULT 14 __do_global_dtors_aux
30: 0000000000201010 1 OBJECT LOCAL DEFAULT 24 completed.7698
31: 0000000000200dc0 0 OBJECT LOCAL DEFAULT 20 __do_global_dtors_aux_fin
32: 0000000000000630 0 FUNC LOCAL DEFAULT 14 frame_dummy
33: 0000000000200db8 0 OBJECT LOCAL DEFAULT 19 __frame_dummy_init_array_
34: 0000000000000000 0 FILE LOCAL DEFAULT ABS compilation_example.c
35: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
36: 0000000000000834 0 OBJECT LOCAL DEFAULT 18 __FRAME_END__
37: 0000000000000000 0 FILE LOCAL DEFAULT ABS
38: 0000000000200dc0 0 NOTYPE LOCAL DEFAULT 19 __init_array_end
39: 0000000000200dc8 0 OBJECT LOCAL DEFAULT 21 _DYNAMIC
40: 0000000000200db8 0 NOTYPE LOCAL DEFAULT 19 __init_array_start
41: 00000000000006f4 0 NOTYPE LOCAL DEFAULT 17 __GNU_EH_FRAME_HDR
42: 0000000000200fb8 0 OBJECT LOCAL DEFAULT 22 _GLOBAL_OFFSET_TABLE_
43: 00000000000006d0 2 FUNC GLOBAL DEFAULT 14 __libc_csu_fini
44: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterTMCloneTab
45: 0000000000201000 0 NOTYPE WEAK DEFAULT 23 data_start
46: 0000000000000000 0 FUNC GLOBAL DEFAULT UND puts@@GLIBC_2.2.5
47: 0000000000201010 0 NOTYPE GLOBAL DEFAULT 23 _edata
48: 00000000000006d4 0 FUNC GLOBAL DEFAULT 15 _fini
49: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@@GLIBC_
50: 0000000000201000 0 NOTYPE GLOBAL DEFAULT 23 __data_start
51: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
52: 0000000000201008 0 OBJECT GLOBAL HIDDEN 23 __dso_handle
53: 00000000000006e0 4 OBJECT GLOBAL DEFAULT 16 _IO_stdin_used
54: 0000000000000660 101 FUNC GLOBAL DEFAULT 14 __libc_csu_init
55: 0000000000201018 0 NOTYPE GLOBAL DEFAULT 24 _end
56: 0000000000000530 43 FUNC GLOBAL DEFAULT 14 _start
57: 0000000000201010 0 NOTYPE GLOBAL DEFAULT 24 __bss_start
58: 000000000000063a 34 FUNC GLOBAL DEFAULT 14 main
59: 0000000000201010 0 OBJECT GLOBAL HIDDEN 23 __TMC_END__
60: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_registerTMCloneTable
61: 0000000000000000 0 FUNC WEAK DEFAULT UND __cxa_finalize@@GLIBC_2.2
62: 00000000000004e8 0 FUNC GLOBAL DEFAULT 11 _init
驻留地址0x000000000000063a是main函数的符号,字节大小34,调试符号提供源代码行和二进制指令间的完整映射关系,描述函数的参数、堆栈帧信息等。对于ELF文件调试符号通常以DWARF格式嵌在二进制文件中。PE文件则以PDB格式单独的符号文件形式存在。release版本的二进制文件会剥离调试符号信息
- 剥离二进制文件

反汇编二进制文件
利用objdump来进行简单的反汇编
- 对象文件,查看只读数据

- 反汇编
$ objdump -M intel -d compilation_example.o
compilation_example.o: 文件格式 elf64-x86-64
Disassembly of section .init:
00000000000004e8 <_init>:
4e8: 48 83 ec 08 sub rsp,0x8
4ec: 48 8b 05 f5 0a 20 00 mov rax,QWORD PTR [rip+0x200af5] # 200fe8 <__gmon_start__>
4f3: 48 85 c0 test rax,rax
4f6: 74 02 je 4fa <_init+0x12>
4f8: ff d0 call rax
4fa: 48 83 c4 08 add rsp,0x8
4fe: c3 ret
Disassembly of section .plt:
0000000000000500 <.plt>:
500: ff 35 ba 0a 20 00 push QWORD PTR [rip+0x200aba] # 200fc0 <_GLOBAL_OFFSET_TABLE_+0x8>
506: ff 25 bc 0a 20 00 jmp QWORD PTR [rip+0x200abc] # 200fc8 <_GLOBAL_OFFSET_TABLE_+0x10>
50c: 0f 1f 40 00 nop DWORD PTR [rax+0x0]
0000000000000510 <puts@plt>:
510: ff 25 ba 0a 20 00 jmp QWORD PTR [rip+0x200aba] # 200fd0 <puts@GLIBC_2.2.5>
516: 68 00 00 00 00 push 0x0
51b: e9 e0 ff ff ff jmp 500 <.plt>
Disassembly of section .plt.got:
0000000000000520 <__cxa_finalize@plt>:
520: ff 25 d2 0a 20 00 jmp QWORD PTR [rip+0x200ad2] # 200ff8 <__cxa_finalize@GLIBC_2.2.5>
526: 66 90 xchg ax,ax
Disassembly of section .text:
0000000000000530 <_start>:
530: 31 ed xor ebp,ebp
532: 49 89 d1 mov r9,rdx
535: 5e pop rsi
536: 48 89 e2 mov rdx,rsp
539: 48 83 e4 f0 and rsp,0xfffffffffffffff0
53d: 50 push rax
53e: 54 push rsp
53f: 4c 8d 05 8a 01 00 00 lea r8,[rip+0x18a] # 6d0 <__libc_csu_fini>
546: 48 8d 0d 13 01 00 00 lea rcx,[rip+0x113] # 660 <__libc_csu_init>
54d: 48 8d 3d e6 00 00 00 lea rdi,[rip+0xe6] # 63a <main>
554: ff 15 86 0a 20 00 call QWORD PTR [rip+0x200a86] # 200fe0 <__libc_start_main@GLIBC_2.2.5>
55a: f4 hlt
55b: 0f 1f 44 00 00 nop DWORD PTR [rax+rax*1+0x0]
0000000000000560 <deregister_tm_clones>:
560: 48 8d 3d a9 0a 20 00 lea rdi,[rip+0x200aa9] # 201010 <__TMC_END__>
567: 55 push rbp
568: 48 8d 05 a1 0a 20 00 lea rax,[rip+0x200aa1] # 201010 <__TMC_END__>
56f: 48 39 f8 cmp rax,rdi
572: 48 89 e5 mov rbp,rsp
575: 74 19 je 590 <deregister_tm_clones+0x30>
577: 48 8b 05 5a 0a 20 00 mov rax,QWORD PTR [rip+0x200a5a] # 200fd8 <_ITM_deregisterTMCloneTable>
57e: 48 85 c0 test rax,rax
581: 74 0d je 590 <deregister_tm_clones+0x30>
583: 5d pop rbp
584: ff e0 jmp rax
586: 66 2e 0f 1f 84 00 00 nop WORD PTR cs:[rax+rax*1+0x0]
58d: 00 00 00
590: 5d pop rbp
591: c3 ret
592: 0f 1f 40 00 nop DWORD PTR [rax+0x0]
596: 66 2e 0f 1f 84 00 00 nop WORD PTR cs:[rax+rax*1+0x0]
59d: 00 00 00
00000000000005a0 <register_tm_clones>:
5a0: 48 8d 3d 69 0a 20 00 lea rdi,[rip+0x200a69] # 201010 <__TMC_END__>
5a7: 48 8d 35 62 0a 20 00 lea rsi,[rip+0x200a62] # 201010 <__TMC_END__>
5ae: 55 push rbp
5af: 48 29 fe sub rsi,rdi
5b2: 48 89 e5 mov rbp,rsp
5b5: 48 c1 fe 03 sar rsi,0x3
5b9: 48 89 f0 mov rax,rsi
5bc: 48 c1 e8 3f shr rax,0x3f
5c0: 48 01 c6 add rsi,rax
5c3: 48 d1 fe sar rsi,1
5c6: 74 18 je 5e0 <register_tm_clones+0x40>
5c8: 48 8b 05 21 0a 20 00 mov rax,QWORD PTR [rip+0x200a21] # 200ff0 <_ITM_registerTMCloneTable>
5cf: 48 85 c0 test rax,rax
5d2: 74 0c je 5e0 <register_tm_clones+0x40>
5d4: 5d pop rbp
5d5: ff e0 jmp rax
5d7: 66 0f 1f 84 00 00 00 nop WORD PTR [rax+rax*1+0x0]
5de: 00 00
5e0: 5d pop rbp
5e1: c3 ret
5e2: 0f 1f 40 00 nop DWORD PTR [rax+0x0]
5e6: 66 2e 0f 1f 84 00 00 nop WORD PTR cs:[rax+rax*1+0x0]
5ed: 00 00 00
00000000000005f0 <__do_global_dtors_aux>:
5f0: 80 3d 19 0a 20 00 00 cmp BYTE PTR [rip+0x200a19],0x0 # 201010 <__TMC_END__>
5f7: 75 2f jne 628 <__do_global_dtors_aux+0x38>
5f9: 48 83 3d f7 09 20 00 cmp QWORD PTR [rip+0x2009f7],0x0 # 200ff8 <__cxa_finalize@GLIBC_2.2.5>
600: 00
601: 55 push rbp
602: 48 89 e5 mov rbp,rsp
605: 74 0c je 613 <__do_global_dtors_aux+0x23>
607: 48 8b 3d fa 09 20 00 mov rdi,QWORD PTR [rip+0x2009fa] # 201008 <__dso_handle>
60e: e8 0d ff ff ff call 520 <__cxa_finalize@plt>
613: e8 48 ff ff ff call 560 <deregister_tm_clones>
618: c6 05 f1 09 20 00 01 mov BYTE PTR [rip+0x2009f1],0x1 # 201010 <__TMC_END__>
61f: 5d pop rbp
620: c3 ret
621: 0f 1f 80 00 00 00 00 nop DWORD PTR [rax+0x0]
628: f3 c3 repz ret
62a: 66 0f 1f 44 00 00 nop WORD PTR [rax+rax*1+0x0]
0000000000000630 <frame_dummy>:
630: 55 push rbp
631: 48 89 e5 mov rbp,rsp
634: 5d pop rbp
635: e9 66 ff ff ff jmp 5a0 <register_tm_clones>
000000000000063a <main>:
63a: 55 push rbp
63b: 48 89 e5 mov rbp,rsp
63e: 48 83 ec 10 sub rsp,0x10
642: 89 7d fc mov DWORD PTR [rbp-0x4],edi
645: 48 89 75 f0 mov QWORD PTR [rbp-0x10],rsi
649: 48 8d 3d 94 00 00 00 lea rdi,[rip+0x94] # 6e4 <_IO_stdin_used+0x4>
650: e8 bb fe ff ff call 510 <puts@plt>
655: b8 00 00 00 00 mov eax,0x0
65a: c9 leave
65b: c3 ret
65c: 0f 1f 40 00 nop DWORD PTR [rax+0x0]
0000000000000660 <__libc_csu_init>:
660: 41 57 push r15
662: 41 56 push r14
664: 49 89 d7 mov r15,rdx
667: 41 55 push r13
669: 41 54 push r12
66b: 4c 8d 25 46 07 20 00 lea r12,[rip+0x200746] # 200db8 <__frame_dummy_init_array_entry>
672: 55 push rbp
673: 48 8d 2d 46 07 20 00 lea rbp,[rip+0x200746] # 200dc0 <__init_array_end>
67a: 53 push rbx
67b: 41 89 fd mov r13d,edi
67e: 49 89 f6 mov r14,rsi
681: 4c 29 e5 sub rbp,r12
684: 48 83 ec 08 sub rsp,0x8
688: 48 c1 fd 03 sar rbp,0x3
68c: e8 57 fe ff ff call 4e8 <_init>
691: 48 85 ed test rbp,rbp
694: 74 20 je 6b6 <__libc_csu_init+0x56>
696: 31 db xor ebx,ebx
698: 0f 1f 84 00 00 00 00 nop DWORD PTR [rax+rax*1+0x0]
69f: 00
6a0: 4c 89 fa mov rdx,r15
6a3: 4c 89 f6 mov rsi,r14
6a6: 44 89 ef mov edi,r13d
6a9: 41 ff 14 dc call QWORD PTR [r12+rbx*8]
6ad: 48 83 c3 01 add rbx,0x1
6b1: 48 39 dd cmp rbp,rbx
6b4: 75 ea jne 6a0 <__libc_csu_init+0x40>
6b6: 48 83 c4 08 add rsp,0x8
6ba: 5b pop rbx
6bb: 5d pop rbp
6bc: 41 5c pop r12
6be: 41 5d pop r13
6c0: 41 5e pop r14
6c2: 41 5f pop r15
6c4: c3 ret
6c5: 90 nop
6c6: 66 2e 0f 1f 84 00 00 nop WORD PTR cs:[rax+rax*1+0x0]
6cd: 00 00 00
00000000000006d0 <__libc_csu_fini>:
6d0: f3 c3 repz ret
Disassembly of section .fini:
00000000000006d4 <_fini>:
6d4: 48 83 ec 08 sub rsp,0x8
6d8: 48 83 c4 08 add rsp,0x8
6dc: c3 ret
- 查看剥离符号的二进制文件,函数已经合并成一大段代码
./a.out: 文件格式 elf64-x86-64
Disassembly of section .init:
00000000000004e8 <.init>:
4e8: 48 83 ec 08 sub rsp,0x8
4ec: 48 8b 05 f5 0a 20 00 mov rax,QWORD PTR [rip+0x200af5] # 200fe8 <__cxa_finalize@plt+0x200ac8>
4f3: 48 85 c0 test rax,rax
4f6: 74 02 je 4fa <puts@plt-0x16>
4f8: ff d0 call rax
4fa: 48 83 c4 08 add rsp,0x8
4fe: c3 ret
Disassembly of section .plt:
0000000000000500 <puts@plt-0x10>:
500: ff 35 ba 0a 20 00 push QWORD PTR [rip+0x200aba] # 200fc0 <__cxa_finalize@plt+0x200aa0>
506: ff 25 bc 0a 20 00 jmp QWORD PTR [rip+0x200abc] # 200fc8 <__cxa_finalize@plt+0x200aa8>
50c: 0f 1f 40 00 nop DWORD PTR [rax+0x0]
0000000000000510 <puts@plt>:
510: ff 25 ba 0a 20 00 jmp QWORD PTR [rip+0x200aba] # 200fd0 <__cxa_finalize@plt+0x200ab0>
516: 68 00 00 00 00 push 0x0
51b: e9 e0 ff ff ff jmp 500 <puts@plt-0x10>
Disassembly of section .plt.got:
0000000000000520 <__cxa_finalize@plt>:
520: ff 25 d2 0a 20 00 jmp QWORD PTR [rip+0x200ad2] # 200ff8 <__cxa_finalize@plt+0x200ad8>
526: 66 90 xchg ax,ax
Disassembly of section .text:
0000000000000530 <.text>:
530: 31 ed xor ebp,ebp
532: 49 89 d1 mov r9,rdx
535: 5e pop rsi
536: 48 89 e2 mov rdx,rsp
539: 48 83 e4 f0 and rsp,0xfffffffffffffff0
53d: 50 push rax
53e: 54 push rsp
53f: 4c 8d 05 8a 01 00 00 lea r8,[rip+0x18a] # 6d0 <__cxa_finalize@plt+0x1b0>
546: 48 8d 0d 13 01 00 00 lea rcx,[rip+0x113] # 660 <__cxa_finalize@plt+0x140>
54d: 48 8d 3d e6 00 00 00 lea rdi,[rip+0xe6] # 63a <__cxa_finalize@plt+0x11a>
554: ff 15 86 0a 20 00 call QWORD PTR [rip+0x200a86] # 200fe0 <__cxa_finalize@plt+0x200ac0>
55a: f4 hlt
55b: 0f 1f 44 00 00 nop DWORD PTR [rax+rax*1+0x0]
560: 48 8d 3d a9 0a 20 00 lea rdi,[rip+0x200aa9] # 201010 <__cxa_finalize@plt+0x200af0>
567: 55 push rbp
568: 48 8d 05 a1 0a 20 00 lea rax,[rip+0x200aa1] # 201010 <__cxa_finalize@plt+0x200af0>
56f: 48 39 f8 cmp rax,rdi
572: 48 89 e5 mov rbp,rsp
575: 74 19 je 590 <__cxa_finalize@plt+0x70>
577: 48 8b 05 5a 0a 20 00 mov rax,QWORD PTR [rip+0x200a5a] # 200fd8 <__cxa_finalize@plt+0x200ab8>
57e: 48 85 c0 test rax,rax
581: 74 0d je 590 <__cxa_finalize@plt+0x70>
583: 5d pop rbp
584: ff e0 jmp rax
586: 66 2e 0f 1f 84 00 00 nop WORD PTR cs:[rax+rax*1+0x0]
58d: 00 00 00
590: 5d pop rbp
591: c3 ret
592: 0f 1f 40 00 nop DWORD PTR [rax+0x0]
596: 66 2e 0f 1f 84 00 00 nop WORD PTR cs:[rax+rax*1+0x0]
59d: 00 00 00
5a0: 48 8d 3d 69 0a 20 00 lea rdi,[rip+0x200a69] # 201010 <__cxa_finalize@plt+0x200af0>
5a7: 48 8d 35 62 0a 20 00 lea rsi,[rip+0x200a62] # 201010 <__cxa_finalize@plt+0x200af0>
5ae: 55 push rbp
5af: 48 29 fe sub rsi,rdi
5b2: 48 89 e5 mov rbp,rsp
5b5: 48 c1 fe 03 sar rsi,0x3
5b9: 48 89 f0 mov rax,rsi
5bc: 48 c1 e8 3f shr rax,0x3f
5c0: 48 01 c6 add rsi,rax
5c3: 48 d1 fe sar rsi,1
5c6: 74 18 je 5e0 <__cxa_finalize@plt+0xc0>
5c8: 48 8b 05 21 0a 20 00 mov rax,QWORD PTR [rip+0x200a21] # 200ff0 <__cxa_finalize@plt+0x200ad0>
5cf: 48 85 c0 test rax,rax
5d2: 74 0c je 5e0 <__cxa_finalize@plt+0xc0>
5d4: 5d pop rbp
5d5: ff e0 jmp rax
5d7: 66 0f 1f 84 00 00 00 nop WORD PTR [rax+rax*1+0x0]
5de: 00 00
5e0: 5d pop rbp
5e1: c3 ret
5e2: 0f 1f 40 00 nop DWORD PTR [rax+0x0]
5e6: 66 2e 0f 1f 84 00 00 nop WORD PTR cs:[rax+rax*1+0x0]
5ed: 00 00 00
5f0: 80 3d 19 0a 20 00 00 cmp BYTE PTR [rip+0x200a19],0x0 # 201010 <__cxa_finalize@plt+0x200af0>
5f7: 75 2f jne 628 <__cxa_finalize@plt+0x108>
5f9: 48 83 3d f7 09 20 00 cmp QWORD PTR [rip+0x2009f7],0x0 # 200ff8 <__cxa_finalize@plt+0x200ad8>
600: 00
601: 55 push rbp
602: 48 89 e5 mov rbp,rsp
605: 74 0c je 613 <__cxa_finalize@plt+0xf3>
607: 48 8b 3d fa 09 20 00 mov rdi,QWORD PTR [rip+0x2009fa] # 201008 <__cxa_finalize@plt+0x200ae8>
60e: e8 0d ff ff ff call 520 <__cxa_finalize@plt>
613: e8 48 ff ff ff call 560 <__cxa_finalize@plt+0x40>
618: c6 05 f1 09 20 00 01 mov BYTE PTR [rip+0x2009f1],0x1 # 201010 <__cxa_finalize@plt+0x200af0>
61f: 5d pop rbp
620: c3 ret
621: 0f 1f 80 00 00 00 00 nop DWORD PTR [rax+0x0]
628: f3 c3 repz ret
62a: 66 0f 1f 44 00 00 nop WORD PTR [rax+rax*1+0x0]
630: 55 push rbp
631: 48 89 e5 mov rbp,rsp
634: 5d pop rbp
635: e9 66 ff ff ff jmp 5a0 <__cxa_finalize@plt+0x80>
63a: 55 push rbp
63b: 48 89 e5 mov rbp,rsp
63e: 48 83 ec 10 sub rsp,0x10
642: 89 7d fc mov DWORD PTR [rbp-0x4],edi
645: 48 89 75 f0 mov QWORD PTR [rbp-0x10],rsi
649: 48 8d 3d 94 00 00 00 lea rdi,[rip+0x94] # 6e4 <__cxa_finalize@plt+0x1c4>
650: e8 bb fe ff ff call 510 <puts@plt>
655: b8 00 00 00 00 mov eax,0x0
65a: c9 leave
65b: c3 ret
65c: 0f 1f 40 00 nop DWORD PTR [rax+0x0]
660: 41 57 push r15
662: 41 56 push r14
664: 49 89 d7 mov r15,rdx
667: 41 55 push r13
669: 41 54 push r12
66b: 4c 8d 25 46 07 20 00 lea r12,[rip+0x200746] # 200db8 <__cxa_finalize@plt+0x200898>
672: 55 push rbp
673: 48 8d 2d 46 07 20 00 lea rbp,[rip+0x200746] # 200dc0 <__cxa_finalize@plt+0x2008a0>
67a: 53 push rbx
67b: 41 89 fd mov r13d,edi
67e: 49 89 f6 mov r14,rsi
681: 4c 29 e5 sub rbp,r12
684: 48 83 ec 08 sub rsp,0x8
688: 48 c1 fd 03 sar rbp,0x3
68c: e8 57 fe ff ff call 4e8 <puts@plt-0x28>
691: 48 85 ed test rbp,rbp
694: 74 20 je 6b6 <__cxa_finalize@plt+0x196>
696: 31 db xor ebx,ebx
698: 0f 1f 84 00 00 00 00 nop DWORD PTR [rax+rax*1+0x0]
69f: 00
6a0: 4c 89 fa mov rdx,r15
6a3: 4c 89 f6 mov rsi,r14
6a6: 44 89 ef mov edi,r13d
6a9: 41 ff 14 dc call QWORD PTR [r12+rbx*8]
6ad: 48 83 c3 01 add rbx,0x1
6b1: 48 39 dd cmp rbp,rbx
6b4: 75 ea jne 6a0 <__cxa_finalize@plt+0x180>
6b6: 48 83 c4 08 add rsp,0x8
6ba: 5b pop rbx
6bb: 5d pop rbp
6bc: 41 5c pop r12
6be: 41 5d pop r13
6c0: 41 5e pop r14
6c2: 41 5f pop r15
6c4: c3 ret
6c5: 90 nop
6c6: 66 2e 0f 1f 84 00 00 nop WORD PTR cs:[rax+rax*1+0x0]
6cd: 00 00 00
6d0: f3 c3 repz ret
Disassembly of section .fini:
00000000000006d4 <.fini>:
6d4: 48 83 ec 08 sub rsp,0x8
6d8: 48 83 c4 08 add rsp,0x8
6dc: c3 ret
- 二进制文件的加载与执行
Linux系统加载FLE文件与Window加载PE文件非常类似,是一个复杂的过程。操作系统首先运行程序创建一个包含虚拟地址空间的进程,然后将解释器映射到进程的虚拟空间内用户层程序通常是一个名为ld-linux-x86-64.so的共享库

- 加载示意

浙公网安备 33010602011771号