尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證正在載入完整 README。 以下為已儲存的摘錄。
Interactive symbolic execution plugin for Ghidra, powered by angr + Z3.
Right-click an address, symbolize the input, click Solve — the plugin finds concrete values that make the program reach your target. Passwords, license keys, flag checkers, crypto parameters — if it's a constraint satisfaction problem, Ponce4Ghidra solves it.
Project Page — architecture diagrams, workflow guide, and SAT/SMT primer.
Constraints Tab — see how the solver derived the password檢視完整 README ↗
Interactive symbolic execution plugin for Ghidra, powered by angr + Z3.
Right-click an address, symbolize the input, click Solve — the plugin finds concrete values that make the program reach your target. Passwords, license keys, flag checkers, crypto parameters — if it's a constraint satisfaction problem, Ponce4Ghidra solves it.
Project Page — architecture diagrams, workflow guide, and SAT/SMT primer.
1. Open test_crackme in Ghidra
2. Right-click 0x1000004d7 (return 1) → Set as Find Target
3. Right-click 0x100000484 (return 0) → Set as Avoid
4. Ponce4Ghidra → Symbolize argv[1] (size: 4)
5. Ponce4Ghidra → Solve Constraints
→ Solved: argv1 = P4Rg
Each constraint maps to a byte of the password: byte0 == 80 ('P'), byte1 == 52 ('4'), byte2 ^ 0x42 == 0x10 ('R'), byte3 + 0x20 == 0x87 ('g').
Multi-solution enumeration on test_license_elf: the solver found 5 valid license keys, all variants of K9mZ-4wR2-Xp7B-3nLf differing in the last byte.
Core
Analysis
Platform
UX
flowchart LR
A["🎯 Set Find/Avoid"] --> B["📝 Symbolize Input"]
B --> C["🔀 angr: Fork at Branches"]
C --> D["📋 Collect Constraints"]
D --> E["🧮 Z3: Solve Equations"]
E --> F["✅ P4Rg"]
Not brute force — a 16-byte input has 2¹²⁸ possibilities. The constraints reduce it to a system Z3 solves in seconds.
┌─────────────┐ JSON/TCP ┌──────────────────┐
│ Ghidra │ ◄────────────► │ angr Engine │
│ Plugin │ port 13370 │ (Python) │
│ (Java) │ │ │
│ │ commands: │ angr.Project │
│ Panel: │ init │ SimState │
│ Variables │ symbolize_* │ SimulationMgr │
│ Find/Avoid │ set_find/avoid│ explore() │
│ Results │ explore │ solver.eval() │
│ Constraints│ solve │ │
│ │ get_state │ Z3 SMT Solver │
│ Actions: │ get_constraints │
│ 8 menu │ replay │ Veritesting │
│ items │ set_options │ Unicorn (opt) │
└─────────────┘ └──────────────────┘
| Method | Use when |
|---|---|
| Symbolize argv[N] | Program reads input from command line. Binary is small/simple. |
| Symbolize Function Argument | You know which function checks the input. Binary is large/complex. Analyzing a .so library. Start here. |
| Symbolize Register | The unknown is a scalar (int/long), not a buffer. |
| Symbolize Memory | The unknown is at a known fixed memory address. |
Rule of thumb: start with Function Argument (faster, targeted). Use argv only when you need the whole program's execution context.
# 1. Create a Python venv with angr
python3 -m venv .venv
source .venv/bin/activate
pip install angr
# Optional: faster concrete execution
pip install unicorn
# 2. Build the Ghidra extension
export GHIDRA_INSTALL_DIR=/path/to/ghidra_11.4.3_PUBLIC
gradle buildExtension
# 3. Install in Ghidra
# Ghidra → File → Install Extensions → Add → select dist/*.zip
# Or manually unzip into ~/Library/ghidra/.../Extensions/
Option A — Let the plugin manage the engine (automatic): Just use the plugin. It starts the engine process when needed.
Option B — Start the engine manually (for development):
cd Ponce4Ghidra
PYTHONPATH=python python3 -m ponce4ghidra_engine -v
The plugin connects to whatever is already on port 13370.
# Run all tests (spawns engine instances on ports 13371+)
PYTHONPATH=python python3 test/test_engine.py
Tests:
| Binary | Format | Password/Key | Find | Avoid |
|---|---|---|---|---|
test_crackme | Mach-O x86_64 | P4Rg | 0x1000004d7 | 0x100000484 |
test_license | Mach-O x86_64 | K9mZ-4wR2-Xp7B-3nLf | 0x100000a38 | 0x100000a4f |
test_license_elf | ELF x86_64 (static) | K9mZ-4wR2-Xp7B-3nLf | 0x1017327 | 0x101731e |
Ponce4Ghidra uses symbolic execution — not brute force, not fuzzing.
if (input[0] == 'P') → byte0 == 0x50A 16-byte input has 2¹²⁸ possibilities. The constraints reduce it to a system Z3 solves in seconds.
See the SAT/SMT Primer for the full explanation with architecture diagrams.
MIT