|
1 | 1 | #!/usr/bin/env python3 |
2 | 2 | import sys |
3 | | -import claripy |
| 3 | +from z3 import BitVec, Solver, And, sat |
4 | 4 |
|
5 | 5 | def main(): |
6 | | - bvs = [claripy.BVS(f'k{i}', 32) for i in range(8)] |
7 | | - solver = claripy.Solver() |
| 6 | + # 建立 8 個 32-bit BitVec 變數 |
| 7 | + bvs = [BitVec(f'k{i}', 32) for i in range(8)] |
| 8 | + solver = Solver() |
8 | 9 |
|
| 10 | + # 0 <= xi <= 255 |
9 | 11 | for x in bvs: |
10 | | - solver.add(x >= 0) |
11 | | - solver.add(x <= 255) |
| 12 | + solver.add(And(x >= 0, x <= 255)) |
12 | 13 |
|
| 14 | + # 約束條件 |
13 | 15 | solver.add(bvs[0] ^ bvs[1] == 0x55) |
14 | 16 | solver.add(bvs[2] + bvs[3] == 200) |
15 | 17 | solver.add(bvs[4] * 3 == bvs[5]) |
16 | 18 | solver.add(bvs[6] - bvs[7] == 1) |
17 | 19 | solver.add(bvs[1] + bvs[2] - bvs[3] == 50) |
18 | 20 | solver.add(bvs[5] ^ bvs[6] == 0x2A) |
19 | 21 |
|
| 22 | + # 限制為可列印 ASCII 字元 (0x20–0x7e),且不等於換行符 |
20 | 23 | for x in bvs: |
21 | | - solver.add(x >= 0x20) |
22 | | - solver.add(x <= 0x7e) |
23 | | - solver.add(x != 0x0a) |
| 24 | + solver.add(And(x >= 0x20, x <= 0x7e, x != 0x0A)) |
24 | 25 |
|
25 | | - if solver.satisfiable(): |
26 | | - vals = [solver.eval(x, 1)[0] for x in bvs] |
| 26 | + # 求解並輸出 |
| 27 | + if solver.check() == sat: |
| 28 | + model = solver.model() |
| 29 | + vals = [model[x].as_long() for x in bvs] |
27 | 30 | solution = bytes(vals) |
| 31 | + # 如果需要十六進制或 ASCII 字串可以這樣: |
28 | 32 | hex_str = " ".join(f"{v:02x}" for v in vals) |
29 | 33 | ascii_str = solution.decode('ascii', errors='replace') |
| 34 | + # 直接把原始 bytes 寫到 stdout |
30 | 35 | sys.stdout.buffer.write(solution) |
| 36 | + # 以下兩行可選:印出 hex / ASCII 方便檢查 |
| 37 | + # print("\nhex:", hex_str) |
| 38 | + # print("ascii:", ascii_str) |
31 | 39 | else: |
32 | 40 | sys.exit(1) |
33 | 41 |
|
|
0 commit comments