# FOR610 Assembly & Reversing Cheat Sheet ## Registers ### 32-bit General Purpose | Register | Purpose | Notes | |----------|---------|-------| | **EAX** | Accumulator, return values | Function returns go here | | **EBX** | Base register | General purpose | | **ECX** | Counter | Loop counts, fastcall param 1 | | **EDX** | Data | Used with EAX in mul/div, fastcall param 2 | | **ESI** | Source index | String ops source | | **EDI** | Destination index | String ops destination | | **ESP** | Stack pointer | Top of stack (grows DOWN) | | **EBP** | Base/frame pointer | Access local vars and params | | **EIP** | Instruction pointer | Next instruction address | | **EFLAGS** | Flags | ZF, CF, SF, OF set by CMP/TEST | ### 64-bit Extensions | 64-bit | 32-bit | 16-bit | 8-bit | Purpose | |--------|--------|--------|-------|---------| | RAX | EAX | AX | AL/AH | Return value | | RCX | ECX | CX | CL | x64 param 1 | | RDX | EDX | DX | DL | x64 param 2 | | R8 | R8D | R8W | R8B | x64 param 3 | | R9 | R9D | R9W | R9B | x64 param 4 | | R10-R15 | R10D-R15D | R10W-R15W | R10B-R15B | General purpose | ### Special | Register | Purpose | |----------|---------| | **FS:[0]** | Pointer to SEH chain (32-bit) | | **FS:[30h]** | Pointer to PEB (Process Environment Block) | --- ## Instructions ### Data Movement | Instruction | Meaning | Example | |-------------|---------|---------| | `MOV dst, src` | Copy src to dst | `MOV EAX, [EBP+8]` — load param 1 | | `LEA dst, [addr]` | Load address (not value) | `LEA R8, [RSP+0x30]` — pass address | | `PUSH val` | Push onto stack (ESP-=4) | `PUSH EBP` — save frame pointer | | `POP dst` | Pop from stack (ESP+=4) | `POP EBP` — restore frame pointer | | `XCHG a, b` | Swap a and b | `XCHG EAX, EBX` | ### Arithmetic | Instruction | Meaning | Example | |-------------|---------|---------| | `ADD dst, src` | dst = dst + src | `ADD ESP, 8` — clean up 2 args | | `SUB dst, src` | dst = dst - src | `SUB ESP, 0x100` — allocate locals | | `INC dst` | dst = dst + 1 | `INC ECX` — loop counter | | `DEC dst` | dst = dst - 1 | `DEC ECX` — loop counter | | `MUL/IMUL` | Multiply (unsigned/signed) | Result in EDX:EAX | | `DIV/IDIV` | Divide (unsigned/signed) | Dividend in EDX:EAX | | `NEG dst` | Two's complement negate | `NEG EAX` | ### Bitwise / Logic | Instruction | Meaning | Malware Use | |-------------|---------|-------------| | `XOR dst, src` | Bitwise XOR | **Obfuscation** (`XOR EAX, key`), zero reg (`XOR EAX, EAX`) | | `AND dst, src` | Bitwise AND | Masking bits | | `OR dst, src` | Bitwise OR | Setting flags | | `NOT dst` | Bitwise NOT | Invert all bits | | `SHL dst, n` | Shift left n bits | Multiply by 2^n | | `SHR dst, n` | Shift right n bits | Unsigned divide by 2^n | | `ROL dst, n` | Rotate left | **Obfuscation** (ROT13-like) | | `ROR dst, n` | Rotate right | **Obfuscation** | ### Compare & Test | Instruction | What it does | Sets flags for | |-------------|-------------|----------------| | `CMP a, b` | Computes a - b (discards result) | All conditional jumps | | `TEST a, b` | Computes a AND b (discards result) | Zero check: `TEST EAX, EAX` | ### Conditional Jumps (after CMP/TEST) **Unsigned (Above/Below):** | Jump | Condition | Meaning | |------|-----------|---------| | `JA` | CF=0, ZF=0 | Jump if Above | | `JAE/JNB` | CF=0 | Jump if Above or Equal | | `JB/JNAE` | CF=1 | Jump if Below | | `JBE/JNA` | CF=1 or ZF=1 | Jump if Below or Equal | **Signed (Greater/Less):** | Jump | Condition | Meaning | |------|-----------|---------| | `JG/JNLE` | ZF=0, SF=OF | Jump if Greater | | `JGE/JNL` | SF=OF | Jump if Greater or Equal | | `JL/JNGE` | SF≠OF | Jump if Less | | `JLE/JNG` | ZF=1 or SF≠OF | Jump if Less or Equal | **Equality:** | Jump | Condition | Meaning | |------|-----------|---------| | `JE/JZ` | ZF=1 | Jump if Equal / Zero | | `JNE/JNZ` | ZF=0 | Jump if Not Equal / Not Zero | | `JS` | SF=1 | Jump if Sign (negative) | | `JNS` | SF=0 | Jump if Not Sign (positive) | ### Function Calls | Instruction | Meaning | |-------------|---------| | `CALL addr` | Push return address, jump to addr | | `RET` | Pop return address, jump to it (cdecl) | | `RET n` | Pop return address, add n to ESP (stdcall) | | `LEAVE` | `MOV ESP, EBP` then `POP EBP` (epilogue shortcut) | ### Other Important | Instruction | Meaning | Significance | |-------------|---------|-------------| | `NOP` | No operation (0x90) | Padding; NOP sled = shellcode indicator | | `INT 3` | Software breakpoint (0xCC) | Debugger trap; anti-debug detection | | `CDQ` | Sign-extend EAX → EDX:EAX | Required before DIV | | `REP MOVSB/D` | Copy ECX bytes from ESI→EDI | Bulk memory copy (memcpy) | | `REP STOSB/D` | Fill ECX bytes at EDI with AL/EAX | Memory fill (memset) | --- ## Function Structure ### 32-bit Prologue & Epilogue ``` PUSH EBP ; Save old frame pointer MOV EBP, ESP ; Set new frame pointer SUB ESP, 0x20 ; Allocate 32 bytes for locals ``` ``` MOV EAX, result ; Set return value LEAVE ; MOV ESP,EBP + POP EBP RET ; Return to caller ``` ### Stack Frame Layout (32-bit) ``` Higher addresses ┌─────────────────┐ │ Param 3 │ [EBP + 0x10] │ Param 2 │ [EBP + 0x0C] │ Param 1 │ [EBP + 0x08] │ Return Address │ [EBP + 0x04] ← pushed by CALL │ Saved EBP │ [EBP] ← pushed by PUSH EBP │ Local var 1 │ [EBP - 0x04] │ Local var 2 │ [EBP - 0x08] │ ... │ ← ESP points here └─────────────────┘ Lower addresses (stack grows DOWN) ``` ### Calling Conventions | Convention | Params | Cleanup | Return | Used by | |-----------|--------|---------|--------|---------| | **cdecl** | Stack (R→L) | **Caller** (`ADD ESP,n`) | EAX | C library functions | | **stdcall** | Stack (R→L) | **Callee** (`RET n`) | EAX | Win32 API (kernel32, etc.) | | **fastcall** | ECX, EDX, then stack | Callee | EAX | Some internal functions | | **thiscall** | ECX=this, then stack | Callee | EAX | C++ member functions | | **x64** | RCX, RDX, R8, R9, then stack | Caller | RAX | All 64-bit Windows | --- ## Control Flow Patterns ### If/Else ```asm CMP EAX, 5 ; Compare JNE else_block ; Jump if not equal ; if-block code JMP end_if else_block: ; else-block code end_if: ``` ### Loop (for/while) ```asm MOV ECX, 10 ; counter = 10 loop_start: ; loop body DEC ECX ; counter-- JNZ loop_start ; if counter != 0, repeat ``` ### AND condition (both must be true) ```asm CMP val1, limit1 JL skip ; if first false, skip CMP val2, limit2 JL skip ; if second false, skip ; both true skip: ``` ### OR condition (either true) ```asm CMP val1, limit1 JG execute ; if first true, go CMP val2, limit2 JLE skip ; if second also false, skip execute: ; at least one true skip: ``` --- ## Anti-Analysis Techniques (Section 5) ### Debugger Detection ```asm ; IsDebuggerPresent check CALL IsDebuggerPresent TEST EAX, EAX JNE detected ; non-zero = debugger present ; PEB BeingDebugged field MOV EAX, FS:[30h] ; PEB pointer MOVZX EAX, [EAX+2] ; BeingDebugged byte TEST EAX, EAX JNE detected ; Timing check (RDTSC) RDTSC ; read timestamp counter ; ... do work ... RDTSC ; read again ; large delta = debugger stepping ``` ### SEH (Structured Exception Handling) ```asm ; Set up SEH handler PUSH handler_addr ; push handler function PUSH FS:[0] ; push current SEH chain MOV FS:[0], ESP ; install new handler ; Trigger exception intentionally XOR ECX, ECX DIV ECX ; divide by zero → handler executes ``` ### Process Hollowing Pattern ``` CreateProcessW(SUSPENDED) ; Create target process suspended NtUnmapViewOfSection() ; Remove original code VirtualAllocEx() ; Allocate new memory WriteProcessMemory() ; Write malicious code ResumeThread() ; Execute injected code ``` ### Code Injection Pattern ``` OpenProcess() ; Get handle to target VirtualAllocEx(RWX) ; Allocate executable memory WriteProcessMemory() ; Write shellcode CreateRemoteThread() ; Execute in target ``` --- ## Key Patterns to Recognize | Pattern | What it means | |---------|--------------| | `XOR EAX, EAX` | Zero out EAX (common idiom) | | `TEST EAX, EAX` + `JZ` | Check if EAX is zero | | `PUSH EBP; MOV EBP,ESP; SUB ESP,n` | Function prologue | | `LEAVE; RET` | Function epilogue | | `CALL; ADD ESP,n` | cdecl call (caller cleanup) | | `CALL; (no ADD ESP)` | stdcall call (callee cleanup) | | `REP MOVSB` with ESI→EDI | Memory copy (like memcpy) | | `FS:[0]` access | SEH manipulation | | `FS:[30h]` access | PEB access (anti-debug) | | NOP sled (many 0x90) | Shellcode indicator | | `VirtualAlloc` + `memcpy` | Unpacking to new memory |