逆向工程 (Reverse Engineering) 是將已編譯的二進位執行檔(如 Linux ELF 或 Windows EXE)進行拆解分析,藉此推導出原始程式邏輯與運作機制的過程。
在 CTF 競賽中,逆向工程主要分為兩大分析手法:
作為逆向工程的第一步,「靜態分析」是最快速且低風險的手法,能幫助我們建立對目標檔案的初步認知。
在 Linux (WSL) 環境中,有幾個內建的文字工具是逆向新手必備的「第一步三連招」:
file 指令:辨識檔案格式觀察目標檔案是 32-bit 還是 64-bit、Linux ELF 還是 Windows PE,以及是否經過 Strip(移除符號表)。
file target_bin
strings 指令:提取硬編碼字串遍歷二進位檔案,找出所有連續長度大於等於 4(預設)的可列印 ASCII/Unicode 字串。許多入門 CTF 題目會直接將 Flag 寫死在程式碼中!
strings target_bin | grep -i "flag"
readelf / objdump:檢視 ELF 區段與反組譯檢視二進位檔案的 Section Header,或是進行基礎的反組譯(Disassembly)。
readelf -h target_bin
我們直接在 WSL 中寫一個簡單的 C 語言程式(將 Flag 硬編碼在內),編譯成二進位檔後,示範如何用 strings 與 Python 腳本挖出 Flag!
在 WSL 終端機執行以下命令,建立並編譯範例程式:
# 1. 建立 C 語言原始碼
cat << 'EOF' > reverse_demo.c
#include <stdio.h>
#include <string.h>
// 將 Flag 硬編碼在程式中
const char secret_flag[] = "picoCTF{st4t1c_4n4lys1s_1s_34sy_a8f92}";
int main() {
char input[50];
printf("Please enter password: ");
scanf("%49s", input);
if (strcmp(input, "super_secret_pass") == 0) {
printf("Access Granted! %s\n", secret_flag);
} else {
printf("Access Denied!\n");
}
return 0;
}
EOF
# 2. 編譯 C 程式
gcc reverse_demo.c -o reverse_demo

strings 進行靜態分析挖寶編譯完成後,我們完全不需輸入正確密碼執行程式,直接對二進位檔案 reverse_demo 進行靜態提取:
# 使用 file 檢視檔案類型
file reverse_demo
# 使用 strings 搜尋含有 picoCTF 的關鍵字
strings reverse_demo | grep "picoCTF"

若想用 Python 寫自動化靜態分析工具,可以讀取二進位檔案並利用正則表達式 (Regex) 搜尋 Flag:
# 創建 day23_static_analysis.py
cat << 'EOF' > day23_static_analysis.py
import re
def extract_flags_from_binary(filepath):
print(f"[*] 正在對檔案 '{filepath}' 進行靜態分析與字串提取...")
with open(filepath, "rb") as f:
content = f.read()
# 利用正則表達式搜尋符合 picoCTF{...} 格式的 ASCII 字串
matches = re.findall(rb'picoCTF\{[^\}]+\}', content)
if matches:
for flag in matches:
print(f"[🎯] 成功挖到硬編碼 Flag: {flag.decode('utf-8')}")
else:
print("[-] 未在檔案中找到符合格式的 Flag。")
if __name__ == "__main__":
extract_flags_from_binary("reverse_demo")
EOF
python3 day23_static_analysis.py
在 WSL 執行腳本後,即可在完全不執行/不破譯密碼的情況下直接印出 Flag:
[*] 正在對檔案 'reverse_demo' 進行靜態分析與字串提取...
[🎯] 成功挖到硬編碼 Flag: picoCTF{st4t1c_4n4lys1s_1s_34sy_a8f92}

在真實世界中,軟體開發者或惡意程式作者為了防止敏感字串透過 strings 被輕易挖掘,通常會採取以下對抗手段:
gcc -s 參數移除符號表,增加函數名稱與變數推導的難度。