Ghidra extension — reverse-engineer .fjm binaries

⬇️ Download the extension (.zip)

🐙 Source on GitHub

What it is

A Ghidra extension for reverse-engineering compiled FlipJump programs — the .fjm binaries produced by the fj compiler. FlipJump is a one-instruction-set computer: a;b flips (inverts) the bit at bit-address a, then jumps to bit-address b. The extension teaches Ghidra to load, disassemble, and analyse that single instruction so you can browse, annotate, and cross-reference a .fjm image the same way you would any other binary.

It has three parts:

  • Loader (FlipJumpLoader) — parses the .fjm format (versions 0–3, including raw-LZMA2 compression and relative jumps), picks the matching word-size language, and maps FlipJump’s bit-addressable memory into Ghidra’s byte-addressable blocks.

  • Processor (flipjump SLEIGH module) — models the single flip ; jump instruction with strict bit-to-byte P-Code, in four word-size variants (flipjump:LE:{8,16,32,64}:default).

  • Analyzer (FlipJumpAnalyzer) — disassembles every op, classifies each as code / data / variable / input, and adds flip/jump Xrefs, IO and label + dbit + x operand annotations, data_/var_ labels, and self-loop / self-modifying-op bookmarks.

Built and tested against Ghidra 12.1 with JDK 21.

How to install

There is no marketplace listing — you install a packaged .zip into Ghidra.

1. Download the extension .zipFlipJump-Ghidra.zip from the latest release.

2. Install it into Ghidra. In the Ghidra project window:

File ▸ Install Extensions ▸ +, choose the downloaded .zip, then restart Ghidra.

For headless/CI use, extract the zip into Ghidra’s user extensions dir instead — e.g. %APPDATA%/ghidra/ghidra_12.1_PUBLIC/Extensions/ on Windows.

3. Import a .fjm. Drag a .fjm file into your project (or File ▸ Import File). The FlipJump loader is selected automatically; let the auto-analysis run to get the markup described below.

Build it yourself

Prefer to build from source? From the docs repo:

cd editors/ghidra-extension
GHIDRA_INSTALL_DIR="/path/to/ghidra_12.1_PUBLIC" bash tools/build_ext.sh
# -> dist/ghidra_<ver>_<date>_FlipJump.zip

The build compiles the SLEIGH spec and packages the extension. Its only third-party dependency (org.tukaani.xz, for version-3 LZMA2 files) ships inside Ghidra, so the build needs no network access. This dated zip is the same artifact published as FlipJump-Ghidra.zip on the release.

How it reads a FlipJump binary

FlipJump memory is bit-addressed; Ghidra is byte-addressed. The extension uses a flat little-endian layout where bit-address a lives at byte a>>3, bit a&7:

  • flip — read the byte at a>>3, toggle bit a&7, write it back.

  • jumpgoto the byte address b>>3 (never the raw bit-address).

Each op a;b is shown as a ; b (no mnemonic), with the FlipJump conventions rendered inline:

Case

Shown as

Why

flip == 0

; b

flip of bit 0 is a no-op

flip == 2w / 2w+1

IO ; b / IO+1 ; b

flipping these bits outputs 0 / 1

flip into a labelled var

label + k, or label + dbit + x

shown relative to the variable

jump is op-aligned (k·dw)

k*dw

op-index form

jump targets the next op

a ;

sequential fall-through — jump omitted

data op

; k*dw (labelled data_<bit-addr>)

a data word

Byte-granular flip/jump targets become real Ghidra references; the bit-granular IO + n and label + dbit + x offsets — which Ghidra references can’t express — are shown as EOL comments. There are four language variants because the word size w is fixed per file (in the header) but a SLEIGH spec is static; the loader reads word_size from the header and selects flipjump:LE:<w>:default.

Source & details

Everything lives in the docs repo at tomhea/flipjump-docs under editors/ghidra-extension/ — the loader, the SLEIGH processor module, and the analyzer, plus build and test scripts. The README there covers the address-mapping, disassembly display, and testing in full. Bug reports and improvements welcome.