All projects

Reverse-engineering tooling

objdiff — agent-readable object diffing

Forked the decompilation community's standard diff tool to emit machine-readable root-cause diagnoses — 21 pattern detectors and fixability verdicts that let AI agents work a 47,000-function match queue autonomously.

ActiveJan 2026 – Presentfreeqaz/objdiff

Rust · MCP · tooling

objdiff comparing original and recompiled PowerPC instruction streams side by side, mismatches highlighted per instruction

objdiff is the standard open-source tool the game-preservation and decompilation community uses to compare recompiled object files against an original binary, instruction by instruction, and compute the match percentage projects live by. My fork teaches it to diagnose instead of just diff: it classifies each mismatch by root cause, assigns a fixability verdict, and emits structured JSON built to be consumed by AI agents through an MCP orchestrator rather than read by a human.

The motivating problem is scale. On a project with roughly 47,000 functions to match, hundreds sit at 97–99% at any moment. Some are fixable with a one-line source change; others are permanently stuck because the linker folded identical functions or the register allocator made an unrecoverable choice. Telling those apart used to mean a human reading raw PowerPC assembly. The fork’s analysis engine — 21 pattern detectors (register swaps, linker-merged code, float-precision quirks, signedness mismatches) and 6 verdict classes from LikelyFixable to AtLimit — makes that call automatically, so an agent knows whether to keep editing, dispatch a permuter, or move on.

The hardest problem was determinism. MSVC on the target platform emits exception-handling funclets that the upstream tool paired by symbol order — nondeterministically — so two byte-identical builds could report different match percentages, corrupting the exact metric the agents optimize against. I rebuilt the pairing around masked byte signatures (relocation bytes zeroed out), made it deterministic with respect to symbol-table order, handled many-to-one pairing of identical funclets, and locked the behavior with tests. A related principle runs through the later work: when bytes only match after relocation masking, the output now discloses it rather than silently overclaiming — a fitness function that lies is worse than none.

Concretely: 40 commits and +19,234 lines across 76 files over upstream, a 5,801-line analysis module with 76 test functions, and four releases cut in three days while firefighting spurious CI regressions. All changes are additive and CLI-only; the GUI and library API are untouched. In production, 6–10 agents consume its verdicts in parallel, closing an edit–rebuild–rediff loop in a few seconds per iteration.

objdiff — agent-readable object diffing | Free Wortley