- Python 100%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
A decompiler for the PS Vita "F00D" security processor, a little-endian Toshiba MeP core, producing structured pseudo-C. Mirrors zecoxao spudec and the Kirk/Spock (startrekdec) and RL78 (rl78dec) tools: an IDA processor module is used purely as a decoder. - Standalone MeP decoder (little-endian, 16/32-bit; 32-bit iff top nibble >= 0xC), ported from the validated IDA 9.4 mep.py module; ISA/semantics from xyzz ghidra-mep (mep.sinc) - Pipeline: lifter -> CFG -> block-local opt -> structuring -> cgen - MeP compare-and-branch folds into relational ifs (no flag layer); movh+or3/add3 address idiom folds to one constant; ldcb/stcb -> control_bus_load/store; jsr(rn) -> (*mem[rn])(); recovers if / while / do-while; JUMPOUT for tail jumps - Runs headless (python -m f00ddec dump.bin; link base auto-detected from reset jmp) or as an IDA plugin (Ctrl-Shift-S one, Ctrl-F5 all), theme highlighting - Validated on a Vita F00D secure_kernel dump: base 0x800000, 52 functions, 0 dangling gotos / 0 unbalanced braces / 0 unmodelled opcodes Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
| f00ddec | ||
| tests | ||
| .gitignore | ||
| f00ddec_plugin.py | ||
| LICENSE | ||
| pyproject.toml | ||
| README.md | ||
f00ddec — a PS Vita F00D (Toshiba MeP) decompiler
f00ddec decompiles firmware for the PlayStation Vita's F00D security
processor — a little-endian Toshiba MeP core — to readable pseudo-C. It is
the MeP analogue of spudec and the
Kirk/Spock startrekdec /
rl78dec: an IDA processor module is used
purely as a decoder, and lifting, control-flow recovery and code generation are
ours.
decoder → lifter → cfg → opt → structure → cgen
What it produces
void sub_80030A(void) // an F00D syscall/exception handler
{
tmp = sp;
sp = 0x807E80; // movh+add3 folded into one constant
mem32[0x807E80] = r0;
r0 = lp;
sub_802686(); sub_8026C6(); sub_8003A0();
r5 = r0; r1 = r0;
sub_8027D0(); r6 = r0;
r7 = control_bus_load(0); // ldcb -- F00D hardware register
r7 = r7 & 0xF000; r7 = r7 >> 4;
control_bus_store(0, r7); // stcb
ei();
r1 = r5;
(*mem32[r6])(); // jsr (r6) -- indirect call
di();
control_bus_store(0, 0x600);
... register save/restore ...
return;
}
Registers print as themselves (r0..r12, tp, gp, sp, and control registers
lp/sar/psw/cfg/…); memory reads as mem8/mem16/mem32 (s8/s16 for
sign-extending loads); MeP compare-and-branch folds into relational ifs; the
movh+or3/add3 address idiom folds to a single constant; loops become
while/do-while; cross-function tail jumps render as JUMPOUT(addr).
Two ways to run it
Headless (no IDA) — a raw F00D flash dump; the link base is auto-detected
from the reset jmp:
python -m f00ddec secure_kernel.bin -o secure_kernel.c
python -m f00ddec secure_kernel.bin --func 0x80030A
python -m f00ddec dump.bin --base 0x800000 --entry 0x800100
As an IDA plugin — open the dump with a MeP processor module (the companion
mep.py "mepf00d" module, or IDA 9.x's native mep), then drop
f00ddec_plugin.py and the f00ddec/ package into
%APPDATA%\Hex-Rays\IDA Pro\plugins\:
| Hotkey | Action |
|---|---|
Ctrl-Shift-S |
decompile the function under the cursor |
Ctrl-F5 |
decompile the whole database (and offer to save it) |
The viewer is theme-highlighted and double-click navigates. Inside IDA the output reuses whatever names you have applied.
The instruction set
Toshiba MeP core: little-endian, mixed 16/32-bit instructions (a word is 32-bit
iff its top nibble is ≥ 0xC), 16 GPRs (r0..r12, tp, gp, sp) plus control
registers. The decoder and lifter follow xyzz's Ghidra SLEIGH
(ghidra-mep, mep.sinc); the same logic
is validated in the companion IDA 9.4 processor module. Control-register access,
control-bus (ldcb/stcb), multiply/divide (hi:lo), and CPU-control
instructions that do not map cleanly onto C are printed honestly as pseudo-calls.
Limitations
- Coprocessor / VLIW (IVC2 etc.) instructions are not modelled (F00D uses the
core ISA); unknown opcodes print as
<mnem>(...) /* unmodelled */. - Entry discovery follows the reset/interrupt vectors and direct calls; indirect
calls (
jsr (rn), jump tables) need seeding with--entry. - No stack-frame reconstruction;
hi/lo,sraand rotates are intrinsics.
Tests
python tests/test_pipeline.py
python tests/test_highlight.py
Hand-assembled, so they need neither IDA nor a firmware dump.
Credits
Built on the MeP reverse-engineering of TeamMolecule (toshiba-mep-idp), xyzz
(ghidra-mep) and the CGEN MeP description. Decompiler design mirrors zecoxao's
spudec. MIT licensed. No firmware is included.