Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import os
- import sys
- import binascii
- import struct
- import re
- def get_data(filename):
- totalbytes = os.path.getsize(filename)
- infile = open(filename, 'rb')
- totalfiledata = infile.read(totalbytes)
- return totalfiledata
- def extract(filename):
- filedata = get_data(filename)
- filedata = filedata[struct.unpack('<I',filedata[0x2c:0x30])[0]:]
- firsttablecount = struct.unpack('<I',filedata[0x8:0xc])[0]
- strentrycount = struct.unpack('<I',filedata[0xc:0x10])[0]
- strentrypos = (firsttablecount*0x10) + 0x20
- stringpos = (firsttablecount*0x10) + (strentrycount*0x20) + 0x20
- newfiledata = ''
- a = 0
- newstringcount = 0
- for entry in range(strentrypos,strentrypos+(strentrycount*0x20),0x20):
- currstringpos = struct.unpack('<I',filedata[entry+0x14:entry+0x18])[0]
- if entry+0x20 != strentrypos+(strentrycount*0x20):
- nextstringpos = struct.unpack('<I',filedata[entry+0x34:entry+0x38])[0]
- stringlen = nextstringpos-currstringpos
- string = filedata[currstringpos:currstringpos+stringlen-1]
- while string.find('\xFF\x41') != -1 or string.find('\xFF\x42') != -1 or string.find('\xFF\x43') != -1 or string.find('\xFF\x44') != -1:
- startfuri = string.find('\xFF\x41')
- if startfuri == -1:
- startfuri = string.find('\xFF\x42')
- if startfuri == -1:
- startfuri = string.find('\xFF\x43')
- if startfuri == -1:
- startfuri = string.find('\xFF\x44')
- if startfuri == -1:
- print 'Start furi going further than fucking 44'
- endfuri = string.find('\xFF\x00',startfuri)
- if startfuri == -1 or endfuri == -1:
- print 'think we hit a bad bit in %x' % currstringpos
- break
- string = string[:startfuri] + string[endfuri+2:]
- while string.find('\xFF\x80') != -1:
- string = string.replace('\xFF\x80','\line')
- if a >= 10:
- print 'replace broke, breaking'
- a = 0
- break
- a += 1
- else:
- string = filedata[currstringpos:len(filedata)-4]
- while string.find('\xFF\x41') != -1 or string.find('\xFF\x42') != -1 or string.find('\xFF\x43') != -1 or string.find('\xFF\x44') != -1:
- startfuri = string.find('\xFF\x41')
- if startfuri == -1:
- startfuri = string.find('\xFF\x42')
- if startfuri == -1:
- startfuri = string.find('\xFF\x43')
- if startfuri == -1:
- startfuri = string.find('\xFF\x44')
- if startfuri == -1:
- print 'Start furi going further than fucking 44'
- endfuri = string.find('\xFF\x00',startfuri)
- if startfuri == -1 or endfuri == -1:
- print 'think we hit a bad bit in %x' % currstringpos
- break
- string = string[:startfuri] + string[endfuri+2:]
- while string.find('\xFF\x80') != -1:
- string = string.replace('\xFF\x80','\line')
- if a >= 10:
- print 'replace broke, breaking'
- a = 0
- break
- a += 1
- a = 0
- newfiledata += string + '\n'
- newstringcount += 1
- newfiledata = 'pBin\n' + str(newstringcount) + '\n' + newfiledata
- outfile = open(filename + '.strings','wb')
- outfile.write(newfiledata)
- outfile.close()
- def runcompile(filename):
- filedata = get_data(filename)
- origdata1 = get_data(filename[:len(filename)-8])
- origdata = origdata1[struct.unpack('<I',origdata1[0x2c:0x30])[0]:]
- strings = filedata.split('\n')
- newfiledata = origdata[:(struct.unpack('<I',origdata[0x8:0xc])[0] * 0x10) + 0x20]
- currpos = len(newfiledata)
- firstrun = True
- currstringsize = 0
- newstrings = ''
- newstringcount = 0
- oldstringcount = int(strings[1])
- strings.pop(0)
- strings.pop(0)
- string2 = ''
- temppos = len(newfiledata)
- tempposscene = 0x20
- linesmade = 0
- totalstringlen = int(len(strings)-1)
- totalstringlen = (struct.unpack('<I',origdata[0x8:0xc])[0] * 0x10) + (totalstringlen*0x20) + 0x20
- LastString = False
- for string in strings:
- if string == '':
- continue
- if string.find('\line') != -1:
- string = string.replace('\line','\xFF\x80')
- if string.find('##') != -1:
- string = string.replace('##','')
- stringlist = string.split(' ')
- for word in stringlist:
- if (currstringsize + len(word)) >= 30:
- if linesmade == 1:
- string2 = string2 + '\page' + word
- totalstringlen += 0x20
- linesmade = 0
- else:
- string2 = string2 + '\xFF\x80' + word
- linesmade += 1
- currstringsize = 0 + len(word)
- else:
- if firstrun == True:
- string2 = word
- currstringsize = len(word)
- firstrun = False
- else:
- string2 = string2 + ' ' + word
- currstringsize += len(word) + 1
- string = string2
- if string.find('\page') != -1:
- newpagestrings = string.split('\page')
- pagesadded = 0
- for newpagestring in newpagestrings:
- if newstringcount == 0 or newpagestring == newpagestrings[0]:
- newfiledata += origdata[currpos:currpos+0x14] + struct.pack('<I',totalstringlen) + origdata[currpos+0x18:currpos+0x20]
- currpos += 0x20
- else:
- newfiledata += origdata[currpos-0x20:currpos-0xc] + struct.pack('<I',totalstringlen) + origdata[currpos-0x8:currpos-0x4] + struct.pack('<I',4294967295)
- for fixstring in range(0,newstringcount-1): #fix string locations as we add new pages
- fixvar = struct.unpack('<I',newfiledata[temppos+0x14:temppos+0x18])[0]
- fixvar += 0x20
- newfiledata = newfiledata[:temppos+0x14] + struct.pack('<I',fixvar) + newfiledata[temppos+0x18:]
- temppos += 0x20
- if pagesadded >= 1:
- for findscene in range(0x20,(struct.unpack('<I',newfiledata[0x8:0xc])[0] * 0x10) + 0x20,0x10):
- #find the scene location we need to add new strings to
- findscenenum = struct.unpack('<I',newfiledata[findscene:findscene+0x4])[0]
- if findscenenum >= newstringcount:
- scenepos = findscene
- scenepos -= 0x10
- amounttofix = (struct.unpack('<I',newfiledata[0x8:0xc])[0]*0x10) - ((scenepos)-0x20)
- break
- if scenepos == 0:
- scenepos = (struct.unpack('<I',newfiledata[0x8:0xc])[0]*0x10) + 0x10
- amounttofix = (struct.unpack('<I',newfiledata[0x8:0xc])[0]*0x10) - ((scenepos)-0x20)
- for fixsceneloc in range(scenepos,amounttofix+scenepos,0x10): #fix scene change stuff too
- if fixsceneloc == scenepos:
- fixvar = struct.unpack('<I',newfiledata[fixsceneloc+0x4:fixsceneloc+0x8])[0]
- fixvar += 0x1
- newfiledata = newfiledata[:fixsceneloc+0x4] + struct.pack('<I',fixvar) + newfiledata[fixsceneloc+0x8:]
- else:
- fixvar = struct.unpack('<I',newfiledata[fixsceneloc:fixsceneloc+0x4])[0]
- fixvar += 0x1
- newfiledata = newfiledata[:fixsceneloc] + struct.pack('<I',fixvar) + newfiledata[fixsceneloc+0x4:]
- pagesadded += 1
- fixvar = 0
- totalstringlen += len(newpagestring)+1
- newstrings += newpagestring + '\x00'
- newstringcount += 1
- temppos = (struct.unpack('<I',origdata[0x8:0xc])[0] * 0x10) + 0x20
- LastString = False
- scenepos = 0
- amounttofix = 0
- else: #no new pages, just add the string
- newfiledata += origdata[currpos:currpos+0x14] + struct.pack('<I',totalstringlen) + origdata[currpos+0x18:currpos+0x20]
- currpos += 0x20
- totalstringlen += len(string) + 1
- newstrings += string + '\x00'
- newstringcount += 1
- firstrun = True
- currstringsize = 0
- linesmade = 0
- string2 = ''
- currstringsize = 0
- stringlist = []
- newpagestrings = []
- newfiledata += newstrings + '\x00\x00\x00'
- newfiledata = newfiledata[:0xc] + struct.pack('<I',newstringcount) + newfiledata[0x10:]
- replacepos = struct.unpack('<I',origdata1[0x2c:0x30])[0]
- newfinalfile = origdata1[:replacepos] + newfiledata
- outfile = open(filename[:len(filename)-8] + '.new','wb')
- outfile.write(newfinalfile)
- outfile.close()
- def texe(filename):
- filedata = get_data(filename)
- stringcount = struct.unpack('<I',filedata[0x8:0xc])[0]
- newfiledata = ''
- a = 0
- for stringentry in range(0x10,(stringcount*0x4)+0x10,0x4):
- stringloc = struct.unpack('<I',filedata[stringentry:stringentry+0x4])[0]
- print "0x%0x" % stringloc
- if stringentry+0x4 == stringcount*0x4+0x10:
- nextstringpos = len(filedata)
- else:
- nextstringpos = struct.unpack('<I',filedata[stringentry+0x4:stringentry+0x8])[0]
- string = filedata[stringloc:nextstringpos-1]
- while string.find('\x0a') != -1:
- string = string.replace('\x0a','\line')
- if a >= 50:
- print 'replace broke, breaking'
- break
- a += 1
- a = 0
- newfiledata += string + '\n'
- outfile = open(filename + '.strings','wb')
- outfile.write(newfiledata)
- outfile.close()
- def texc(filename):
- filedata = get_data(filename)
- origfiledata = get_data(filename[:len(filename)-8])
- newfiledata = ''
- newfiledata = origfiledata[:0x10]
- strings = filedata.split('\n')
- currpos = 0x10
- totalstringlen = (struct.unpack('<I',origfiledata[0x8:0xc])[0] * 0x4) + 0x10
- newstrings = ''
- for string in strings:
- if string == '':
- continue
- if string.find('\line') != -1:
- string = string.replace('\line','\x0a')
- string += '\x00'
- newfiledata += struct.pack('<I',totalstringlen)
- newstrings += string
- currpos += 0x4
- totalstringlen += len(string)
- newfiledata += newstrings
- outfile = open(filename[:len(filename)-8] + '.new','wb')
- outfile.write(newfiledata)
- outfile.close()
- if __name__ == '__main__':
- if sys.argv[1] == '-e':
- testfile = get_data(sys.argv[2])
- if testfile[:0x4] == 'pBin':
- extract(sys.argv[2])
- else:
- texe(sys.argv[2])
- elif sys.argv[1] == '-c':
- testfile = get_data(sys.argv[2])
- if testfile[:0x4] == 'pBin':
- runcompile(sys.argv[2])
- else:
- texc(sys.argv[2])
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement