Example: Read and write NAND partitions

In this example we will take a dumped Nintendo 3DS NAND image and extract data from the partitions.

Use GodMode9 to dump the NAND and essential files from your console. No examples files are provided.

Note

This is only an introduction to the NAND class assuming a valid NAND backup is being used. There are plenty of ways for this to go wrong in practice, from a corrupt TWL MBR, to no embedded essentials backup or an outdated one (such as lacking hwcal0 and hwcal1 or containing un-updated files like movable).

(soon) The full NAND module documentation helps you to figure out how to handle these cases.

First we need to import NAND, and use it to open our NAND backup. In this case we will assume it has the GodMode9 essentials backup embedded.

When opening a NAND backup file without any additional arguments, it is read-only by default.

>>> from pyctr.type.nand import NAND
>>> nand = NAND('nand.bin')

With this we now immediately have access to decrypted versions of every NCSD partition and the GodMode9 bonus partition if it exists. We can also access the essentials backup with the essential attribute, an ExeFSReader object.

Most of the time when interacting with a NAND backup, we’ll want to access CTR NAND. There is a convenience function that will immediately open the CTR NAND FAT32 partition and enable access to the filesystem, open_ctr_fat(). This returns a PyFatBytesIOFS, provided by pyfatfs.

>>> ctrfat = nand.open_ctr_fat()

With that let’s list the files and open one.

>>> ctrfat.listdir('/')
['data', 'ro', 'rw', 'ticket', 'title', 'tmp', 'fixdata', 'dbs', 'private', '__journal.nn_']
>>> ctrfat.listdir('/private')
['movable.sed']
>>> msed_file = ctrfat.open('/private/movable.sed', 'rb')
>>> msed_file.seek(0x110)
>>> msed = msed_file.read(0x10)
>>> print('movable.sed key:', msed.hex())
movable.sed key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Once done, let’s remember to close all the files properly.

>>> msed_file.close()
>>> ctrnand.close()
>>> nand.close()

Writing

We’ve done enough reading. Let’s write some files to the NAND now.

To do this, the second argument for NAND should be given 'rb+'.

>>> from pyctr.type.nand import NAND, NANDSection
>>> from pyfatfs.PyFatFS import PyFatBytesIOFS
>>> nand = NAND('nand.bin', 'rb+')
>>> ctrfat = nand.open_ctr_fat()

With the NAND in read-write mode we can open files for writing now.

>>> myfile = ctrfat.open('/myfile.txt', 'wb')
>>> myfile.write(b'my contents')
>>> myfile.close()

Context managers

Files can all be opened using context managers as well.

with NAND('nand.bin') as nand:
    with nand.open_ctr_fat() as ctrfat:
        with ctrfat.open('/myfile.txt', 'rb') as f:
            print(f.read())

Next steps

Now that you know the basics of reading and writing to a NAND backup, you may want to check out these methods: