Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import os
- import sys
- #Constants taken from insani tools.
- LITTLE_ENDIAN = 1
- BIG_ENDIAN = -1
- BYTE_LENGTH = 1
- SHORT_LENGTH = 2
- INT_LENGTH = 4
- LONG_LENGTH = 8
- ERROR_NONE = 0
- ERROR_WARNING = 1
- ERROR_ABORT = 2
- def assert_string(infile, value, severity = ERROR_NONE) :
- # Checks to see that the file has the given string at the current location.
- # Advances the file position past the end of the string. Returns true if
- # assertion succeeds, false otherwise, and optionally prints a warning and
- # aborts via raising an exception on failure.
- actual = infile.read(len(value))
- if actual != value :
- if severity != ERROR_NONE :
- print 'Expected "%s" at position 0x%X but saw "%s".' % \
- (escape_string(value),infile.tell()-len(actual),escape_string(actual))
- if severity == ERROR_ABORT :
- print 'Aborting!'
- raise 'assert_string'
- return False
- else :
- return True
- #m twist stuff. Note that this has been modified from the standard.
- _N = 0x270
- M = 0x18D
- #MATRIX_A = 0x9908B0DF #/* constant vector a */
- MATRIX_A = 0x9908D0BF #/* constant vector a */
- UPPER_MASK = 0x80000000 #/* most significant w-r bits */
- LOWER_MASK = 0x7fffffff #/* least significant r bits */
- #ogg correction. Maybe needed on other types...
- mt = [0] * _N; #/* the array for the state vector */
- mti = _N+1; #/* mti==_N+1 means mt[_N] is not initialized */
- #m twist functions
- def srand(s):
- global mti
- mt[0] = s & 0xffffffff
- mti = 1
- while (mti<_N):
- mt[mti] = (0x6C078965 * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti)
- #/* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
- #/* In the previous versions, MSBs of the seed affect */
- #/* only MSBs of the array mt[]. */
- #/* 2002/01/09 modified by Makoto Matsumoto */
- mt[mti] &= 0xffffffff;
- #/* for >32 bit machines */
- mti += 1
- def rand():
- global mti
- mag01 = [0x0, MATRIX_A]
- #/* mag01[x] = x * MATRIX_A for x=0,1 */
- if (mti >= _N): #/* generate _N words at one time */
- if (mti == _N+1): #/* if init_genrand() has not been called, */
- srand(0x1571) #/* a default initial seed is used */
- kk = 0
- while (kk<_N-M):
- y = ((mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK) )
- mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1]
- kk += 1
- while (kk<_N-1):
- y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK)
- mt[kk] = mt[kk+(M-_N)] ^ (y >> 1) ^ mag01[y & 0x1]
- kk += 1
- y = ((mt[_N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK) & 0xFFFFFFFF)
- mt[_N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1]
- mti = 0
- y = mt[mti]
- mti += 1
- #/* Tempering */
- #y ^= (y >> 11) & 0xFFFFFFFF
- #y ^= ((y & 0xFF3A58AD) << 7) & 0xFFFFFFFF
- #y ^= ((y & 0xFFFFDF8C) << 15) & 0xFFFFFFFF
- #y ^= (y >> 18) & 0xFFFFFFFF
- y ^= (y >> 11)
- y ^= ((y << 7) & 0x9d2c5680)
- y ^= ((y << 15) & 0xefc60000)
- y ^= (y >> 18)
- return y
- def readbytes(infile, bytecount):
- ret = ""
- offset = 0
- while (offset < bytecount):
- byte = long(ord(infile.read(1)))
- key = rand()&0xFF
- byte ^= key
- ret += chr(byte)
- offset += 1
- return ret
- def readsimplebytes(infile, bytecount, xorkey):
- ret = ""
- offset = 0
- while (offset < bytecount):
- byte = long(ord(infile.read(1)))
- byte ^= xorkey
- ret += chr(byte)
- offset += 1
- return ret
- def converttoint(bytes, size=INT_LENGTH, endian=LITTLE_ENDIAN):
- result = 0
- for i in xrange(size):
- temp=long(ord(bytes[i]))
- if endian == LITTLE_ENDIAN :
- result |= (temp << (8*i))
- elif endian == BIG_ENDIAN :
- result = (result << 8) | temp
- else :
- raise 'converttoint', 'Unknown endian specification'
- return result
- def convertfromint(value, size=INT_LENGTH, endian=LITTLE_ENDIAN):
- result = ""
- for i in xrange(size):
- if endian == LITTLE_ENDIAN :
- #result |= (temp << (8*i))
- temp = (value >> (8*i)) & 0x00FF
- elif endian == BIG_ENDIAN :
- #result = (result << 8) | temp
- temp = (value >> (8*(size-i-1))) & 0x00FF
- else :
- raise 'convertfromint', 'Unknown endian specification'
- result += chr(temp)
- return result
- def fixPNG(data, filekey, correctionsize):
- #First the header
- data = '\x89PNG' + data[4:]
- datalist = list(data)
- for i in xrange(len(data)-correctionsize):
- datalist[i+correctionsize] = chr(ord(datalist[i+correctionsize]) ^ filekey)
- return "".join(datalist)
- #program
- files = sys.argv[1:]
- for filename in files:
- infile = open(filename, 'rb')
- assert_string(infile, "TZF\x00\x03\x01", ERROR_WARNING)
- srand(0)
- filekey = converttoint(readbytes(infile, 1), 1)
- indexkey = converttoint(readbytes(infile, 1), 1)
- zero = converttoint(readbytes(infile, 4), 4)
- filecount = converttoint(readbytes(infile, 4), 4)
- print "Found", filecount, "files in archive", filename
- srand(indexkey)
- print 'Index key:', indexkey, 'File key:', filekey
- dirname = filename[0:filename.find(".")]
- if not os.path.isdir(dirname):
- os.mkdir(dirname)
- correctionsize = 99999999
- extension = 'file'
- if (dirname == 'moe01'):
- correctionsize = 90
- extension = 'png'
- elif dirname == 'moe05':
- correctionsize = 125
- extension = 'png'
- elif (dirname == 'moe02'):
- extension = 'wav'
- elif (dirname == 'moe03'):
- extension = 'ogg'
- elif (dirname == 'moe04'):
- extension = 'lua'
- #extension = 'png'
- indices = []
- for i in xrange(filecount):
- indexraw = readbytes(infile, 0x30)
- indexrawlist = list(indexraw)
- for k in xrange(0x20):
- indexrawlist[k] = chr( ord(indexrawlist[k]) ^ 0xD5)
- indexraw = "".join(indexrawlist)
- index = {}
- index['unk1'] = converttoint(indexraw[0:4], 4)
- index['unk2'] = converttoint(indexraw[4:8], 4)
- index['unk3'] = converttoint(indexraw[8:12], 4)
- index['const'] = indexraw[12:32]
- index['realsize'] = converttoint(indexraw[32:36], 4)
- index['filesize'] = converttoint(indexraw[36:40], 4)
- index['filestart'] = converttoint(indexraw[40:44], 4)
- index['unk4'] = converttoint(indexraw[44:48], 4)
- print "File %04d: Size %08X (%08X) starting at %08X" % (i, index['filesize'], index['realsize'], index['filestart'])
- print "\tOther values: %08X, %08X, %08X, %08X" % (index['unk1'], index['unk2'], index['unk3'], index['unk4'])
- print ""
- position = infile.tell()
- infile.seek(index['filestart'])
- filedata = readsimplebytes(infile, index['realsize'], filekey)
- infile.seek(position)
- if (extension == 'ogg'):
- filedata = 'OggS' + filedata[4:]
- elif (extension == 'png'):
- filedata = fixPNG(filedata, filekey, correctionsize)
- outfile = open(dirname + '\\' + "%04d.%s" % (i, extension), 'wb')
- outfile.write(filedata)
- outfile.close()
- #print "Current position is", infile.tell()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement