Slide 1

Slide 1 text

C0mput3r 5ecur!7y Windows ReversingDarkArt [email protected] !1

Slide 2

Slide 2 text

• Master degree at CSIE, NTUST • Security Researcher - chrO.ot, TDOHacker • Speaker - BlackHat, DEFCON, beVX, VXCON, HITCON >_cat ./Bio !2

Slide 3

Slide 3 text

• General Compiler • Recap: Intel x86 Basic • x86 Instruction Set • x86 Calling Convention • Let's Mess Up IDA Pro ;) • Obfuscation Tricks • Junk Instructions • Control Flow Obfuscation • Structured Exception Handling (SEH) • Virtual Machine (Packer Style) >_cat ./lab !3

Slide 4

Slide 4 text

[email protected] General Compiler !4

Slide 5

Slide 5 text

General Compiler !5 Source.cpp Object Files Main.exe Compiler Assembly Codes Assembler Linker

Slide 6

Slide 6 text

>_cat msgbox.c !6 #include int main() { MessageBoxA( 0, "hi there.", "info", 0 ); return 0; }

Slide 7

Slide 7 text

based on x86 Calling Convention !7 #include int main(void) { MessageBoxA( 0, "hi there.", "info", 0 ); return 0; } push 0 push "info" push "hi there." push 0 call MessageBoxA xor eax, eax ret en.wikipedia.org/wiki/X86_calling_conventions

Slide 8

Slide 8 text

>_Compiler 8 xor eax, eax ret push 0 push "info" push "hi there." push 0 call MessageBoxA 0xdead: "info" 0xbeef: "hi there." .rdata section 0xcafe: 0x7630EA99 .idata section (Import Address Table)

Slide 9

Slide 9 text

>_Compiler !9 xor eax, eax ret push 0 push offset "info" push offset "hi there." push 0 call MessageBoxA 0xdead: "info" 0xbeef: "hi there." .rdata section 0xcafe: 0x7630EA99 .idata section (Import Address Table)

Slide 10

Slide 10 text

>_Compiler !10 xor eax, eax ret push 0 push 0x40dead push 0x40beef push 0 call ds:0x40cafe 0xdead: "info" 0xbeef: "hi there." .rdata section 0xcafe: 0x7630EA99 .idata section (Import Address Table)

Slide 11

Slide 11 text

[email protected] >_Periodic Table? !11 sparksandflames.com/files/x86InstructionChart.html

Slide 12

Slide 12 text

>_Assembler push 0 ; 6A 00 push 0x40dead ; 68 AD DE 40 00 push 0x40beef ; 68 EF BE 40 00 push 0 ; 6A 00 call ds:0x40cafe ; FF 15 FE CA 00 00 xor eax, eax ; 33 C0 ret ; C3 !12

Slide 13

Slide 13 text

!13 Main.exe .text Section 6A 00 68 AD DE 00 00 68 EF BE 00 00 6A 00 FF 15 FE CA 00 00 33 C0 C3 0xdead: "info" 0xbeef: "hi there." 0xcafe: 0x7630EA99 .rdata Section .idata Section

Slide 14

Slide 14 text

[email protected] Address Space Layout Randomization !14

Slide 15

Slide 15 text

>_Memory Process iexplorer.exe ntdll.dll kernel32.dll ... Low Address custom.dll xxxxxx.dll module.dll High Address Thread Stack

Slide 16

Slide 16 text

>_Memory Process iexplorer.exe ntdll.dll kernel32.dll ... Low Address custom.dll xxxxxx.dll module.dll High Address *.exe file should be loaded at 0x400000 by default third-party *.dll file System Modules Thread Stack

Slide 17

Slide 17 text

>_ASLR Process iexplorer.exe ntdll.dll kernel32.dll ... custom.dll xxxxxx.dll module.dll Process iexplorer.exe ntdll.dll kernel32.dll ... custom.dll xxxxxx.dll module.dll Process iexplorer.exe ntdll.dll kernel32.dll ... custom.dll xxxxxx.dll module.dll third-party *.exe & *.dll files are loaded at different addresses when create process. System Modules are only randomized after reboot.

Slide 18

Slide 18 text

!18 Main.exe .text Section 6A 00 68 AD DE 40 00 68 EF BE 40 00 6A 00 FF 15 FE CA 40 00 33 C0 C3 0xdead: "info" 0xbeef: "hi there." 0xcafe: 0x7630EA99 .rdata Section .idata Section >_Issue I don't know how to randomize *.exe module address :(

Slide 19

Slide 19 text

!19 Main.exe .text Section 6A 00 68 AD DE 40 00 68 EF BE 40 00 6A 00 FF 15 FE CA 40 00 33 C0 C3 0xdead: "info" 0xbeef: "hi there." 0xcafe: 0x7630EA99 .rdata Section .idata Section Relocation Table (aka PIE)

Slide 20

Slide 20 text

>_Relocation • Process loader won't implement ASLR on *.exe module without relocation table, even if you enable the ASLR option on the *.exe file. • There're serval relocation blocks stored the offset of assembly codes which includes resource, global variable, data from the other section. • In the .text section, every 0x1000 bytes of assembly code are grouped into a relocation block. All the relocation blocks are grouped into a relocation table. !20

Slide 21

Slide 21 text

>_PE Bear !21

Slide 22

Slide 22 text

>_PE Bear !22

Slide 23

Slide 23 text

[email protected] Recap: x86 Assembly !23

Slide 24

Slide 24 text

[email protected] >_Periodic Table? !24 sparksandflames.com/files/x86InstructionChart.html

Slide 25

Slide 25 text

雅量量 x86 指令集是⼀一種很有雅量量的語⾔言 !25 ⼈人總會去尋求⾃自⼰己喜歡的事物,每個⼈人的看法或觀點不同, 並沒有什什麼關係,重要的是──⼈人與⼈人之間,應該有彼此容忍 和尊重對⽅方的看法與觀點的雅量量。

Slide 26

Slide 26 text

>_CISC !26 Bytecodes on .text section 35 FF 15 FE CA 40 00 0: 35 ff 15 fe ca - xor eax,0xcafe15ff 5: 40 - inc eax

Slide 27

Slide 27 text

0: ff 15 fe ca 40 00 - call DWORD PTR ds:0x40cafe !27 Bytecodes on .text section 35 FF 15 FE CA 40 00 0: 35 ff 15 fe ca - xor eax,0xcafe15ff 5: 40 - inc eax >_CISC

Slide 28

Slide 28 text

0: ff 15 fe ca 40 00 - call DWORD PTR ds:0x40cafe !28 Bytecodes on .text section 35 FF 15 FE CA 40 00 0: 35 ff 15 fe ca - xor eax,0xcafe15ff 5: 40 - inc eax 0: 15 fe ca 40 00 adc eax,0x40cafe >_CISC

Slide 29

Slide 29 text

0: ff 15 fe ca 40 00 - call DWORD PTR ds:0x40cafe !29 Bytecodes on .text section 35 FF 15 FE CA 40 00 0: 35 ff 15 fe ca - xor eax,0xcafe15ff 5: 40 - inc eax 0: 15 fe ca 40 00 adc eax,0x40cafe >_CISC ROP-Chain

Slide 30

Slide 30 text

>_Thread !30 addr @ 401000: 6A 00 68 AD DE 40 00 68 EF BE 40 00 6A 00 FF 15 FE CA 40 00 33 C0 C3 push 0 push 0x40dead push 0x40beef push 0 call ds:0x40cafe xor eax, eax ret via x86 Instruction Set Registers eax 41414141 ebx 42424242 ecx 43434343 edx 44444444 ... ... esp 7ffffffc ebp 7ffffffc eip 401000

Slide 31

Slide 31 text

>_Thread !31 addr @ 401000: 6A 00 68 AD DE 40 00 68 EF BE 40 00 6A 00 FF 15 FE CA 40 00 33 C0 C3 push 0 push 0x40dead push 0x40beef push 0 call ds:0x40cafe xor eax, eax ret via x86 Instruction Set Registers eax 41414141 ebx 42424242 ecx 43434343 edx 44444444 ... ... esp 7ffffffc ebp 7ffffffc eip 401000 Process aaaaaaaaa.exe ntdll.dll kernel32.dll ... Low Address custom.dll xxxxxx.dll module.dll High Address Thread Stack

Slide 32

Slide 32 text

>_Heap uint32_t buf[3] = { 1, 2, 3 }; buf[1] = 0xAAAAAAAA; buf[2] = 0x12345678; !32 Low Address = 0x100 (buf) High Address &(buf[0]) = 0x100 buf[0] = 1 00 00 00 01 &(buf[1]) = 0x104 buf[1] = 0xAAAAAAAA AA AA AA AA &(buf[2]) = 0x108 buf[2] = 0x12345678 78 56 34 12

Slide 33

Slide 33 text

>_Stack uint32_t stack[100]; uint32_t index = 99; void x86_push(uint32_t in) { stack[--index] = in; } void x86_pop(&out) { x = stack[index++]; } !33 Low Address = 0x100 (stack) High Address esp = 0x100 + sizeof(uint32_t) * 99 Allocate Local Memory Release Local Memory

Slide 34

Slide 34 text

>_Stack push eax push ebx pop edx !34 Low Address = 0x100 (stack) High Address eax 1 ebx 2 edx 3 esp = 0x28c index = 99

Slide 35

Slide 35 text

>_Stack push eax push ebx pop edx !35 Low Address = 0x100 (stack) High Address eax 1 ebx 2 edx 3 00 00 00 01 esp = 0x288 index = 98 esp = 0x28c index = 99

Slide 36

Slide 36 text

>_Stack push eax push ebx pop edx !36 Low Address = 0x100 (stack) High Address eax 1 ebx 2 edx 3 00 00 00 01 esp = 0x288 index = 98 esp = 0x28c index = 99 00 00 00 02 esp = 0x284 index = 97

Slide 37

Slide 37 text

>_Stack push eax push ebx pop edx !37 Low Address = 0x100 (stack) High Address eax 1 ebx 2 edx 2 00 00 00 01 esp = 0x288 index = 98 esp = 0x28c index = 99 00 00 00 02 esp = 0x284 index = 97

Slide 38

Slide 38 text

[email protected] x86 Calling Convention !38

Slide 39

Slide 39 text

>_Calling Convention !39 en.wikipedia.org/wiki/X86_calling_conventions add: push ebp mov ebp, esp sub esp, 0x04 mov eax, [ebp+0x08] add eax, [ebp+0x0C] add eax, [ebp+0x10] mov [ebp-0x04], eax mov eax, [ebp-0x04] mov esp, ebp pop ebp ret

Slide 40

Slide 40 text

>_Calling Convention !40 en.wikipedia.org/wiki/X86_calling_conventions add: push ebp mov ebp, esp sub esp, 0x04 mov eax, [ebp+0x08] add eax, [ebp+0x0C] add eax, [ebp+0x10] mov [ebp-0x04], eax mov eax, [ebp-0x04] mov esp, ebp pop ebp ret The Begin of function The end of function

Slide 41

Slide 41 text

>_Function !41 Low Address = 0x100 (stack) High Address esp = 0x28c index = 99 add: push ebp mov ebp, esp sub esp, 0x04 mov eax, [ebp+0x08] add eax, [ebp+0x0C] add eax, [ebp+0x10] mov [ebp-0x04], eax mov eax, [ebp-0x04] mov esp, ebp pop ebp ret push 3 push 2 push 1 call add add esp,0x0c // add(1, 2, 3)

Slide 42

Slide 42 text

!42 Low Address = 0x100 (stack) High Address esp = 0x28c index = 99 add: push ebp mov ebp, esp sub esp, 0x04 mov eax, [ebp+0x08] add eax, [ebp+0x0C] add eax, [ebp+0x10] mov [ebp-0x04], eax mov eax, [ebp-0x04] mov esp, ebp pop ebp ret push 3 push 2 push 1 call add add esp,0x0c // add(1, 2, 3) 00 00 00 03 esp = 0x288 index = 98

Slide 43

Slide 43 text

!43 Low Address = 0x100 (stack) High Address esp = 0x28c index = 99 add: push ebp mov ebp, esp sub esp, 0x04 mov eax, [ebp+0x08] add eax, [ebp+0x0C] add eax, [ebp+0x10] mov [ebp-0x04], eax mov eax, [ebp-0x04] mov esp, ebp pop ebp ret push 3 push 2 push 1 call add add esp,0x0c // add(1, 2, 3) 00 00 00 03 esp = 0x288 index = 98 00 00 00 02 esp = 0x284 index = 97

Slide 44

Slide 44 text

!44 Low Address = 0x100 (stack) High Address esp = 0x28c index = 99 add: push ebp mov ebp, esp sub esp, 0x04 mov eax, [ebp+0x08] add eax, [ebp+0x0C] add eax, [ebp+0x10] mov [ebp-0x04], eax mov eax, [ebp-0x04] mov esp, ebp pop ebp ret push 3 push 2 push 1 call add add esp,0x0c // add(1, 2, 3) 00 00 00 03 esp = 0x288 index = 98 00 00 00 02 esp = 0x284 index = 97 00 00 00 01 esp = 0x280 index = 96

Slide 45

Slide 45 text

!45 Low Address = 0x100 (stack) High Address esp = 0x28c index = 99 add: push ebp mov ebp, esp sub esp, 0x04 mov eax, [ebp+0x08] add eax, [ebp+0x0C] add eax, [ebp+0x10] mov [ebp-0x04], eax mov eax, [ebp-0x04] mov esp, ebp pop ebp ret push 3 push 2 push 1 call add add esp,0x0c // add(1, 2, 3) esp = 0x288 index = 98 00 00 00 02 esp = 0x284 index = 97 00 00 00 01 esp = 0x280 index = 96 ret addr esp = 0x27c index = 95 00 00 00 03

Slide 46

Slide 46 text

!46 Low Address = 0x100 (stack) High Address esp = 0x28c index = 99 add: push ebp mov ebp, esp sub esp, 0x04 mov eax, [ebp+0x08] add eax, [ebp+0x0C] add eax, [ebp+0x10] mov [ebp-0x04], eax mov eax, [ebp-0x04] mov esp, ebp pop ebp ret push 3 push 2 push 1 call add add esp,0x0c // add(1, 2, 3) esp = 0x288 index = 98 00 00 00 02 esp = 0x284 index = 97 00 00 00 01 esp = 0x280 index = 96 ret addr esp = 0x27c index = 95 old ebp esp = 0x278 index = 94 00 00 00 03

Slide 47

Slide 47 text

!47 Low Address = 0x100 (stack) High Address esp = 0x28c index = 99 add: push ebp mov ebp, esp sub esp, 0x04 mov eax, [ebp+0x08] add eax, [ebp+0x0C] add eax, [ebp+0x10] mov [ebp-0x04], eax mov eax, [ebp-0x04] mov esp, ebp pop ebp ret push 3 push 2 push 1 call add add esp,0x0c // add(1, 2, 3) esp = 0x288 index = 98 00 00 00 02 esp = 0x284 index = 97 00 00 00 01 esp = 0x280 index = 96 ret addr esp = 0x27c index = 95 old ebp esp = 0x278 index = 94 ebp = 0x278 (the base pointer for the current stack frame) 00 00 00 03

Slide 48

Slide 48 text

!48 Low Address = 0x100 (stack) High Address esp = 0x28c index = 99 add: push ebp mov ebp, esp sub esp, 0x04 mov eax, [ebp+0x08] add eax, [ebp+0x0C] add eax, [ebp+0x10] mov [ebp-0x04], eax mov eax, [ebp-0x04] mov esp, ebp pop ebp ret push 3 push 2 push 1 call add add esp,0x0c // add(1, 2, 3) esp = 0x288 index = 98 00 00 00 02 esp = 0x284 index = 97 00 00 00 01 esp = 0x280 index = 96 ret addr esp = 0x27c index = 95 old ebp esp = 0x278 index = 94 ebp = 0x278 (the base pointer for the current stack frame) local buf esp = 0x274 index = 93 00 00 00 03

Slide 49

Slide 49 text

!49 Low Address = 0x100 (stack) High Address esp = 0x28c index = 99 add: push ebp mov ebp, esp sub esp, 0x04 mov eax, [ebp+0x08] add eax, [ebp+0x0C] add eax, [ebp+0x10] mov [ebp-0x04], eax mov eax, [ebp-0x04] mov esp, ebp pop ebp ret push 3 push 2 push 1 call add add esp,0x0c // add(1, 2, 3) esp = 0x288 index = 98 00 00 00 02 esp = 0x284 index = 97 00 00 00 01 esp = 0x280 index = 96 ret addr esp = 0x27c index = 95 old ebp esp = 0x278 index = 94 ebp = 0x278 (the base pointer for the current stack frame) local buf esp = 0x274 index = 93 ebp ebp+4 arg1: ebp+8 arg2: ebp+0x0c arg3: ebp+0x10 00 00 00 03

Slide 50

Slide 50 text

!50 Low Address = 0x100 (stack) High Address esp = 0x28c index = 99 add: push ebp mov ebp, esp sub esp, 0x04 mov eax, [ebp+0x08] add eax, [ebp+0x0C] add eax, [ebp+0x10] mov [ebp-0x04], eax mov eax, [ebp-0x04] mov esp, ebp pop ebp ret push 3 push 2 push 1 call add add esp,0x0c // add(1, 2, 3) esp = 0x288 index = 98 00 00 00 02 esp = 0x284 index = 97 00 00 00 01 esp = 0x280 index = 96 ret addr esp = 0x27c index = 95 old ebp esp = 0x278 index = 94 ebp = 0x278 (the base pointer for the current stack frame) local buf esp = 0x274 index = 93 ebp ebp+4 arg1: ebp+8 arg2: ebp+0x0c arg3: ebp+0x10 00 00 00 03

Slide 51

Slide 51 text

!51 Low Address = 0x100 (stack) High Address esp = 0x28c index = 99 add: push ebp mov ebp, esp sub esp, 0x04 mov eax, [ebp+0x08] add eax, [ebp+0x0C] add eax, [ebp+0x10] mov [ebp-0x04], eax mov eax, [ebp-0x04] mov esp, ebp pop ebp ret push 3 push 2 push 1 call add add esp,0x0c // add(1, 2, 3) esp = 0x288 index = 98 00 00 00 02 esp = 0x284 index = 97 00 00 00 01 esp = 0x280 index = 96 ret addr esp = 0x27c index = 95 old ebp esp = 0x278 index = 94 ebp = 0x278 (the base pointer for the current stack frame) 6 esp = 0x274 index = 93 ebp ebp+4 arg1: ebp+8 arg2: ebp+0x0c arg3: ebp+0x10 00 00 00 03

Slide 52

Slide 52 text

!52 Low Address = 0x100 (stack) High Address esp = 0x28c index = 99 add: push ebp mov ebp, esp sub esp, 0x04 mov eax, [ebp+0x08] add eax, [ebp+0x0C] add eax, [ebp+0x10] mov [ebp-0x04], eax mov eax, [ebp-0x04] mov esp, ebp pop ebp ret push 3 push 2 push 1 call add add esp,0x0c // add(1, 2, 3) esp = 0x288 index = 98 00 00 00 02 esp = 0x284 index = 97 00 00 00 01 esp = 0x280 index = 96 ret addr esp = 0x27c index = 95 old ebp esp = 0x278 index = 94 ebp = 0x278 (the base pointer for the current stack frame) 6 ebp ebp+4 arg1: ebp+8 arg2: ebp+0x0c arg3: ebp+0x10 00 00 00 03

Slide 53

Slide 53 text

!53 Low Address = 0x100 (stack) High Address esp = 0x28c index = 99 add: push ebp mov ebp, esp sub esp, 0x04 mov eax, [ebp+0x08] add eax, [ebp+0x0C] add eax, [ebp+0x10] mov [ebp-0x04], eax mov eax, [ebp-0x04] mov esp, ebp pop ebp ret push 3 push 2 push 1 call add add esp,0x0c // add(1, 2, 3) esp = 0x288 index = 98 00 00 00 02 esp = 0x284 index = 97 00 00 00 01 esp = 0x280 index = 96 ret addr esp = 0x27c index = 95 old ebp 6 ebp ebp+4 arg1: ebp+8 arg2: ebp+0x0c arg3: ebp+0x10 00 00 00 03

Slide 54

Slide 54 text

!54 Low Address = 0x100 (stack) High Address esp = 0x28c index = 99 add: push ebp mov ebp, esp sub esp, 0x04 mov eax, [ebp+0x08] add eax, [ebp+0x0C] add eax, [ebp+0x10] mov [ebp-0x04], eax mov eax, [ebp-0x04] mov esp, ebp pop ebp ret push 3 push 2 push 1 call add add esp,0x0c // add(1, 2, 3) esp = 0x288 index = 98 00 00 00 02 esp = 0x284 index = 97 00 00 00 01 esp = 0x280 index = 96 ret addr old ebp 6 ebp ebp+4 arg1: ebp+8 arg2: ebp+0x0c arg3: ebp+0x10 00 00 00 03

Slide 55

Slide 55 text

!55 Low Address = 0x100 (stack) High Address esp = 0x28c index = 99 add: push ebp mov ebp, esp sub esp, 0x04 mov eax, [ebp+0x08] add eax, [ebp+0x0C] add eax, [ebp+0x10] mov [ebp-0x04], eax mov eax, [ebp-0x04] mov esp, ebp pop ebp ret push 3 push 2 push 1 call add add esp,0x0c // add(1, 2, 3) 00 00 00 03 00 00 00 02 00 00 00 01 ret addr old ebp 6 ebp ebp+4 arg1: ebp+8 arg2: ebp+0x0c arg3: ebp+0x10

Slide 56

Slide 56 text

[email protected] Structured Exception Handling (SEH) !56

Slide 57

Slide 57 text

Structured exception handling enables you to have complete control over the handling of exceptions, provides support for debuggers, and is usable across all programming languages and machines. Vectored exception handling is an extension to structured exception handling. >_SEH docs.microsoft.com/en-us/windows/desktop/debug/structured-exception-handling

Slide 58

Slide 58 text

>_Visual C++ !58 Actually SEH is a feature to support try {} catch (...) {} and...

Slide 59

Slide 59 text

!59

Slide 60

Slide 60 text

>_Visual C++ !60

Slide 61

Slide 61 text

[email protected] Thread Information Block —— Break into how Win32 API works !61

Slide 62

Slide 62 text

>_TIB In computing, the Win32 Thread Information Block (TIB) is a data structure in Win32 on x86 that stores information about the currently running thread. This structure is also known as the Thread Environment Block (TEB). The TIB can be used to get a lot of information on the process without calling Win32 API. Examples include emulating GetLastError(), GetVersion(). Through the pointer to the PEB one can obtain access to the import tables (IAT), process startup arguments, image name, etc. It is accessed from the FS segment register when operating on 32 bits, and from GS in 64 bits. !62 en.wikipedia.org/wiki/Win32_Thread_Information_Block

Slide 63

Slide 63 text

>_TIB !63

Slide 64

Slide 64 text

[email protected] >_TIB (undocumented) !64 struct TEB { //NT_TIB structure portion EXCEPTION_REGISTRATION* ExceptionList; //0x0000 / Current Structured Exception Handling frame void* StackBase; //0x0004 / Bottom of stack (high address) void* StackLimit; //0x0008 / Ceiling of stack (low address) void* SubSystemTib; //0x000C union { void* FiberData; //0x0010 DWORD Version; //0x0010 } dword10; void* ArbitraryUserPointer; //0x0014 TEB* Self; //0x0018 //NT_TIB ends (NT subsystem independent part) void* EnvironmentPointer; //0x001C CLIENT_ID ClientId; //0x0020 // ClientId.ProcessId //0x0020 / value retrieved by GetCurrentProcessId() // ClientId.ThreadId //0x0024 / value retrieved by GetCurrentThreadId() void* ActiveRpcHandle; //0x0028 void* ThreadLocalStoragePointer; //0x002C PEB* ProcessEnvironmentBlock; //0x0030 ... bytepointer.com/resources/tebpeb32.htm

Slide 65

Slide 65 text

[email protected] >_TIB (undocumented) !65 struct TEB { //NT_TIB structure portion EXCEPTION_REGISTRATION* ExceptionList; //0x0000 / Current Structured Exception Handling frame void* StackBase; //0x0004 / Bottom of stack (high address) void* StackLimit; //0x0008 / Ceiling of stack (low address) void* SubSystemTib; //0x000C union { void* FiberData; //0x0010 DWORD Version; //0x0010 } dword10; void* ArbitraryUserPointer; //0x0014 TEB* Self; //0x0018 //NT_TIB ends (NT subsystem independent part) void* EnvironmentPointer; //0x001C CLIENT_ID ClientId; //0x0020 // ClientId.ProcessId //0x0020 / value retrieved by GetCurrentProcessId() // ClientId.ThreadId //0x0024 / value retrieved by GetCurrentThreadId() void* ActiveRpcHandle; //0x0028 void* ThreadLocalStoragePointer; //0x002C PEB* ProcessEnvironmentBlock; //0x0030 ... bytepointer.com/resources/tebpeb32.htm EXCEPTION_REGISTRATION* ExceptionList; //0x0000

Slide 66

Slide 66 text

>_x64dbg !66 We can use the command "teb()" to fetch the current TEB table address.

Slide 67

Slide 67 text

>_x64dbg !67 We can use the command "teb()" to fetch the current TEB table address. Point to handler-chain

Slide 68

Slide 68 text

>_x64dbg !68 teb() = 0x5b0000

Slide 69

Slide 69 text

>_SEH Record !69 Thread Exception TEB fs:[0] SEH Chain fs:[4] StackBase fs:[8] StackLimt fs:[c] SubSystem Handler 3 Callback Handler Ptr Prev Handler Handler 2 Callback Handler Ptr Prev Handler Handler 1 Callback Handler Ptr -1 (end)

Slide 70

Slide 70 text

>_SEH !70

Slide 71

Slide 71 text

>_SEH !71 push ebp mov ebp, esp push offset __ehhandler$_main push fs:[0] mov fs:[0], esp mov [0], 1 xor eax, eax mov ecx, [esp] mov large fs:0, ecx mov esp, ebp pop ebp retn Return value Function codes Register a handler Unregister a handler The begin of function The end of function

Slide 72

Slide 72 text

>_Stack Frame !72 Low Address (stack) High Address ret addr old ebp ebp (current stack frame) SEH record esp ebp ebp+4 arg3 arg2 arg1 ebp+8 ebp+0x0c ebp+0x10 canery SEH record Previous SEH Record addr Current Handler buffer

Slide 73

Slide 73 text

>_Buffer Overflow !73 Low Address (stack) High Address ret addr old ebp ebp (current stack frame) SEH record esp ebp ebp+4 arg3 arg2 arg1 ebp+8 ebp+0x0c ebp+0x10 canery SEH record Previous SEH Record addr Current Handler buffer

Slide 74

Slide 74 text

>_Buffer Overflow !74 Low Address (stack) High Address ret addr old ebp ebp (current stack frame) SEH record esp ebp ebp+4 arg3 arg2 arg1 ebp+8 ebp+0x0c ebp+0x10 canery SEH record Previous SEH Record addr Current Handler buffer Buffer Overflow from low addr to high addr

Slide 75

Slide 75 text

>_Buffer Overflow !75 Low Address (stack) High Address ret addr old ebp ebp (current stack frame) SEH record esp ebp ebp+4 arg3 arg2 arg1 ebp+8 ebp+0x0c ebp+0x10 canery SEH record Previous SEH Record addr Current Handler buffer Buffer Overflow from low addr to high addr buffer memory out of bounds

Slide 76

Slide 76 text

[email protected] Lab 1: Knock down the handler !76

Slide 77

Slide 77 text

[email protected] Th3 D4Rk Art: Anti-analysis Techniques D4Rk !77

Slide 78

Slide 78 text

>_Anti-analysis • Most static analysis tools (e.g. IDA Pro, Snowman, Hopper, etc.) transform machine code to Control-Flow Graph or C-like pseudocode based on the x86 Calling Convention. !78

Slide 79

Slide 79 text

>_Anti-analysis • Issues • Break Stack Frame • Junk Instructions • Relace Orignal Instructions • VM-like Protection • Abusing SEH !79

Slide 80

Slide 80 text

[email protected] Obfuscation Tricks !80

Slide 81

Slide 81 text

>_Junk Instructions • nop • xchg eax, ebx; xchg ebx, eax • inc eax, dec eax; • lodsb, lodsw, lodsd • stosb, stosw, stosd • scasb • std, stc, sti • rdtsc • Just do nothing !81

Slide 82

Slide 82 text

>_Junk Instructions !82 IDA Pseudocode

Slide 83

Slide 83 text

>_Junk Instructions !83 IDA Pseudocode

Slide 84

Slide 84 text

>_Replacing Codes • jmp xxx = push xxx; ret • call xxx = push retAddr; jmp xxx
 = push retAddr; push xxx; ret • mov eax, ebx = push ebx; pop eax • sub esp, 0x04 = lea esp, [esp-0x04] • push xxx = sub esp, 0x04; mov [esp], xxx
 = lea esp, [esp-0x04]; mov [esp], xxx ...etc !84

Slide 85

Slide 85 text

Black Hat Asia 2018: BREAKING STATE-OF-THE-ART BINARY CODE OBFUSCATION VIA PROGRAM SYNTHESIS • https://www.blackhat.com/docs/asia-18/asia-18-Blazytko- Breaking-State-Of-The-Art-Binary-Code-Obfuscation-Via- Program-Synthesis.pdf • https://www.blackhat.com/docs/asia-18/asia-18-Blazytko- Breaking-State-Of-The-Art-Binary-Code-Obfuscation-Via- Program-Synthesis-wp.pdf >_Virtual Machines !85

Slide 86

Slide 86 text

!86 >_Virtual Machines

Slide 87

Slide 87 text

>_Virtual Machines !87

Slide 88

Slide 88 text

!88 >_Virtual Machines

Slide 89

Slide 89 text

!89 >_Virtual Machines

Slide 90

Slide 90 text

• Call $+5; pop eax • push xx; push xx; call entry
 entry: add esp, 0x0c • push next; push xxxx; call [esp+0x04]; add esp, 0x08
 next: add esp, 0x0c • ret 0xff !90 >_Control Flow

Slide 91

Slide 91 text

!91 >_Control Flow

Slide 92

Slide 92 text

!92 >_Abusing SEH

Slide 93

Slide 93 text

!93 >_Abusing SEH The SEH handler is always a lonely region.

Slide 94

Slide 94 text

[email protected] Lab 2: Obfuscation Challenge !94

Slide 95

Slide 95 text

Thanks. [email protected] Slide Github @aaaddress1 Facebook !95