Files
mrcharles 1b447b77ad Initial public release: dockerized reverse-engineering workbench
ChipBench packages Ghidra, radare2, binwalk, chip-programming tools,
simulators, and firmware-unpacking utilities into one reproducible container
for analyzing raw chip dumps entirely from the command line or an AI CLI.
Headless Jython scripts drive import, forced-disassembly sweeps, live
queries, and bulk decompilation exports without any GUI.

Derived from a private engagement environment, generalized for public
release under AGPLv3. No engagement-specific artifacts are included.

💘 Generated with Crush

Assisted-by: Crush:glm-5.2
2026-08-18 11:15:05 -05:00

57 lines
1.8 KiB
Python

# -*- coding: utf-8 -*-
#
# Part of ChipBench (AGPLv3). SPDX-FileCopyrightText: 2026 Starting Line Productions LLC
# AutoFuncs.py -- create functions at every LCALL/LJMP target + scheduler
# jumptable entries, iterating until stable. Handles call tables (JMP @A+DPTR)
# where the table entries are LJMPs by treating table bodies as code.
from ghidra.program.model.address import AddressSet
from ghidra.app.cmd.function import CreateFunctionCmd
from ghidra.app.cmd.disassemble import DisassembleCommand
from ghidra.app.plugin.core.analysis import AutoAnalysisManager
prog = currentProgram
af = prog.getAddressFactory()
cs = af.getDefaultAddressSpace()
fm = prog.getFunctionManager()
mem = prog.getMemory()
def A(x): return cs.getAddress(x)
def mk(a):
if a < 0x10000 and fm.getFunctionAt(a) is None:
CreateFunctionCmd(a).applyTo(prog, monitor)
rounds = 0
prev = -1
while rounds < 4:
n = 0
for i in range(0x0000, 0xEE00):
try:
b = mem.getByte(A(i)) & 0xFF
except:
continue
if b == 0x12 or b == 0x02: # LCALL/LJMP
try:
hi = mem.getByte(A(i+1)) & 0xFF
lo = mem.getByte(A(i+2)) & 0xFF
except:
continue
t = (hi << 8) | lo
if 0x0008 <= t < 0xEE00:
if fm.getFunctionAt(A(t)) is None:
if CreateFunctionCmd(A(t)).applyTo(prog, monitor):
n += 1
# reanalyze
mgr = AutoAnalysisManager.getAnalysisManager(prog)
mgr.reAnalyzeAll(None)
mgr.startAnalysis(monitor)
cur = fm.getFunctionCount()
print("round %d: +%d new, total %d" % (rounds, n, cur))
if cur == prev:
break
prev = cur
rounds += 1
print("AutoFuncs done: %d functions, %d instructions" % (
fm.getFunctionCount(), prog.getListing().getNumInstructions()))