Skip to content

Commit 213b072

Browse files
authored
Merge pull request #534 from wei020789/lab8
[LAB8] 313553053
2 parents 9b01de2 + 2f02066 commit 213b072

File tree

1 file changed

+65
-4
lines changed

1 file changed

+65
-4
lines changed

lab8/solve.py

Lines changed: 65 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,72 @@
11
#!/usr/bin/env python3
22

3-
import angr,sys
3+
import angr
4+
import claripy
5+
import sys
46

57
def main():
6-
secret_key = b""
7-
sys.stdout.buffer.write(secret_key)
8+
# 1. 載入執行檔
9+
# auto_load_libs=False 可以加快速度,因為這個挑戰不需要共享函式庫的複雜互動
10+
project = angr.Project("./chal", auto_load_libs=False)
11+
12+
# 2. 設定符號化輸入
13+
# chal.c 中的 gate 函式期望輸入長度為 8
14+
KEY_LEN = 8
15+
16+
# 創建 KEY_LEN 個 8 位元的符號變數 (代表字元)
17+
sym_input_chars = [claripy.BVS(f'char_{i}', 8) for i in range(KEY_LEN)]
18+
# 將這些符號字元串接成一個大的位元向量
19+
sym_stdin_bvv = claripy.Concat(*sym_input_chars)
20+
21+
# 3. 創建初始狀態
22+
# 將符號位元向量作為 stdin 傳遞給程式的入口點狀態
23+
# angr 的 SimProcedures 會模擬 fgets 從這個符號 stdin 中讀取數據
24+
initial_state = project.factory.entry_state(stdin=sym_stdin_bvv)
25+
26+
# 4. (可選) 新增限制條件
27+
# 限制每個符號字元都在可列印 ASCII 範圍內 (32 到 126)
28+
# 這有助於 angr 更快找到有意義的解,並避免非預期的字元
29+
for char_sym in sym_input_chars:
30+
initial_state.solver.add(char_sym >= 32) # 空格 ' '
31+
initial_state.solver.add(char_sym <= 126) # 波浪號 '~'
32+
33+
# 5. 創建 SimulationManager
34+
simgr = project.factory.simulation_manager(initial_state)
35+
36+
# 6. 探索路徑
37+
# 目標是找到一個狀態,其 stdout 包含 "Correct!"`
38+
# 同時,我們可以避免那些明確打印 "Wrong key!" 的路徑 (雖然不是嚴格必要,但可能加快搜索)
39+
find_condition = lambda state: b"Correct!" in state.posix.dumps(1)
40+
avoid_condition = lambda state: b"Wrong key!" in state.posix.dumps(1)
41+
42+
simgr.explore(find=find_condition, avoid=avoid_condition)
43+
44+
secret_key_found = b""
45+
46+
# 7. 檢查結果並解析金鑰
47+
if simgr.found:
48+
found_state = simgr.found[0]
49+
50+
# 從找到的狀態中,解析出每個符號字元的具體值
51+
key_parts = []
52+
for i in range(KEY_LEN):
53+
key_parts.append(found_state.solver.eval(sym_input_chars[i], cast_to=bytes))
54+
55+
secret_key_found = b"".join(key_parts)
56+
57+
# (用於本地測試調試)
58+
# sys.stderr.buffer.write(b"Found secret key: " + secret_key_found + b"\n")
59+
60+
else:
61+
# (用於本地測試調試)
62+
# sys.stderr.buffer.write(b"Could not find the secret key.\n")
63+
pass
64+
65+
# 8. 將秘密金鑰寫入 stdout
66+
# validate.sh 會讀取這個 stdout
67+
sys.stdout.buffer.write(secret_key_found)
68+
sys.stdout.buffer.flush()
869

970

1071
if __name__ == '__main__':
11-
main()
72+
main()

0 commit comments

Comments
 (0)