Ghidra
Ghidra เป็น reverse engineering suite ฟรีจาก NSA ที่มี decompiler คุณภาพสูงแปลง assembly เป็น pseudo-C เป็นเครื่องมือหลักของ CTF reversing บทนี้ลงลึกตั้งแต่การ import, การ navigate ทุกหน้าต่าง, คีย์ลัดครบ, การ rename/retype ให้ decompiler อ่านง่าย, เทคนิคแก้โจทย์ (หา flag check, patch), และ Ghidra scripting
1. Ghidra คืออะไรและทำไมใช้
Ghidra เป็น RE suite ฟรี/open-source จาก NSA จุดเด่นคือ decompiler ที่แปลง machine code กลับเป็น pseudo-C อ่านได้ ทำให้เข้าใจ logic โดยไม่ต้องอ่าน assembly ทั้งหมด รองรับหลาย architecture (x86/x64/ARM/MIPS/...) และฟรี (ต่างจาก IDA Pro ที่แพง) เป็นตัวเลือกหลักของ CTF reversing เพราะคุณภาพ decompiler ใกล้เคียง IDA แต่ไม่มีค่าใช้จ่าย
2. เริ่มต้น — project และ analysis
- 1เปิด Ghidra → สร้าง Non-Shared Project → ตั้งชื่อ
- 2File → Import File → เลือก binary (Ghidra ระบุ format/arch อัตโนมัติ)
- 3ดับเบิลคลิกไฟล์ในโปรเจกต์ → เปิด CodeBrowser
- 4ตอบ Yes เมื่อถามให้ auto-analyze (เลือก analyzer default ก็พอ)
- 5รอ analysis เสร็จ (มุมขวาล่าง) — Ghidra หาฟังก์ชัน/string/xref/type ให้
- 6เริ่มที่ Symbol Tree → Functions → main (หรือ entry ถ้าไม่มี main)
entry แล้วตามไป function ที่ถูกเรียกใน __libc_start_main (argument แรกคือ main)3. หน้าต่างหลักและการ navigate
| หน้าต่าง | ใช้ทำอะไร |
|---|---|
| Listing (กลาง) | disassembly (assembly) + address |
| Decompiler (ขวา) | pseudo-C — อ่านง่ายสุด |
| Symbol Tree (ซ้าย) | functions, labels, imports, exports |
| Data Type Manager | struct, enum, typedef |
| Defined Strings | string ทั้งหมดในไฟล์ (Window menu) |
| Function Graph | control flow graph ของฟังก์ชัน |
| Bytes | hex view |
Listing กับ Decompiler sync กัน — คลิกบรรทัดใน decompiler จะ highlight assembly ที่ตรงกัน ช่วยเชื่อมระดับสูง (C) กับระดับล่าง (asm) double-click ชื่อฟังก์ชัน/ตัวแปร = กระโดดไป definition, Alt+Left = ย้อนกลับ
4. คีย์ลัดสำคัญ
| คีย์ | ทำอะไร |
|---|---|
| L | rename ตัวแปร/ฟังก์ชัน/label |
| Ctrl+L | retype (เปลี่ยน data type) |
| ; | ใส่ comment |
| X | cross-references (ใครเรียก/ใช้ object นี้) |
| G | goto address/label/symbol |
| Alt+← / Alt+→ | ย้อนกลับ/ไปข้างหน้า (history) |
| Ctrl+Shift+E | search strings / memory |
| F | สร้างฟังก์ชัน (ถ้าไม่ detect) |
| C | clear code (แปลงกลับเป็น data) |
| space | สลับ Listing ↔ Function Graph |
5. ทำ decompiler ให้อ่านง่าย (หัวใจ)
decompiler ดิบอ่านยาก (ชื่อ local_28, uVar1, FUN_00401234) การ rename + retype ทีละนิดทำให้โค้ดอ่านเข้าใจขึ้นมาก — เป็นทักษะสำคัญที่สุดของการ reverse ฟังก์ชันซับซ้อน ยิ่งตั้งชื่อตรงเท่าไหร่ logic ยิ่งชัด
- rename ตัวแปร (L):
local_28→user_inputตามที่เข้าใจ - retype (Ctrl+L): เปลี่ยน type ให้ตรง เช่น
undefined8→char *หรือ apply struct - rename ฟังก์ชัน (L):
FUN_00401234→check_passwordตามหน้าที่ - comment (;): จุดที่เข้าใจแล้ว กันลืม
- สร้าง struct ใน Data Type Manager ถ้าโปรแกรมใช้ struct → apply แล้ว field มีชื่อ
- แก้ function signature (Ctrl+ที่ชื่อฟังก์ชันใน decompiler) ให้ argument ถูกต้อง
6. เทคนิคแก้โจทย์ CTF
- หา flag check: Defined Strings (Ctrl+Shift+E) หา 'Correct'/'Wrong'/'flag' → X ดู xref → ไปฟังก์ชันที่เทียบ
- reverse algorithm: อ่าน decompiler ของ check function → เข้าใจ transform → เขียน solver ย้อนกลับ (Python)
- strcmp/memcmp: หา call เหล่านี้ → argument ที่สองมัก hardcode flag/password
- xor/encode loop: เจอ loop ที่ xor → ดู key → decode เอง
- patch: Listing → คลิกขวา instruction → Patch Instruction (เช่น JNZ→JZ ข้าม check) → File → Export Program (format Original File)
- ใช้คู่ dynamic: อ่าน Ghidra เข้าใจโครงสร้าง → gdb ยืนยันค่า runtime (ดู Dynamic Analysis)
7. Ghidra Scripting
Ghidra มี Script Manager (Window → Script Manager) รัน script Python (Jython) หรือ Java เพื่อ automate — เช่น deobfuscate (decode string ที่ถูก xor ทั้งไฟล์), patch หลายจุด, ดึงข้อมูล ใช้ Flat API (currentProgram, getFunctionAt(), getInstructionAt())
# Window > Script Manager > New Script (Python)
# ตัวอย่าง: พิมพ์ทุกฟังก์ชัน + address
fm = currentProgram.getFunctionManager()
for func in fm.getFunctions(True):
print(hex(func.getEntryPoint().getOffset()), func.getName())
# อ่าน byte ที่ address (เช่น decode xor string)
addr = toAddr(0x402000)
data = getBytes(addr, 16)
key = 0x42
print("".join(chr((b & 0xff) ^ key) for b in data))
# มี Python console: Window > Python ทดสอบ interactive ได้8. Quick Reference
- decompiler ฟรีจาก NSA — pseudo-C; import → auto-analyze → main
- หน้าต่าง: Listing (asm) + Decompiler (C) sync กัน; Symbol Tree
- คีย์: L rename, Ctrl+L retype, X xref, G goto, ; comment
- Ctrl+Shift+E = strings (เริ่มทุกโจทย์ที่นี่)
- อ่านง่าย: rename+retype ตัวแปร/ฟังก์ชันทีละนิด, สร้าง struct
- flag check: string 'Correct' → X xref → reverse algorithm
- patch: คลิกขวา → Patch Instruction → Export; scripting: Flat API
🧭 จับมือทำทีละขั้น (มีแค่ Kali) + ถ้าติดไปไหนต่อ
สมมติเพิ่งได้ binary จากโจทย์ CTF เปิด Kali ว่างๆ ยังไม่รู้จะกดตรงไหนก่อนใน Ghidra ทำตามนี้ทีละขั้น
- 1file ./binary — เช็ค ELF/PE, 32/64bit, stripped หรือไม่
- 2strings -n 8 ./binary | grep -iE 'flag|pass' ลองทางลัดก่อนเสียเวลาเปิด Ghidra
- 3เปิด Ghidra → File → New Project (Non-Shared) → ตั้งชื่อโปรเจกต์
- 4File → Import File เลือก binary → ดับเบิลคลิกเปิด CodeBrowser
- 5ตอบ Yes ให้ Auto Analyze (ใช้ default analyzer) รอจนแถบล่างขวาวิเคราะห์เสร็จ
- 6Symbol Tree → Functions → main (ถ้า stripped ไปที่ entry แล้วตาม call ที่ 2 ใน __libc_start_main)
- 7เปิด Decompile panel คู่กับ Listing อ่าน pseudo-C ทีละฟังก์ชัน
- 8Ctrl+Shift+E เปิด Defined Strings หา 'Correct'/'flag'/'Wrong' แล้วกด X ดู xref กลับไปโค้ด
- 9กด L rename ตัวแปร, Ctrl+L retype ทีละจุดจนอ่านง่ายขึ้น
- 10เข้าใจ logic แล้วตัดสินใจ: เขียน solver คำนวณ flag เอง หรือ patch ให้ผ่าน check
| ขั้นตอน/งาน | เครื่องมือใน Kali | ติดตั้งเพิ่ม (ถ้าไม่มี) | เครื่องมือออนไลน์ |
|---|---|---|---|
| ดู arch/type ก่อนเปิดเครื่องมือ | file | - | - |
| ดึงข้อความเร็วๆ | strings | - | CyberChef |
| เปิด decompiler หลัก (ฟรี) | ghidra | apt install ghidra | dogbolt.org (ลองหลาย decompiler พร้อมกัน) |
| เทียบผล assembly กับ compiler ต้นทาง | - | - | godbolt.org |
| disassemble เร็วจาก CLI | radare2/rizin, objdump | apt install radare2 | onlinedisassembler.com |
| ยืนยันค่าตอนรันจริง | gdb (pwndbg/gef) | apt install gdb; git clone gef | - |
| เขียน script อัตโนมัติ (decode/patch หลายจุด) | ghidra (Python script) | - | - |
| ถอดรหัส/คำนวณเพิ่มเติมจาก logic ที่เจอ | python3 | - | CyberChef, dcode.fr |
โน้ตของฉัน
ยังไม่มีโน้ตสำหรับหัวข้อนี้