Skip to content

Instantly share code, notes, and snippets.

@lardratboy
Created November 23, 2024 01:36
Show Gist options
  • Save lardratboy/ba712f13cc018095cf86c12771f9558e to your computer and use it in GitHub Desktop.
Save lardratboy/ba712f13cc018095cf86c12771f9558e to your computer and use it in GitHub Desktop.
import io, struct, argparse
class Chunk:
def __init__(self, id):
self.id = id
self.children = []
def process_chunk( input, parent_chunk, remaining_data, depth = 0 ):
if None != parent_chunk.id and not parent_chunk.id in [ 'MULT', 'WRAP', 'TALK', 'TLKB', 'LECF', 'LFLF', 'SONG', 'NEST', 'SOUN', 'DIGI', 'AKOS', 'AWIZ' ]:
input.seek( input.tell() + remaining_data )
print( ' ' * depth + f'{parent_chunk.id} size={remaining_data}' )
return
print( ' ' * depth + f'processing {parent_chunk.id}' )
while 0 < remaining_data:
id = input.read( 4 ).decode( 'ascii' )
size = struct.unpack( '>I', input.read( 4 ))[0]
chunk = Chunk( id )
parent_chunk.children.append( chunk )
process_chunk( input, chunk, size - 8, depth + 1 )
remaining_data -= size
def parse_chunks_for_file( filename, xor_key = None ):
with open(filename,'rb') as f: raw_data = f.read()
if xor_key: raw_data = bytes( a ^ xor_key for a in raw_data )
input = io.BytesIO( raw_data )
root_chunk = Chunk( None )
process_chunk( input, root_chunk, len( raw_data ) )
return root_chunk
def main():
parser = argparse.ArgumentParser( description='dump humongous chunks' )
parser.add_argument( 'filename', help='filename' )
parser.add_argument( '-x', '--xor', type=int, default=None, help='xor decryption key (use 105)')
args = parser.parse_args()
file_chunks = parse_chunks_for_file( args.filename, xor_key=args.xor )
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment