Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Decompression algorithm spreadsheet:
- # https://docs.google.com/spreadsheets/d/1ipgx25yp0XOtf-48-5a5j78TL67fE_6a2vXCiFvcxYo/edit#gid=0
- # Both lines 101 and 147 go to line 278. I couldn't figure out how these are related
- # So I made everything after 278 into a subroutine (and made almost all variables globals)
- import struct, os
- def get_data(filename):
- totalbytes = os.path.getsize(filename)
- infile = open(filename, 'rb')
- totalfiledata = infile.read(totalbytes)
- infile.close()
- return totalfiledata
- def load_flag_bits():
- global num_flag_bits, flag_bits, input_pos, filedata
- flag_bits = struct.unpack('<H',filedata[input_pos:input_pos+2])[0]
- ## print 'New flag bits: {:016b}'.format(flag_bits) #Prints flag bits
- input_pos += 2
- num_flag_bits = 0x10
- def sub_0x89b11dc():
- global num_flag_bits, flag_bits, a0, a1, a2, v1, v2, s0, s1, s2, s4
- global input_pos, filedata, output, output_size
- #1 -> s2 = 2
- #01 -> s2 = 3
- #001 -> s2 = 4
- #0001 -> s2 = 5
- #00001 -> s2 = 6 plus next three flag bits (a number between 0 and 7)
- #00000 -> s2 = next byte of input plus 0xE
- if num_flag_bits == 0:
- load_flag_bits()
- flag_bit = flag_bits & 1
- flag_bits = flag_bits >> 1
- num_flag_bits -= 1
- s2 = 2
- if flag_bit == 0: #0x89b123c
- if num_flag_bits == 0:
- load_flag_bits()
- flag_bit = flag_bits & 1
- flag_bits = flag_bits >> 1
- num_flag_bits -= 1
- s2 = 3
- if flag_bit == 0: #0x89b12a0
- if num_flag_bits == 0:
- load_flag_bits()
- flag_bit = flag_bits & 1
- flag_bits = flag_bits >> 1
- num_flag_bits -= 1
- s2 = 4
- if flag_bit == 0: #0x89b1308
- if num_flag_bits == 0:
- load_flag_bits()
- flag_bit = flag_bits & 1
- flag_bits = flag_bits >> 1
- num_flag_bits -= 1
- s2 = 5
- if flag_bit == 0: #0x89b1370
- if num_flag_bits == 0:
- load_flag_bits()
- flag_bit = flag_bits & 1
- flag_bits = flag_bits >> 1
- num_flag_bits -= 1
- if flag_bit == 0: #0x89b13d8
- s2 = ord(filedata[input_pos])
- input_pos += 1
- s2 += 0xE
- else:
- t0 = 3
- a2 = 0
- while t0 != 0:
- v0 = a2 << 1
- a2 = v0 & 0xFFFF
- if num_flag_bits == 0:
- load_flag_bits()
- v1 = flag_bits & 1
- flag_bits = flag_bits >> 1
- num_flag_bits -= 1
- v1 += a2
- t0 -= 1
- a2 = v1 & 0xFFFF
- s2 = a2 & 0xFFFF
- s2 += 6
- #Starting "copy from buffer" operation
- #a1 is how far to go back, s2 is how much to copy
- s0 = len(output) - a1 #Where to start copying
- s4 = s2 + output_size
- v1 = 0
- if 0x3FFF0 < s4: #0x89b14b8
- return False
- ## if unpacked_size < s4: #0x89b14c8
- ## return False
- ## if s2 >= 4: #0x89b14d0
- ## v0 = len(output) - s0 #How far back to start copying
- ##
- ## if v0 >= 4: #0x89b14e8
- ## print 'Fail'
- ## quit()
- ## v0 = s0 + s2 #???
- ## #Go to 0x89B1528 (where to start is <4 back and size >=4)
- if s2 != 0: #0x89b14f0
- a1 = 0
- while a1 != s2:
- output += output[s0]
- s0 += 1
- a1 += 1
- output_size = s4
- v1 = 0
- return True
- def decompress_text(filename):
- global filedata, input_pos, num_flag_bits, flag_bits, output, output_size, \
- unpacked_size, a1, a2, a3, s2, s4, v0, v1
- filedata = get_data(filename + '.orig')
- output = ''
- output_size = 8
- output += filedata[:8]
- input_pos = 8
- num_flag_bits = 0
- #89b0df0
- while True:
- if num_flag_bits == 0:
- load_flag_bits()
- flag_bit = flag_bits & 1
- flag_bits = flag_bits >> 1
- num_flag_bits -= 1
- if flag_bit == 0: #89b0e48
- output += filedata[input_pos]
- input_pos += 1
- output_size += 1
- continue
- else: #89b0e98
- if num_flag_bits == 0:
- load_flag_bits()
- flag_bit = flag_bits & 1
- flag_bits = flag_bits >> 1
- num_flag_bits -= 1
- if flag_bit == 0: #89b0ef4
- a1 = ord(filedata[input_pos])
- input_pos += 1
- flag = sub_0x89b11dc()
- if flag:
- continue
- else:
- break
- else: #89b0f20
- a3 = 0x5
- a2 = 0
- while a3 != 0: #This JC is at 0x89b0fa0
- v0 = a2 << 1 #89b0f30
- a2 = v0 & 0xFFFF
- if num_flag_bits == 0:
- load_flag_bits()
- v1 = flag_bits & 1
- flag_bits = flag_bits >> 1
- num_flag_bits -= 1
- v1 += a2
- a3 -= 1
- a2 = v1 & 0xFFFF
- a2 = a2 << 8
- a2 += ord(filedata[input_pos])
- input_pos += 1
- if a2 == 0:
- break
- a1 = a2
- if a2 != 1: #0x89b0fd0
- flag = sub_0x89b11dc()
- if flag:
- continue
- else:
- break
- if num_flag_bits == 0: #0x89b0fd8
- load_flag_bits()
- flag_bit = flag_bits & 1
- flag_bits = flag_bits >> 1
- num_flag_bits -= 1
- if flag_bit == 0: #89b101c
- a3 = 4
- a2 = 0
- while a3 != 0:
- v0 = a2 << 1
- a2 = v0 & 0xFFFF
- if num_flag_bits == 0: #0x89b0fd8
- load_flag_bits()
- v1 = flag_bits & 1
- flag_bits = flag_bits >> 1
- num_flag_bits -= 1
- v1 += a2
- a3 -= 1
- a2 = v1 & 0xFFFF
- s2 = a2 & 0xFFFF
- s4 = s2 + 0xE
- # Go to 0x89b1190
- else: #0x89b10dc
- a3 = 4
- a2 = 0
- while a3 != 0:
- v0 = a2 << 1
- a2 = v0 & 0xFFFF
- if num_flag_bits == 0: #0x89b0fd8
- load_flag_bits()
- v1 = flag_bits & 1
- flag_bits = flag_bits >> 1
- num_flag_bits -= 1
- v1 += a2
- a3 -= 1
- a2 = v1 & 0xFFFF
- s2 = a2 << 8
- s2 += ord(filedata[input_pos])
- input_pos += 1
- s4 = s2 + 0xE
- a1 = ord(filedata[input_pos]) #0x89b1190
- input_pos += 1
- output += chr(a1)*s4
- output_size += s4
- continue
- input_pos += 4
- output_file = open(filename + '.unpack2','wb')
- output_file.write(output)
- output_file.close()
- decompress_text('T_TITLE._DT')
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement