/netmd-exploits

A collection of netmd exploits usable with netmd-js

Primary LanguageTypeScriptGNU General Public License v2.0GPL-2.0

netmd-exploits

What is it?

netmd-exploits is a library aiming to store all the available exploits for Sony NetMD devices.

What exploits are available?

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, R1.400, R1.300, R1.200, R1.100, R1.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.

Examples

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

Hacking

If you would like to help with adding compatibility for your device, pull requests are welcome.

An exploit's structure

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.

Loading and unloading exploits

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 inbuilt assembler

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!

Example

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);
})();

Credits

The assembler built into netmd-exploits is a modified version of keystone-js by AlexAltea