Advertisement
Lavos

Inotoridori no Sekai

Aug 27th, 2014
216
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.55 KB | None | 0 0
  1. import struct,os,sys,re
  2.  
  3. opcodes = [
  4.             [0x1,'0x1',['b','b',]],[0x2,'call',['d',]],[0x3,'0x3',['w',]],[0x4,'0x4-return',[]],
  5.             [0x5,'0x5',[]],[0x6,'0x6-condjump',['d']],
  6.             [0x7,'0x7-condjump',['d']],[0x8,'0x8',[]],[0x9,'0x9',[]],
  7.             [0xa,'0xa',['d',]],[0xb,'0xb',['w',]],[0xc,'0xc',['b',]],[0xe,'string',['str']],
  8.             [0xf,'0xf',['w',]],[0x10,'0x10',['b',]],[0x11,'0x11',['w',]],[0x12,'0x12',['b',]],
  9.             [0x14,'0x14',[]],[0x15,'0x15',['w',]],[0x16,'0x16',['b',]],
  10.             [0x17,'0x17',['w',]],[0x18,'0x18',['b']],[0x19,'0x19',[]],
  11.             [0x1a,'0x1a',[]],[0x1b,'0x1b',[]],[0x1c,'0x1c',[]],[0x1d,'0x1d',[]],[0x1e,'0x1e',[]],
  12.             [0x1f,'0x1f',[]],[0x20,'0x20',[]],[0x21,'0x21',[]],
  13.             [0x22,'0x22',[]],[0x23,'0x23',[]],[0x24,'0x24',[]],
  14.             [0x25,'0x25',[]],[0x26,'0x26',[]],[0x27,'0x27',[]],
  15.           ]
  16.  
  17. def get_data(filename):
  18.     totalbytes = os.path.getsize(filename)
  19.     infile = open(filename, 'rb')
  20.     totalfiledata = infile.read(totalbytes)
  21.     return totalfiledata
  22.  
  23. def extract(filename):
  24.     filedata = bytearray(open(filename,'rb').read())
  25.     newfiledata = '====== Script ======\n\n==== Function 0 ====\n\n'
  26.     endpos = struct.unpack('<I',filedata[0:4])[0]
  27.     pos = 4
  28.     funccount = 1
  29.     opcodecount = 0
  30.     jumplocs = {}
  31.  
  32.     print 'Extracting...'
  33.    
  34.     while pos < endpos:
  35.         opcode = struct.unpack('<B',filedata[pos:pos+1])[0]
  36.        
  37.         c = 0
  38.         while c != len(opcodes):
  39.             if opcodes[c][0] == opcode:
  40.                 name = opcodes[c][1]
  41.                 params = opcodes[c][2]
  42.                 break;
  43.             if c+1 == len(opcodes):
  44.                 print 'Unknown opcode %x at loc %x' % (opcode,pos)
  45.                 outfile = open('out.txt','wb')
  46.                 outfile.write(newfiledata)
  47.                 outfile.close()
  48.                 sys.exit()
  49.             c += 1
  50.  
  51.         newfiledata += ('%x :: ' % pos) + '{ ' + name + ' '
  52.         pos += 1
  53.  
  54.         for a in xrange(0,len(params)):
  55.             if params[a] == 'b':
  56.                 var = struct.unpack('<B',filedata[pos:pos+1])[0]
  57.                 newfiledata += '%x ' % var
  58.                 pos += 1
  59.             elif params[a] == 'w':
  60.                 var = struct.unpack('<H',filedata[pos:pos+2])[0]
  61.                 newfiledata += '%x ' % var
  62.                 pos += 2
  63.             elif params[a] == 'd':
  64.                 var = struct.unpack('<I',filedata[pos:pos+4])[0]
  65.                 newfiledata += '%x ' % var
  66.                 pos += 4
  67.             elif params[a] == 'str':
  68.                 strlen = struct.unpack('<B',filedata[pos:pos+1])[0]
  69.                 newfiledata += '"' + filedata[pos+1:pos+1+strlen-1] + '" '
  70.                 pos += strlen+1
  71.  
  72.         newfiledata += '}\n'
  73.  
  74.         if opcode == 0x4 and struct.unpack('<B',filedata[pos:pos+1])[0] != 0x4 and pos < endpos:
  75.             newfiledata += '\n==== Function %d ====\n\n' % funccount
  76.             if pos == struct.unpack('<I',filedata[endpos:endpos+4])[0]:
  77.                 newfiledata = newfiledata[:-1] + '### Main Script Start ###\n\n'
  78.             funccount += 1
  79.         opcodecount += 1
  80.  
  81.     pos += 4
  82.     newfiledata += '\n\n====== Extra ======\n### Do not edit below this point ###\n%x %x %x %x %x %x\n\n==== Strings ====\n\n' % (filedata[pos],filedata[pos+1],filedata[pos+2],filedata[pos+3],filedata[pos+4],filedata[pos+5])
  83.     newfiledata += '%s\n' % (filedata[pos+7:pos+7+struct.unpack('<B',filedata[pos+6:pos+7])[0]-1])
  84.     strcnt = struct.unpack('<B',filedata[pos+0x2b:pos+0x2c])[0]
  85.     pos += 0x2d
  86.     for i in xrange(0,strcnt):
  87.         strlen = struct.unpack('<B',filedata[pos+1:pos+2])[0]
  88.         newfiledata += '%s - %d\n' % (filedata[pos+2:pos+2+strlen-1],struct.unpack('<B',filedata[pos:pos+1])[0])
  89.         pos += 2 + strlen
  90.            
  91.        
  92.     outfile = open(filename + '.txt','wb')
  93.     outfile.write(newfiledata)
  94.     outfile.close()
  95.  
  96.     print 'Done!'
  97.  
  98. def comp(filename):
  99.     filedata = get_data(filename)
  100.     newfiledata = ''
  101.     newfiledata += struct.pack('<I',0x0)
  102.     data = re.split('(======.+?======)',filedata)
  103.     script = data[2].splitlines()
  104.     lastpos = -1
  105.  
  106.     origlocs = {}
  107.     fixlocs = []
  108.  
  109.     print 'Compiling...'
  110.  
  111.     for i in xrange(0,len(script)):
  112.         line = re.findall(r'(?:[^\s,"]|"(?:\\.|[^"])*")+',script[i])
  113.         if len(line) > 0:
  114.             if line[0] != '' and line[0] != '====':
  115.                 if line[0] == '###' and line[1] == 'Main' and line[2] == 'Script':
  116.                     scriptstart = len(newfiledata)
  117.                 else:
  118.                     newloc = False
  119.                     if line[1] == '::':
  120.                         origlocs[int(line[0],16)] = len(newfiledata)
  121.                         line.pop(0)
  122.                         line.pop(0)
  123.                     else:
  124.                         newloc = True
  125.                        
  126.                     line.pop(0)
  127.                     line.pop(len(line)-1)
  128.                    
  129.                     c = 0
  130.                     while c < len(opcodes):
  131.                         if opcodes[c][1] == line[0]:
  132.                             newfiledata += struct.pack('<B',opcodes[c][0])
  133.                             params = opcodes[c][2]
  134.                             break;
  135.                         if c+1 == len(opcodes):
  136.                             print 'Unknown opcode %s on line %d' % (line[0],i)
  137.                             sys.exit()
  138.                         c += 1
  139.                     line.pop(0)
  140.                    
  141.                     varsmoved = 0
  142.                     for a in xrange(0,len(params)):
  143.                         if params[a] == 'b':
  144.                             newfiledata += struct.pack('<B',int(line[a],16))
  145.                         elif params[a] == 'w':
  146.                             newfiledata += struct.pack('<H',int(line[a],16))
  147.                         elif params[a] == 'd':
  148.                             if opcodes[c][0] == 0x2 or opcodes[c][0] == 0x6 or opcodes[c][0] == 0x7 and varsmoved == 0:
  149.                                 fixlocs.append([len(newfiledata),int(line[a],16)])
  150.                                 newfiledata += struct.pack('<I',0x0)
  151.                             else:
  152.                                 newfiledata += struct.pack('<I',int(line[a],16))
  153.                         elif params[a] == 'str':
  154.                             line[a] = line[a][1:-1]
  155.                             newfiledata += struct.pack('<B',len(line[a])+1)
  156.                             newfiledata += line[a] + '\x00'
  157.                         else:
  158.                             print 'param error'
  159.                             sys.exit()
  160.                         varsmoved += 1
  161.  
  162.     for i in range(0,len(fixlocs)):
  163.         if fixlocs[i][1] not in origlocs:
  164.             print 'bad loc fixlocs[i][1]'
  165.             sys.exit()
  166.         loc = origlocs[fixlocs[i][1]]
  167.         newfiledata = newfiledata[:fixlocs[i][0]] + struct.pack('<I',loc) + newfiledata[fixlocs[i][0]+0x4:]
  168.  
  169.     newfiledata = struct.pack('<I',len(newfiledata)) + newfiledata[0x4:] + struct.pack('<I',scriptstart)
  170.        
  171.     extralines = data[4].splitlines()
  172.     linesmoved = 0
  173.     strcnt = 0
  174.     for i in xrange(0,len(extralines)):
  175.         if extralines[i].find('===') == -1 and extralines[i].find('###') == -1 and extralines[i] != '':
  176.             if extralines[i].find('-') != -1:
  177.                 line = extralines[i].split('-')
  178.                 newfiledata += struct.pack('<B',int(line[1])) + struct.pack('<B',len(line[0])) + line[0][:-1] + '\x00'
  179.                 strcnt += 1
  180.             else:
  181.                 line = extralines[i].split(' ')
  182.                 if linesmoved == 0:
  183.                     for a in range(0,len(line)):
  184.                         newfiledata += struct.pack('<B',int(line[a],16))
  185.                     linesmoved += 1
  186.                 else:
  187.                     newfiledata += struct.pack('<B',len(line[0])+len(line[1])+2) + line[0] + ' ' + line[1] + '\x00'
  188.                     fixloc = len(newfiledata)
  189.                     newfiledata += struct.pack('<H',0x0)
  190.     newfiledata = newfiledata[:fixloc] + struct.pack('<B',strcnt) + newfiledata[fixloc+1:]
  191.     newfiledata += '\x00\x00'
  192.  
  193.     print 'Done!'
  194.        
  195.     outfile = open(filename.rsplit('.',1)[0] + '.new','wb')
  196.     outfile.write(newfiledata)
  197.     outfile.close()
  198.  
  199. if __name__ == '__main__':
  200.     if sys.argv[1] == '-e':
  201.         extract(sys.argv[2])
  202.     elif sys.argv[1] == '-c':
  203.         comp(sys.argv[2])
  204.     else:
  205.         print 'usage: script.py <-e/-c> <filename>'
  206.         print '-e - extract'
  207.         print '-c - compile'
  208.         sys.exit()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement