Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import os
- import zlib
- import io
- import struct
- import sys
- def decodeTitleId(titleId):
- tidData=struct.unpack(">2sH",bytes.fromhex(titleId))
- return "%s-%d" % (tidData[0].decode(),tidData[1])
- def extractGODXCP(fname,contentDir,licenseMask):
- 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),byteorder="big")
- totalDataSize=int.from_bytes(hdr.read(0x08),byteorder="big")
- 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))
- #titleDir="%s [%s]" % (gameName.replace(":"," -"), titleId.upper())
- titleDir=titleId.upper()
- outdir=os.path.join(contentDir,"0000000000000000",titleDir,contentType.upper())
- os.makedirs(outdir,exist_ok=True)
- outpath=os.path.join(outdir,contentId[:32].upper()+titleId[:2].upper())
- f2=open(outpath,"wb")
- f2.write(hdr.getvalue())
- # Fix header.
- f2.seek(0)
- f2.write(b"LIVE")
- f2.write(b"\x00"*0x228)
- # Add license mask.
- data=struct.pack(">qii",-1,licenseMask,1)
- f2.write(data)
- data=struct.pack(">qii",-1,licenseMask,0)
- f2.write(data)
- f2.close()
- # Write data files.
- 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__":
- contentDir=sys.argv[2] if len(sys.argv)>2 else "content"
- licenseMask=sys.argv[3] if len(sys.argv)>3 else 0
- extractGODXCP(sys.argv[1],contentDir,licenseMask)
Advertisement
Add Comment
Please, Sign In to add comment