Skip to content

Instantly share code, notes, and snippets.

@swarzesherz
Last active August 29, 2015 14:14
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save swarzesherz/651f69b2e8e5c370a0f4 to your computer and use it in GitHub Desktop.
Save swarzesherz/651f69b2e8e5c370a0f4 to your computer and use it in GitHub Desktop.
3DSFAT16tool
# -*- coding: utf-8 -*-
# version 1.0
import os
import sys
import argparse
import math
import numpy
if not sys.version_info[:2] == (2, 7):
print '*****\n!!!!!Warning - Only tested with Python 2.7!!!!!\n*****\n'
parser = argparse.ArgumentParser()
parser.add_argument('nand_file', action='store', help='NAND file (must exist for dumping and injecting)')
parser.add_argument('fat16_file', action='store', help='FAT16 file (only should exist for injecting, fat16 file will be written/overwrite when dumping)')
parser.add_argument('fat16_xorpad', action='store', help='FAT16 xorpad file')
choose = parser.add_mutually_exclusive_group()
choose.add_argument('-d', action='store_true', default=False, dest='dump', help='Dump FAT16 from NAND file')
choose.add_argument('-i', action='store_true', default=False, dest='inject', help='Inject FAT16 into NAND file')
parser.add_argument('-n3ds', action='store_true', default=False, dest='n3ds', help='Use for N3DS NAND dumps')
parser.add_argument('-lowmem', action='store_true', default=False, dest='lowmem', help='Use if you have low RAM available')
arguments = parser.parse_args()
#https://stackoverflow.com/questions/5734691/fastest-bitwise-xor-between-two-multibyte-binary-data-variables
def xor(data, key):
import numpy, math
# key multiplication in order to match the data length
key = (key*int(math.ceil(float(len(data))/float(len(key)))))[:len(data)]
# Select the type size in bytes
for i in (8,4,2,1):
if not len(data) % i: break
if i == 8: dt = numpy.dtype('<Q8');
elif i == 4: dt = numpy.dtype('<L4');
elif i == 2: dt = numpy.dtype('<H2');
else: dt = numpy.dtype('B');
return numpy.bitwise_xor(numpy.fromstring(key, dtype=dt), numpy.fromstring(data, dtype=dt)).tostring()
if (arguments.dump is arguments.inject):
print 'Please choose -d or -i to dump or inject the fat16 partition'
exit(0)
print '*******\n3DSFAT16tool\n*******\n'
start = 0x0B930000
size = 0x2F3E3600
chunksize = 0x3200000 #10MB(0XA00000) RAM usage ~77.531MiB, 25MB(0X1900000) RAM usage ~77.531MiB, 50MB(0X3200000) RAM usage ~364.840MiB
fsOffset = 0x2CA00
if(arguments.n3ds):
size = 0x41D2D200
fsOffset = 0x2AE00
if not os.path.isfile(arguments.nand_file):
print 'NAND file cannot be found'
exit(0)
if (arguments.inject):
if not os.path.isfile(arguments.fat16_file):
print 'FAT16 file cannot be found'
exit(0)
with open(arguments.fat16_file, 'rb') as r, open(arguments.nand_file, 'rb+') as w, open(arguments.fat16_xorpad, 'rb') as x:
print 'Injecting... please wait'
if arguments.lowmem:
for i in range(0, size, chunksize):
w.seek(start+fsOffset+i)
x.seek(fsOffset+i)
chunksize = size % chunksize if size < chunksize else chunksize
fat16 = r.read(chunksize)
xorpad = x.read(chunksize)
w.write(xor(fat16, xorpad))
size -= chunksize
else:
w.seek(start+fsOffset)
x.seek(fsOffset)
fat16 = r.read(size)
xorpad = x.read(size)
w.write(xor(fat16, xorpad))
if (arguments.dump):
if os.path.isfile(arguments.fat16_file):
print 'FAT16 with this name and path already exists, file will be overwritten'
with open(arguments.nand_file, 'rb') as r, open(arguments.fat16_file, 'wb') as w, open(arguments.fat16_xorpad, 'rb') as x:
print 'Dumping... please wait'
if arguments.lowmem:
for i in range(0, size, chunksize):
r.seek(start+fsOffset+i)
x.seek(fsOffset+i)
chunksize = size % chunksize if size < chunksize else chunksize
fat16 = r.read(chunksize)
xorpad = x.read(chunksize)
w.write(xor(fat16, xorpad))
size -= chunksize
else:
r.seek(start+fsOffset)
x.seek(fsOffset)
fat16 = r.read(size)
xorpad = x.read(size)
w.write(xor(fat16, xorpad))
print ''
print 'Finished'
@alatnet
Copy link

alatnet commented Jun 3, 2015

works fine with python 3.4. you just need to install numpy and convert the print statements to print functions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment