netmd-exploits
is a library aiming to store all the available exploits for Sony NetMD devices.
The exploits currently available are:
Exploit name | Firmware Versions* compatible | JavaScript class name |
---|---|---|
Firmware Dumping | All versions supported | FirmwareDumper |
USB Code Execution | S1.600, S1.500, S1.400, S1.300, S1.200, S1.100, S1.000, R1.400, R1.300, R1.200, R1.100, R1.000, Hr1.000, Hn1.000, Hn1.100, Hn1.10A, Hn1.200, Hx1.070, Hx1.090, Hx1.0A0 | USBCodeExecution |
Tetris | S1.600, S1.500, S1.400, S1.300, S1.200, S1.100, S1.000 | Tetris |
Force TOC Flushing | S1.600, S1.500, S1.400, S1.300, S1.200, S1.100, S1.000, R1.400, R1.300, R1.200, R1.100, R1.000 | ForcedTOCEdit |
Upload SP Mono | S1.600, S1.500, S1.400, S1.300, S1.200, S1.100, S1.000, R1.400, R1.300, R1.200, R1.100, R1.000 | MonoSPUpload |
Atrac USB Control Transfer | S1.600, S1.500, S1.400, S1.300, S1.200, S1.100, S1.000, |
CachedSectorControlDownload |
Atrac USB No-RAM Transfer | S1.600, S1.500, S1.400, S1.300, S1.200, S1.100, S1.000, R1.400, R1.300, R1.200, R1.100, R1.000 | CachedSectorNoRAMDownload |
Atrac USB Bulk Transfer | S1.600, S1.500, S1.400, S1.300, S1.200, S1.100, S1.000, Hr1.000, Hn1.000, Hn1.100, Hn1.10A, Hn1.200 | CachedSectorBulkDownload |
SP Faster Upload | S1.600, S1.500, S1.400, S1.300, S1.200, S1.100, S1.000 | PCMFasterUpload |
ATRAC1 Upload | S1.600, S1.500, S1.400, S1.300, S1.200, S1.100, S1.000 | SPUpload |
EEprom Write Lock | S1.600, S1.500, S1.400, S1.300, S1.200, S1.100, S1.000, R1.400, R1.300, R1.200, R1.100, R1.000 | KillEepromWrite |
Disc Spinning Notifier** | S1.600, S1.500, S1.400, S1.300, S1.200, S1.100, S1.000, R*, Hr*, Hn* | WaitForDiscToStopSpinning |
Unbounded memory access | Hr1.000, Hn1.000, Hn1.100, Hn1.10A, Hn1.200 | HiMDUnboundedReading |
HiMD USB Class Override | Hr1.000, Hn1.000, Hn1.100, Hn1.10A, Hn1.200, Hx1.070, Hx1.090, Hx1.0A0 | HiMDUSBClassOverride |
*The firmware versions listed here consist of the SOC type letter:
- R - CXD2677 (Type R)
- S - CXD2678 / CXD2680 (Type S)
- Hn - CXD2681 (gen1)
- Hr - CXD2681 (gen2)
- Hx - CXD2687
And the actual firmware version reported by the device.
**WaitForDiscToStopSpinning only supports Type-S devices, on Type-R and HiMD it always waits 10 seconds.
Unit | SoC | Firmware version | netmd-exploits firmware version |
---|---|---|---|
Sony MZ-N510 | CXD2680 | 1.600 | S1.600 |
Sony MZ-N710 | CXD2680 | 1.600 | S1.600 |
Sony MZ-N1 | CXD2677 | 1.200 | R1.200 |
Sony MZ-N10 | CXD2678 | 1.200 | S1.300 |
Sony MZ-RH10 | CXD2681 (gen2) | 1.000 | Hr1.000 |
Sony MZ-NH600 | CXD2681 (gen1) | 1.000 | Hn1.000 |
Sony MZ-RH1 | CXD2687 | 1.0A0 | Hx1.0A0 |
If you would like to help with adding compatibility for your device, pull requests are welcome.
The library keeps track of what exploits are compatible with what versions with the help of src/compatibility.ts
.
Every exploit class has to inherit the Exploit
abstract class. It provides multiple functions which make it easier to load the correct versions of exploits for every firmware version.
The constants that depend on the firmware version are stored in a VersionStore
map returned from getPropertyStore()
, from which it's possible to get values by calling getProperty
, or by referencing their names in assembly code, prefixed with a '$'. Every exploit class has to also define a static _name
const, used for compatibility checking.
Once an exploit is loaded using ExploitStateManager.require
or ExploitStateManager.envelop
, the exploit's init()
method is called. Because of how exploits are loaded, exploits shouldn't
have their own constructor. Instead, init()
should be used as an asynchronous constructor.
To unload an exploit you can use ExploitStateManager.unload
. When using ExploitStateManager.envelop
, this action will be done automatically.
When an exploit is unloaded, its unload()
method is called, where the exploit can perform cleanup.
All behavior-modifying exploits should have a valid unload()
method defined, in order to automatically restore the device to the default state.
If an exploit is using patches, the unload()
method should clear the patches from the device, and then call this.stateManager.freePatch()
, to mark the patch as unused.
All the patches for which ExploitStateManager.freePatch()
wasn't called will automatically be unloaded from the device by the state manager.
If a patch is loaded by ExploitStateManager.require
, and then reloaded again using ExploitStateManager.envelop
, it will not be unloaded after returning from envelop()
.
To unload it, ExploitStateManager.unload
has to be called.
The assembler has full support for macros (prefixed with '@'), VersionStore
constants (prefixed with '$'), as well as variables, passed to the assemble
function (prefixed with '%').
The macros available for every assembly program are stored in src/assembler/core-macros.ts
.
Exploits can define private macros in the _macros
property of the VersionStore
returned from getPropertyStore()
.
Happy hacking!
Below is an extremely basic example, which when run will download the first track from the disc onto the computer using the best suited exploit for it:
import { DevicesIds, openNewDevice } from 'netmd-js'
import { AtracRecovery, getBestSuited, ExploitStateManager } from 'netmd-exploits';
import { WebUSB } from 'usb';
import fs from 'fs';
(async() => {
const usb = new WebUSB({ allowedDevices: DevicesIds, deviceTimeout: 1000000 });
const dev = await openNewDevice(usb);
const stateManager = await ExploitStateManager.create(dev!);
const exploit = await stateManager.require(getBestSuited(AtracRecovery));
fs.writeFileSync(await exploit.downloadTrack(0, console.log));
await stateManager.unload(getBestSuited(AtracRecovery));
process.exit(0);
})();
The assembler built into netmd-exploits
is a modified version of keystone-js by AlexAltea