mirror of
https://github.com/rvtr/TwlIPL.git
synced 2025-10-31 06:01:12 -04:00
git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/TwlIPL/trunk@2281 b08762b0-b915-fc4b-9d8c-17b2551a87ff
151 lines
5.4 KiB
Python
151 lines
5.4 KiB
Python
#!/usr/bin/env python
|
|
# -*- coding:utf-8 -*-
|
|
|
|
import sys, os, struct
|
|
import string, random
|
|
import re, shutil, binascii
|
|
|
|
def roundup(val, align):
|
|
return int((val+align-1)/align)*align
|
|
|
|
def randstr(n):
|
|
words = ''.join([string.digits,string.letters,'.','+'])
|
|
return ''.join(random.choice(words) for i in xrange(n))
|
|
|
|
def main():
|
|
try:
|
|
tadfile = sys.argv[1]
|
|
except:
|
|
print '%s : please specfy the tad file' % (sys.argv[0])
|
|
exit(-1)
|
|
|
|
#--- parse *.tad
|
|
fin = open(tadfile, 'rb')
|
|
try:
|
|
tadData = fin.read()
|
|
except:
|
|
fin.close()
|
|
start, end = 0, struct.calcsize('>l2sh6l')
|
|
(hdrSize, tadType, tadVersion, certSize, crlSize, ticketSize, tmdSize,
|
|
contentSize, metaSize) = struct.unpack('>l2sh6l', tadData[start:end])
|
|
certOffset = roundup(hdrSize, 64)
|
|
crlOffset = roundup(certOffset + certSize, 64)
|
|
ticketOffset = roundup(crlOffset + crlSize, 64)
|
|
tmdOffset = roundup(ticketOffset + ticketSize, 64)
|
|
contentOffset = roundup(tmdOffset + tmdSize, 64)
|
|
metaOffset = roundup(contentOffset + contentSize, 64)
|
|
fileSize = roundup(metaOffset + metaSize, 64)
|
|
|
|
#print '-'*20+'\n'
|
|
#print ' hdrSize %s\n' % hdrSize,
|
|
#print ' tadType %s\n' % tadType,
|
|
#print ' tadVersion, %s\n' % tadVersion,
|
|
#print ' certSize, %s\n' % certSize,
|
|
#print ' crlSize, %s\n' % crlSize,
|
|
#print ' ticketSize, %s\n' % ticketSize,
|
|
#print ' tmdSize, %s\n' % tmdSize,
|
|
#print ' contentSize, %s\n' % contentSize,
|
|
#print ' metaSize %s'
|
|
#print '\n'+'-'*20
|
|
#open("cert.bin", 'wb').write(tadData[certOffset:certOffset+certSize])
|
|
#open("crl.bin", 'wb').write(tadData[crlOffset:crlOffset+crlSize])
|
|
#open("ticket.bin", 'wb').write(tadData[ticketOffset:ticketOffset+ticketSize])
|
|
#open("tmd.bin", 'wb').write(tadData[tmdOffset:tmdOffset+tmdSize])
|
|
#open("content.bin", 'wb').write(tadData[contentOffset:contentOffset+contentSize])
|
|
#open("meta.bin", 'wb').write(tadData[metaOffset:metaOffset+metaSize])
|
|
|
|
#--- parse TMD
|
|
tmd = tadData[tmdOffset:tmdOffset+tmdSize]
|
|
|
|
#--- RSA2048 signature
|
|
(sigB, sigE) = (0, struct.calcsize('>i256s60s64s'))
|
|
(IOSCCertSigType, IOSCRsaSig2048, IOSCSigDummy, IOSCName)\
|
|
= struct.unpack('>i256s60s64s', tmd[sigB:sigE])
|
|
|
|
#print "=== RSA2048 signature ==============="
|
|
#print "IOSCCertSigType : %x" % IOSCCertSigType
|
|
#print "IOSCRsaSig2048 : %s" % IOSCRsaSig2048
|
|
#print "IOSCSigDummy : %s" % IOSCSigDummy
|
|
#print "IOSCName : %s" % IOSCName
|
|
|
|
#--- ESTitleMetaHeader
|
|
(tmhB, tmhE) = (sigE, sigE+struct.calcsize('>4B5iH62si3H'))
|
|
(version,
|
|
caCrlVersion,
|
|
signerCrlVersion,
|
|
dummy,
|
|
sysVersion_H,
|
|
sysVersion_L,
|
|
titleId_H,
|
|
titleId_L,
|
|
titleType,
|
|
groupID,
|
|
reserved,
|
|
accessRights,
|
|
titleVersion,
|
|
numContents,
|
|
bootIndex) = struct.unpack('>4B5iH62si3H',tmd[tmhB:tmhE])
|
|
|
|
print "=== ESTitleMetaHeader ==============="
|
|
#print ('version : %d ') % version
|
|
#print ('caCrlVersion : %d ') % caCrlVersion
|
|
#print ('signerCrlVersion : %d ') % signerCrlVersion
|
|
#print ('dummy : %s ') % dummy
|
|
#print ('sysVersion_H : %x ') % sysVersion_H
|
|
#print ('sysVersion_L : %x ') % sysVersion_L
|
|
print ('titleId_H : %08x ') % titleId_H
|
|
print ('titleId_L : %08x ') % titleId_L
|
|
#print ('titleType : %x ') % titleType
|
|
print ('groupID : %x ') % groupID
|
|
#print ('reserved[62] : %s ') % reserved
|
|
#print ('accessRights : %d ') % accessRights
|
|
print ('titleVersion : %d ') % titleVersion
|
|
#print ('numContents : %d ') % numContents
|
|
#print ('bootIndex : %d ') % bootIndex
|
|
|
|
#--- make directory for cls
|
|
tadpath = os.path.dirname(tadfile)
|
|
gamecode = binascii.unhexlify('%x'%titleId_L)
|
|
keycode = gamecode[:3]
|
|
sysdic = { 'HNA':'menu',
|
|
'HNB':'setting',
|
|
'HNC':'wfirm',
|
|
'HND':'dlplay',
|
|
'HNE':'pchat',
|
|
'HNF':'shop',
|
|
'HNG':'browser',
|
|
'HNH':'whlist',
|
|
'HNI':'photo',
|
|
'HNJ':'nzv',
|
|
'HNK':'sound',
|
|
'HNL':'verdata',
|
|
}
|
|
try:
|
|
suffix = sysdic.get(keycode)
|
|
if suffix:
|
|
clsdir = ''.join(['./',gamecode,'-',suffix])
|
|
else:
|
|
clsdir = ''.join(['./',gamecode])
|
|
os.mkdir(clsdir)
|
|
except:
|
|
print '%s : can not create dir %s' % (sys.argv[0],clsdir)
|
|
|
|
#--- write properties
|
|
properties = open(''.join([clsdir,'/properties']),'w')
|
|
properties.write('TITLE_ID\t\t\t\t%08x%08x\n' % (titleId_H, titleId_L))
|
|
properties.write('TITLE_NAME\t\t\t\t%s\n' % gamecode)
|
|
properties.write('TITLE_TYPE\t\t\t\t%s\n' % 'TWL_SYS')
|
|
properties.write('PASSWORD\t\t\t\t%s\n' % randstr(64))
|
|
properties.write('ALLOW_COMMON_TICKET\t\t%s\n' % '1')
|
|
|
|
#--- make version dir
|
|
verdir = ''.join([clsdir,'/v',str(titleVersion)])
|
|
try:
|
|
os.mkdir(verdir)
|
|
except:
|
|
print '%s : can not create dir %s' % (sys.argv[0],verdir)
|
|
else:
|
|
shutil.copy(tadfile,verdir)
|
|
|
|
if __name__ == '__main__':
|
|
sys.exit(main() or 0) |