Passthrough mount of a Nintendo Switch nand dump on linux

averne

May 2025

Introduction

This is a short post I’m doing as a way to fix this knowledge somewhere, because I’ve found myself having to reinvent the wheel every time I’ve wanted to do this.
Nintendo Switch dumps tend to be quite heavy and unwieldy, so it sucks when you want to extract a single file from them and have to first unpeel several layers of partitioning, while extracting huge files over and over.

By chaining a few tools and utilities, you can achieve a passthrough mount from the raw nand dump, to the actual filesystem.

Setup

  1. Clone and compile busehac. Use make RELEASE=1 -j$(nproc)I’ve hit some kind of obscure bug last time, where mbedtls global state was somehow corrupted on executable load. This might’ve been because the mbedcrypto library was compiled in release mode, while the tool was compiled in debug mode. If busehac stops responding on launch, make sure to compile on release mode.
    You can also add -DRELEASE to the CFLAGS in the Make script to remove the noisy debug logging.
  2. Enable network block devices: sudo modprobe nbd.
  3. Find out the partition layout: fdisk -l rawnand.bin. Verify the sector size, which should be 0x200 bytes. Note the partition start and size (I’ll refer to those as pstart and psize).
    You can correlate with the info on switchbrew.
  4. Setup a loop device over the partition: sudo losetup -f --show --offset $((0x200*pstart)) --sizelimit $((0x200*psize)) rawnand.bin. This will output a loop device node, loopnode.
  5. Launch busehac: sudo busehac --keyfile keys.txt N loopnode /dev/nbd0, where N is the bis key number (see switchbrew for mapping). The keys file should contain the BIS keys for this nand dump.
  6. Finally, mount the decrypted partition: sudo mount -o ro /dev/nbd0 mount.Make sure to mount as read-only. I wouldn’t trust busehac for writes.

You can also read the decrypted partition data directly:This is useful if you want to extract the decrypted Prodinfo.

$ sudo dd if=/dev/nbd0 bs=$((0x100)) count=1 status=none | xxd 
00000000: ebe9 9000 0000 0000 0000 0000 0220 2000  .............  .
00000010: 0200 0000 00f8 0000 3f00 1000 0000 0000  ........?.......
00000020: 0000 e006 006e 0000 0000 0000 0200 0000  .....n..........
00000030: 0100 0600 0000 0000 0000 0000 0000 0000  ................
00000040: 8001 2900 0000 004e 4f20 4e41 4d45 2020  ..)....NO NAME  
00000050: 2020 4641 5433 3220 2020 0000 0000 0000    FAT32   ......
00000060: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000070: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000080: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000090: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000a0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000b0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000c0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000d0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000e0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000f0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

Teardown

  1. Unmount the partition: sudo umount mount.
  2. Stop busehac.
  3. Destroy the loop device: sudo losetup -d loopnode.

Addendum: Flashing another console’s Prodinfo

This describes the steps required to boot a console using a donor Prodinfo, which can be used to temporarily unban a unit.