Files
nils 27c21396f8 QuNexus v2.2.1 firmware: reverse-engineered disassembly & pseudocode
Decompiled from stock QuNexus_Firmware_v2.2.1.bin (EFM8UB20F64G / 8051,
base 0x2400, 54279 bytes) with radare2 6.2.0.

- qunexus_v2.2.1.asm : full linear disassembly (37287 lines, byte-faithful)
- pseudocode_all.c   : r2 pdc pseudocode for all 1002 functions
- functions.txt     : function index (1002 functions)
- regen.sh + r2script.r2 : one-command reproduction (brew install radare2)

Verified: reconstructing the binary from the asm byte-columns reproduces the
original image byte-for-byte (30560 instructions + 195 data gaps).
2026-08-17 22:22:21 +02:00

3.6 KiB
Raw Permalink Blame History

QuNexus firmware v2.2.1 — reverse-engineered source

Disassembly and pseudo-decompilation of the Keith McMillen / KESUMO QuNexus application firmware (EFM8UB20F64G, an 8051-core MCU), produced with radare2.

This is a nested git repository (its own repo, living under the parent qunexus-qt6 project). It is self-contained: the stock input binary is included so every artifact here can be regenerated with one command.

Input

File What
QuNexus_Firmware_v2.2.1.bin stock v2.2.1 application image, flat binary, base 0x2400, 54 279 bytes, spans 0x2400–0xF806. (The bootloader region 0x0000–0x23FF is not in this image and is not decompiled here.)

Generated artifacts

File What Lines
qunexus_v2.2.1.asm Full linear disassembly of the whole image, absolute code-space addresses (0x2400+), with xrefs & comments. Nothing omitted. 37 287
pseudocode_all.c r2 pdc C-like pseudocode for all 1002 functions. 668 complete; 334 end with // chop (r2's size limit on big functions — see those in the asm). 38 396
functions.txt r2 function index: address size nblocks name — 1002 functions. 1 002

Reproduce

brew install radare2          # one-time
./regen.sh                    # rebuilds the three artifacts from the .bin

regen.sh runs r2 -a 8051 -b 8 -m 0x2400 -i r2script.r2 QuNexus_Firmware_v2.2.1.bin. r2script.r2 is the exact radare2 script used.

Faithfulness — does it re-compile?

The disassembly is byte-faithful: reconstructing the binary from the asm's byte columns (30 560 instructions + 195 small data gaps) reproduces the original 54 279-byte image byte-for-byte. So the listing is a complete, accurate representation — nothing lost or corrupted.

The r2 .asm file is not directly valid input to an 8051 assembler (it is r2 display format: function borders, xref comments, fcn.xxxx labels, address prefixes). To re-assemble into a flashable binary it must be converted to a real assembler's syntax (e.g. sdas8051 from SDCC, or Keil A51): strip r2 annotations, turn ljmp/lcall targets into labels, emit the 195 data gaps as .db, and set .org 0x2400. With that conversion it re-assembles to the identical binary. (Round-trip via SDCC is the natural next step if needed.)

Known landmarks (verified in the output)

Address Meaning
0x2400 app reset vector (ljmp 0xb691)
0xA57B USB-MIDI router: cable number → destination ring buffer
0xDF05 USB-MIDI event dispatcher
0xDF28 LCALL 0xA57B — the single call site the USB-1→CV patch retargets
0x8126 23-byte 0xFF padding region the patch's stub is written into
0xE8E6 LJMP 0x0000 — the only bootloader-entry jump
0xB48D SysEx command handler (bootloader-entry path)

Caveats

  • r2's 8051 auto-analysis is decent but imperfect: data-in-code regions decode as the matching instruction (a linear-sweep artifact). Use ljmp/lcall/ acall targets and functions.txt as the map of real code.
  • pdc chops ~1/3 of functions (the big ones). The asm listing covers them fully. For unchopped Ghidra-quality pseudocode, the r2ghidra plugin (r2pm install r2ghidra, then pdg @ func) is the upgrade path.

Provenance

Decompiled 2026-08-17 from the stock QuNexus_Firmware_v2.2.1.bin (the same image shipped in the qunexus-qt6 editor's Qt resources as QuNexus_Firmware_v2.2.1-cs512.syx). The reverse-engineering was done in service of a USB-1→CV routing patch (see ../patch_usb1_to_cv.py and ../c2probe/); this repo captures the reference disassembly of the unmodified firmware.