Repository navigation
Releases: Ablation-Tool/ablation
Release list
v2.67.0: ISO 26262 TCL3 coverage gate and compliance artifacts.
ISO 26262 TCL3 coverage gate and compliance artifacts.
Taint engine reaches 85.29% statement coverage. The gate is enforced at
fail_under = 85 in pyproject.toml so a regression in taint logic fails
the test suite before it reaches a firmware engagement.
New:
tests/test_taint_labeled_coverage.py: 73 targeted tests covering
TaintState.join()lattice paths,invalidate_base(), ARC atomic
instructions, x86_constinstructions, MIPS/PPC FP handlers, and
record_trace=Truepaths across all 6 qualified taint engine modules.docs/ABLATION-STANDARDS.md: compliance matrix v1.3.0 — 29 MET, 0 PARTIAL,
against NIST SP 800-218 (SSDF), CISA Secure by Design, ISO 26262 TCL3,
MIL-HDBK-115C, and DoWI 8430.01.docs/safety-manual.md: ISO 26262 Part 8 Clause 11 safety manual.docs/known-anomalies/: 16 known-anomaly files, one per taint tracker.docs/sbom/ablation-sbom.json: software bill of materials (pip-licenses).requirements-hashed.txt: hash-pinned dependency lockfile (pip-compile).scripts/monitor-supply-chain.sh: weekly pip-audit CVE scan.scripts/verify-account.sh: pre-push account verification gate.tests/conformance/: 43 ABI conformance tests for RH850 and TriCore.- README compliance badges: NIST SP 800-218, CISA Secure by Design,
MIL-HDBK-115C. SECURITY.md: Security Practices section documenting all controls.
v2.66.0: BinaryLifter: SH-2A backend upgraded to CFG + structured control flow.
BinaryLifter: SH-2A backend upgraded to CFG + structured control flow.
Replaces the linear-walk lifter with a full decompiler pipeline.
Changed:
_lift_sh2a()now builds a CFG (cfg_sh2a.build_cfg) and runs the
dominator-based structurizer (structurizer.Structurizer) before emitting
pseudo-C. Output is nowif/while/forstructured code instead ofgoto
chains. Falls back to linear block-ordered emit if the structurizer raises._SH2aState.emit()is unchanged — it remains the per-instruction emitter
callback, called by the structurizer via a lambda.
v2.65.0: Structurizer: ISA-neutral dominator-based structured control-flow pass.
Structurizer: ISA-neutral dominator-based structured control-flow pass.
New module: ablation/analyzers/structurizer.py.
3 things that were not possible before in Ablation:
- No structured output for any ISA. Every CFG-backed lifter produced
goto-based IR. Structural reconstruction (if/while/for) was absent. - No post-dominator tree. Post-dominators are needed to find the "join"
point after an if/else diamond.PostDomTreefills this gap. - No ISA-neutral decompiler pass. The structurizer works on any CFG that
exposes.blocks,.entry,.flow,.flow_r()— the same interface as
dataflow_engine.CFG. Any ISA CFG module can plug in.
New:
Structurizer(cfg): builds dominator tree + loop info + post-dominator tree,
then walks RPO to emitWhileNode,IfNode,SequenceNode,ReturnNode,
BreakNode,ContinueNode.Structurizer.structure() -> StructuredNode: returns the tree.Structurizer.emit(insn_emitter, func_name) -> str: renders to pseudo-C.PostDomTree(cfg): immediate post-dominator tree via reversed-CFG DomTree.
Used to find if/else join points.- All node types exported:
SequenceNode,InsnNode,IfNode,WhileNode,
BreakNode,ContinueNode,ReturnNode. - Docs:
docs/module-reference/structurizer.md.
v2.64.0: cfg_sh2a: SH-2A control-flow graph builder.
cfg_sh2a: SH-2A control-flow graph builder.
New module: ablation/analyzers/cfg_sh2a.py.
3 things that were not possible before in Ablation:
- No CFG for SH-2A. Every other ISA with a lifter backend also had a CFG
module; SH-2A was the only exception. Without a CFG, the structurizer and
DomTree cannot run on SH-2A firmware. - No delay-slot semantics in any CFG builder. SH-2A's delay-slot model
(one instruction always executes after a branch before the branch fires) is
architecturally distinct from all prior CFG modules (ARM, V850, ARC, x86).
cfg_sh2acorrectly attaches the delay-slot instruction to the terminating
block so successor VAs are computed from after the delay slot, not from
after the branch. - No
.flow/.flow_r()interface on SH-2A CFG.dataflow_engine.DomTree
and all backward-dataflow passes require these.cfg_sh2a.CFGadds both
as computed properties.
New:
Block(start, insns, succs, preds): basic block for SH-2A. Delay-slot
instruction is the lastinsnsentry when the terminator has a delay slot.CFG(blocks, entry)with.flowproperty and.flow_r()method for
duck-type compatibility withdataflow_engine.CFG.build_cfg(insns, entry=None) -> CFG: three-pass construction
(leader scan → partition → edge fill).- Delay-slot semantics: WITH delay slot = {bra, bsr, jsr, bt/s, bf/s, rts, rte};
WITHOUT = {bt, bf, rts/n}. BRAF/BSRF/JMP@Rn decode as MISC → open blocks
(documented limitation). - Compatible with
DomTree,LoopInfofromdataflow_enginevia duck typing. - Docs:
docs/module-reference/cfg-sh2a.md.
v2.63.0: BinaryLifter: SH-2A backend (`_lift_sh2a` + `_SH2aState`).** Adds Renesas SH-2A
BinaryLifter: SH-2A backend (_lift_sh2a + _SH2aState). Adds Renesas SH-2A (SH7058/SH7059)
as the 18th ISA supported by BinaryLifter.lift_function().
New:
_lift_sh2a(func_va, max_insns): lifts an SH-2A function to pseudo-C IR. UsesEcuSH2aDecoder
directly (no Capstone, no subprocess). Flat ECU ROM fallback: when_sectionsis empty (no ELF
header), treatsfunc_vaas a direct file offset (base_va=0). Truncates at first RETURN +
delay-slot instruction to prevent running into zero-padded ROM space._SH2aState: register-tracking state machine for SH-2A (Renesas SuperH calling convention).
R4-R7 = arg0-arg3; R0 = return value; R15 = stack pointer. Dispatches onSH2aInsn.insn_type
directly (no regex) — clean becauseEcuSH2aDecoderpre-categorizes every instruction. Handles
LR_SAVE/LR_RESTORE (prologue comment), RETURN, CALL (direct + indirect JSR), BRANCH (conditional
BT/BF + unconditional BRA + indirect JMP), LOAD (MOV.L/W/B with displacement), STORE, and MISC.
Taint propagation from tainted args through call results and loads.- Arch dispatch:
sh2a,sh-2a,sh2all dispatch to_lift_sh2a. - 46 tests in
tests/test_binary_lifter_sh2a.py. - Docs:
docs/module-reference/binary-lifter-sh2a.md.
v2.62.0: CppVtableReconstructorAnalyzer: ET_EXEC fix + generic consumer tracing for Loong
CppVtableReconstructorAnalyzer: ET_EXEC fix + generic consumer tracing for LoongArch64/MIPS/PPC.
Bug fixes:
_check_itanium_header: was usingvtable_vaas a raw file byte index; correct only for ET_DYN
(PIE, VA≈0) — always returned False for ET_EXEC (non-PIE, VA=0x400000+). Fixed: new
_va_to_file_offset(va)helper converts VA → file offset via section headers._trace_arm64:self._data[text_va:]sliced by VA not file offset; empty on ET_EXEC. Fixed:
self._data[text_off:]usingtext_sec.offset.
Enhancements:
_trace_generic: arch-agnostic consumer tracer that scans.textfor the vtable VA as a
pointer-sized literal (LE/BE from EI_DATA; width 4 for ppc32, 8 otherwise). Runs on
LoongArch64, MIPS, PPC32, PPC64, RISC-V, and any future arch. x86-64 and ARM64 still use
full ISA-specific tracers.- Removed "IDAPython" / "IDA" references from module docstring;
emit_ida_script()generates a
type-annotation + comment script with no external tool dependency.
v2.61.0: FlatBinaryFuncStartScanner: arch-agnostic function-start scanner for flat ECU RO
FlatBinaryFuncStartScanner: arch-agnostic function-start scanner for flat ECU ROMs. Combines
call-target harvesting (BFS from the reset vector following direct call instructions) and ISA-specific
prologue pattern scanning. Uses EcuArchDetector internally — HIGH/MEDIUM confidence selects one ISA
catalog, LOW confidence unions all five.
FlatBinaryFuncStartScanner:scan(arch=None)→FuncStartResult;archoverride skips detectionFuncStartResult:arch,confidence,function_starts(sorted union),call_targets,prologue_hits,detect_result- Call harvesting: Thumb2 BL/BLX (ARM Cortex-M), BSR.W/BSR.L (M68K), BL (PPC32/VLE), BSR (SH-2A); stops at return instruction or 512 instructions
- Prologue scan: Thumb2 PUSH+LR (
0xB5xx), LINK.W A6 (0x4E56+neg), MFLR r0 (7C0802A6), e_stwu r1 (0x1C21+neg D8), STS.L PR (0x4F22) + leaf STS PR from_path()/from_bytes()wrappers;max_call_depthcaps BFS recursion- 27 tests; FORGE gate: PASSED (0 findings)
v2.60.0: EcuArchDetector: ISA fingerprinter for unknown flat ECU ROM images.** Five discr
EcuArchDetector: ISA fingerprinter for unknown flat ECU ROM images. Five discriminators
identify the instruction set of a raw binary with no ELF/IHEX wrapper, returning a HIGH/MEDIUM/LOW
confidence verdict and the best-match ISA token, enabling automatic decoder selection before any
disassembly step.
EcuArchDetector:detect()→ArchDetectResult;candidates()→list[ArchCandidate]sorted by scoreArchDetectResult:arch,confidence(HIGH/MEDIUM/LOW),score,reason,candidates,is_confidentArchCandidate:arch,score,reason- ARM Cortex-M: LE vector table — MSP in SRAM
0x20000000–0x3FFFFFFF+ Thumb reset handler; score 0.90 (both) / 0.55 (MSP only) - M68K/CPU32: BE reset vector in-range + LINK.W A6, #-N prologue density; score 0.85 / 0.70 / 0.35
- PPC32 Book E: primary opcode density (0x08-0x0F, 0x38-0x3F, 0x80-0x9F ranges); fires at ≥ 35% density
- PPC VLE:
(byte0 & 0x90) == 0x10halfword density; score =min(density * 2.5, 0.92)at ≥ 15% density - SH-2A: BE reset vector at offset 4 + STS.L PR (0x4F22) density + RTS (0x000B) density; score 0.88/0.75/0.60/0.40
from_path()/from_bytes()convenience wrappers;sample_size=0scans full image- 31 tests; FORGE gate: PASSED (0 findings)
v2.59.0: EcuSH2aDecoder: Renesas SH-2A decoder for Honda/Subaru ECU firmware.** Pure-Pyth
EcuSH2aDecoder: Renesas SH-2A decoder for Honda/Subaru ECU firmware. Pure-Python decoder
for the SH-2A ISA (Renesas SH7058/SH7059). Capstone 5.0.7 has no SH-2A support; this module
closes the gap and enables BinaryContext, WindowAnalyzer, and manual RE on Honda CBR250RR and
Subaru (SH7058S, EcuFlash corpus) ECU ROMs.
EcuSH2aDecoder:disassemble(),decode_one(),function_starts(),insn_length()SH2aInsn:offset,is_32bit,mnemonic,insn_type,raw,target,rd,rs,imminsn_type: RETURN, BRANCH, CALL, LR_SAVE, LR_RESTORE, LOAD, STORE, MISC- 32-bit SH-2A discrimination: four
0xF00Fmasks per Renesas SH2A HW Manual Rev.2.00; MOWI20 uses0xF00F == 0x0005(not0xF0FF) because imm[19:16] occupies bits[7:4] and varies function_starts()primary:STS.L PR, @-R15(0x4F22); secondary:STS PR, Rnleaf prologue with preceding-STS.L suppression- Branch targets include SH-2 delay slot:
target = VA + 4 + disp * 2 - PC-relative load:
(VA + 4 & ~3) + disp * 4(4-byte aligned PC) from_path()/from_bytes()convenience wrappers;FileNotFoundErrorwrapped with context- 69 tests; FORGE gate: PASSED (0 findings)
v2.58.0: EcuM68kDecoder: M68K/CPU32 decoder for GM P-series ECU firmware.** Wraps Capston
EcuM68kDecoder: M68K/CPU32 decoder for GM P-series ECU firmware. Wraps Capstone
(CS_ARCH_M68K / CS_MODE_M68K_020) with ECU-specific prologue scanning and pipeline-compatible
M68kInsn dataclass. CPU32 is a 68020 derivative; Capstone 5.0.7 has no CS_MODE_M68K_CPU32 but
020 mode decodes the GM P-series instruction set correctly.
EcuM68kDecoder:disassemble()(Capstone-backed),decode_one(),function_starts()(pure scan),insn_length()M68kInsn:offset,mnemonic,op_str,insn_type,raw,size,targetfunction_starts()primary signal:LINK.W A6, #-N(0x4E56+ negative 16-bit displacement); secondary:MOVEM.L regs, -(SP)(0x48E7) when not immediately after a LINKinsn_type: RETURN (rts/rtd/rte/rtr), BRANCH (bra/b*/jmp), CALL (jsr/bsr), PROLOGUE (link.w A6 neg), MISC- Branch targets strip Capstone
.w/.lsize suffix from$addr.wformat disassemble()/decode_one()raiseImportErrorwith install instructions when Capstone missing;function_starts()andinsn_length()are pure-Python (no Capstone)- Cs() constructed at
__init__time (not lazily) to eliminate thread-safety race - 26 tests; FORGE gate: PASSED (0 findings)