Loading 3D model… large boards can take a moment.
This repo contains guides, payloads, schematics and scripts for use with PSP2's "SD boot mode".
On all Playstation Vita/TV units the System Controller ("syscon", "ernie") has an RPC server activated by a specific hardware circuit. When activated, syscon listens over UART for commands that can range from simple diag checks, fuse reads, calibrations, to special features such as NVS R/W that require authorization using handshakes with secret keys. More information as well as circuit schematics and RPC clients can be found in the bert repository.
An authorized JIG interface client can trigger a special, alternative boot mode inside the BootROM. In this mode, which we dubbed "sdboot", a signed second_loader.enp is loaded from an unauthenticated MMC/SD storage inside the GameCard slot and decrypted using an alternative set of per-console keys.
In sdboot, after copying itself from 0x40000 to 0x5c000, BootROM first reads a single block (0x200 bytes) from the external storage to 0x40000, verifies if second_loader offset and size fields are valid, then reads second_loader to 0x40000.
The issue is that the exception vectors are hardcoded to 0x40000, so any exceptions in BootROM during (or after) second_loader is read will cause a "jump" to the read data - resulting in arbitrary code execution.
A simple way to trigger an exception is to perform a Fault Injection attack. Because all faults/exceptions result in code execution, the FI setup does not need to be precise, and can be approached in a spray-and-pray manner.
This project makes use of Voltage Fault Injection, specifically the "crowbar" method, performed by a low cost setup with the Teensy 4 mcu system at heart.
The result is a consistent BootROM code execution of a arbitrary code blob loaded from an unauthenticated MMC/SD storage inside the GameCard slot.
With psp2sdboot, the default code blob is bob, it starts an RPC server that can be used for research or executing additional specialized payloads with functionality such as key retrieval, data dumping, unbricking and more.
There are at least two (magnet) wire solder points - Core_VDD (orange) and GC_dat0 (yellow).
The MOSFET wires should be insulated and kept as short as possible, you can even solder its legs directly to the Core_VDD capacitor.
The original setup was Windows + WSL1, but the instructions should work fine on Windows, Linux and MacOS.
The "root", working directory should be a local copy of this repository.
tools/mkfake.c with GCCbob/bob_rpc.py, teensy4vfi/teensy_rpc.py, and bert/bert.pybob directory in payloads/, and copy there the bob build and header files
bob/build/* to payloads/bob/bob/source/include to payloads/bob/env.bat
A raw SD card image can be created using the previously compiled mkfake utility, the syntax is mkfake <code_blob> -o <output> where:
payloads/bob/bob_glitch.binThe provided sdboot.py is a python script that loops reboot->glitch->check until bob is successfully loaded and executed.
Its accepted arguments/parameters and their descriptions can be listed with sdboot help.
The first step is determining optimal timing parameters range for the main sdboot script, which will then find the more precise/consistent glitch timings.
The width of a glitch that always causes an unrecoverable crash is called the "threshold", this should be the upper width boundary - sdboot's width_max argument.
It can be determined by the following procedure:
sdboot width=100 width_max=100000 width_step=100
sdboot width=<cutoff_width-100> width_max=<cutoff_width+100> width_step=20
up_to_read is a special 0-width glitch queued to find an empty sector read op, which compensates for a high SD init/read jitter.
The idea is that as long as it lands in the middle of an empty sector being read (dat0 pulled down), the actual fault injection glitch can be precisely triggered and timed from dat0 going up.
It can be determined by altering the following command: sdboot up_to_read_mark=100 up_to_read=298400000. Change up_to_read until the mosfet line spike happens around the middle of an empty sector read.
The second step is running the sdboot python script, and letting it find a correct combination of offset and width parameters
Script arguments are based on the values found during the Calibration step, with an added broad offset range:
sdboot up_to_read=<up_to_read> width=<threshold-(2*width_step)> width_max=<threshold+width_step> width_step=20 offset=100 offset_max=10000 offset_mult=10 offset_step=40
got sd boot: off=<offset>[<offset_mult>] width=<width> message will be displayed and the script will stop
After bob presence is confirmed with bob ping, you can use the bob_rpc script to conduct further research or copy and run MeP payloads. Available RPC commands can be listed by calling the script without any arguments - bob.
You should put your custom payloads inside the payloads/ directory.
They can statically link to bob and bootrom for basic funtionality, see the linker example. Headers can be found in payloads/bob/include/.
Payloads can be executed anywhere in the physical memory, keep in mind that some is uninitialized - eg DRAM.
file_send <offset> <payload_file>exec <offset> <arg0> <arg1> <arg2_data>, where arg2_data is a buffer passed as arg2exece <offset> <arg0> <arg1> <arg2> <arg..>, up to 8 args totalProvided is a basic keydumper - payloads/keydumper - it can be used to get the SLSK enc/dec key partials, SNVS enc/dec keys, and the SMI encryption keys.
bob file_dump.The provided eMMC dumper - payloads/emmc-dump - contains code to read/write eMMC as well as the SD card. It can be used for larger data handling, eMMC dump/unbrick, crypto research and more.
At the time of writing, there is no single tool to diagnose and fix common "bricks".
You need to get the boot log, read henkaku wiki to find the probable brick cause, and use the provided tools/payloads to fix the console.
nvs-write 0x481 0x1 00This project was made in collaboration with Proxima and Mathieulh.
Additional thanks to:
No comments yet. Be the first to ask about this board.