50 lines
1.8 KiB
Python
Executable file
50 lines
1.8 KiB
Python
Executable file
#!/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()
|