Advertisement
Nicknine

X360 GoD XCP Unpacker

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