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)