Nicknine

X360 GoD XCP Unpacker

Apr 10th, 2025 (edited)
284
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.27 KB | None | 0 0
  1. import os
  2. import zlib
  3. import io
  4. import struct
  5. import sys
  6.  
  7. def decodeTitleId(titleId):
  8.     tidData=struct.unpack(">2sH",bytes.fromhex(titleId))
  9.     return "%s-%d" % (tidData[0].decode(),tidData[1])
  10.  
  11. def extractGODXCP(fname,contentDir,licenseMask):
  12.     def decompressBlock(f):
  13.         out=io.BytesIO()
  14.         decomp=zlib.decompressobj()
  15.         while not decomp.eof:
  16.             data=f.read(0x8000)
  17.             decdata=decomp.decompress(data)
  18.             out.write(decdata)
  19.  
  20.         extraSize=len(decomp.unused_data)
  21.         f.seek(-extraSize,1)
  22.         return out.getvalue()
  23.  
  24.     def decompressPayload(f,f2,outsize,fsize):
  25.         while f2.tell()!=outsize and f.tell()!=fsize:
  26.             data=decompressBlock(f)
  27.             writeSize=min(len(data),outsize-f2.tell())
  28.             f2.write(data[:writeSize])
  29.  
  30.         return data[writeSize:]
  31.  
  32.     f=open(fname,"rb")
  33.     f.seek(0,2)
  34.     fsize=f.tell()
  35.     f.seek(0)
  36.  
  37.     # Write header.
  38.     hdr=io.BytesIO()
  39.     extraData=decompressPayload(f,hdr,0xb000,fsize)
  40.  
  41.     hdr.seek(0x32c)
  42.     contentId=hdr.read(0x14).hex()
  43.     hdr.seek(0x344)
  44.     contentType=hdr.read(0x04).hex()
  45.     hdr.seek(0x354)
  46.     mediaId=hdr.read(0x04).hex()
  47.     version=hdr.read(0x04).hex()
  48.     baseVersion=hdr.read(0x04).hex()
  49.     titleId=hdr.read(0x04).hex()
  50.     titleIdTxt=decodeTitleId(titleId)
  51.     hdr.seek(0x366)
  52.     disc=int.from_bytes(hdr.read(0x01))
  53.     numDiscs=int.from_bytes(hdr.read(0x01))
  54.     hdr.seek(0x39d)
  55.     numDataFiles=int.from_bytes(hdr.read(0x04),byteorder="big")
  56.     totalDataSize=int.from_bytes(hdr.read(0x08),byteorder="big")
  57.     hdr.seek(0x411)
  58.     contentName=hdr.read(0x100).decode("utf-16be").split("\0",1)[0]
  59.     hdr.seek(0x1691)
  60.     gameName=hdr.read(0x80).decode("utf-16be").split("\0",1)[0]
  61.  
  62.     print("Title: %s\nTitle ID: %s / %s\nMedia ID: %s\nVersion: %s\nBase version: %s\nContent ID: %s\nContent type: %s" %
  63.           (contentName,titleId,titleIdTxt,mediaId,version,baseVersion,contentId,contentType))
  64.  
  65.     #titleDir="%s [%s]" % (gameName.replace(":"," -"), titleId.upper())
  66.     titleDir=titleId.upper()
  67.  
  68.     outdir=os.path.join(contentDir,"0000000000000000",titleDir,contentType.upper())
  69.     os.makedirs(outdir,exist_ok=True)
  70.     outpath=os.path.join(outdir,contentId[:32].upper()+titleId[:2].upper())
  71.  
  72.     f2=open(outpath,"wb")
  73.     f2.write(hdr.getvalue())
  74.  
  75.     # Fix header.
  76.     f2.seek(0)
  77.     f2.write(b"LIVE")
  78.     f2.write(b"\x00"*0x228)
  79.  
  80.     # Add license mask.
  81.     data=struct.pack(">qii",-1,licenseMask,1)
  82.     f2.write(data)
  83.     data=struct.pack(">qii",-1,licenseMask,0)
  84.     f2.write(data)
  85.    
  86.     f2.close()
  87.  
  88.     # Write data files.
  89.     outdir=outpath+".data"
  90.     os.makedirs(outdir,exist_ok=True)
  91.     writtenSize=0
  92.  
  93.     for i in range(numDataFiles):
  94.         outpath=os.path.join(outdir,"Data%04d" % (i))
  95.         print(outpath)
  96.         f2=open(outpath,"wb")
  97.         if extraData: f2.write(extraData)
  98.         extraData=decompressPayload(f,f2,0xa290000,fsize)
  99.         writtenSize+=f2.tell()
  100.         f2.close()
  101.  
  102.         if writtenSize==totalDataSize:
  103.             break
  104.  
  105.     f.close()
  106.  
  107. if __name__=="__main__":
  108.     contentDir=sys.argv[2] if len(sys.argv)>2 else "content"
  109.     licenseMask=sys.argv[3] if len(sys.argv)>3 else 0
  110.     extractGODXCP(sys.argv[1],contentDir,licenseMask)
  111.  
Advertisement
Add Comment
Please, Sign In to add comment