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的共享库

  • 加载示意

posted on 2022-03-01 15:11  #搬砖仔  阅读(422)  评论(0)    收藏  举报

导航