IDA Pro patching and headless activation toolkit. Tested on IDA Pro 9.3 (Linux x86-64).
Complete automation for patching and activating IDA Pro without the GUI License Manager:
| Step | Script | What it does |
|---|---|---|
| 1 | patch_modulus.py |
Patch RSA modulus in libida.so / libida32.so |
| 2 | find_eula_guard.py |
Patch EULA headless guards in libidalib.so / ida |
| 3 | keygen.js |
Generate idapro.hexlic license file |
| 4 | setup_license.py |
Place hexlic, accept EULA, verify |
| — | patch_ida.py |
Master script: runs all of the above |
# Full setup — patches binaries, generates license, accepts EULA
python3 patch_ida.py --ida-dir /path/to/ida
# Check status only (no changes)
python3 patch_ida.py --check
# Binary patches only, skip license
python3 patch_ida.py --steps modulus,guard
# License setup only (requires pre-patched binaries)
python3 setup_license.py --generateRuns all 6 steps: modulus → guard → license → eula → python → verify.
python3 patch_ida.py # full setup
python3 patch_ida.py --check # status only
python3 patch_ida.py --steps modulus,guard # specific steps
python3 patch_ida.py --skip-steps license # skip steps
python3 patch_ida.py --ida-dir /opt/ida93 # custom pathReplaces EDFD425CF978 → EDFD42CBF978 in ALL occurrences (unlike keygen.js which only patches the first).
python3 patch_modulus.py libida.so libida32.so # check
python3 patch_modulus.py libida.so libida32.so --apply # patchLocates and patches the jne/jnz branches that block headless mode when the EULA hasn't been accepted. Handles both rel8 (jne rel8 → jmp) and rel32 (jne rel32 → nop+jmp) forms.
Deps: pip install capstone lief
python3 find_eula_guard.py libidalib.so # find guards
python3 find_eula_guard.py libidalib.so --apply # patch in place
python3 find_eula_guard.py ida --apply # patch the ida binary tooKnown guard offsets (v9.3.260213):
libidalib.so:0x95cbf(rel8),0x95ccb(rel32),0x95cd8(rel32)idabinary:0x1719fa(rel8),0x171a06(rel32),0x171a13(rel32)
Generates idapro.hexlic with addons: LUMINA, TEAMS, HEXX86, HEXX64, HEXARM, HEXARM64, HEXMIPS, HEXMIPS64, HEXPPC, HEXPPC64, HEXRV, HEXRV64, HEXARC, HEXARC64, HEXV850.
node keygen.js
# Edit name/email in the script before runningGenerates (or copies) hexlic, places it where IDA looks, and accepts the EULA via headless IDA.
python3 setup_license.py # use existing hexlic
python3 setup_license.py --generate # run keygen.js first
python3 setup_license.py --check # status only
python3 setup_license.py --hexlic file # use specific file
python3 setup_license.py --name X --email Y # custom identitySets EULA 90 = 1 in ~/.idapro/ida.reg. Run via IDA:
QT_QPA_PLATFORM=offscreen ./ida -B -S/path/to/accept_eula.py /bin/lsPrints IDA version and EULA status:
TVHEADLESS=1 ./idat -B -S/path/to/ida_probe.py /bin/lsidat -A alone does not load the idapython3.so plugin. Use -B (batch mode) or -c -A:
# ✓ Correct
TVHEADLESS=1 idat -B -S/path/to/script.py <binary>
# ✗ Wrong — script won't execute
TVHEADLESS=1 idat -A -S/path/to/script.py <binary>The ida (GUI) binary works headless with offscreen Qt:
QT_QPA_PLATFORM=offscreen ./ida -A -S/path/to/script.py <binary>- Magic:
iDa7 - Registry sub-key:
IDAPRO.ida-pro.9.3\0(notIDAPRO\0like v9.0) - Int entries:
key\0 04 size(4B BE) value(4B LE) - Ends with a 4-byte checksum — let IDA write the registry, don't hand-edit it
| File | Offset(s) | Change |
|---|---|---|
libida.so |
2 occurrences | EDFD425CF978 → EDFD42CBF978 |
libida32.so |
2 occurrences | EDFD425CF978 → EDFD42CBF978 |
libidalib.so |
0x95cbf, 0x95ccb, 0x95cd8 |
jne → jmp / nop+jmp |
ida |
0x1719fa, 0x171a06, 0x171a13 |
jne → jmp / nop+jmp |
Educational use only. You must own a valid IDA Pro license to use this software.