import darmu import sys def dump_binary(emu, fname): buf = emu.image for raw, size, addr in emu.mappings: print 'dumping', hex(addr), repr(emu.read(addr, size)) buf = buf[:raw] + emu.read(addr, size) + buf[raw+size:] open(fname, 'wb').write(buf) if __name__ == '__main__': if len(sys.argv) == 1: print 'Usage: %s ' % sys.argv[0] exit(0) image = open(sys.argv[1], 'rb').read() emu = darmu.Darmu(image, 0x2000) #emu.mapping(image[:0x2610], 0x2610, 0x8000) #emu.mapping(image[0x2e90:], 0x1c5c, 0xbe90) #emu.entry_point(0xc17c) emu.mapping(0, 0x1c5c, 0x8000) emu.mapping(0x1e9c, 0xc88, 0xae9c) emu.mapping(0x1c44, 0x18, 0x9c44) emu.entry_point(0xb0d8) dump_count = 0 while emu.r15 and emu.single_step(): # the xor decryption key #if emu.r15 == 0xb0e8: #print hex(emu.r0) # right before the syscall, grab the starting and ending address if emu.r15 == 0xb098 or emu.r15 == 0xb630: start = emu.r0 end = emu.r1 print 'start', hex(start), 'end', hex(end) sys.stdout.flush() if dump_count == 0: header = emu.read(0x8000, 0x64) print 'header', repr(header) elif dump_count == 1: print 'header', repr(emu.read(0x8000, 0x64)) emu.write(0x8000, header) print 'header', repr(emu.read(0x8000, 0x64)) dump_binary(emu, '%s-%d.out' % (sys.argv[1], dump_count)) dump_count += 1 # jump into the decrypted buffer if emu.r15 == 0xb110: buf = emu.read(start, end-start) # emu stuff if emu.r15 == 0xb718: print 'opcode', emu.r1 sys.stdout.flush() #emu.entry_point(0x8558) #while emu.single_step(): #pass #print>>sys.stderr, repr(buf) #buf = image[:start-0xae9c+0x1e9c] + buf + image[end-0xae9c+0x1e9c:] #open(sys.argv[1] + '.out', 'wb').write(buf)