def emit_thumb(self, opcode): """16 bit thumb instructions""" da = darm.disasm_thumb(opcode) s = '?' if da: s = str(da) self.ui.put('%08x: %04x %s\n' % (self.pc, opcode, s)) self.pc += 2
import struct import darm # https://github.com/jbremer/darm # Read RAM dump. dump = "" with open("DUMP.BIN", "rb") as f: dump = f.read() # Read decrypted launcher. data = "" with open("Launcher.dat", "rb") as f: data = f.read() # Format entries. for i in xrange(len(data)/4): v = struct.unpack("<I", data[i*4:i*4+4])[0] inst = "" if v >= 0x100000 and v <= 0x252000: # This is gonna work just fine. if v & 1: addr = (v - 0x100000) & 0xFFFFFFFE inst = darm.disasm_thumb(struct.unpack("<H", dump[addr:addr+2])[0]) else: addr = v - 0x100000 inst = darm.disasm_armv7(struct.unpack("<I", dump[addr:addr+4])[0]) if inst == None: print "{0:08X}: {1:08X}".format(i*4, v) else: print "{0:08X}: {1:08X} - {2}".format(i*4, v, inst) else: print "{0:08X}: {1:08X}".format(i*4, v)
# "encrypted" data retrieved directly from the binary encrypted = [ 0xcaa9e1a1, 0xcae9e1a3, 0xca29e1ad, 0xca69e1af, 0xcba9e1a9, 0xcbe9e1ab, 0x7454edda, 0xaae7f8eb, 0x8ad3c78a, 0xc4c58ada, 0x9999c6d9, 0xcb8ac6cf, 0xcfcc8ae3, 0xc8dfcfde, ] # "decrypted" decrypted = [_ ^ 0xaaaaaaaa for _ in encrypted] # 16bit thumb instructions insns = sum(([_ & 0xffff, _ >> 16] for _ in decrypted), []) off, s = 0, '' for ins in insns: value, d = '', darm.disasm_thumb(ins) # load a literal if str(d.instr) == 'LDR' and str(d.Rn) == 'PC': value = struct.pack('I', decrypted[(off + d.imm + 4) / 4]) s += value # return elif str(d.instr) == 'BX': break print '#%d' % off, str(d), repr(value) off += 2 print 'Key:', s