Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import struct,os,sys,tarfile,StringIO
- opcodes = [
- [0x0,'0x0',0],[0x1,'0x1',0],[0x2,'0x2',1],[0x3,'string',1],[0x4,'0x4',1],[0x5,'0x5',1],
- [0x6,'0x6',0],[0x8,'jump-0x8',1],[0x9,'jump-0x9',1],
- [0xd,'call-0xd',2],[0xe,'0xe',2],[0xf,'return',0],
- [0x10,'0x10',0],[0x11,'0x11',0],[0x12,'0x12',1],
- [0x13,'0x13',1],[0x14,'0x14',1],[0x2c,'0x2c',1],
- [0x3c,'0x3c',0],[0x3d,'0x3d',0],[0x3e,'0x3e',0],[0x40,'0x40',0],[0x41,'0x41',0],[0x43,'0x43',0],[0x45,'0x45',0],
- #unchecked
- [0x2e,'0x2e',1],[0x30,'0x30',0],[0x31,'0x31',0],[0x32,'0x32',0],[0x33,'0x33',0],[0x34,'0x34',0],[0x36,'0x36',0],
- [0x3f,'0x3f',0],[0x44,'0x44',0],
- ]
- def get_data(filename):
- totalbytes = os.path.getsize(filename)
- infile = open(filename, 'rb')
- totalfiledata = infile.read(totalbytes)
- return totalfiledata
- def extract(filename,typea):
- filedata = get_data(filename)
- newfiledata = ''
- i = 0
- while i < len(filedata):
- opcode = struct.unpack('<I',filedata[i:i+4])[0]
- if opcode >= 0x100:
- break;
- c = 0
- while c != len(opcodes):
- if opcodes[c][0] == opcode:
- variablecount = opcodes[c][2]
- name = opcodes[c][1]
- break;
- if c+1 == len(opcodes):
- print 'Unknown opcode: %x at loc: %x' % (opcode,i)
- outfile = open('out.txt','wb')
- outfile.write(newfiledata)
- outfile.close()
- sys.exit()
- c += 1
- newfiledata += ('%x::' % i) + name + ' { '
- varsmoved = 0
- i += 4
- for a in xrange(0,variablecount):
- var = struct.unpack('<I',filedata[i:i+4])[0]
- if opcode == 0x3:
- string = filedata[var*0x4:filedata.find('\x00',var*0x4)]
- newfiledata += '/////////////////////////////////////\n' + string + '\n///////////////////////////////////////////////////'
- elif opcode == 0x8:
- newfiledata += '%x ' % (var*0x4)
- elif opcode == 0x9:
- newfiledata += '%x ' % (var*0x4)
- elif opcode == 0xd and varsmoved == 1:
- newfiledata += '%x ' % (var*0x4)
- else:
- newfiledata += '%x ' % var
- varsmoved += 1
- i += 4
- newfiledata += '}\n'
- if opcode == 0xf:
- newfiledata += '\n'
- if typea == '-e2':
- outfile = open('Scripts\\' + filename.rsplit('\\',2)[1] + '\\' + filename.rsplit('\\',1)[1] + '.txt','wb')
- else:
- outfile = open(filename + '.txt','wb')
- outfile.write(newfiledata)
- outfile.close()
- def compiled(filename,typea):
- filedata = get_data(filename).splitlines()
- newfiledata = ''
- newstrings = ''
- stringlocs = []
- fixjumplocs = {}
- alllocs = {}
- i = 0
- while i < len(filedata):
- if filedata[i] != '':
- newline = False
- try:
- line = filedata[i].split('::')[1].split(' ')
- except Exception:
- newline = True
- line = filedata[i].split(' ')
- c = 0
- while c != len(opcodes):
- if opcodes[c][1] == line[0]:
- variablecount = opcodes[c][2]
- opcode = opcodes[c][0]
- if newline == True:
- alllocs[len(newfiledata) / 0x4] = (len(newfiledata) / 0x4)
- else:
- alllocs[int(filedata[i].split('::')[0],16) / 0x4] = (len(newfiledata) / 0x4)
- break;
- if c+1 == len(opcodes):
- print 'Unknown opcode: %s on line: %d' % (line[0],i)
- outfile = open('out.data','wb')
- outfile.write(newfiledata)
- outfile.close()
- sys.exit()
- c += 1
- newfiledata += struct.pack('<I',opcode)
- line.pop(0)
- line.pop(0)
- line.pop(len(line)-1)
- for a in xrange(0,variablecount):
- if opcode == 0x3:
- i += 1
- line = filedata[i]
- newstring = ''
- if line.find('/////') == -1:
- while i < len(filedata):
- newstring += line
- i += 1
- line = filedata[i]
- if line.find('/////') != -1:
- break;
- else:
- newstring += '\n'
- if newstring == '' or len(newstring) % 0x4 == 0:
- newstring += '\x00\x00\x00\x00'
- while len(newstring) % 0x4 != 0:
- newstring += '\x00'
- stringlocs.append([len(newfiledata),newstring])
- newfiledata += struct.pack('<I',0x0) # fix later
- else:
- var = int(line[a],16)
- if opcode == 0x8:
- #var /= 0x4
- fixjumplocs[len(newfiledata)] = var / 0x4
- newfiledata += struct.pack('<I',0) # fix later
- elif opcode == 0x9:
- #var /= 0x4
- fixjumplocs[len(newfiledata)] = var / 0x4
- newfiledata += struct.pack('<I',0) # fix later
- elif opcode == 0xd and a == 1:
- #var /= 0x4
- fixjumplocs[len(newfiledata)] = var / 0x4
- newfiledata += struct.pack('<I',0) # fix later
- else:
- newfiledata += struct.pack('<I',var)
- i += 1
- #fix jump locs
- for filedataloc,jumploc in fixjumplocs.iteritems():
- jumploctmp = alllocs[jumploc]
- newfiledata = newfiledata[:filedataloc] + struct.pack('<I',jumploctmp) + newfiledata[filedataloc+0x4:]
- #fix string locs
- for i in xrange(0,len(stringlocs)):
- newfiledata = newfiledata[:stringlocs[i][0]] + struct.pack('<I',len(newfiledata) / 0x4) + newfiledata[stringlocs[i][0]+0x4:]
- newfiledata += stringlocs[i][1]
- if typea == '-c1':
- outfile = open(filename.rsplit('.',1)[0],'wb')
- outfile.write(newfiledata)
- outfile.close()
- else:
- return newfiledata
- def unpackscripts(filename):
- tf = tarfile.TarFile(sys.argv[2] + '\\' + filename)
- members = tf.getmembers()
- if not os.path.exists('Unpacked\\' + filename[:-4]):
- os.mkdir('Unpacked\\' + filename[:-4])
- for member in members:
- tf.extract(member, 'Unpacked\\' + filename[:-4])
- if __name__ == '__main__':
- if sys.argv[1] == '-e1':
- extract(sys.argv[2],'-e1')
- elif sys.argv[1] == '-e2':
- if not os.path.exists('Scripts'):
- os.mkdir('Scripts')
- for root, dirs, files in os.walk(sys.argv[2]):
- try:
- print 'Extracting %s' % os.path.join(root).rsplit('\\',1)[1]
- except Exception:
- continue;
- for filename in files:
- if filename.find('.ssb') != -1:
- if not os.path.exists('Scripts\\' + os.path.join(root).rsplit('\\',1)[1]):
- os.mkdir('Scripts\\' + os.path.join(root).rsplit('\\',1)[1])
- extract(os.path.join(root, filename),'-e2')
- elif sys.argv[1] == '-c1':
- compiled(sys.argv[2],'-c1')
- elif sys.argv[1] == '-c2':
- if not os.path.exists('Compiled'):
- os.mkdir('Compiled')
- for root, dirs, files in os.walk(sys.argv[2]):
- try:
- print 'Compiling %s' % os.path.join(root).rsplit('\\',1)[1]
- except Exception:
- continue;
- tf = tarfile.open('Compiled\\' + os.path.join(root).rsplit('\\',1)[1] + '.TAR','w')
- for filename in files:
- if filename.find('.txt') != -1:
- filedata = StringIO.StringIO(compiled(os.path.join(root, filename),'-c2'))
- info = tarfile.TarInfo(name=filename)
- info.size = len(filedata.buf)
- tf.addfile(tarinfo=info,fileobj=filedata)
- tf.close()
- elif sys.argv[1] == '-unpack':
- if not os.path.exists('Unpacked'):
- os.mkdir('Unpacked')
- for filename in os.listdir(sys.argv[2]):
- if filename.find('.TAR') != -1:
- print 'Extracting %s' % filename
- unpackscripts(filename)
- else:
- print 'Bad args'
- sys.exit()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement