Cheatsheet#

Trang tra cứu nhanh — gom lại các bảng/kiến thức mình hay phải lật lại tìm trong chính các bài viết của mình. Mỗi mục đều có link về bài gốc để đọc đầy đủ ngữ cảnh. Chia theo nhóm lớn (chọn tab bên dưới) để đỡ phải cuộn qua thứ không liên quan tới thứ đang cần tra.

Reverse Engineering#

x86 Data Types#

TênKích thướcWindows APIKiểu C tương đươngDirective khai báo
Byte8 bitBYTEunsigned chardb
Word16 bitWORDunsigned shortdw
Dword32 bitDWORDunsigned longdd
Qword64 bitQWORDunsigned long longdq

x86 Registers (32-bit)#

8 thanh ghi mục đích chung: EAX, EBX, ECX, EDX, ESI, EDI, EBP, ESP. Chỉ 4 thanh ghi đầu chia được thành sub-register:

EAX (32-bit) └─ AX (16-bit) ─┬─ AH (8-bit cao)
                              └─ AL (8-bit thấp)

ESI, EDI, EBP, ESP chỉ chia được tới 16-bit (SI, DI, BP, SP), không có dạng 8-bit cao/thấp riêng.

3 loại operand:

LoạiMô tảVí dụ
ImmediateGiá trị là chính operand đó8, 10h, -123, 'A'
RegisterGiá trị nằm trong thanh ghieax, si, ecx, esp
MemoryTham chiếu tới một địa chỉ bộ nhớ[00020001], [ebp+08h], [eax+esi]

Công thức địa chỉ hiệu dụng: Effective Address = Base + Index × Scale + Displacement

→ Chapter 1 - x86 Basics

Stack & PUSH/POP#

Stack phát triển về phía địa chỉ thấp hơn. ESP luôn trỏ đỉnh hiện tại.

; PUSH tương đương:
sub esp, 4
mov [esp], <operand>

; POP tương đương:
mov <đích>, [esp]
add esp, 4

→ Chapter 2 - The Stack

CALL / RET / Vòng đời Function Call#

CALL target = push <địa chỉ lệnh kế tiếp> rồi jmp target. RET pop giá trị đó ra rồi nhảy tới. RET n (vd ret 8) tự cộng thêm n byte vào ESP sau khi pop — đây là callee cleanup.

Vòng đời: chuẩn bị tham số (push phải→trái) → CALL (push return address) → hàm chạy → RET (pop return address) → dọn stack (tùy convention).

String trong binary: ASCII (1 byte/ký tự, kết 0x00) vs Unicode UTF-16LE (2 byte/ký tự, kết 0x00 0x00).

→ Chapter 3 - Flow Control

Stack Frame (Prologue/Epilogue)#

; Prologue
push ebp
mov ebp, esp
sub esp, N            ; cấp N byte cho biến cục bộ

; Epilogue
mov esp, ebp
pop ebp
ret [n]
  • Tham số → offset dương từ EBP: [ebp+8] = tham số 1, [ebp+0xC] = tham số 2…
  • Biến cục bộ → offset âm từ EBP: [ebp-4], [ebp-8]…

Calling Conventions#

STDCALLCDECL__fastcall (x64)
Ai dọn stackCallee (RET n)Caller (ADD ESP, n)Callee
Thường thấy ởWindows API (WINAPI)Hàm C chuẩn, printfWindows x64 mặc định
Tham số qua thanh ghiKhôngKhông4 đầu: RCX, RDX, R8, R9

→ Chapter 4 - Function Constructs

Conditional Jumps#

CMP a,b tính a-b nội bộ; TEST a,b tính a AND b nội bộ — chỉ set EFLAGS, không ghi kết quả.

SignedÝ nghĩaUnsignedÝ nghĩaChungÝ nghĩa
JL<JB<JZ/JE==
JLE≤JBE≤JNZ/JNE!=
JG>JA>
JGE≥JAE≥

Mẹo đọc nhanh: dịch mnemonic thành toán tử rồi đọc “nhảy nếu [operand1] toán_tử [operand2]”. Compiler thường đảo ngược điều kiện khi dịch if (nhảy nếu false để bỏ qua thân if).

→ Chapter 5 - Conditional Branching

Debugging & Patching#

Kỹ thuậtTồn tạiRủi ro
Sửa Register/FlagTạm thời (mất khi restart)Thấp
Sửa Instruction Pointer (Set IP)Tạm thờiCó thể làm lệch stack nếu bỏ qua đoạn dọn stack
Patch code vào fileVĩnh viễnLàm hỏng chữ ký số, phải đúng số byte lệnh cũ/mới
NOP’ing-outVĩnh viễnPhải biết đúng độ dài byte lệnh gốc, thiếu/thừa đều crash

→ Chapter 6 - Debugging Techniques

MUL / IMUL#

LệnhKích thướcPhép tínhKết quả
MUL (unsigned)32-bitEAX × r/m32EDX:EAX
IMUL (signed, 1 toán hạng)32-bitEAX × r/m32EDX:EAX
IMUL (2 toán hạng)—đích = đích × nguồncắt bớt nếu tràn
IMUL (3 toán hạng)—đích = nguồn × hằng sốcắt bớt nếu tràn

String Instructions & Repeat Prefix#

Dùng ESI (nguồn)/EDI (đích), tự tăng/giảm theo Direction Flag (CLD=tăng, STD=giảm):

LệnhTác dụng
MOVSCopy [ESI] → [EDI]
STOSGhi EAX/AL → [EDI] (zero hóa buffer nếu EAX=0 trước)
SCASSo EAX/AL với [EDI], chỉ set flag

REP (lặp theo ECX), REPE/REPZ (lặp khi ZF=1 và ECX>0), REPNE/REPNZ (lặp khi ZF=0 và ECX>0).

Intrinsic hay gặp: memcpy()→rep movs*, memset()→rep stos*, strlen()→repne scasb — lý do nhiều khi không thấy CALL nào tới các hàm này trong disassembly.

Structs & Switch/Jump Table#

Struct biến mất hoàn toàn sau compile — nhận ra qua: 1 lệnh memset/STOS khởi tạo nguyên vùng nhớ liên tục, hoặc nhiều lệnh cộng các offset cố định vào cùng 1 base.

Switch nhiều case liên tiếp → compiler dùng jump table:

cmp eax, 4
ja default_case
jmp [jump_table + eax*4]
jump_table:
    dd case_0, case_1, case_2, case_3, case_4

→ Chapter 7 - Intermediate Disassembly

x86-64 Registers & __fastcall#

Mở rộng 8 thanh ghi gốc lên 64-bit (tiền tố R), thêm R8-R15.

Thứ tự tham sốThanh ghi
1RCX
2RDX
3R8
4R9

Tham số thứ 5 trở đi ra stack tại [RSP+0x20]. Home space = 32-byte caller luôn chừa sẵn ngay dưới return address, để callee spill 4 tham số thanh ghi ra bộ nhớ khi cần. RBP ở x64 không bắt buộc làm frame pointer nữa vì RSP không đổi suốt thân hàm.

MOVSX/MOVSXD giữ dấu khi mở rộng; MOVZX lấp số 0. Không có MOVZXD vì MOV vào thanh ghi 32-bit đã tự zero-extend nửa cao của thanh ghi 64-bit.

→ Chapter 8 - x86-64 Assembly

Windows API & Internals#

Hungarian Notation#

Kiểu WindowsTiền tốVí dụÝ nghĩa
WORDwwYearsố nguyên 16-bit unsigned
DWORDdwdwSizesố nguyên 32-bit unsigned
LPCSTRlplpFileNamecon trỏ tới chuỗi ASCII hằng

SAL Annotation (trong function prototype)#

AnnotationÝ nghĩa
_In_Caller cung cấp, hàm chỉ đọc
_Out_Hàm ghi ra
_Inout_Cả hai chiều
_In_opt_Tùy chọn, được truyền NULL

Handles#

Handle = index vào bảng handle riêng của từng process — cùng giá trị handle ở 2 process khác nhau có thể trỏ tới 2 object hoàn toàn khác nhau. Vòng đời điển hình: CreateFile → dùng handle (ReadFile…) → CloseHandle.

File API Workflow#

I/O:         CreateFile → ReadFile / WriteFile → CloseHandle
Enumeration: FindFirstFile → FindNextFile → FindClose

Windows Registry#

Root KeyViết tắtMô tả
HKEY_CURRENT_USERHKCUDữ liệu user đang đăng nhập
HKEY_USERSHKUThông tin mọi account trên máy
HKEY_CLASSES_ROOTHKCRLiên kết loại file, COM object
HKEY_LOCAL_MACHINEHKLMCấu hình toàn hệ thống
HKEY_CURRENT_CONFIGHKCCHardware profile hiện tại

Malware nhắm nhiều nhất: HKLM và HKCU.

RegCreateKeyEx / RegOpenKeyEx → RegQueryValueEx / RegSetValueEx → RegCloseKey

Process Loading (PE Loader)#

Khi 1 file .exe chạy, code đầu tiên thực thi không phải entry point của chương trình — mà là Windows loader (ntdll.dll):

  1. Parse PE header
  2. Dựng virtual memory, map section vào bộ nhớ
  3. Đệ quy resolve import table (load DLL → resolve import của chính DLL đó)
  4. Chuyển quyền thực thi tới AddressOfEntryPoint

LoadLibrary + GetProcAddress = resolve hàm thủ công lúc runtime (Runtime Dynamic Linking) — malware hay dùng để né import table tĩnh.

DLL Usage (ví dụ thực tế)#

LoadLibraryA("msvcrt.dll")         -> trả về HMODULE (địa chỉ base DLL)
GetProcAddress(hModule, "printf")  -> trả về địa chỉ thật của hàm

Gọi hàm gián tiếp qua con trỏ vừa lấy — không thấy CALL printf tường minh trong disassembly, chỉ thấy CALL [con trỏ].

Windows Networking#

TầngLuồng gọi
Winsock (client)socket → connect
Winsock (server)socket → bind → listen → accept
WinInet (HTTP)InternetOpen → InternetConnect → HttpOpenRequest → HttpSendRequest → InternetReadFile → InternetCloseHandle

Chuỗi gọi WinInet là dấu vết rất rõ để lần ra C2 domain/IP qua import + xref.

→ Chapter 9 - Reversing Windows Binaries

SOC / Threat Hunting#

Ưu tiên theo dõi đầu tiên#

  1. 1102 — audit log bị xóa (luôn luôn khẩn cấp)
  2. 4625 hàng loạt rồi 4624 thành công — brute-force trót lọt
  3. 4688 / Sysmon 1 với command line đáng ngờ (-enc, IEX, DownloadString…)
  4. Sysmon 10 nhắm lsass.exe — credential dumping
  5. 4769 số lượng lớn, encryption type yếu — Kerberoasting
  6. 7045 với binary path lạ — persistence/lateral movement
  7. 4104 — nội dung PowerShell script sau khi deobfuscate

Logon / Logoff#

Event IDÝ nghĩa
4624Đăng nhập thành công
4625Đăng nhập thất bại
4634Đăng xuất
4648Đăng nhập bằng credential tường minh (runas)
4672Tài khoản đặc quyền vừa đăng nhập

Logon Type (đi kèm 4624):

TypeÝ nghĩa
2Interactive — tại máy
3Network — SMB…
4Batch — scheduled task
5Service
7Unlock
8NetworkCleartext
9NewCredentials (runas /netonly)
10RemoteInteractive — RDP
11CachedInteractive

Account Management#

Event IDÝ nghĩa
4720Tạo user mới
4722Enable account
4724Reset password account khác
4728/4732/4756Thêm vào nhóm global/local/universal
4738Thuộc tính account bị đổi

Pattern đáng ngờ: 4720 → 4732 vào Administrators = backdoor account.

Kerberos#

Event IDÝ nghĩaLiên quan
4768Request TGTBước đầu xác thực
4769Request Service TicketKerberoasting
4771Pre-auth thất bạiBrute-force / AS-REP Roasting

Process / Object / Audit#

Event IDÝ nghĩa
4688Process mới (cần bật audit command-line riêng)
4663Hành động cụ thể lên object (đọc/ghi/xóa)
5140/5145Truy cập network share
4719Audit policy bị đổi
1102Audit log bị xóa sạch
7045Service mới cài (System log)
4103/4104PowerShell module log / Script Block Log

Sysmon Event IDs#

IDÝ nghĩaVì sao quan trọng
1Process CreateThay 4688, kèm hash/cmdline/parent
3Network ConnectPhát hiện C2 beaconing
6Driver LoadDriver độc hại/rootkit
7Image LoadDLL injection/sideloading
8CreateRemoteThreadProcess injection kinh điển
10Process AccessTarget lsass.exe = credential dumping
11File Create
12/13/14Registry EventTheo dõi key persistence
15FileCreateStreamHashAlternate Data Stream
22DNS QueryDNS tunneling

→ Windows Event ID nên biết


Trang này mình sẽ cập nhật dần mỗi khi có bảng tra cứu mới đáng gom vào.