反汇编初探(一)
环境
操作系统:MacOS
编译器:LLVM
反编译工具:Disassembler
一.反汇编的意义
对于一个C语言工程师来说,汇编语言几乎是一门必修课,而对于一个黑客来说,反汇编就是敲开各种漏洞的大门了,在这篇文章中,我们会正向逆向全部走一遍,以期能获得反汇编姿势的初级奥义♂
二.编译♂
1.预处理
在C语言的编译中,第一步就是预处理了,我们本着能少写就少写的原则就用《C指针浅谈》一文中的C语言代码来作为我们编译和逆向分析的目标代码来愉快的玩耍。
但是在这之前我们要稍微修改一下代码。
code:
#include "stdio.h"
#include "stdlib.h"
#define MORPHEUS 723
#define SUEHPROM 327
int main(int argc, char* argv[]){
int a;
printf("&a = %d a = %d\n",&a,a);
a = MORPHEUS;
printf("&a = %d a = %d\n",&a,a);
printf("%d",&a);
int *b;
printf("&b = %d b = %d\n",&b,b);
b = &a;
printf("&b = %d b = %d *b = %d\n",&b,b,*b);
int **c;
printf("&c = %d c = %d\n",&c,c);
c = &b;
printf("&c = %d c = %d *c = %d **c = %d\n",&c,c,*c,**c);
int ***d;
printf("&d = %d d = %d\n",&d,d);
d = &c;
printf("&d = %d d = %d *d = %d **d = %d ***d = %d\n",&d,d,*d,**d,***d);
b = (int*)malloc(sizeof(int*)*1);
*b = SUEHPROM;
printf("&b = %d b = %d *b = %d\n",&b,b,*b);
int *const p1 = (int *)malloc(sizeof(int*)*1);
printf("&p1 = %d p1 = %d *p1 = %d\n",&p1,p1,*p1);
int const *p2;
printf("&p2 = % p2 = %d *p2 = %d\n",&p2,p2,*p2);
int const *const p3 = (int *)malloc(sizeof(int*)*1);
printf("&p3 = % p3 = %d *p3 = %d\n",&p3,p3,*p3);
return 0;
}
相比上次,我们增加了两个宏定义。
我们知道对于LLVM编译器来说,编译输出可执行文件的过程可以分为四个阶段:
预处理,汇编,编译,链接。
由预处理来完成汇编前对源代码的文本处理,然后由汇编器把C源码汇编成相应的汇编代码,再由编译部分把汇编程序编译成二进制机器码,最后再把各个机器码程序段链接到一起成为完整的可执行程序。
那么我们先看看预处理阶段编译器做了什么
输入命令
clang -E test_main.cpp -o ./output/test_main.i
cat ./output/test_main.i
这个时候会输出一大段代码,包含了头文件中的各种声明及定义
我们截取源代码部分的预处理结果
int main(int argc, char* argv[]){
int a;
printf("&a = %d a = %d\n",&a,a);
a = 723;
printf("&a = %d a = %d\n",&a,a);
printf("%d",&a);
int *b;
printf("&b = %d b = %d\n",&b,b);
b = &a;
printf("&b = %d b = %d *b = %d\n",&b,b,*b);
int **c;
printf("&c = %d c = %d\n",&c,c);
c = &b;
printf("&c = %d c = %d *c = %d **c = %d\n",&c,c,*c,**c);
int ***d;
printf("&d = %d d = %d\n",&d,d);
d = &c;
printf("&d = %d d = %d *d = %d **d = %d ***d = %d\n",&d,d,*d,**d,***d);
b = (int*)malloc(sizeof(int*)*1);
*b = 327;
printf("&b = %d b = %d *b = %d\n",&b,b,*b);
int *const p1 = (int *)malloc(sizeof(int*)*1);
printf("&p1 = %d p1 = %d *p1 = %d\n",&p1,p1,*p1);
int const *p2;
printf("&p2 = % p2 = %d *p2 = %d\n",&p2,p2,*p2);
int const *const p3 = (int *)malloc(sizeof(int*)*1);
printf("&p3 = % p3 = %d *p3 = %d\n",&p3,p3,*p3);
return 0;
}
define宏定义的内容被定义定义结果给完全取代掉了
所以在预处理的过程中,程序完成了对源代码中宏定义的替换,以及对引入的头文件的倒入,头文件声明的引入将使编译程序在阶段3中生成的机器编码能在阶段4中被正确的链接,所以当编译程序在link阶段出现error的时候,可以对各种头文件进行检查。检查程序的引用是否正确。
2.汇编
我们对源代码进行汇编
输入命令:
clang -S test_main.cpp -o ./output/test_main.s
得到文件test_main.s,查看test_main.s中的内容
Code:
.section __TEXT,__text,regular,pure_instructions
.macosx_version_min 10, 12
.globl _main
.p2align 4, 0x90
_main: ## @main
.cfi_startproc
## BB#0:
pushq %rbp
Ltmp0:
.cfi_def_cfa_offset 16
Ltmp1:
.cfi_offset %rbp, -16
movq %rsp, %rbp
Ltmp2:
.cfi_def_cfa_register %rbp
subq $128, %rsp
leaq L_.str(%rip), %rax
leaq -20(%rbp), %rcx
movl $0, -4(%rbp)
movl %edi, -8(%rbp)
movq %rsi, -16(%rbp)
movl -20(%rbp), %edx
movq %rax, %rdi
movq %rcx, %rsi
movb $0, %al
callq _printf
leaq L_.str(%rip), %rdi
leaq -20(%rbp), %rsi
movl $723, -20(%rbp) ## imm = 0x2D3
movl -20(%rbp), %edx
movl %eax, -76(%rbp) ## 4-byte Spill
movb $0, %al
callq _printf
leaq L_.str.1(%rip), %rdi
leaq -20(%rbp), %rsi
movl %eax, -80(%rbp) ## 4-byte Spill
movb $0, %al
callq _printf
leaq L_.str.2(%rip), %rdi
leaq -32(%rbp), %rsi
movq -32(%rbp), %rdx
movl %eax, -84(%rbp) ## 4-byte Spill
movb $0, %al
callq _printf
leaq L_.str.3(%rip), %rdi
leaq -32(%rbp), %rsi
leaq -20(%rbp), %rcx
movq %rcx, -32(%rbp)
movq -32(%rbp), %rdx
movq -32(%rbp), %rcx
movl (%rcx), %ecx
movl %eax, -88(%rbp) ## 4-byte Spill
movb $0, %al
callq _printf
leaq L_.str.4(%rip), %rdi
leaq -40(%rbp), %rsi
movq -40(%rbp), %rdx
movl %eax, -92(%rbp) ## 4-byte Spill
movb $0, %al
callq _printf
leaq L_.str.5(%rip), %rdi
leaq -40(%rbp), %rsi
leaq -32(%rbp), %rdx
movq %rdx, -40(%rbp)
movq -40(%rbp), %rdx
movq -40(%rbp), %r8
movq (%r8), %rcx
movq -40(%rbp), %r8
movq (%r8), %r8
movl (%r8), %r8d
movl %eax, -96(%rbp) ## 4-byte Spill
movb $0, %al
callq _printf
leaq L_.str.6(%rip), %rdi
leaq -48(%rbp), %rsi
movq -48(%rbp), %rdx
movl %eax, -100(%rbp) ## 4-byte Spill
movb $0, %al
callq _printf
leaq L_.str.7(%rip), %rdi
leaq -48(%rbp), %rsi
leaq -40(%rbp), %rcx
movq %rcx, -48(%rbp)
movq -48(%rbp), %rdx
movq -48(%rbp), %rcx
movq (%rcx), %rcx
movq -48(%rbp), %r9
movq (%r9), %r9
movq (%r9), %r8
movq -48(%rbp), %r9
movq (%r9), %r9
movq (%r9), %r9
movl (%r9), %r9d
movl %eax, -104(%rbp) ## 4-byte Spill
movb $0, %al
callq _printf
movl $8, %r9d
movl %r9d, %edi
movl %eax, -108(%rbp) ## 4-byte Spill
callq _malloc
leaq L_.str.3(%rip), %rdi
leaq -32(%rbp), %rsi
movq %rax, -32(%rbp)
movq -32(%rbp), %rax
movl $327, (%rax) ## imm = 0x147
movq -32(%rbp), %rdx
movq -32(%rbp), %rax
movl (%rax), %ecx
movb $0, %al
callq _printf
movl $8, %ecx
movl %ecx, %edi
movl %eax, -112(%rbp) ## 4-byte Spill
callq _malloc
leaq L_.str.8(%rip), %rdi
leaq -56(%rbp), %rsi
movq %rax, -56(%rbp)
movq -56(%rbp), %rdx
movq -56(%rbp), %rax
movl (%rax), %ecx
movb $0, %al
callq _printf
leaq L_.str.9(%rip), %rdi
leaq -64(%rbp), %rsi
movq -64(%rbp), %rdx
movq -64(%rbp), %r8
movl (%r8), %ecx
movl %eax, -116(%rbp) ## 4-byte Spill
movb $0, %al
callq _printf
movl $8, %ecx
movl %ecx, %edi
movl %eax, -120(%rbp) ## 4-byte Spill
callq _malloc
leaq L_.str.10(%rip), %rdi
leaq -72(%rbp), %rsi
movq %rax, -72(%rbp)
movq -72(%rbp), %rdx
movq -72(%rbp), %rax
movl (%rax), %ecx
movb $0, %al
callq _printf
xorl %ecx, %ecx
movl %eax, -124(%rbp) ## 4-byte Spill
movl %ecx, %eax
addq $128, %rsp
popq %rbp
retq
.cfi_endproc
.section __TEXT,__cstring,cstring_literals
L_.str: ## @.str
.asciz "&a = %d a = %d\n"
L_.str.1: ## @.str.1
.asciz "%d"
L_.str.2: ## @.str.2
.asciz "&b = %d b = %d\n"
L_.str.3: ## @.str.3
.asciz "&b = %d b = %d *b = %d\n"
L_.str.4: ## @.str.4
.asciz "&c = %d c = %d\n"
L_.str.5: ## @.str.5
.asciz "&c = %d c = %d *c = %d **c = %d\n"
L_.str.6: ## @.str.6
.asciz "&d = %d d = %d\n"
L_.str.7: ## @.str.7
.asciz "&d = %d d = %d *d = %d **d = %d ***d = %d\n"
L_.str.8: ## @.str.8
.asciz "&p1 = %d p1 = %d *p1 = %d\n"
L_.str.9: ## @.str.9
.asciz "&p2 = % p2 = %d *p2 = %d\n"
L_.str.10: ## @.str.10
.asciz "&p3 = % p3 = %d *p3 = %d\n"
.subsections_via_symbols
3.编译
接下来我们对汇编代码进行编译,生成二进制的.o文件
命令
clang -c test_main.cpp -o ./output/test_main
然后通过.o文件生成最后的可执行文件
命令
clang ./output/test_main.o -o ./output/test_main
./output/test_main
得到程序正常输出的结果
&a = 1363859820 a = 0
&a = 1363859820 a = 723
1363859820&b = 1363859808 b = 0
&b = 1363859808 b = 1363859820 *b = 723
&c = 1363859800 c = 0
&c = 1363859800 c = 1363859808 *c = 1363859820 **c = 723
&d = 1363859792 d = 0
&d = 1363859792 d = 1363859800 *d = 1363859808 **d = 1363859820 ***d = 723
&b = 1363859808 b = -1698692272 *b = 327
&p1 = 1363859784 p1 = -1698683408 *p1 = 0
&p2 = 0x7fff514ad9402 = 474678464 *p2 = 25
&p3 = 0x7fff514ad9383 = -1698683392 *p3 = 0
4.反汇编
输出了汇编结果及可执行程序之后,就要开始今天的核心内容——逆向。
在这里我们使用macOS平台下一款非常好用的反汇编软件Disassembler来进行机器码到汇编代码的转换。
首先我们对没有link过的.o文件反汇编得到:
/*
--------------------------------------------------------------------------------
File: /test/output/test_main.o
MachO file
CPU: intel/x86_64
64 bits (Little Endian)
--------------------------------------------------------------------------------
*/
; Segment
; Range: [0x0; 0x3a8[ (936 bytes)
; File offset : [544; 1480[ (936 bytes)
; Permissions: readable / writable / executable
; Section __text
; Range: [0x0; 0x214[ (532 bytes)
; File offset : [544; 1076[ (532 bytes)
; Flags: 0x80000400
; S_REGULAR
; S_ATTR_PURE_INSTRUCTIONS
; S_ATTR_SOME_INSTRUCTIONS
; ================ B E G I N N I N G O F P R O C E D U R E ================
; Variables:
; var_4: -4
; var_8: -8
; var_10: -16
; var_14: -20
; var_20: -32
; var_28: -40
; var_30: -48
; var_38: -56
; var_40: -64
; var_48: -72
; var_4C: -76
; var_50: -80
; var_54: -84
; var_58: -88
; var_5C: -92
; var_60: -96
; var_64: -100
; var_68: -104
; var_6C: -108
; var_70: -112
; var_74: -116
; var_78: -120
; var_7C: -124
_main:
0000000000000000 push rbp
0000000000000001 mov rbp, rsp
0000000000000004 sub rsp, 0x80
000000000000000b lea rax, qword [0x214] ; "&a = %d a = %d\\n"
0000000000000012 lea rcx, qword [rbp+var_14]
0000000000000016 mov dword [rbp+var_4], 0x0
000000000000001d mov dword [rbp+var_8], edi
0000000000000020 mov qword [rbp+var_10], rsi
0000000000000024 mov edx, dword [rbp+var_14]
0000000000000027 mov rdi, rax ; argument "format" for method _printf
000000000000002a mov rsi, rcx
000000000000002d mov al, 0x0
000000000000002f call _printf
0000000000000034 lea rdi, qword [0x214] ; "&a = %d a = %d\\n", argument "format" for method _printf
000000000000003b lea rsi, qword [rbp+var_14]
000000000000003f mov dword [rbp+var_14], 0x2d3
0000000000000046 mov edx, dword [rbp+var_14]
0000000000000049 mov dword [rbp+var_4C], eax
000000000000004c mov al, 0x0
000000000000004e call _printf
0000000000000053 lea rdi, qword [0x227] ; "%d", argument "format" for method _printf
000000000000005a lea rsi, qword [rbp+var_14]
000000000000005e mov dword [rbp+var_50], eax
0000000000000061 mov al, 0x0
0000000000000063 call _printf
0000000000000068 lea rdi, qword [0x22a] ; "&b = %d b = %d\\n", argument "format" for method _printf
000000000000006f lea rsi, qword [rbp+var_20]
0000000000000073 mov rdx, qword [rbp+var_20]
0000000000000077 mov dword [rbp+var_54], eax
000000000000007a mov al, 0x0
000000000000007c call _printf
0000000000000081 lea rdi, qword [0x23d] ; "&b = %d b = %d *b = %d\\n", argument "format" for method _printf
0000000000000088 lea rsi, qword [rbp+var_20]
000000000000008c lea rcx, qword [rbp+var_14]
0000000000000090 mov qword [rbp+var_20], rcx
0000000000000094 mov rdx, qword [rbp+var_20]
0000000000000098 mov rcx, qword [rbp+var_20]
000000000000009c mov ecx, dword [rcx]
000000000000009e mov dword [rbp+var_58], eax
00000000000000a1 mov al, 0x0
00000000000000a3 call _printf
00000000000000a8 lea rdi, qword [0x25b] ; "&c = %d c = %d\\n", argument "format" for method _printf
00000000000000af lea rsi, qword [rbp+var_28]
00000000000000b3 mov rdx, qword [rbp+var_28]
00000000000000b7 mov dword [rbp+var_5C], eax
00000000000000ba mov al, 0x0
00000000000000bc call _printf
00000000000000c1 lea rdi, qword [0x26e] ; "&c = %d c = %d *c = %d **c = %d\\n", argument "format" for method _printf
00000000000000c8 lea rsi, qword [rbp+var_28]
00000000000000cc lea rdx, qword [rbp+var_20]
00000000000000d0 mov qword [rbp+var_28], rdx
00000000000000d4 mov rdx, qword [rbp+var_28]
00000000000000d8 mov r8, qword [rbp+var_28]
00000000000000dc mov rcx, qword [r8]
00000000000000df mov r8, qword [rbp+var_28]
00000000000000e3 mov r8, qword [r8]
00000000000000e6 mov r8d, dword [r8]
00000000000000e9 mov dword [rbp+var_60], eax
00000000000000ec mov al, 0x0
00000000000000ee call _printf
00000000000000f3 lea rdi, qword [0x298] ; "&d = %d d = %d\\n", argument "format" for method _printf
00000000000000fa lea rsi, qword [rbp+var_30]
00000000000000fe mov rdx, qword [rbp+var_30]
0000000000000102 mov dword [rbp+var_64], eax
0000000000000105 mov al, 0x0
0000000000000107 call _printf
000000000000010c lea rdi, qword [0x2ab] ; "&d = %d d = %d *d = %d **d = %d ***d = %d\\n", argument "format" for method _printf
0000000000000113 lea rsi, qword [rbp+var_30]
0000000000000117 lea rcx, qword [rbp+var_28]
000000000000011b mov qword [rbp+var_30], rcx
000000000000011f mov rdx, qword [rbp+var_30]
0000000000000123 mov rcx, qword [rbp+var_30]
0000000000000127 mov rcx, qword [rcx]
000000000000012a mov r9, qword [rbp+var_30]
000000000000012e mov r9, qword [r9]
0000000000000131 mov r8, qword [r9]
0000000000000134 mov r9, qword [rbp+var_30]
0000000000000138 mov r9, qword [r9]
000000000000013b mov r9, qword [r9]
000000000000013e mov r9d, dword [r9]
0000000000000141 mov dword [rbp+var_68], eax
0000000000000144 mov al, 0x0
0000000000000146 call _printf
000000000000014b mov r9d, 0x8
0000000000000151 mov edi, r9d ; argument "size" for method _malloc
0000000000000154 mov dword [rbp+var_6C], eax
0000000000000157 call _malloc
000000000000015c lea rdi, qword [0x23d] ; "&b = %d b = %d *b = %d\\n", argument "format" for method _printf
0000000000000163 lea rsi, qword [rbp+var_20]
0000000000000167 mov qword [rbp+var_20], rax
000000000000016b mov rax, qword [rbp+var_20]
000000000000016f mov dword [rax], 0x147
0000000000000175 mov rdx, qword [rbp+var_20]
0000000000000179 mov rax, qword [rbp+var_20]
000000000000017d mov ecx, dword [rax]
000000000000017f mov al, 0x0
0000000000000181 call _printf
0000000000000186 mov ecx, 0x8
000000000000018b mov edi, ecx ; argument "size" for method _malloc
000000000000018d mov dword [rbp+var_70], eax
0000000000000190 call _malloc
0000000000000195 lea rdi, qword [0x2e2] ; "&p1 = %d p1 = %d *p1 = %d\\n", argument "format" for method _printf
000000000000019c lea rsi, qword [rbp+var_38]
00000000000001a0 mov qword [rbp+var_38], rax
00000000000001a4 mov rdx, qword [rbp+var_38]
00000000000001a8 mov rax, qword [rbp+var_38]
00000000000001ac mov ecx, dword [rax]
00000000000001ae mov al, 0x0
00000000000001b0 call _printf
00000000000001b5 lea rdi, qword [0x303] ; "&p2 = % p2 = %d *p2 = %d\\n", argument "format" for method _printf
00000000000001bc lea rsi, qword [rbp+var_40]
00000000000001c0 mov rdx, qword [rbp+var_40]
00000000000001c4 mov r8, qword [rbp+var_40]
00000000000001c8 mov ecx, dword [r8]
00000000000001cb mov dword [rbp+var_74], eax
00000000000001ce mov al, 0x0
00000000000001d0 call _printf
00000000000001d5 mov ecx, 0x8
00000000000001da mov edi, ecx ; argument "size" for method _malloc
00000000000001dc mov dword [rbp+var_78], eax
00000000000001df call _malloc
00000000000001e4 lea rdi, qword [0x323] ; "&p3 = % p3 = %d *p3 = %d\\n", argument "format" for method _printf
00000000000001eb lea rsi, qword [rbp+var_48]
00000000000001ef mov qword [rbp+var_48], rax
00000000000001f3 mov rdx, qword [rbp+var_48]
00000000000001f7 mov rax, qword [rbp+var_48]
00000000000001fb mov ecx, dword [rax]
00000000000001fd mov al, 0x0
00000000000001ff call _printf
0000000000000204 xor ecx, ecx
0000000000000206 mov dword [rbp+var_7C], eax
0000000000000209 mov eax, ecx
000000000000020b add rsp, 0x80
0000000000000212 pop rbp
0000000000000213 ret
; endp
接下来我们对link之后的文件反汇编得到:
; Section __text
; Range: [0x100000c40; 0x100000e54[ (532 bytes)
; File offset : [3136; 3668[ (532 bytes)
; Flags: 0x80000400
; S_REGULAR
; S_ATTR_PURE_INSTRUCTIONS
; S_ATTR_SOME_INSTRUCTIONS
; ================ B E G I N N I N G O F P R O C E D U R E ================
; Variables:
; var_4: -4
; var_8: -8
; var_10: -16
; var_14: -20
; var_20: -32
; var_28: -40
; var_30: -48
; var_38: -56
; var_40: -64
; var_48: -72
; var_4C: -76
; var_50: -80
; var_54: -84
; var_58: -88
; var_5C: -92
; var_60: -96
; var_64: -100
; var_68: -104
; var_6C: -108
; var_70: -112
; var_74: -116
; var_78: -120
; var_7C: -124
_main:
0000000100000c40 push rbp
0000000100000c41 mov rbp, rsp
0000000100000c44 sub rsp, 0x80
0000000100000c4b lea rax, qword [0x100000e84] ; "&a = %d a = %d\\n"
0000000100000c52 lea rcx, qword [rbp+var_14]
0000000100000c56 mov dword [rbp+var_4], 0x0
0000000100000c5d mov dword [rbp+var_8], edi
0000000100000c60 mov qword [rbp+var_10], rsi
0000000100000c64 mov edx, dword [rbp+var_14]
0000000100000c67 mov rdi, rax ; argument "format" for method imp___stubs__printf
0000000100000c6a mov rsi, rcx
0000000100000c6d mov al, 0x0
0000000100000c6f call imp___stubs__printf
0000000100000c74 lea rdi, qword [0x100000e84] ; "&a = %d a = %d\\n", argument "format" for method imp___stubs__printf
0000000100000c7b lea rsi, qword [rbp+var_14]
0000000100000c7f mov dword [rbp+var_14], 0x2d3
0000000100000c86 mov edx, dword [rbp+var_14]
0000000100000c89 mov dword [rbp+var_4C], eax
0000000100000c8c mov al, 0x0
0000000100000c8e call imp___stubs__printf
0000000100000c93 lea rdi, qword [0x100000e97] ; "%d", argument "format" for method imp___stubs__printf
0000000100000c9a lea rsi, qword [rbp+var_14]
0000000100000c9e mov dword [rbp+var_50], eax
0000000100000ca1 mov al, 0x0
0000000100000ca3 call imp___stubs__printf
0000000100000ca8 lea rdi, qword [0x100000e9a] ; "&b = %d b = %d\\n", argument "format" for method imp___stubs__printf
0000000100000caf lea rsi, qword [rbp+var_20]
0000000100000cb3 mov rdx, qword [rbp+var_20]
0000000100000cb7 mov dword [rbp+var_54], eax
0000000100000cba mov al, 0x0
0000000100000cbc call imp___stubs__printf
0000000100000cc1 lea rdi, qword [0x100000ead] ; "&b = %d b = %d *b = %d\\n", argument "format" for method imp___stubs__printf
0000000100000cc8 lea rsi, qword [rbp+var_20]
0000000100000ccc lea rcx, qword [rbp+var_14]
0000000100000cd0 mov qword [rbp+var_20], rcx
0000000100000cd4 mov rdx, qword [rbp+var_20]
0000000100000cd8 mov rcx, qword [rbp+var_20]
0000000100000cdc mov ecx, dword [rcx]
0000000100000cde mov dword [rbp+var_58], eax
0000000100000ce1 mov al, 0x0
0000000100000ce3 call imp___stubs__printf
0000000100000ce8 lea rdi, qword [0x100000ecb] ; "&c = %d c = %d\\n", argument "format" for method imp___stubs__printf
0000000100000cef lea rsi, qword [rbp+var_28]
0000000100000cf3 mov rdx, qword [rbp+var_28]
0000000100000cf7 mov dword [rbp+var_5C], eax
0000000100000cfa mov al, 0x0
0000000100000cfc call imp___stubs__printf
0000000100000d01 lea rdi, qword [0x100000ede] ; "&c = %d c = %d *c = %d **c = %d\\n", argument "format" for method imp___stubs__printf
0000000100000d08 lea rsi, qword [rbp+var_28]
0000000100000d0c lea rdx, qword [rbp+var_20]
0000000100000d10 mov qword [rbp+var_28], rdx
0000000100000d14 mov rdx, qword [rbp+var_28]
0000000100000d18 mov r8, qword [rbp+var_28]
0000000100000d1c mov rcx, qword [r8]
0000000100000d1f mov r8, qword [rbp+var_28]
0000000100000d23 mov r8, qword [r8]
0000000100000d26 mov r8d, dword [r8]
0000000100000d29 mov dword [rbp+var_60], eax
0000000100000d2c mov al, 0x0
0000000100000d2e call imp___stubs__printf
0000000100000d33 lea rdi, qword [0x100000f08] ; "&d = %d d = %d\\n", argument "format" for method imp___stubs__printf
0000000100000d3a lea rsi, qword [rbp+var_30]
0000000100000d3e mov rdx, qword [rbp+var_30]
0000000100000d42 mov dword [rbp+var_64], eax
0000000100000d45 mov al, 0x0
0000000100000d47 call imp___stubs__printf
0000000100000d4c lea rdi, qword [0x100000f1b] ; "&d = %d d = %d *d = %d **d = %d ***d = %d\\n", argument "format" for method imp___stubs__printf
0000000100000d53 lea rsi, qword [rbp+var_30]
0000000100000d57 lea rcx, qword [rbp+var_28]
0000000100000d5b mov qword [rbp+var_30], rcx
0000000100000d5f mov rdx, qword [rbp+var_30]
0000000100000d63 mov rcx, qword [rbp+var_30]
0000000100000d67 mov rcx, qword [rcx]
0000000100000d6a mov r9, qword [rbp+var_30]
0000000100000d6e mov r9, qword [r9]
0000000100000d71 mov r8, qword [r9]
0000000100000d74 mov r9, qword [rbp+var_30]
0000000100000d78 mov r9, qword [r9]
0000000100000d7b mov r9, qword [r9]
0000000100000d7e mov r9d, dword [r9]
0000000100000d81 mov dword [rbp+var_68], eax
0000000100000d84 mov al, 0x0
0000000100000d86 call imp___stubs__printf
0000000100000d8b mov r9d, 0x8
0000000100000d91 mov edi, r9d ; argument "size" for method imp___stubs__malloc
0000000100000d94 mov dword [rbp+var_6C], eax
0000000100000d97 call imp___stubs__malloc
0000000100000d9c lea rdi, qword [0x100000ead] ; "&b = %d b = %d *b = %d\\n", argument "format" for method imp___stubs__printf
0000000100000da3 lea rsi, qword [rbp+var_20]
0000000100000da7 mov qword [rbp+var_20], rax
0000000100000dab mov rax, qword [rbp+var_20]
0000000100000daf mov dword [rax], 0x147
0000000100000db5 mov rdx, qword [rbp+var_20]
0000000100000db9 mov rax, qword [rbp+var_20]
0000000100000dbd mov ecx, dword [rax]
0000000100000dbf mov al, 0x0
0000000100000dc1 call imp___stubs__printf
0000000100000dc6 mov ecx, 0x8
0000000100000dcb mov edi, ecx ; argument "size" for method imp___stubs__malloc
0000000100000dcd mov dword [rbp+var_70], eax
0000000100000dd0 call imp___stubs__malloc
0000000100000dd5 lea rdi, qword [0x100000f52] ; "&p1 = %d p1 = %d *p1 = %d\\n", argument "format" for method imp___stubs__printf
0000000100000ddc lea rsi, qword [rbp+var_38]
0000000100000de0 mov qword [rbp+var_38], rax
0000000100000de4 mov rdx, qword [rbp+var_38]
0000000100000de8 mov rax, qword [rbp+var_38]
0000000100000dec mov ecx, dword [rax]
0000000100000dee mov al, 0x0
0000000100000df0 call imp___stubs__printf
0000000100000df5 lea rdi, qword [0x100000f73] ; "&p2 = % p2 = %d *p2 = %d\\n", argument "format" for method imp___stubs__printf
0000000100000dfc lea rsi, qword [rbp+var_40]
0000000100000e00 mov rdx, qword [rbp+var_40]
0000000100000e04 mov r8, qword [rbp+var_40]
0000000100000e08 mov ecx, dword [r8]
0000000100000e0b mov dword [rbp+var_74], eax
0000000100000e0e mov al, 0x0
0000000100000e10 call imp___stubs__printf
0000000100000e15 mov ecx, 0x8
0000000100000e1a mov edi, ecx ; argument "size" for method imp___stubs__malloc
0000000100000e1c mov dword [rbp+var_78], eax
0000000100000e1f call imp___stubs__malloc
0000000100000e24 lea rdi, qword [0x100000f93] ; "&p3 = % p3 = %d *p3 = %d\\n", argument "format" for method imp___stubs__printf
0000000100000e2b lea rsi, qword [rbp+var_48]
0000000100000e2f mov qword [rbp+var_48], rax
0000000100000e33 mov rdx, qword [rbp+var_48]
0000000100000e37 mov rax, qword [rbp+var_48]
0000000100000e3b mov ecx, dword [rax]
0000000100000e3d mov al, 0x0
0000000100000e3f call imp___stubs__printf
0000000100000e44 xor ecx, ecx
0000000100000e46 mov dword [rbp+var_7C], eax
0000000100000e49 mov eax, ecx
0000000100000e4b add rsp, 0x80
0000000100000e52 pop rbp
0000000100000e53 ret
; endp
因为只是简单的一个文件的编译,所以并不会生成多个.o文件等待链接,所以实际上这两份反汇编代码的代码段是一样的,区别只是在文件的头部格式里。
4.代码分析
现在我们来对反汇编之后的代码进行分析。(需要一定的堆,栈,80x86汇编及程序段知识)
144787-3627fd1acac439b2.pngpush rbp
mov rbp, rsp
这两行是main函数的起始部分,我们知道函数的调用,需要先将当前运行到的代码地址压入堆栈,然后把函数段的地址放入代码段的指针寄存器中,这样才会在其后执行到这段代码。
上面两行代码,是一波非常虎的操作,它干了啥呢?首先将当前栈基地址压入堆栈,然后将当前栈顶指针放入基址指针寄存器,也就是说之前的栈顶变成了现在的栈底,当前栈顶栈底重合称为了一个新的空栈,对,一个新的空栈的建立仅仅用了两行机器码完成,而我们了解了这种操作之后就会猜想,当我们跨过栈基地址读到的最后一段数据是不是就是上一个堆栈的栈基地址?这样一个基地址一个基地址的跳跃是不是就可以获得操作系统boot时ASLR之后的地址了?总之,不论你想做什么,这种时候尽情的发挥你猥琐的才华就是了~~~