Slide 1

Slide 1 text

逆向⼯工程 REVERSING ENGINEERING

Slide 2

Slide 2 text

• blog • http://blog.terrynini.tw/ • 提問的智慧 • https://legacy.gitbook.com/book/ryanhanwu/how-to-ask- questions-the-smart-way/details INTRODUCTION

Slide 3

Slide 3 text

逆向⼯工程是什什麼? INTRODUCTION • 簡⽽而⾔言之,就是在沒有原始碼的情況下,做⼀一些好快樂好開⼼心的事情。 • 我們可以: • Debug • 把某些訊息拿掉(廣告⋯⋯) • 打補丁 (修正功能、翻譯成中⽂文介⾯面⋯⋯) • ⼆二次開發(samba⋯⋯) • 分析軟體⾏行行為(惡惡意軟體分析、抓程式抄襲⋯⋯) • …

Slide 4

Slide 4 text

執⾏行行檔是怎麼來來的(以編譯語⾔言的為例例) INTRODUCTION HelloWorld.c HelloWorld.i HelloWorld.s 剛學會C的你 HelloWorld.o Library *.obj HelloWorld Preprocessor:前處理理器 Compiler:編譯器 Assembler:組譯器 Linker:連結器 Preprocess Compile Assemble Link

Slide 5

Slide 5 text

GCC INTRODUCTION • GNU編譯器套裝(英語:GNU Compiler Collection,縮寫為GCC) • 到完成前處理理為⽌止: • gcc -E HelloWorld.c -o HelloWorld.i • 到完成編譯為⽌止: • gcc -S HelloWorld.c -o HelloWorld.s • 到完成組譯為⽌止: • gcc -c HelloWorld.c -o HelloWorld.o • 到完成連結: • gcc HelloWorld.c -o HelloWorld • 優化選項(有 -O0 到 -O3,0表⽰示不優化、3則是開啟所有優化) • gcc -O3 HelloWorld.c -o HelloWorld *編譯成32bit 要加 -m32

Slide 6

Slide 6 text

DEMO 000

Slide 7

Slide 7 text

PRACTICE 隨⼿手寫個程式看看他長怎樣 000

Slide 8

Slide 8 text

執⾏行行檔是怎麼來來的 INTRODUCTION • CPU有兩兩⼤大類指令集:精簡指令集(RISC)及複雜指令集(CISC) • ⼀一種機器語⾔言對應⼀一種指令集,所以我們有⼀一堆種類的機器語⾔言 • 組合語⾔言是機器語⾔言的助記符號,就是以⽂文字符號來來代替單純的數 字編碼,所以我們也有⼀一堆組合語⾔言 • 因此要逆向沒有原始碼的程式,⾸首先我們要先理理解組合語⾔言

Slide 9

Slide 9 text

X86 ASSEMBLY

Slide 10

Slide 10 text

X86 ASSEMBLY • 屬於複雜指令集(CISC) • 但是⽬目前的x86架構的CPU,核⼼心其實是RISC • ⽬目前你⼿手邊⼤大部分的桌機、筆電都是x86或是x86-64的架構 • 有著各式各樣神奇的指令,但是絕⼤大多數不常看到:reference • 我們有兩兩種常⾒見見語法 Intel syntax、AT&T syntax,其實差不多 • 組合語⾔言非常底層,所以會⾯面對許多硬體實作所造成的限制 • 沒有要寫組語,純粹看懂就好 • 組語怎樣寫都會動,重點是 Application Binary Interface (ABI)

Slide 11

Slide 11 text

mov x , 110 mov z , 0 mov z , x add z , x sub z , x inc z dec z x = 110; z = 0; z = x; z = z + x; z = z - x; z += 1; z -= 1; X86 ASSEMBLY 從C開始 C看起來來 組語感覺上是這樣 mov ebx , 110 mov eax , 0 mov eax , ebx add eax , ebx sub eax , ebx inc eax dec eax 組語更更像這樣

Slide 12

Slide 12 text

X86 ASSEMBLY 從C開始 mov ebx , 110 mov eax , 0 mov eax , ebx add eax , ebx sub eax , ebx inc eax dec eax Intel syntax movl $110, %ebx movl $0, %eax mov %ebx , %eax add %eax , %ebx sub %ebx , %eax inc %eax dec %eax AT&T syntax mov ebx , 110 ebx = 110 movl $110, %ebx 110 -> ebx

Slide 13

Slide 13 text

X86 ASSEMBLY 暫存器 組合語言基本上就是在操作硬體 所以我們可以使用的運算元也有所限制 AH AL BH BL CH CL DH DL AX BX CX DX EAX EBX ECX EDX ESI EDI EBP ESP 8bits 16bits 32bits EIP

Slide 14

Slide 14 text

X86 ASSEMBLY 基本四則運算 • 加減乘除 add / sub / mul / div • add eax, ebx ( eax = eax + ebx) • 乘法除法比較⿇麻煩⼀一點,先跳過 • 遞增遞減 inc / dec • inc eax ( eax = eax + 1) • 賦值 mov • mov eax, ebx (eax = ebx)

Slide 15

Slide 15 text

X86 ASSEMBLY 存取記憶體 記憶體 0x9a 0xffffcf30 0xffffcf39 0xffffcf38 0xffffcf37 0xffffcf36 0xffffcf35 0xffffcf34 0xffffcf33 0xffffcf32 0xffffcf31 0x12 0x34 0x56 0x78 0x03 ESI = 0xffffcf30 BYTE PTR [ESI] = ? WORD PTR [ESI] = ? DWORD PTR[ESI] = ? 0xde 0xad 0xef 0xbe ESI 0xffffcf30

Slide 16

Slide 16 text

X86 ASSEMBLY 記憶體 0x9a 0xffffcf30 0xffffcf39 0xffffcf38 0xffffcf37 0xffffcf36 0xffffcf35 0xffffcf34 0xffffcf33 0xffffcf32 0xffffcf31 0x12 0x34 0x56 0x78 0x03 ESI = 0xffffcf30 BYTE PTR [ESI] = 0x12 WORD PTR [ESI] = ? DWORD PTR[ESI] = ? 0xde 0xad 0xef 0xbe ESI 0xffffcf30 存取記憶體

Slide 17

Slide 17 text

X86 ASSEMBLY 記憶體 0x9a 0xffffcf30 0xffffcf39 0xffffcf38 0xffffcf37 0xffffcf36 0xffffcf35 0xffffcf34 0xffffcf33 0xffffcf32 0xffffcf31 0x12 0x34 0x56 0x78 0x03 ESI = 0xffffcf30 BYTE PTR [ESI] = 0x12 WORD PTR [ESI] = 0x3412 DWORD PTR[ESI] = ? 0xde 0xad 0xef 0xbe ESI 0xffffcf30 存取記憶體

Slide 18

Slide 18 text

X86 ASSEMBLY ESI 0xffffcf30 記憶體 0xde 0xad 0xef 0x9a 0xffffcf30 0xffffcf39 0xffffcf38 0xffffcf37 0xffffcf36 0xffffcf35 0xffffcf34 0xffffcf33 0xffffcf32 0xffffcf31 0x12 0x34 0x56 0x78 0xbe 0x03 ESI = 0xffffcf30 BYTE PTR [ESI] = 0x12 WORD PTR [ESI] = 0x3412 DWORD PTR[ESI] = 0x78563412 存取記憶體

Slide 19

Slide 19 text

X86 ASSEMBLY 記憶體 0xde 0xad 0xef 0x9a 0xffffcf30 0xffffcf39 0xffffcf38 0xffffcf37 0xffffcf36 0xffffcf35 0xffffcf34 0xffffcf33 0xffffcf32 0xffffcf31 0x12 0x34 0x56 0x78 0xbe 0x03 LITTLE ENDIAN & BIG ENDIAN ESI = 0xffffcf30 BYTE PTR [ESI] = 0x12 WORD PTR [ESI] = 0x3412 DWORD PTR[ESI] = 0x78563412 這就是 Little Endian : 數字中的⾼高位放在記憶體的⾼高位 數字中的低位放在記憶體的低位

Slide 20

Slide 20 text

X86 ASSEMBLY 記憶體 0xde 0xad 0xef 0x9a 0xffffcf30 0xffffcf39 0xffffcf38 0xffffcf37 0xffffcf36 0xffffcf35 0xffffcf34 0xffffcf33 0xffffcf32 0xffffcf31 0x12 0x34 0x56 0x78 0xbe 0x03 LITTLE ENDIAN & BIG ENDIAN 所以如果 ESI = 0xffffcf35 mov EAX , DWORD PTR[ESI] EAX = ? 這就是 Little Endian : 數字中的⾼高位放在記憶體的⾼高位 數字中的低位放在記憶體的低位

Slide 21

Slide 21 text

X86 ASSEMBLY 記憶體 0xde 0xad 0xef 0x9a 0xffffcf30 0xffffcf39 0xffffcf38 0xffffcf37 0xffffcf36 0xffffcf35 0xffffcf34 0xffffcf33 0xffffcf32 0xffffcf31 0x12 0x34 0x56 0x78 0xbe 0x03 LITTLE ENDIAN & BIG ENDIAN 所以如果 ESI = 0xffffcf35 mov EAX , DWORD PTR[ESI] EAX = 0xdeadbeef 這就是 Little Endian : 數字中的⾼高位放在記憶體的⾼高位 數字中的低位放在記憶體的低位

Slide 22

Slide 22 text

X86 ASSEMBLY 記憶體 0xde 0xad 0xef 0x9a 0xffffcf30 0xffffcf39 0xffffcf38 0xffffcf37 0xffffcf36 0xffffcf35 0xffffcf34 0xffffcf33 0xffffcf32 0xffffcf31 0x12 0x34 0x56 0x78 0xbe 0x03 ESI = 0xffffcf35 lea EAX , DWORD PTR[ESI] EAX = 0xffffcf35 lea EAX , DWORD PTR[ESI + 4] EAX = 0xffffcf39 存取記憶體 lea(取址): 把後⾯面運算元的記憶體位置放到前⾯面的運算元

Slide 23

Slide 23 text

X86 ASSEMBLY 邏輯判斷與流程控制 • and • and eax, ebx (eax = eax & ebx) • or • or eax, ebx ( eax = eax | ebx) • not (取1補數) • not eax (eax = !eax) • xor • xor eax, ebx (eax = eax ⨁ ebx) • neg (negative,取2補數) • neg eax (eax = - eax) • test • 跟and⼀一樣,但是不會把結果放進運算元 • cmp (compare) • ⽤用sub來來比⼤大⼩小,但是不會把結果放進運 算元


Slide 24

Slide 24 text

X86 ASSEMBLY 邏輯判斷與流程控制 int var1 = 1; int var2 = 2; if ( var1 > var2) var1 = 3; var2 = 200; C mov eax, 1 mov ebx, 2 cmp eax, ebx jle target mov eax, 3 target : mov ebx, 200 組語會像(local variable 不是長這樣)

Slide 25

Slide 25 text

X86 ASSEMBLY EFLAGS

Slide 26

Slide 26 text

X86 ASSEMBLY 補數 1 0 1 0 0 1 0 0 1 0 0 0 1 1 1 1 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 取 1 補數 0 1 0 1 1 0 1 1 0 1 1 1 0 0 0 0 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 取 2 補數(取 1 補數加上 1) 0 1 0 1 1 0 1 1 0 1 1 1 0 0 0 1 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

Slide 27

Slide 27 text

X86 ASSEMBLY 補數 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 1 取 2 補數就當作是 -1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

Slide 28

Slide 28 text

X86 ASSEMBLY 有號整數&無號整數 • 當作無號整數時: • 2^15 + 1 = 32769 • 當作有號整數時: • -32767 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

Slide 29

Slide 29 text

X86 ASSEMBLY EFLAGS • Carry Flag: • 無號整數運算超過範圍(最⾼高位 bit 借位或是進位),就設定成 True • 例例如 8 bit 整數 255 + 1 = 0 、 0 - 1 = 255 • Overflow Flag: • 有號整數運算超過範圍的時候設定成 True • 例例如:2147483647 + 1 = - 2147483648 • Sign Flag: • 取最⾼高⼀一個 bit,如果是 1 就設定成 True,表⽰示負數 • Zero Flag • 運算結果是 0,ZF 就設定成 True

Slide 30

Slide 30 text

X86 ASSEMBLY CMP 無號整數 有號整數 ZF CF 代表結果 FALSE TRUE eax < ebx FALSE FALSE eax > ebx TRUE FALSE eax = ebx cmp eax, ebx EFLAG 代表結果 sign flag ≠ overflow flag eax < ebx sign flag = overflow flag eax > ebx ZF = True eax = ebx compare 時並不管有號還無號、把flag全部設好,有號無號讓jump指令決定

Slide 31

Slide 31 text

X86 ASSEMBLY JUMP JA Jump if above JNBE Jump if not below or not equal ( Jump if above) JAE Jump if above or equal JNB Jump if not below (=JAE) JB Jump if below JNAE Jump if not above or not equal(=JB) JBE Jump if below or equal JNA Jump if not above(=JBE) JG Jump if greater JNLE Jump if not less or not equal(=JG) JGE Jump if greater or equal JNL Jump if not less (=JGE) JL Jump if less JNGE Jump if not greater or not equal(=JL) JLE Jump if less or equal JNG Jump if not greater (=JLE) JE Jump if equal JNE Jump if not equal JMP 不管,跳 無號整數 有號整數

Slide 32

Slide 32 text

001 DEMO

Slide 33

Slide 33 text

001 PRACTICE

Slide 34

Slide 34 text

BINARY ANALYZE

Slide 35

Slide 35 text

BINARY ANALYZE 介紹 • 所以我們要怎樣分析?只能看⼀一堆不會動的奇妙妙的code? • 可以簡單分成兩兩種分析⽅方式: • 靜態分析 (static analyze) • 動態分析 (dynamic analyze) • 各有各的好處,我們可以交替使⽤用來來理理解⼀一⽀支程式

Slide 36

Slide 36 text

BINARY ANALYZE ⼯工具 • 我們有各式各樣的⼯工具,debugger、反組譯、反編譯等: • objdump、gdb、gdb-peda、radare2、ida、hopper、 x64dbg、ollydbg、bochs…… • ⼯工具就是給⼈人⽤用的,知道原則就不難 • 不知道哪個好⽤用就都試試 • 我們先從有視窗的debugger開始 工具可以幫助你理解程式 但你要知道自己想知道什麼

Slide 37

Slide 37 text

BINARY ANALYZE X64DBG 暫存器 堆疊 記憶體 反組譯視窗 記憶體 位置 機器語言 組合語言 註解、標籤

Slide 38

Slide 38 text

BINARY ANALYZE X64DBG 不用快捷鍵我就把你掐死 按鍵 功能 按鍵 功能 F4 執⾏行行到指定的⾏行行為⽌止 Ctrl+G 跳到某個address F7 單步執⾏行行(Step into) Enter 查看Function F8 單步執⾏行行(Step over) * 回到EIP的位置 F9 執⾏行行 - 回到上⼀一個位置 Ctrl+F2 重新開始 ; 新增註解 Ctrl+F9 執⾏行行到return後停⽌止 : 新增標籤

Slide 39

Slide 39 text

DEMO 初めてのpatch 002

Slide 40

Slide 40 text

PRACTICE 初めてのpatch 002

Slide 41

Slide 41 text

BINARY ANALYZE 再C⼀一⼝口 • X86 Calling Convention : 規定如何傳參參數給function,⼤大致上就是 將參參數由右⾄至左push進stack當中,細節還有分為cdecl、stdcall 、 fastcall、thiscall(C++)。 //C int test(int a, int b, int c){ int result; result = a; result += b; result += c; return result; } int main(){ test(1,2,3); } Main Test STAC 1 2 3 3 2 1 3 2 1

Slide 42

Slide 42 text

BINARY ANALYZE 記憶體中的STACK 這是你以為的 STACK 3 2 1 這是記憶體中 的STACK 1 2 3 這是記憶體 1 2 3 低位址 ⾼高位址 HEAP OS BSS DATA TEXT

Slide 43

Slide 43 text

BINARY ANALYZE STACK FRAME 記憶體中的STACK 低位址 ⾼高位址 previous ebp 0xffffcf4c 0xffffcf48 0xffffcf44 0xffffcf40 0xffffcf3c 0xffffcf38 0xffffcf34 0xffffcf30 0xffffcf2c 0xffffcf28 esp

Slide 44

Slide 44 text

BINARY ANALYZE STACK FRAME 記憶體中的STACK 低位址 ⾼高位址 ebp esp 0xffffcf4c 0xffffcf48 0xffffcf44 0xffffcf40 0xffffcf3c 0xffffcf38 0xffffcf34 0xffffcf30 0xffffcf2c 0xffffcf28 previous ebp

Slide 45

Slide 45 text

BINARY ANALYZE STACK FRAME 記憶體中的STACK 低位址 ⾼高位址 ebp 0x00000003 esp 0xffffcf4c 0xffffcf48 0xffffcf44 0xffffcf40 0xffffcf3c 0xffffcf38 0xffffcf34 0xffffcf30 0xffffcf2c 0xffffcf28 previous ebp

Slide 46

Slide 46 text

BINARY ANALYZE STACK FRAME 記憶體中的STACK 低位址 ⾼高位址 ebp 0x00000003 0x00000002 esp 0xffffcf4c 0xffffcf48 0xffffcf44 0xffffcf40 0xffffcf3c 0xffffcf38 0xffffcf34 0xffffcf30 0xffffcf2c 0xffffcf28 previous ebp

Slide 47

Slide 47 text

BINARY ANALYZE STACK FRAME 記憶體中的STACK 低位址 ⾼高位址 ebp 0x00000003 0x00000002 0x00000001 esp 0xffffcf4c 0xffffcf48 0xffffcf44 0xffffcf40 0xffffcf3c 0xffffcf38 0xffffcf34 0xffffcf30 0xffffcf2c 0xffffcf28 previous ebp

Slide 48

Slide 48 text

return address BINARY ANALYZE STACK FRAME 記憶體中的STACK 低位址 ⾼高位址 ebp 0x00000003 0x00000002 0x00000001 esp 0x08048406 0xffffcf4c 0xffffcf48 0xffffcf44 0xffffcf40 0xffffcf3c 0xffffcf38 0xffffcf34 0xffffcf30 0xffffcf2c 0xffffcf28 previous ebp

Slide 49

Slide 49 text

return address 0xffffcf4c previous ebp BINARY ANALYZE STACK FRAME 記憶體中的STACK 低位址 ⾼高位址 ebp 0x00000003 0x00000002 0x00000001 esp 0x08048406 0xffffcf4c 0xffffcf48 0xffffcf44 0xffffcf40 0xffffcf3c 0xffffcf38 0xffffcf34 0xffffcf30 0xffffcf2c 0xffffcf28 previous ebp

Slide 50

Slide 50 text

return address 0xffffcf4c BINARY ANALYZE STACK FRAME 記憶體中的STACK 低位址 ⾼高位址 0x00000003 0x00000002 0x00000001 0x08048406 0xffffcf4c 0xffffcf48 0xffffcf44 0xffffcf40 0xffffcf3c 0xffffcf38 0xffffcf34 0xffffcf30 0xffffcf2c 0xffffcf28 esp ebp previous ebp previous ebp

Slide 51

Slide 51 text

return address 0xffffcf4c BINARY ANALYZE STACK FRAME 記憶體中的STACK 低位址 ⾼高位址 0x00000003 0x00000002 0x00000001 esp 0x08048406 0xffffcf4c 0xffffcf48 0xffffcf44 0xffffcf40 0xffffcf3c 0xffffcf38 0xffffcf34 0xffffcf30 0xffffcf2c 0xffffcf28 ebp buffer for local variables previous ebp previous ebp

Slide 52

Slide 52 text

return address 0xffffcf4c BINARY ANALYZE STACK FRAME 記憶體中的STACK 低位址 ⾼高位址 0x00000003 0x00000002 0x00000001 esp 0x08048406 0xffffcf4c 0xffffcf48 0xffffcf44 0xffffcf40 0xffffcf3c 0xffffcf38 0xffffcf34 0xffffcf30 0xffffcf2c 0xffffcf28 ebp eax 0x00000001 buffer for local variables previous ebp previous ebp

Slide 53

Slide 53 text

return address 0xffffcf4c BINARY ANALYZE STACK FRAME 記憶體中的STACK 低位址 ⾼高位址 0x00000003 0x00000002 0x00000001 esp 0x08048406 0xffffcf4c 0xffffcf48 0xffffcf44 0xffffcf40 0xffffcf3c 0xffffcf38 0xffffcf34 0xffffcf30 0xffffcf2c 0xffffcf28 ebp eax 0x00000001 buffer for local variables 0x00000001 previous ebp previous ebp

Slide 54

Slide 54 text

return address 0xffffcf4c BINARY ANALYZE STACK FRAME 記憶體中的STACK 低位址 ⾼高位址 0x00000003 0x00000002 0x00000001 esp 0x08048406 0xffffcf4c 0xffffcf48 0xffffcf44 0xffffcf40 0xffffcf3c 0xffffcf38 0xffffcf34 0xffffcf30 0xffffcf2c 0xffffcf28 ebp eax 0x00000002 buffer for local variables 0x00000001 previous ebp previous ebp

Slide 55

Slide 55 text

return address 0xffffcf4c BINARY ANALYZE STACK FRAME 記憶體中的STACK 低位址 ⾼高位址 0x00000003 0x00000002 0x00000001 esp 0x08048406 0xffffcf4c 0xffffcf48 0xffffcf44 0xffffcf40 0xffffcf3c 0xffffcf38 0xffffcf34 0xffffcf30 0xffffcf2c 0xffffcf28 ebp eax 0x00000002 buffer for local variables 0x00000003 previous ebp previous ebp

Slide 56

Slide 56 text

return address 0xffffcf4c BINARY ANALYZE STACK FRAME 記憶體中的STACK 低位址 ⾼高位址 0x00000003 0x00000002 0x00000001 esp 0x08048406 0xffffcf4c 0xffffcf48 0xffffcf44 0xffffcf40 0xffffcf3c 0xffffcf38 0xffffcf34 0xffffcf30 0xffffcf2c 0xffffcf28 ebp eax 0x00000003 buffer for local variables 0x00000003 previous ebp previous ebp

Slide 57

Slide 57 text

return address 0xffffcf4c BINARY ANALYZE STACK FRAME 記憶體中的STACK 低位址 ⾼高位址 0x00000003 0x00000002 0x00000001 esp 0x08048406 0xffffcf4c 0xffffcf48 0xffffcf44 0xffffcf40 0xffffcf3c 0xffffcf38 0xffffcf34 0xffffcf30 0xffffcf2c 0xffffcf28 ebp eax 0x00000003 buffer for local variables 0x00000006 previous ebp previous ebp

Slide 58

Slide 58 text

return address 0xffffcf4c BINARY ANALYZE STACK FRAME 記憶體中的STACK 低位址 ⾼高位址 0x00000003 0x00000002 0x00000001 esp 0x08048406 0xffffcf4c 0xffffcf48 0xffffcf44 0xffffcf40 0xffffcf3c 0xffffcf38 0xffffcf34 0xffffcf30 0xffffcf2c 0xffffcf28 ebp eax 0x00000006 buffer for local variables 0x00000006 previous ebp previous ebp

Slide 59

Slide 59 text

return address 0xffffcf4c BINARY ANALYZE STACK FRAME 記憶體中的STACK 低位址 ⾼高位址 0x00000003 0x00000002 0x00000001 esp 0x08048406 0xffffcf4c 0xffffcf48 0xffffcf44 0xffffcf40 0xffffcf3c 0xffffcf38 0xffffcf34 0xffffcf30 0xffffcf2c 0xffffcf28 ebp leave = mov esp, ebp pop ebp previous ebp previous ebp

Slide 60

Slide 60 text

return address BINARY ANALYZE STACK FRAME 記憶體中的STACK 低位址 ⾼高位址 0x00000003 0x00000002 0x00000001 esp 0x08048406 0xffffcf4c 0xffffcf48 0xffffcf44 0xffffcf40 0xffffcf3c 0xffffcf38 0xffffcf34 0xffffcf30 0xffffcf2c 0xffffcf28 leave = mov esp, ebp pop ebp ebp previous ebp

Slide 61

Slide 61 text

return address BINARY ANALYZE STACK FRAME 記憶體中的STACK 低位址 ⾼高位址 0x00000003 0x00000002 0x00000001 0xffffcf4c 0xffffcf48 0xffffcf44 0xffffcf40 0xffffcf3c 0xffffcf38 0xffffcf34 0xffffcf30 0xffffcf2c 0xffffcf28 ebp ret = pop eip esp 0x08048406 previous ebp

Slide 62

Slide 62 text

BINARY ANALYZE STACK FRAME 記憶體中的STACK 低位址 ⾼高位址 0x00000003 0x00000002 0x00000001 esp 0xffffcf4c 0xffffcf48 0xffffcf44 0xffffcf40 0xffffcf3c 0xffffcf38 0xffffcf34 0xffffcf30 0xffffcf2c 0xffffcf28 ebp ret = pop eip previous ebp

Slide 63

Slide 63 text

BINARY ANALYZE STACK FRAME 記憶體中的STACK 低位址 ⾼高位址 esp 0xffffcf4c 0xffffcf48 0xffffcf44 0xffffcf40 0xffffcf3c 0xffffcf38 0xffffcf34 0xffffcf30 0xffffcf2c 0xffffcf28 ebp previous ebp

Slide 64

Slide 64 text

PRACTICE Abex’s crackme1 003

Slide 65

Slide 65 text

DEMO Abex’s crackme1 003

Slide 66

Slide 66 text

BINARY ANALYZE • 入⼝口點通常不是main,⽽而是⼀一段Startup Code • 打開⼿手邊的程式跟abex’s crackme 比較看看 • 如果⾃自⼰己寫組語的話基本上是不需要Startup Code,這是⼀一個標準 化的感覺 • 既然是標準,那就有可能有好多標準,因此我們可以透過入⼝口點的 特徵來來辨別是什什麼語⾔言寫的或是什什麼編譯器編譯的 • 既然有標準,那就容易易有⼯工具

Slide 67

Slide 67 text

PRACTICE ⼩小可愛別怕GUI來來了了 004

Slide 68

Slide 68 text

DEMO Callback function會懲罰你 004

Slide 69

Slide 69 text

BINARY ANALYZE 4WAY TO FIND TARGET • 所以我要怎樣找到關鍵的程式片段? • 前⾯面兩兩個學過了了,讓我們從3、4說起 1. 逐步執行 2. 尋找字串 3. 呼叫API時下斷點 4. API被呼叫時下斷點

Slide 70

Slide 70 text

BINARY ANALYZE 4WAY TO FIND TARGET • ⾸首先,什什麼是API? • Application Programming Interface • 我們必須透過API與作業系統互動,作業系統就是皇上,朕不給,你 不能搶,只有規範好的API能夠取得相關權限或資源(沒有漏洞洞的話 拉) 3. 呼叫API時下斷點

Slide 71

Slide 71 text

BINARY ANALYZE 4WAY TO FIND TARGET • 因此只要看到程式彈出視窗,我們就可以認為程式有使⽤用windows 的MessageBox function,在Debbuger的調⽤用列列表中找出所有call MessageBox,來來找到跟這個彈出視窗相關的程式片段 • 不⼀一定是API,如果程式有⼀一個神秘function,你也可以這樣來來鎖定 該function • 但是還是有可能找不到,為什什麼呢? 3. 呼叫API時下斷點

Slide 72

Slide 72 text

BINARY ANALYZE 4WAY TO FIND TARGET • 我們不⼀一定要⽤用call MessageBox,我們還能: • 假設Message Box這個function在0x75E5F8B0 • 1. push return address 進 stack然後jmp過去0x75E5F8B0 • 2. 把0x75e7f8b0放進eax,call eax • 3. 各種各種!! • 但是要怎麼取得MessageBox的function address? 3. 呼叫API時下斷點

Slide 73

Slide 73 text

BINARY ANALYZE 4WAY TO FIND TARGET • 兩兩種鏈結⽅方式:static link、dynamic link • Static link會把引⽤用到的程式都⼀一起包起來來,所以檔案會較⼤大,執⾏行行速 度較快,但是更更改上較沒有彈性 • Dynamic link不把引⽤用到的程式包進來來,檔案較⼩小,執⾏行行速度較慢,更更 改上較有彈性 • 系統API這種許多程式都會使⽤用的東⻄西,使⽤用dynamic link還有節省記憶 體的好處 • Dynamic link在windows下以.dll(dynamic link library)的⽅方式實作,在 linux下是.so(share object)
 3. 呼叫API時下斷點

Slide 74

Slide 74 text

BINARY ANALYZE 4WAY TO FIND TARGET • IAT (Import Address Table): • 就是⼀一張寫著dynamic link的function位置在哪的table • 以MessageBox為例例,他被放在user32.dll: • ⼀一開始程式會⽤用loadlibrary把user32.dll放進記憶體當中 • 然後使⽤用GetProcAddress找到MessageBox的address • 填入IAT • 啊所以呢? 3. 呼叫API時下斷點

Slide 75

Slide 75 text

BINARY ANALYZE 4WAY TO FIND TARGET • 啊所以呢? • 那我⼀一開始不說我要⽤用MessageBox,他就不會被放在IAT拉 • 我中間⾃自⼰己LoadLibrary、GetProcAddress就好了了 • 這樣就不會這麼容易易就找到關鍵的地⽅方 • 阿怎麼辦? 3. 呼叫API時下斷點

Slide 76

Slide 76 text

BINARY ANALYZE 4WAY TO FIND TARGET • 在function address下斷點,然後看堆疊中的return address,回去 找呼叫這個api的程式片段 4. API被呼叫時下斷點

Slide 77

Slide 77 text

DEMO 我知道你不知道我在說什什麼 004

Slide 78

Slide 78 text

PRACTICE 現在你懂了了 004

Slide 79

Slide 79 text

BINARY ANALYZE 程式在記憶體中的樣⼦子 File Process Header Null .text Null .data Null .rsrc Null Header Null .text Null .data Null .rsrc Null Offset Address 00000000 00000A00 00400000 00401000 00402000 00403000 00404000 00000400 00000600 00000800

Slide 80

Slide 80 text

BINARY ANALYZE 程式在記憶體中的樣⼦子 Process Header Null .text Null .data Null .rsrc Null Address 00400000 00401000 00402000 00403000 00404000 我順序沒畫錯 你要仔細看 這是記憶體 1 2 3 低位址 ⾼高位址 HEAP OS BSS DATA TEXT

Slide 81

Slide 81 text

BINARY ANALYZE VIRTUAL ADDRESS SPACE

Slide 82

Slide 82 text

BINARY ANALYZE PE FILE FORMAT • PE(Portable Executable):windows下的可執⾏行行檔、函式庫、 service都是PE(.exe .dll .sys) • 檔案格式會記錄⼀一些加載程式的⼀一些資訊,例例如我們前⾯面提到的 IAT,還有section的描述等等 • 在linux下的檔案格式稱作ELF(Executable Linkable Format),Mac OS下則是使⽤用Mach-O • 檔案格式不同,當然也無法被加載 • 就算⼿手動將格式改成⼀一樣也不⾒見見得能執⾏行行,每個系統規範的API並不 相同

Slide 83

Slide 83 text

BINARY ANALYZE PE FILE FORMAT Offset VirtualAddress Headers Null .text Null .data Null .rsrc Null Headers Null .text Null .data Null .rsrc Null NumberOfSections : 3 FileAlignment : 512 SectionAlignment:4096 SizeOfImage SizeOfHeaders SizeOfRawData SizeOfRawData SizeOfRawData PointertoRawData PointertoRawData PointertoRawData ImageBase VirtualSize VirtualSize VirtualSize VirtualAddress VirtualAddress VirtualAddress (RVA)Relative Virtual Address = VirtualAddress - ImageBase

Slide 84

Slide 84 text

BINARY ANALYZE PE FILE FORMAT Headers Null .text Null .data Null .rsrc Null Dos Header Dos Stub NT Header .text header .data header .rsrc header MZ e_lfanew PE00 This program cannot run in DOS

Slide 85

Slide 85 text

BINARY ANALYZE PE FILE FORMAT Dos Header Dos Stub NT Header .text header .data header .rsrc header MZ e_lfanew PE00 This program cannot run in DOS File Header Machine NumberOfSections TimeDataStamp PointerToSymbolTable NumberOfSymbols SizeOfOptionalHeader Characteristics Optional Header Magic : 010b(32bits), 020b(64bits) AddressOfEntryPoint ImageBase SectionAlignment FileAlignment SizeOfImage SizeOfHeaders…..more Section Header VirtualSize VirtualAddress SizeOfRawData PointToRawData Characteristics

Slide 86

Slide 86 text

DEMO 讓你看看我的PE 005

Slide 87

Slide 87 text

PRACTICE 005

Slide 88

Slide 88 text

BINARY ANALYZE 殼 • 壓縮殼: • 讓程式變⼩小,執⾏行行的時候程式會⾃自⼰己幫⾃自⼰己解壓縮 • 加密殼: • 主要⽬目的是為了了保護其中的資料,不讓⼈人隨意修改或盜取 • 另外還可以透過⾃自校驗來來檢查程式是否有被更更動

Slide 89

Slide 89 text

BINARY ANALYZE UPX Dos Header Dos Stub NT Header .text header .data header .rsrc header Null .text Null .data Null .rsrc Null Dos Header Dos Stub NT Header .UPX0 header .UPX1 header .rsrc header Null .UPX0 .UPX1 Null .rsrc Null Unpacking Packing File File

Slide 90

Slide 90 text

BINARY ANALYZE 壓縮殼UPX • UPX是⼀一款真正的壓縮殼: • 會執⾏行行Upx1中的解壓縮程式片段,把原始程式解壓縮⾄至UPX0 • OEP (Original Entry Point): • 原始程式的Entry Point,即解壓縮完後開始執⾏行行原始程式的地⽅方

Slide 91

Slide 91 text

PRACTICE 006

Slide 92

Slide 92 text

DEMO 006

Slide 93

Slide 93 text

其他資源 • 我也不是每個都有⽤用過拉,總之想知道什什麼你就該⾃自⼰己去挖,這也只是參參考參參考⽽而已 • http://reversing.kr/ • https://beginners.re/ • https://challenges.re/ • https://picoctf.com/ • https://ringzer0team.com/ • https://ctftime.org/event/list/upcoming (直接上ctftime找比賽)