mtk-wifi-fw/tools/ghidra_scripts/force_disasm.py

51 lines
1.8 KiB
Python
Raw Normal View History

#!/usr/bin/env python3
"""Force-disassemble every executable block, then re-analyze.
Firmware images have no entry graph into most code, so default analysis
leaves large undisassembled regions (no xrefs to their strings).
Usage: <proj_dir> <proj_name> <program_path_in_project>
"""
import os
import sys
import pyghidra
pyghidra.start()
from ghidra.app.cmd.disassemble import DisassembleCommand # noqa: E402
from ghidra.app.plugin.core.analysis import AutoAnalysisManager # noqa: E402
from ghidra.program.model.address import AddressSet # noqa: E402
from ghidra.util.task import ConsoleTaskMonitor # noqa: E402
proj_dir, proj_name, prog_path = sys.argv[1], sys.argv[2], sys.argv[3]
monitor = ConsoleTaskMonitor()
proj = pyghidra.open_project(os.path.abspath(proj_dir), proj_name)
with pyghidra.program_context(proj, prog_path) as prog:
mem = prog.getMemory()
listing = prog.getListing()
total = AddressSet()
for b in mem.getBlocks():
if b.isExecute() and 'elf' not in b.getName():
total.addRange(b.getStart(), b.getEnd())
before_ins = listing.getNumInstructions()
before_fun = prog.getFunctionManager().getFunctionCount()
print('before: %d instructions, %d functions'
% (before_ins, before_fun))
cmd = DisassembleCommand(total, total, False)
with pyghidra.transaction(prog, 'force disasm'):
ok = cmd.applyTo(prog, monitor)
print('disasm apply:', ok)
from ghidra.app.script import GhidraScriptUtil
from ghidra.program.flatapi import FlatProgramAPI
GhidraScriptUtil.acquireBundleHostReference()
try:
FlatProgramAPI(prog).analyzeAll(prog)
finally:
GhidraScriptUtil.releaseBundleHostReference()
print('after: %d instructions, %d functions'
% (listing.getNumInstructions(),
prog.getFunctionManager().getFunctionCount()))
proj.close()