環(huán)境
操作系統(tǒng):MacOS
編譯器:LLVM
反編譯工具:Disassembler
一.反匯編的意義
對(duì)于一個(gè)C語言工程師來說扔枫,匯編語言幾乎是一門必修課偏陪,而對(duì)于一個(gè)黑客來說祝迂,反匯編就是敲開各種漏洞的大門了姐军,在這篇文章中,我們會(huì)正向逆向全部走一遍宇攻,以期能獲得反匯編姿勢(shì)的初級(jí)奧義♂
二.編譯♂
1.預(yù)處理
在C語言的編譯中惫叛,第一步就是預(yù)處理了,我們本著能少寫就少寫的原則就用《C指針淺談》一文中的C語言代碼來作為我們編譯和逆向分析的目標(biāo)代碼來愉快的玩耍逞刷。
但是在這之前我們要稍微修改一下代碼嘉涌。
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;
}
相比上次,我們?cè)黾恿藘蓚€(gè)宏定義夸浅。
我們知道對(duì)于LLVM編譯器來說仑最,編譯輸出可執(zhí)行文件的過程可以分為四個(gè)階段:
預(yù)處理,匯編帆喇,編譯警医,鏈接。
由預(yù)處理來完成匯編前對(duì)源代碼的文本處理坯钦,然后由匯編器把C源碼匯編成相應(yīng)的匯編代碼预皇,再由編譯部分把匯編程序編譯成二進(jìn)制機(jī)器碼,最后再把各個(gè)機(jī)器碼程序段鏈接到一起成為完整的可執(zhí)行程序婉刀。
那么我們先看看預(yù)處理階段編譯器做了什么
輸入命令
clang -E test_main.cpp -o ./output/test_main.i
cat ./output/test_main.i
這個(gè)時(shí)候會(huì)輸出一大段代碼吟温,包含了頭文件中的各種聲明及定義
我們截取源代碼部分的預(yù)處理結(jié)果
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宏定義的內(nèi)容被定義定義結(jié)果給完全取代掉了
所以在預(yù)處理的過程中,程序完成了對(duì)源代碼中宏定義的替換突颊,以及對(duì)引入的頭文件的倒入鲁豪,頭文件聲明的引入將使編譯程序在階段3中生成的機(jī)器編碼能在階段4中被正確的鏈接,所以當(dāng)編譯程序在link階段出現(xiàn)error的時(shí)候律秃,可以對(duì)各種頭文件進(jìn)行檢查呈昔。檢查程序的引用是否正確。
2.匯編
我們對(duì)源代碼進(jìn)行匯編
輸入命令:
clang -S test_main.cpp -o ./output/test_main.s
得到文件test_main.s友绝,查看test_main.s中的內(nèi)容
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.編譯
接下來我們對(duì)匯編代碼進(jìn)行編譯,生成二進(jìn)制的.o文件
命令
clang -c test_main.cpp -o ./output/test_main
然后通過.o文件生成最后的可執(zhí)行文件
命令
clang ./output/test_main.o -o ./output/test_main
./output/test_main
得到程序正常輸出的結(jié)果
&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.反匯編
輸出了匯編結(jié)果及可執(zhí)行程序之后肝劲,就要開始今天的核心內(nèi)容——逆向迁客。
在這里我們使用macOS平臺(tái)下一款非常好用的反匯編軟件Disassembler來進(jìn)行機(jī)器碼到匯編代碼的轉(zhuǎn)換郭宝。
首先我們對(duì)沒有l(wèi)ink過的.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
接下來我們對(duì)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
因?yàn)橹皇呛唵蔚囊粋€(gè)文件的編譯,所以并不會(huì)生成多個(gè).o文件等待鏈接掷漱,所以實(shí)際上這兩份反匯編代碼的代碼段是一樣的粘室,區(qū)別只是在文件的頭部格式里。
4.代碼分析
現(xiàn)在我們來對(duì)反匯編之后的代碼進(jìn)行分析卜范。(需要一定的堆衔统,棧,80x86匯編及程序段知識(shí))
push rbp
mov rbp, rsp
這兩行是main函數(shù)的起始部分海雪,我們知道函數(shù)的調(diào)用锦爵,需要先將當(dāng)前運(yùn)行到的代碼地址壓入堆棧,然后把函數(shù)段的地址放入代碼段的指針寄存器中奥裸,這樣才會(huì)在其后執(zhí)行到這段代碼险掀。
上面兩行代碼,是一波非惩逯妫虎的操作樟氢,它干了啥呢?首先將當(dāng)前椣丽基地址壓入堆棧埠啃,然后將當(dāng)前棧頂指針放入基址指針寄存器,也就是說之前的棧頂變成了現(xiàn)在的棧底伟恶,當(dāng)前棧頂棧底重合稱為了一個(gè)新的空棧碴开,對(duì),一個(gè)新的空棧的建立僅僅用了兩行機(jī)器碼完成知押,而我們了解了這種操作之后就會(huì)猜想叹螟,當(dāng)我們跨過棧基地址讀到的最后一段數(shù)據(jù)是不是就是上一個(gè)堆棧的椞ǘⅲ基地址罢绽?這樣一個(gè)基地址一個(gè)基地址的跳躍是不是就可以獲得操作系統(tǒng)boot時(shí)ASLR之后的地址了?總之静盅,不論你想做什么良价,這種時(shí)候盡情的發(fā)揮你猥瑣的才華就是了~~~