Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import os
- import zlib
- import io
- import struct
- import sys
- import hashlib
- def decodeTitleId(titleId):
- tidData=struct.unpack(">2sH",bytes.fromhex(titleId))
- return "%s-%d" % (tidData[0].decode(),tidData[1])
- def generateGODName(titleId,mediaId,disc,numDiscs):
- sha1=hashlib.sha1()
- sha1.update(bytes.fromhex(titleId))
- sha1.update(bytes.fromhex(mediaId))
- sha1.update(disc.to_bytes())
- sha1.update(numDiscs.to_bytes())
- return sha1.hexdigest().upper()[:20]
- def extractGODXCP(fname,contentDir):
- def decompressBlock(f):
- out=io.BytesIO()
- decomp=zlib.decompressobj()
- while not decomp.eof:
- data=f.read(0x8000)
- decdata=decomp.decompress(data)
- out.write(decdata)
- extraSize=len(decomp.unused_data)
- f.seek(-extraSize,1)
- return out.getvalue()
- def decompressPayload(f,f2,outsize,fsize):
- while f2.tell()!=outsize and f.tell()!=fsize:
- data=decompressBlock(f)
- writeSize=min(len(data),outsize-f2.tell())
- f2.write(data[:writeSize])
- return data[writeSize:]
- f=open(fname,"rb")
- f.seek(0,2)
- fsize=f.tell()
- f.seek(0)
- # Write header.
- hdr=io.BytesIO()
- extraData=decompressPayload(f,hdr,0xb000,fsize)
- hdr.seek(0x32c)
- contentId=hdr.read(0x14).hex()
- hdr.seek(0x344)
- contentType=hdr.read(0x04).hex()
- hdr.seek(0x354)
- mediaId=hdr.read(0x04).hex()
- version=hdr.read(0x04).hex()
- baseVersion=hdr.read(0x04).hex()
- titleId=hdr.read(0x04).hex()
- titleIdTxt=decodeTitleId(titleId)
- hdr.seek(0x366)
- disc=int.from_bytes(hdr.read(0x01))
- numDiscs=int.from_bytes(hdr.read(0x01))
- hdr.seek(0x39d)
- numDataFiles=int.from_bytes(hdr.read(0x04))
- totalDataSize=int.from_bytes(hdr.read(0x08))
- hdr.seek(0x411)
- contentName=hdr.read(0x100).decode("utf-16be").split("\0",1)[0]
- hdr.seek(0x1691)
- gameName=hdr.read(0x80).decode("utf-16be").split("\0",1)[0]
- print("Title: %s\nTitle ID: %s / %s\nMedia ID: %s\nVersion: %s\nBase version: %s\nContent ID: %s\nContent type: %s" %
- (contentName,titleId,titleIdTxt,mediaId,version,baseVersion,contentId,contentType))
- outdir=os.path.join(contentDir,titleId.upper(),contentType.upper())
- os.makedirs(outdir,exist_ok=True)
- godName=generateGODName(titleId,mediaId,disc,numDiscs)
- outpath=os.path.join(outdir,godName)
- f2=open(outpath,"wb")
- f2.write(hdr.getvalue())
- f2.close()
- outdir=outpath+".data"
- os.makedirs(outdir,exist_ok=True)
- writtenSize=0
- for i in range(numDataFiles):
- outpath=os.path.join(outdir,"Data%04d" % (i))
- print(outpath)
- f2=open(outpath,"wb")
- if extraData: f2.write(extraData)
- extraData=decompressPayload(f,f2,0xa290000,fsize)
- writtenSize+=f2.tell()
- f2.close()
- if writtenSize==totalDataSize:
- break
- f.close()
- if __name__=="__main__":
- extractGODXCP(sys.argv[1],"content")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement