Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Computer Security 資安實務: Windows Reversing [Dark...

adr
October 04, 2018
1.7k

Computer Security 資安實務: Windows Reversing [Dark Art]

台科資安實務 2018/10/05
直播連結: https://www.youtube.com/watch?v=cBAXClitYIQ

adr

October 04, 2018
Tweet

More Decks by adr

Transcript

  1. • Master degree at CSIE, NTUST • Security Researcher -

    chrO.ot, TDOHacker • Speaker - BlackHat, DEFCON, beVX, VXCON, HITCON >_cat ./Bio !2
  2. • 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
  3. based on x86 Calling Convention !7 #include <Windows.h> 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
  4. >_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)
  5. >_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)
  6. >_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)
  7. >_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
  8. !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
  9. >_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
  10. >_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.
  11. !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 :(
  12. !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)
  13. >_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
  14. >_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
  15. 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
  16. 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
  17. 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
  18. >_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
  19. >_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
  20. >_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
  21. >_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
  22. >_Stack push eax push ebx pop edx !34 Low Address

    = 0x100 (stack) High Address eax 1 ebx 2 edx 3 esp = 0x28c index = 99
  23. >_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
  24. >_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
  25. >_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
  26. >_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
  27. >_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
  28. >_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)
  29. !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
  30. !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
  31. !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
  32. !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
  33. !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
  34. !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
  35. !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
  36. !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
  37. !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
  38. !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
  39. !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
  40. !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
  41. !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
  42. !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
  43. 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
  44. !59

  45. >_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
  46. [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
  47. [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
  48. >_x64dbg !67 We can use the command "teb()" to fetch

    the current TEB table address. Point to handler-chain
  49. >_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)
  50. >_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
  51. >_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
  52. >_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
  53. >_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
  54. >_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
  55. >_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
  56. >_Anti-analysis • Issues • Break Stack Frame • Junk Instructions

    • Relace Orignal Instructions • VM-like Protection • Abusing SEH !79
  57. >_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
  58. >_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
  59. 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
  60. • 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