Field Manual
Cheatsheets
Quick-lookup reference tables for everything this course covers by hand. Not a substitute for the lessons — a fast reminder once you already know why a field matters.
x86-64 Registers & Calling Conventions
| Register | Common use | Windows x64 (caller/callee-saved) | System V AMD64 (Linux/macOS) |
|---|---|---|---|
RAX | Accumulator, return value | Caller-saved | Caller-saved |
RBX | General purpose | Callee-saved | Callee-saved |
RCX | 1st int arg (Win) / loop counter | Caller-saved · arg 1 | Caller-saved · arg 4 |
RDX | 2nd int arg (Win) / I/O port, remainder | Caller-saved · arg 2 | Caller-saved · arg 3 |
RSI | Source index (string ops) / arg 2 (SysV) | Callee-saved | Caller-saved · arg 2 |
RDI | Destination index (string ops) / arg 1 (SysV) | Callee-saved | Caller-saved · arg 1 |
RBP | Frame/base pointer | Callee-saved | Callee-saved |
RSP | Stack pointer | Callee-saved | Callee-saved |
R8 | 3rd int arg (Win) / 5th (SysV) | Caller-saved · arg 3 | Caller-saved · arg 5 |
R9 | 4th int arg (Win) / 6th (SysV) | Caller-saved · arg 4 | Caller-saved · arg 6 |
R10–R11 | Scratch | Caller-saved | Caller-saved |
R12–R15 | General purpose | Callee-saved | Callee-saved |
Windows x64: first four integer/pointer args in RCX, RDX, R8, R9; the rest on the stack. The caller always reserves 32 bytes of shadow space above the return address, even if the callee has fewer than 4 args. Float/double args use XMM0–XMM3 in parallel with the integer slots (an arg is in either the GPR or the XMM register for its position, never both).
System V AMD64 (Linux/macOS): first six integer/pointer args in RDI, RSI, RDX, RCX, R8, R9; floats in XMM0–XMM7. No shadow space, but there's a 128-byte red zone below RSP that leaf functions can use without adjusting the stack pointer.
Common x86-64 Instructions
| Instruction | Meaning |
|---|---|
mov dst, src | Copy value |
lea dst, [expr] | Load the computed address — doesn't dereference. Often used as arithmetic (lea rax, [rbx+rcx*4]). |
push / pop | Push to / pop from the stack, adjusting RSP |
add / sub | Add / subtract |
inc / dec | Increment / decrement by 1 (doesn't affect CF) |
and / or / xor / not | Bitwise operations. xor reg, reg is the idiomatic way to zero a register. |
shl/sal, shr, sar | Shift left, logical shift right, arithmetic (sign-preserving) shift right |
cmp a, b | Computes a - b, sets flags, discards the result |
test a, b | Computes a AND b, sets flags, discards the result — test reg, reg is the idiomatic zero-check |
jmp | Unconditional jump |
call / ret | Push return address and jump to a function / pop it and jump back |
nop | No-op (also the classic padding/alignment filler byte, 0x90) |
int3 | Software breakpoint interrupt (0xCC) — what a debugger writes over an instruction to trap execution |
syscall | Enter the kernel (x86-64 Linux/macOS syscall instruction) |
Conditional jumps read the flags cmp/test just set:
| Mnemonic | Condition | Typical use |
|---|---|---|
je / jz | ZF=1 | Equal / zero |
jne / jnz | ZF=0 | Not equal / non-zero |
jg / jnle | ZF=0 and SF=OF | Signed greater-than |
jge | SF=OF | Signed greater-or-equal |
jl | SF≠OF | Signed less-than |
jle | ZF=1 or SF≠OF | Signed less-or-equal |
ja | CF=0 and ZF=0 | Unsigned above |
jb / jc | CF=1 | Unsigned below / carry set |
x86-64 Stack Frame Layout
The stack grows downward (toward lower addresses). A standard prologue —
push rbp
mov rbp, rsp
sub rsp, 0x20 ; reserve space for locals— produces this layout, read relative to RBP:
| Address | Contents |
|---|---|
[rbp+16], [rbp+24]... | Stack-passed arguments (5th+ on Windows, 7th+ on System V) |
[rbp+8] | Return address (pushed by call) |
[rbp+0] | Saved caller RBP (pushed by the prologue) |
[rbp-8] … [rbp-N] | Local variables |
RSP | Points at the current top of the stack, below the locals |
A classic stack-smash overflows a local buffer far enough to overwrite the saved RBP and then the return address — the exact byte count from the start of the buffer to [rbp+8] is what lab-19 asks you to compute. The matching epilogue, leave; ret (or mov rsp, rbp; pop rbp; ret), reverses the prologue and jumps to whatever address now sits at the top of the stack.
ARM64 (AArch64) Quick Reference
| Register | Common use | AAPCS64 calling convention |
|---|---|---|
X0–X7 | General purpose (W0–W7 = low 32 bits) | Argument / return value registers |
X8 | Indirect result register | Used for large struct returns |
X9–X15 | General purpose | Caller-saved (temporary) |
X16–X17 | Intra-procedure-call temp (IP0/IP1) | Caller-saved, used by the linker for veneers |
X18 | Platform register | Reserved on some platforms — don't assume it's free |
X19–X28 | General purpose | Callee-saved |
X29 | Frame pointer (FP) | Callee-saved |
X30 | Link register (LR) — holds the return address | Callee-saved |
SP | Stack pointer | Must stay 16-byte aligned |
XZR / WZR | Hardwired zero register | Reading always gives 0; writes are discarded |
Unlike x86, ARM is a load-store architecture — arithmetic instructions only operate on registers, never directly on memory. There's also no dedicated call instruction with an implicit stack push: BL puts the return address straight into X30, and a leaf function that never calls anything else doesn't need to touch the stack at all.
| Instruction | Meaning |
|---|---|
mov Xd, Xn | Copy register / move immediate |
ldr Xd, [Xn] | Load from memory into a register |
str Xd, [Xn] | Store a register to memory |
add / sub | Add / subtract |
cmp Xn, Xm | Compare (subtract and set flags, discard result) |
b <label> | Unconditional branch |
b.eq / b.ne / b.gt / b.lt | Conditional branch on the flags cmp just set |
bl <label> | Branch with link — call: X30 ← return address, then jump |
ret | Return via the address in X30 (or an explicit register: ret Xn) |
PE Format Quick Reference
| Offset | Field | Notes |
|---|---|---|
0x00 | e_magic | "MZ" — DOS header signature |
0x3C | e_lfanew | 4-byte offset to the PE signature. Everything from 0x40 to here is the DOS stub — a classic hiding spot. |
e_lfanew | Signature | "PE\0\0" |
| +4 | COFF File Header (20 bytes) | Machine, NumberOfSections, TimeDateStamp, SizeOfOptionalHeader, Characteristics |
| +24 | Optional Header (PE32+) | Magic=0x20B, AddressOfEntryPoint (RVA), ImageBase, SectionAlignment, FileAlignment, SizeOfImage, Subsystem, DllCharacteristics, 16-entry DataDirectory[] |
| after Optional Header | Section Table | NumberOfSections × 40-byte IMAGE_SECTION_HEADER entries |
Data Directory index → contents:
| Index | Directory |
|---|---|
| 0 | Export Table |
| 1 | Import Table |
| 2 | Resource Table |
| 5 | Base Relocation Table |
| 6 | Debug |
| 9 | TLS Table |
| 10 | Load Config Table |
| 12 | Import Address Table (IAT) |
| 14 | CLR Runtime Header (.NET binaries) |
Section characteristics (bitflags): 0x20000000 EXECUTE · 0x40000000 READ · 0x80000000 WRITE. A section with all three set (0xE0000000-family, "RWX") is the classic packing/injection red flag — see lab-11 and lab-16.
ELF Format Quick Reference
| Offset | Field | Notes |
|---|---|---|
0x00 | e_ident[16] | \x7fELF, then class (1=32-bit, 2=64-bit), data (1=little-endian), version, OS/ABI |
0x10 | e_type | 1=ET_REL, 2=ET_EXEC, 3=ET_DYN (PIE / shared object), 4=ET_CORE |
0x12 | e_machine | 0x3E=x86-64, 0xB7=AArch64, 0x03=i386 |
0x18 | e_entry | Entry point virtual address |
0x20 | e_phoff | File offset of the program header table |
0x28 | e_shoff | File offset of the section header table (0 if stripped) |
0x36 | e_phentsize / e_phnum | Size and count of program header entries |
Program header p_type values:
| Value | Type | Meaning |
|---|---|---|
| 1 | PT_LOAD | A segment to map into memory (code or data) |
| 2 | PT_DYNAMIC | Dynamic linking info (needed libraries, relocations) |
| 3 | PT_INTERP | Path to the dynamic linker, e.g. /lib64/ld-linux-x86-64.so.2 |
| 4 | PT_NOTE | Auxiliary vendor/OS note data |
| 6 | PT_PHDR | Location of the program header table itself, once mapped |
| 7 | PT_TLS | Thread-local storage template |
p_flags: 1=PF_X (execute) · 2=PF_W (write) · 4=PF_R (read) — combined by OR, e.g. 5 = R+X.
Common File Signatures
The first bytes of a file ("magic bytes") identify its format regardless of extension — the first thing to check on an unknown sample.
| Bytes (hex) | ASCII | Format |
|---|---|---|
4D 5A | MZ | DOS/PE executable (.exe, .dll, .sys) |
7F 45 4C 46 | .ELF | ELF (Linux executable/library) |
FE ED FA CE / CF | — | Mach-O 32-bit / 64-bit (macOS executable) |
CA FE BA BE | — | Mach-O Fat/Universal binary — also the Java .class file magic number |
50 4B 03 04 | PK.. | ZIP — also the container for JAR, APK, and Office Open XML (.docx/.xlsx/.pptx) |
25 50 44 46 | %PDF | |
89 50 4E 47 0D 0A 1A 0A | .PNG.... | PNG |
FF D8 FF | — | JPEG |
47 49 46 38 | GIF8 | GIF |
1F 8B | — | GZIP |
52 61 72 21 1A 07 | Rar!.. | RAR archive |
37 7A BC AF 27 1C | — | 7-Zip archive |
Debugger Command Reference
| Action | x64dbg | GDB |
|---|---|---|
| Set breakpoint | bp <addr> | break *<addr> / b <func> |
| Run | F9 | run / r |
| Continue | F9 | continue / c |
| Step into | F7 | stepi / si |
| Step over | F8 | nexti / ni |
| Show registers | Registers panel (always visible) | info registers / i r |
| Examine memory | Dump panel, "Follow in Dump" | x/20xb $rsp |
| Disassemble | CPU panel (always visible) | disassemble / disas |
| Hardware breakpoint on write | right-click memory → "Break on write" | watch *<addr> |
| List loaded modules | Memory Map (Alt+M) | info proc mappings |
WinAPI Capability Clusters
Individual imports are weak signals — legitimate software uses most of these too. A cluster of related imports is what turns "possible" into "likely." These are the exact clusters this course's labs are built around:
| Capability | API cluster |
|---|---|
| Process injection | OpenProcess → VirtualAllocEx → WriteProcessMemory → CreateRemoteThread |
| Keylogging (hook-based) | SetWindowsHookExA (WH_KEYBOARD_LL) + GetForegroundWindow |
| Keylogging (polling) | GetAsyncKeyState in a loop + GetForegroundWindow |
| Registry persistence | RegCreateKeyExW → RegSetValueExW (typically a ...\CurrentVersion\Run key) |
| Service persistence | CreateServiceW → StartServiceW |
| C2 / beaconing (WinINet) | InternetOpenW → InternetConnectW → HttpSendRequestW |
| Anti-debugging | IsDebuggerPresent, CheckRemoteDebuggerPresent, NtQueryInformationProcess |
| DLL search-order hijack targets | small app-local DLLs commonly missing from KnownDLLs: version.dll, dwmapi.dll, uxtheme.dll |
Anti-Debugging Techniques
How a sample checks whether it's being watched — and the static/dynamic tell for each check, per lab-10.
| Technique | How it works |
|---|---|
IsDebuggerPresent() | Reads the BeingDebugged flag in the PEB — the cheapest, most-checked-for anti-debug call |
CheckRemoteDebuggerPresent() | Same check, but works even if the debugger attached to a different process is asked about this one |
NtQueryInformationProcess | ProcessDebugPort/ProcessDebugFlags/ProcessDebugObjectHandle — lower-level equivalents that don't show up as an obvious "debugger" import |
PEB NtGlobalFlag | Debuggers set specific heap-allocation flags; a sample can read the flag directly from the PEB without calling any API at all |
| Timing checks | RDTSC or GetTickCount before/after a block of code — single-stepping through a debugger is orders of magnitude slower than normal execution |
INT3 scanning | Checksums its own code section looking for the 0xCC bytes a software breakpoint writes in place of the original instruction |
| Hardware breakpoint detection | GetThreadContext and inspect DR0–DR3 — sees hardware breakpoints that never touch the code bytes themselves |
Packer Signatures
Static tells that identify which packer compressed/obfuscated a binary — the first move on any sample flagged by high section entropy, per lab-16.
| Packer | Signature / section names |
|---|---|
| UPX | UPX! signature; sections UPX0, UPX1 — most common, open-source, trivially reversible with upx -d |
| ASPack | ASPack string; sections .aspack, .adata |
| Themida | sections .themida, .tmd — heavy anti-debug/anti-VM, not a quick unpack |
| VMProtect | sections .vmp0, .vmp1 — virtualizes code into a custom bytecode, not just compression |
| Enigma | sections .enigma, .edata |
| PECompact | PEC2 signature; sections .pec1, .pec2 |
| MPRESS | MPRESS section name — free, LZMA-based |
Persistence Locations
Where malware re-establishes itself after a reboot or logout — the standard checklist for triage and cleanup, per lab-14.
| Mechanism | Location |
|---|---|
| Registry Run key | HKCU\Software\Microsoft\Windows\CurrentVersion\Run (also HKLM for machine-wide, and RunOnce for a single-shot variant) |
| Services | HKLM\SYSTEM\CurrentControlSet\Services — installed via CreateServiceW |
| Winlogon | HKLM\...\Winlogon — Shell/Userinit values run at every logon |
| Startup folder | %APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup — anything dropped here runs at next logon, no registry needed |
| Scheduled Tasks | Task Scheduler (schtasks / ITaskScheduler) — can trigger on a schedule, on logon, or on idle |
| AppInit_DLLs | HKLM\...\Windows AppInit_DLLs value — loads a DLL into every process that also loads User32.dll |
| WMI Event Subscription | WMI repository — fileless, survives without a corresponding file on disk |
ASCII Quick Reference
Ranges worth recognizing on sight in a hex viewer's ASCII column, without memorizing all 128 codepoints.
| Range (hex) | Characters |
|---|---|
0x30–0x39 | 0–9 |
0x41–0x5A | A–Z |
0x61–0x7A | a–z |
0x20 | Space |
0x00 | NUL — C-string terminator |
0x09 | Tab |
0x0A / 0x0D | LF / CR — Unix vs. Windows line endings (\r\n together = Windows) |
0x7F | DEL — outside the normal printable range, often shows as a stray byte between printable strings |
A run of alternating printable-byte / 0x00 bytes (e.g. 48 00 69 00 = "H.i.") is UTF-16LE — the wide-string encoding Windows APIs favor. Plain strings without -el misses these entirely.