Advertisement
qazmlpok

moedan extract

May 15th, 2012
118
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.64 KB | None | 0 0
  1. import os
  2. import sys
  3.  
  4. #Constants taken from insani tools.
  5. LITTLE_ENDIAN = 1
  6. BIG_ENDIAN = -1
  7.  
  8. BYTE_LENGTH = 1
  9. SHORT_LENGTH = 2
  10. INT_LENGTH = 4
  11. LONG_LENGTH = 8
  12.  
  13. ERROR_NONE = 0
  14. ERROR_WARNING = 1
  15. ERROR_ABORT = 2
  16.  
  17. def assert_string(infile, value, severity = ERROR_NONE) :
  18. # Checks to see that the file has the given string at the current location.
  19. # Advances the file position past the end of the string.  Returns true if
  20. # assertion succeeds, false otherwise, and optionally prints a warning and
  21. # aborts via raising an exception on failure.
  22.  
  23.    actual = infile.read(len(value))
  24.    if actual != value :
  25.       if severity != ERROR_NONE :
  26.          print 'Expected "%s" at position 0x%X but saw "%s".' % \
  27.           (escape_string(value),infile.tell()-len(actual),escape_string(actual))
  28.       if severity == ERROR_ABORT :
  29.          print 'Aborting!'
  30.          raise 'assert_string'
  31.       return False
  32.    else :
  33.       return True
  34.  
  35. #m twist stuff. Note that this has been modified from the standard.
  36. _N = 0x270
  37. M = 0x18D
  38. #MATRIX_A = 0x9908B0DF   #/* constant vector a */
  39. MATRIX_A = 0x9908D0BF   #/* constant vector a */
  40. UPPER_MASK = 0x80000000 #/* most significant w-r bits */
  41. LOWER_MASK = 0x7fffffff #/* least significant r bits */
  42.  
  43. #ogg correction. Maybe needed on other types...
  44.  
  45. mt = [0] * _N; #/* the array for the state vector  */
  46. mti = _N+1; #/* mti==_N+1 means mt[_N] is not initialized */
  47. #m twist functions
  48.  
  49. def srand(s):
  50.     global mti
  51.  
  52.     mt[0] = s & 0xffffffff
  53.     mti = 1
  54.     while (mti<_N):
  55.         mt[mti] = (0x6C078965 * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti)
  56.         #/* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
  57.         #/* In the previous versions, MSBs of the seed affect   */
  58.         #/* only MSBs of the array mt[].                        */
  59.         #/* 2002/01/09 modified by Makoto Matsumoto             */
  60.         mt[mti] &= 0xffffffff;
  61.         #/* for >32 bit machines */
  62.         mti += 1
  63.  
  64.  
  65. def rand():
  66.     global mti
  67.  
  68.     mag01 = [0x0, MATRIX_A]
  69.     #/* mag01[x] = x * MATRIX_A  for x=0,1 */
  70.  
  71.     if (mti >= _N): #/* generate _N words at one time */
  72.  
  73.         if (mti == _N+1):   #/* if init_genrand() has not been called, */
  74.             srand(0x1571) #/* a default initial seed is used */
  75.  
  76.         kk = 0
  77.         while (kk<_N-M):
  78.             y = ((mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK) )
  79.             mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1]
  80.             kk += 1
  81.  
  82.         while (kk<_N-1):
  83.             y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK)
  84.             mt[kk] = mt[kk+(M-_N)] ^ (y >> 1) ^ mag01[y & 0x1]
  85.             kk += 1
  86.  
  87.         y = ((mt[_N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK) & 0xFFFFFFFF)
  88.         mt[_N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1]
  89.  
  90.         mti = 0
  91.  
  92.     y = mt[mti]
  93.     mti += 1
  94.  
  95.     #/* Tempering */
  96.     #y ^= (y >> 11) & 0xFFFFFFFF
  97.     #y ^= ((y & 0xFF3A58AD) << 7) & 0xFFFFFFFF
  98.     #y ^= ((y & 0xFFFFDF8C) << 15) & 0xFFFFFFFF
  99.     #y ^= (y >> 18) & 0xFFFFFFFF
  100.  
  101.     y ^= (y >> 11)
  102.     y ^= ((y << 7) & 0x9d2c5680)
  103.     y ^= ((y << 15) & 0xefc60000)
  104.     y ^= (y >> 18)
  105.  
  106.     return y
  107.  
  108. def readbytes(infile, bytecount):
  109.     ret = ""
  110.     offset = 0
  111.     while (offset < bytecount):
  112.         byte = long(ord(infile.read(1)))
  113.  
  114.         key = rand()&0xFF
  115.         byte ^= key
  116.  
  117.         ret += chr(byte)
  118.  
  119.         offset += 1
  120.  
  121.     return ret
  122.  
  123. def readsimplebytes(infile, bytecount, xorkey):
  124.     ret = ""
  125.     offset = 0
  126.     while (offset < bytecount):
  127.         byte = long(ord(infile.read(1)))
  128.  
  129.         byte ^= xorkey
  130.  
  131.         ret += chr(byte)
  132.  
  133.         offset += 1
  134.  
  135.     return ret
  136.  
  137. def converttoint(bytes, size=INT_LENGTH, endian=LITTLE_ENDIAN):
  138.     result = 0
  139.     for i in xrange(size):
  140.         temp=long(ord(bytes[i]))
  141.         if endian == LITTLE_ENDIAN :
  142.             result |= (temp << (8*i))
  143.         elif endian == BIG_ENDIAN :
  144.             result = (result << 8) | temp
  145.         else :
  146.                 raise 'converttoint', 'Unknown endian specification'
  147.  
  148.         return result
  149.  
  150. def convertfromint(value, size=INT_LENGTH, endian=LITTLE_ENDIAN):
  151.     result = ""
  152.     for i in xrange(size):
  153.         if endian == LITTLE_ENDIAN :
  154.             #result |= (temp << (8*i))
  155.             temp = (value >> (8*i)) & 0x00FF
  156.         elif endian == BIG_ENDIAN :
  157.             #result = (result << 8) | temp
  158.             temp = (value >> (8*(size-i-1))) & 0x00FF
  159.         else :
  160.                 raise 'convertfromint', 'Unknown endian specification'
  161.             result += chr(temp)
  162.  
  163.         return result
  164.  
  165. def fixPNG(data, filekey, correctionsize):
  166.     #First the header
  167.     data = '\x89PNG' + data[4:]
  168.  
  169.     datalist = list(data)
  170.     for i in xrange(len(data)-correctionsize):
  171.         datalist[i+correctionsize] = chr(ord(datalist[i+correctionsize]) ^ filekey)
  172.  
  173.     return "".join(datalist)
  174.  
  175.  
  176. #program
  177.  
  178. files = sys.argv[1:]
  179. for filename in files:
  180.     infile = open(filename, 'rb')
  181.     assert_string(infile, "TZF\x00\x03\x01", ERROR_WARNING)
  182.  
  183.     srand(0)
  184.  
  185.     filekey = converttoint(readbytes(infile, 1), 1)
  186.     indexkey = converttoint(readbytes(infile, 1), 1)
  187.  
  188.     zero = converttoint(readbytes(infile, 4), 4)
  189.     filecount = converttoint(readbytes(infile, 4), 4)
  190.  
  191.     print "Found", filecount, "files in archive", filename
  192.  
  193.     srand(indexkey)
  194.     print 'Index key:', indexkey, 'File key:', filekey
  195.  
  196.     dirname = filename[0:filename.find(".")]
  197.     if not os.path.isdir(dirname):
  198.         os.mkdir(dirname)
  199.  
  200.     correctionsize = 99999999
  201.     extension = 'file'
  202.     if (dirname == 'moe01'):
  203.         correctionsize = 90
  204.         extension = 'png'
  205.     elif dirname == 'moe05':
  206.         correctionsize = 125
  207.         extension = 'png'
  208.     elif (dirname == 'moe02'):
  209.         extension = 'wav'
  210.     elif (dirname == 'moe03'):
  211.         extension = 'ogg'
  212.     elif (dirname == 'moe04'):
  213.         extension = 'lua'
  214.         #extension = 'png'
  215.  
  216.     indices = []
  217.     for i in xrange(filecount):
  218.         indexraw = readbytes(infile, 0x30)
  219.  
  220.         indexrawlist = list(indexraw)
  221.         for k in xrange(0x20):
  222.             indexrawlist[k] = chr( ord(indexrawlist[k]) ^ 0xD5)
  223.  
  224.         indexraw = "".join(indexrawlist)
  225.  
  226.         index = {}
  227.         index['unk1'] = converttoint(indexraw[0:4], 4)
  228.         index['unk2'] = converttoint(indexraw[4:8], 4)
  229.         index['unk3'] = converttoint(indexraw[8:12], 4)
  230.         index['const'] = indexraw[12:32]
  231.         index['realsize'] = converttoint(indexraw[32:36], 4)
  232.         index['filesize'] = converttoint(indexraw[36:40], 4)
  233.         index['filestart'] = converttoint(indexraw[40:44], 4)
  234.         index['unk4'] = converttoint(indexraw[44:48], 4)
  235.  
  236.         print "File %04d:  Size %08X (%08X) starting at %08X" % (i, index['filesize'], index['realsize'], index['filestart'])
  237.         print "\tOther values: %08X, %08X, %08X, %08X" % (index['unk1'], index['unk2'], index['unk3'], index['unk4'])
  238.         print ""
  239.  
  240.         position = infile.tell()
  241.         infile.seek(index['filestart'])
  242.         filedata = readsimplebytes(infile, index['realsize'], filekey)
  243.         infile.seek(position)
  244.  
  245.         if (extension == 'ogg'):
  246.             filedata = 'OggS' + filedata[4:]
  247.         elif (extension == 'png'):
  248.             filedata = fixPNG(filedata, filekey, correctionsize)
  249.  
  250.         outfile = open(dirname + '\\' + "%04d.%s" % (i, extension), 'wb')
  251.         outfile.write(filedata)
  252.         outfile.close()
  253.  
  254.     #print "Current position is", infile.tell()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement