Advertisement
Guest User

Untitled

a guest
May 2nd, 2014
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 16.03 KB | None | 0 0
  1. import os
  2. import sys
  3. import binascii
  4. import struct
  5. import re
  6.  
  7. def get_data(filename):
  8. totalbytes = os.path.getsize(filename)
  9. infile = open(filename, 'rb')
  10. totalfiledata = infile.read(totalbytes)
  11. return totalfiledata
  12.  
  13. opcodes = [
  14. [0x1,'retn',7],[0x2,'jmp',7],[0x3,'jmpcond',7],[0x4,'text',7],[0x5,'0x5',7],[0x6,'0x6',7],[0x7,'0x7',7],
  15. [0x8,'0x8',7],[0x9,'0x9',7],[0xa,'0xa',7],[0xb,'0xb',7],[0xc,'0xc',7],[0xd,'0xd',7],[0xe,'0xe',7],
  16. [0xf,'0xf',7],[0x10,'0x10',7],[0x11,'0x11',7],[0x12,'0x12',7],[0x13,'0x13',7],[0x14,'0x14',7],[0x15,'0x15',7],
  17. [0x16,'0x16',7],[0x17,'0x17',7],[0x18,'0x18',7],[0x19,'0x19',7],[0x1a,'0x1a',7],[0x1b,'0x1b',7],[0x1c,'0x1c',7],
  18. [0x1d,'0x1d',7],[0x1e,'0x1e',7],[0x1f,'0x1f',7],[0x20,'0x20',7],[0x21,'0x21',7],[0x22,'0x22',7],[0x23,'0x23',7],
  19. [0x24,'0x24',7],[0x25,'0x25',7],[0x26,'0x26',7],[0x27,'0x27',7],[0x28,'0x28',7],[0x29,'0x29',7],[0x2a,'0x2a',7],
  20. [0x2b,'0x2b',7],[0x2c,'0x2c',7],[0x2d,'0x2d',7],[0x2e,'0x2e',7],[0x2f,'0x2f',7],[0x30,'0x30',7],[0x31,'0x31',7],
  21. [0x32,'0x32',7],[0x33,'0x33',7],[0x34,'0x34',7],[0x35,'0x35',7],[0x36,'0x36',7],[0x37,'0x37',7],[0x38,'0x38',7],
  22. [0x39,'0x39',7],[0x3a,'0x3a',7],[0x3b,'0x3b',7],[0x3c,'shop',7],[0x3d,'0x3d',7],[0x3e,'0x3e',7],[0x3f,'0x3f',7],
  23. [0x40,'0x40',7],[0x41,'0x41',7],[0x42,'0x42',7],[0x43,'0x43',7],[0x44,'0x44',7],[0x45,'0x45',7],[0x46,'0x46',7],
  24. [0x47,'0x47',7],[0x48,'0x48',7],[0x49,'0x49',7],[0x4a,'0x4a',7],[0x4b,'0x4b',7],[0x4c,'0x4c',7],[0x4d,'0x4d',7],
  25. [0x4e,'0x4e',7],[0x4f,'char',7],[0x50,'0x50',7],[0x51,'0x51',7],[0x52,'0x52',7],[0x53,'0x53',7],[0x54,'0x54',7],
  26. [0x55,'0x55',7],[0x56,'0x56',7],[0x57,'0x57',7],[0x58,'0x58',7],[0x59,'0x59',7],[0x5a,'0x5a',7],[0x5b,'0x5b',7],
  27. [0x5c,'0x5c',7],[0x5d,'0x5d',7],[0x5e,'0x5e',7],[0x5f,'0x5f',7],[0x60,'0x60',7],[0x61,'0x61',7],[0x62,'0x62',7],
  28. [0x63,'0x63',7],[0x64,'0x64',7],[0x65,'0x65',7],[0x66,'0x66',7],[0x67,'0x67',7],[0x68,'0x68',7],[0x69,'0x69',7],
  29. [0x6a,'0x6a',7],[0x6b,'0x6b',7],[0x6c,'0x6c',7],[0x6d,'0x6d',7],[0x6e,'0x6e',7],[0x6f,'0x6f',7],[0x70,'0x70',7],
  30. [0x71,'0x71',7],[0x72,'0x72',7],[0x73,'0x73',7],[0x74,'0x74',7],[0x75,'0x75',7],[0x76,'0x76',7],[0x77,'0x77',7],
  31. [0x78,'video',7],[0x79,'0x79',7],[0x7a,'0x7a',7],[0x7b,'0x7b',7],[0x7c,'0x7c',7],[0x7d,'0x7d',7],[0x7e,'0x7e',7],
  32. [0x7f,'0x7f',7],[0x80,'0x80',7],[0x81,'0x81',7],[0x82,'0x82',7],[0x83,'0x83',7],[0x84,'0x84',7],[0x85,'0x85',7],
  33. [0x86,'0x86',7],[0x87,'0x87',7],
  34. ]
  35.  
  36. def extract(filename):
  37. filedata = get_data(filename)
  38. table1 = struct.unpack('<H',filedata[0x1c:0x1e])[0] * 0x10
  39. table2 = struct.unpack('<H',filedata[0x1e:0x20])[0] * 0x10
  40. table3 = struct.unpack('<H',filedata[0x20:0x22])[0] * 0x10
  41. table4 = struct.unpack('<H',filedata[0x22:0x24])[0] * 0x10
  42. table5 = struct.unpack('<H',filedata[0x2c:0x2e])[0] * 0x10
  43. table6 = 0x1000
  44. table7 = struct.unpack('<H',filedata[0x24:0x26])[0] * 0x20
  45. table8 = struct.unpack('<H',filedata[0x26:0x28])[0] * 0x2
  46. maxlength = struct.unpack('<H',filedata[0x28:0x2a])[0] * 0x20
  47. table10 = struct.unpack('<H',filedata[0x2a:0x2c])[0]
  48. outfiledata = ''
  49. opcodeblockstart = 0x40 + table1 + table2 + table3 + table4 + table5 + table6 + table7 + table8
  50. i = opcodeblockstart
  51. blocksmoved = 0
  52. outfile = open(os.path.splitext(filename)[0] + '.data','wb')
  53.  
  54. outfiledata += filename + '\n'
  55. lastopcode = 0
  56. firstrun = True
  57. functioncount = 0
  58. functions = []
  59. functablelen = table8
  60. for a in range(i-functablelen,i,0x2):
  61. functions.append(struct.unpack('<H',filedata[a:a+0x2])[0])
  62.  
  63. while i != opcodeblockstart+maxlength: # loop while not end of opcode block
  64. if functions[functioncount] == ((i-opcodeblockstart) / 0x20):
  65. if firstrun == True:
  66. firstrun = False
  67. else:
  68. outfiledata += '}\n\n'
  69. try:
  70. outfiledata += 'function_%x --- length: %x\n{\n' % (blocksmoved,(functions[functioncount+1]-blocksmoved))
  71. functioncount += 1
  72. except Exception:
  73. outfiledata += 'function_%x --- length: %x\n{\n' % (blocksmoved,(maxlength/0x20)-blocksmoved)
  74.  
  75. c = 0
  76. opcode = struct.unpack('<I',filedata[i:i+0x4])[0] # first dword is always our opcode
  77. while c != len(opcodes):
  78. if opcodes[c][0] == opcode: # is this a match to one of our opcodes
  79. variables = opcodes[c][2]
  80. name = ('%x' % (blocksmoved)) + ' { ' + opcodes[c][1] # the text to replace the opcode with
  81. blocksmoved += 1
  82. break;
  83. if c+1 == len(opcodes):
  84. print 'Unknown opcode: %x at loc: %x' % (opcode,i)
  85. sys.exit()
  86. c += 1
  87.  
  88. outfiledata += name + ' '
  89. for a in range(i+0x4,i+0x4+(variables*4),0x4): # run through each variable for the opcode
  90. var = struct.unpack('<I',filedata[a:a+0x4])[0]
  91. if opcode == 0x4 and a == i+0x4+0x4*4: # get string for 0x4 opcode
  92. outfiledata += '"' + filedata[opcodeblockstart+maxlength+var:filedata.find('\x00',opcodeblockstart+maxlength+var,len(filedata))] + '" '
  93. elif opcode == 0x3c and a == i+0x4+0x4*4: # get string for 0x3c opcode
  94. outfiledata += '"' + filedata[opcodeblockstart+maxlength+var:filedata.find('\x00',opcodeblockstart+maxlength+var,len(filedata))] + '" '
  95. elif opcode == 0x21 and a == i+0x4+0x4*4: # get string for 0x21 opcode
  96. outfiledata += '"' + filedata[opcodeblockstart+maxlength+var:filedata.find('\x00',opcodeblockstart+maxlength+var,len(filedata))] + '" '
  97. elif opcode == 0x78 and a == i+0x4+0x4*4: # get string for 0x78 opcode
  98. outfiledata += '"' + filedata[opcodeblockstart+maxlength+var:filedata.find('\x00',opcodeblockstart+maxlength+var,len(filedata))] + '" '
  99. elif opcode == 0x4f and a == i+0x4+0x4*4: # get string for 0x4f opcode
  100. outfiledata += '"' + filedata[opcodeblockstart+maxlength+var:filedata.find('\x00',opcodeblockstart+maxlength+var,len(filedata))] + '" '
  101. else:
  102. outfiledata += ('%0x' % var) + ' ' # not a string, so just add the variable
  103.  
  104. outfiledata += ' }\n'
  105. lastopcode = opcode
  106. i += 0x20
  107. if i == opcodeblockstart+maxlength:
  108. outfiledata += '}'
  109. outfile.write(outfiledata) # write the opcode out to our data file
  110. outfiledata = ''
  111.  
  112. blocksmoved2 = 0
  113.  
  114. def insert(filename):
  115. filedata = get_data(filename)
  116. newopcodes = filedata.split('\n') # split our data by lines for each opcode
  117. newstrings = ''
  118. newfiledata = ''
  119. oldfilename = newopcodes[0]
  120. newopcodes.remove(newopcodes[0])
  121. b = 0
  122. c = 0
  123. blocksmoved = 0
  124. variables = 0
  125. totallinesadded = 0
  126. linesadded = []
  127. blocksmoved = 0
  128. positionsofinsert = []
  129. positionsofremove = []
  130. lastorigline = 0
  131. firstrun = True
  132.  
  133. for i in range(0,len(newopcodes)):
  134. thisline = newopcodes[i] # get our new opcode
  135. if (thisline != '') and (thisline.find('function_') == -1) and (thisline != '{') and (thisline != '}'): # make sure it's not empty or just a function label
  136. if thisline.find('"') != -1: # does this line have a string in it. Could match the opcodes against all known text ones, do that if " causes problems
  137. strings = thisline.find('"')
  138. stringe = thisline.find('"',strings+1)
  139. string = thisline[strings+1:stringe]
  140. string += '\x00'
  141. if newstrings.find(string) == -1:
  142. newstrings += string
  143. thisline = thisline[:strings] + 'TEXT ' + thisline[stringe+2:] # replace the string with a temp string, this is so it doesn't break the below split
  144. else:
  145. newstringpos = newstrings.find(string)
  146. thisline = thisline[:strings] + 'DUPE ' + thisline[stringe+2:] # replace the string with a temp string, this is so it doesn't break the below split
  147.  
  148. newvariables = thisline.split(' ') # split the line into variables
  149. isorigline = ''
  150. if newvariables[1] == '{':
  151. isorigline = newvariables[0]
  152. newvariables.remove(isorigline)
  153.  
  154. newvariables.remove('{') # remove excess
  155. newvariables.remove('}')
  156. newvariables.remove('')
  157. a = 0
  158. f = 0
  159. d = 0
  160. diffcount = 0
  161. if isorigline == '':
  162. positionsofinsert.append(lastorigline)
  163. else:
  164. isorigline = int(isorigline,16)
  165. if firstrun == True:
  166. lastorigline = isorigline
  167. firstrun = False
  168. elif lastorigline == isorigline:
  169. print 'ERROR WITH LINE COUNT.\nOUTPUT WILL BE BROKEN\nReason could be that your edits are formatted badly\nor an unknown opcode.'
  170. elif (lastorigline != isorigline):
  171. while lastorigline+1 < isorigline:
  172. lastorigline += 1
  173. positionsofremove.append(isorigline)
  174. lastorigline = isorigline
  175.  
  176. while a != len(newvariables):
  177. if newvariables[f] != '{' and newvariables[f] != '}' and newvariables[f] != '':
  178. if a == 0: # first is always our opcode
  179. d = 0
  180. while d != len(opcodes):
  181. if opcodes[d][1] == newvariables[f]: #does this match on of our opcodes
  182. newfiledata += struct.pack('<I',opcodes[d][0]) # pack the opcode into our new filedata
  183. break;
  184. if d+1 == len(opcodes):
  185. print 'Unknown opcode: %x in line: %s' % (opcode,f)
  186. sys.exit()
  187. d += 1
  188. else:
  189. if newvariables[f] == 'TEXT': # if we had a string as this variable, replace with its pointer (current length of our new strings)
  190. newfiledata += struct.pack('<I',len(newstrings)-(len(string)))
  191. newvariables[f+1] = str(hex(len(string)-1))
  192. elif newvariables[f] == 'DUPE': # if we had a string as this variable, we already have this string in the file, point to it
  193. newfiledata += struct.pack('<I',newstringpos)
  194. newvariables[f+1] = str(hex(len(string)-1))
  195. newstringpos = 0
  196. else: # not a string, so just pack the variable again
  197. newvariables[f] = int(newvariables[f],16)
  198. newfiledata += struct.pack('<I',newvariables[f])
  199. a += 1
  200. f += 1
  201. string = ''
  202. f = 0
  203. d = 0
  204. c = 0
  205. a = 0
  206. blocksmoved = 0
  207. variables = 0
  208. s = 0
  209. tmpfix = 0
  210. tmpfix2 = 0
  211.  
  212. if len(positionsofinsert) > 0 or len(positionsofremove) > 0: #fix all our 0x2 and 0x3 jumps to match the amount removed/added
  213. while s != len(newfiledata):
  214. thisval = struct.unpack('<I',newfiledata[s:s+0x4])[0]
  215. if thisval == 0x2:
  216. fixme = struct.unpack('<I',newfiledata[s+0x4:s+0x8])[0]
  217. tmpfix = fixme
  218. if len(positionsofinsert) > 0:
  219. for g in range(0,len(positionsofinsert)):
  220. if tmpfix >= positionsofinsert[g]:
  221. fixme += 0x1
  222. if len(positionsofremove) > 0:
  223. for g in range(0,len(positionsofremove)):
  224. if tmpfix >= positionsofremove[g]:
  225. fixme -= 0x1
  226. newfiledata = newfiledata[:s+0x4] + struct.pack('<I',fixme) + newfiledata[s+0x8:]
  227.  
  228. elif thisval == 0x3:
  229. fixme = struct.unpack('<I',newfiledata[s+0xc:s+0x10])[0]
  230. tmpfix = fixme
  231. if len(positionsofinsert) > 0:
  232. for g in range(0,len(positionsofinsert)):
  233. if tmpfix >= positionsofinsert[g]:
  234. fixme += 0x1
  235. if len(positionsofremove) > 0:
  236. for g in range(0,len(positionsofremove)):
  237. if tmpfix >= positionsofremove[g]:
  238. fixme -= 0x1
  239. newfiledata = newfiledata[:s+0xc] + struct.pack('<I',fixme) + newfiledata[s+0x10:]
  240.  
  241. fixme = struct.unpack('<I',newfiledata[s+0x10:s+0x14])[0]
  242. tmpfix = fixme
  243. if len(positionsofinsert) > 0:
  244. for g in range(0,len(positionsofinsert)):
  245. if tmpfix >= positionsofinsert[g]:
  246. fixme += 0x1
  247. if len(positionsofremove) > 0:
  248. for g in range(0,len(positionsofremove)):
  249. if tmpfix >= positionsofremove[g]:
  250. fixme -= 0x1
  251. newfiledata = newfiledata[:s+0x10] + struct.pack('<I',fixme) + newfiledata[s+0x14:]
  252.  
  253. s += 0x20
  254. blocksmoved += 1
  255.  
  256. filedata1 = get_data(oldfilename)
  257. table1 = struct.unpack('<H',filedata1[0x1c:0x1e])[0] * 0x10
  258. table2 = struct.unpack('<H',filedata1[0x1e:0x20])[0] * 0x10
  259. table3 = struct.unpack('<H',filedata1[0x20:0x22])[0] * 0x10
  260. table4 = struct.unpack('<H',filedata1[0x22:0x24])[0] * 0x10
  261. table5 = struct.unpack('<H',filedata1[0x2c:0x2e])[0] * 0x10
  262. table6 = 0x1000
  263. table7 = struct.unpack('<H',filedata1[0x24:0x26])[0] * 0x20
  264. table8 = struct.unpack('<H',filedata1[0x26:0x28])[0] * 0x2
  265. opcodeblockstart = 0x40 + table1 + table2 + table3 + table4 + table5 + table6 + table7 + table8
  266.  
  267. newfiledata1 = filedata1[:opcodeblockstart-(struct.unpack('<H',filedata1[0x26:0x28])[0]*0x2)] # this gets original data up to the point we edit
  268. newfiledata2 = filedata1[opcodeblockstart-(struct.unpack('<H',filedata1[0x26:0x28])[0]*0x2):opcodeblockstart] # this is the table before the opcode block
  269. newfiledataloctable = ''
  270. tmpfix = 0
  271. tmpfix2 = 0
  272. first1run = True
  273.  
  274. if len(positionsofinsert) > 0 or len(positionsofremove) > 0:
  275. for fixloc in range(0x0,len(newfiledata2),0x2): # we have to fix this table as well, as each word is a block number
  276. fixlocval = struct.unpack('<H',newfiledata2[fixloc:fixloc+0x2])[0]
  277. tmpfix = fixlocval
  278. if len(positionsofinsert) > 0:
  279. for g in range(0,len(positionsofinsert)):
  280. if tmpfix >= positionsofinsert[g]:
  281. fixlocval += 0x1
  282. if len(positionsofremove) > 0:
  283. for g in range(0,len(positionsofremove)):
  284. if tmpfix >= positionsofremove[g]:
  285. fixlocval -= 0x1
  286. newfiledataloctable += struct.pack('<H',fixlocval)
  287. elif len(positionsofinsert) == 0 and len(positionsofremove) == 0:
  288. newfiledataloctable = newfiledata2
  289.  
  290. # put together our new file, and fix the 2 length variables for opcode block length, and text block length
  291. newfiledata = newfiledata1[:0x28] + struct.pack('<H',len(newfiledata)/0x20) + struct.pack('<H',len(newstrings)) + newfiledata1[0x2c:] + newfiledataloctable + newfiledata
  292. newfiledata += newstrings
  293.  
  294. outfile = open(os.path.splitext(filename)[0],'wb')
  295. outfile.write(newfiledata)
  296. outfile.close()
  297.  
  298.  
  299. if __name__ == '__main__':
  300. if sys.argv[2] == '-e':
  301. extract(sys.argv[1])
  302. elif sys.argv[2] == '-i':
  303. insert(sys.argv[1])
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement