Skip to content

Releases: Ablation-Tool/ablation

v2.67.0: ISO 26262 TCL3 coverage gate and compliance artifacts.

Choose a tag to compare

@Ablation-Tool Ablation-Tool released this 10 Oct 22:27

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 _const instructions, MIPS/PPC FP handlers, and
    record_trace=True paths 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.

Choose a tag to compare

@Ablation-Tool Ablation-Tool released this 10 Oct 22:27

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 now if/while/for structured code instead of goto
    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.

Choose a tag to compare

@Ablation-Tool Ablation-Tool released this 10 Oct 22:27

Structurizer: ISA-neutral dominator-based structured control-flow pass.

New module: ablation/analyzers/structurizer.py.

3 things that were not possible before in Ablation:

  1. No structured output for any ISA. Every CFG-backed lifter produced
    goto-based IR. Structural reconstruction (if/while/for) was absent.
  2. No post-dominator tree. Post-dominators are needed to find the "join"
    point after an if/else diamond. PostDomTree fills this gap.
  3. 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 emit WhileNode, 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.

Choose a tag to compare

@Ablation-Tool Ablation-Tool released this 10 Oct 22:27

cfg_sh2a: SH-2A control-flow graph builder.

New module: ablation/analyzers/cfg_sh2a.py.

3 things that were not possible before in Ablation:

  1. 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.
  2. 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_sh2a correctly attaches the delay-slot instruction to the terminating
    block so successor VAs are computed from after the delay slot, not from
    after the branch.
  3. No .flow / .flow_r() interface on SH-2A CFG. dataflow_engine.DomTree
    and all backward-dataflow passes require these. cfg_sh2a.CFG adds both
    as computed properties.

New:

  • Block(start, insns, succs, preds): basic block for SH-2A. Delay-slot
    instruction is the last insns entry when the terminator has a delay slot.
  • CFG(blocks, entry) with .flow property and .flow_r() method for
    duck-type compatibility with dataflow_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, LoopInfo from dataflow_engine via duck typing.
  • Docs: docs/module-reference/cfg-sh2a.md.

v2.63.0: BinaryLifter: SH-2A backend (`_lift_sh2a` + `_SH2aState`).** Adds Renesas SH-2A

Choose a tag to compare

@Ablation-Tool Ablation-Tool released this 10 Oct 22:27

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. Uses EcuSH2aDecoder
    directly (no Capstone, no subprocess). Flat ECU ROM fallback: when _sections is empty (no ELF
    header), treats func_va as 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 on SH2aInsn.insn_type
    directly (no regex) — clean because EcuSH2aDecoder pre-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, sh2 all 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

Choose a tag to compare

@Ablation-Tool Ablation-Tool released this 10 Oct 22:27

CppVtableReconstructorAnalyzer: ET_EXEC fix + generic consumer tracing for LoongArch64/MIPS/PPC.

Bug fixes:

  • _check_itanium_header: was using vtable_va as 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:] using text_sec.offset.

Enhancements:

  • _trace_generic: arch-agnostic consumer tracer that scans .text for 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

Choose a tag to compare

@Ablation-Tool Ablation-Tool released this 10 Oct 22:27

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; arch override skips detection
  • FuncStartResult: 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_depth caps BFS recursion
  • 27 tests; FORGE gate: PASSED (0 findings)

v2.60.0: EcuArchDetector: ISA fingerprinter for unknown flat ECU ROM images.** Five discr

Choose a tag to compare

@Ablation-Tool Ablation-Tool released this 10 Oct 22:26

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 score
  • ArchDetectResult: arch, confidence (HIGH/MEDIUM/LOW), score, reason, candidates, is_confident
  • ArchCandidate: 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) == 0x10 halfword 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=0 scans full image
  • 31 tests; FORGE gate: PASSED (0 findings)

v2.59.0: EcuSH2aDecoder: Renesas SH-2A decoder for Honda/Subaru ECU firmware.** Pure-Pyth

Choose a tag to compare

@Ablation-Tool Ablation-Tool released this 10 Oct 22:26

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, imm
  • insn_type: RETURN, BRANCH, CALL, LR_SAVE, LR_RESTORE, LOAD, STORE, MISC
  • 32-bit SH-2A discrimination: four 0xF00F masks per Renesas SH2A HW Manual Rev.2.00; MOWI20 uses 0xF00F == 0x0005 (not 0xF0FF) because imm[19:16] occupies bits[7:4] and varies
  • function_starts() primary: STS.L PR, @-R15 (0x4F22); secondary: STS PR, Rn leaf 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; FileNotFoundError wrapped with context
  • 69 tests; FORGE gate: PASSED (0 findings)

v2.58.0: EcuM68kDecoder: M68K/CPU32 decoder for GM P-series ECU firmware.** Wraps Capston

Choose a tag to compare

@Ablation-Tool Ablation-Tool released this 10 Oct 22:26

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, target
  • function_starts() primary signal: LINK.W A6, #-N (0x4E56 + negative 16-bit displacement); secondary: MOVEM.L regs, -(SP) (0x48E7) when not immediately after a LINK
  • insn_type: RETURN (rts/rtd/rte/rtr), BRANCH (bra/b*/jmp), CALL (jsr/bsr), PROLOGUE (link.w A6 neg), MISC
  • Branch targets strip Capstone .w/.l size suffix from $addr.w format
  • disassemble()/decode_one() raise ImportError with install instructions when Capstone missing; function_starts() and insn_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)