mirror of
https://github.com/encounter/Decrypt9.git
synced 2026-03-30 11:06:30 -07:00
84 lines
2.6 KiB
Python
84 lines
2.6 KiB
Python
#!/usr/bin/env python2
|
|
import sys
|
|
import os
|
|
import struct
|
|
import hashlib
|
|
|
|
|
|
def round_up(numToRound, multiple): #From http://stackoverflow.com/a/3407254
|
|
if multiple == 0:
|
|
return numToRound
|
|
|
|
remainder = abs(numToRound) % multiple
|
|
if remainder == 0:
|
|
return numToRound
|
|
if numToRound < 0:
|
|
return -(abs(numToRound) - remainder)
|
|
return numToRound + multiple - remainder
|
|
|
|
|
|
# Part of this code from https://stackoverflow.com/questions/120656/directory-listing-in-python
|
|
def parse_dir(foldername, ctrlist):
|
|
savedpath = os.getcwd()
|
|
try:
|
|
os.chdir('./' + foldername)
|
|
except Exception as ex:
|
|
return
|
|
|
|
for dirname, dirnames, filenames in os.walk('.'):
|
|
for filename in filenames:
|
|
if 'quota.dat' in filename.lower():
|
|
continue
|
|
|
|
fsizeMB = round_up(os.stat(os.path.join(dirname, filename)).st_size, 1024*1024) / (1024*1024)
|
|
fname = '/' + foldername + os.path.join(dirname, filename)[1:].replace('\\','/')
|
|
|
|
digest = hashlib.sha256(fname.encode('utf-16le') + '\x00\x00').digest()
|
|
x = struct.unpack("<LLLLLLLL", digest)
|
|
ctr = struct.pack("<LLLL", x[0] ^ x[4], x[1] ^ x[5], x[2] ^ x[6], x[3] ^ x[7])
|
|
|
|
fname = '/' + fname[1:].replace('/','.') + '.xorpad'
|
|
if len(fname) > 180:
|
|
print "Filename too long. This shouldn't happen."
|
|
print '%s' % fname
|
|
raise SystemExit(0)
|
|
ctrlist.append([ctr, fname, fsizeMB, fname])
|
|
os.chdir(savedpath)
|
|
|
|
|
|
if len(sys.argv) < 2:
|
|
print 'usage: sdinfo_gen.py folderpath'
|
|
print 'folderpath: folder on your SD that contains "dbs", "title", etc.'
|
|
print 'For example, sdinfo_gen.py "X:/Nintendo 3DS/xxxxxxxxx/xxxxxxxx/"'
|
|
raise SystemExit(0)
|
|
|
|
savedpath = os.getcwd()
|
|
try:
|
|
os.chdir(sys.argv[1])
|
|
except Exception as ex:
|
|
print str(ex)
|
|
raise SystemExit(0)
|
|
|
|
ctrlist = []
|
|
|
|
parse_dir('dbs', ctrlist)
|
|
parse_dir('extdata', ctrlist)
|
|
parse_dir('title', ctrlist)
|
|
# parsedir('backups', ctrlist) # Untested
|
|
|
|
os.chdir(savedpath)
|
|
|
|
if not ctrlist == []:
|
|
fh = open('SDinfo.bin', 'wb')
|
|
listlen = len(ctrlist)
|
|
fh.write(struct.pack('<L', listlen)) # Number of entries
|
|
for x in ctrlist:
|
|
fh.write(x[0]) # Counter
|
|
fh.write(struct.pack('<L', x[2])) # File size in MB (rounded up)
|
|
fh.write(x[1]) # Output filename
|
|
if len(x[1]) < 180:
|
|
fh.write('\x00'*(180-len(x[1]))) # Pad filename out to 180 bytes
|
|
print 'SDinfo.bin generated.'
|
|
else:
|
|
print "Couldn't find any content. Wrong folder?"
|