Created
June 16, 2017 05:33
-
-
Save aquynh/f4a78534c5412cef4901eecc93878557 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# Sample code for MIPS of Unicorn. Nguyen Anh Quynh <[email protected]> | |
# Python sample ported by Loi Anh Tuan <[email protected]> | |
from traceback import format_exc | |
from unicorn import * | |
from unicorn.mips_const import * | |
#400790 24020123 addiu $v0, $zero, 0x123 | |
#400794 03e00008 jr $ra | |
#400798 00000000 nop | |
#40079c 0c1001e4 jal 0x400790 <--- start | |
#4007a0 00000000 nop | |
#4007a4 00000000 nop <--- stop | |
MIPS_CODE_EB = "".join([ | |
"\x24\x02\x01\x23", # li $v0, 0x123 | |
"\x03\xe0\x00\x08", # jr $ra | |
"\x00\x00\x00\x00", # nop | |
"\x0c\x10\x01\xe4", # jal 0x400790 | |
"\x00\x00\x00\x00", # nop | |
"\x00\x00\x00\x00", # nop | |
]) | |
# memory address where emulation starts | |
ADDRESS = 0x0400790 | |
current_start = 0x40079c | |
end_address = 0x4007a4 | |
# callback for tracing instructions | |
def hook_code(uc, address, size, user_data): | |
#print "" | |
print "_" * 80 | |
print " Tracing instruction at 0x%x, instruction size = 0x%x\n" %(address, size) | |
zr = uc.reg_read(UC_MIPS_REG_ZERO) | |
at = uc.reg_read(UC_MIPS_REG_AT) | |
v0 = uc.reg_read(UC_MIPS_REG_V0) | |
v1 = uc.reg_read(UC_MIPS_REG_V1) | |
a0 = uc.reg_read(UC_MIPS_REG_A0) | |
a1 = uc.reg_read(UC_MIPS_REG_A1) | |
a2 = uc.reg_read(UC_MIPS_REG_A2) | |
a3 = uc.reg_read(UC_MIPS_REG_A3) | |
t0 = uc.reg_read(UC_MIPS_REG_T0) | |
t1 = uc.reg_read(UC_MIPS_REG_T1) | |
t2 = uc.reg_read(UC_MIPS_REG_T2) | |
t3 = uc.reg_read(UC_MIPS_REG_T3) | |
t4 = uc.reg_read(UC_MIPS_REG_T4) | |
t5 = uc.reg_read(UC_MIPS_REG_T5) | |
t6 = uc.reg_read(UC_MIPS_REG_T6) | |
t7 = uc.reg_read(UC_MIPS_REG_T7) | |
s0 = uc.reg_read(UC_MIPS_REG_S0) | |
s1 = uc.reg_read(UC_MIPS_REG_S1) | |
s2 = uc.reg_read(UC_MIPS_REG_S2) | |
s3 = uc.reg_read(UC_MIPS_REG_S3) | |
s4 = uc.reg_read(UC_MIPS_REG_S4) | |
s5 = uc.reg_read(UC_MIPS_REG_S5) | |
s6 = uc.reg_read(UC_MIPS_REG_S6) | |
s7 = uc.reg_read(UC_MIPS_REG_S7) | |
gp = uc.reg_read(UC_MIPS_REG_GP) | |
sp = uc.reg_read(UC_MIPS_REG_SP) | |
pc = uc.reg_read(UC_MIPS_REG_PC) | |
ra = uc.reg_read(UC_MIPS_REG_RA) | |
fp = uc.reg_read(UC_MIPS_REG_FP) | |
print " $0 = 0x%08x at = 0x%08x v0 = 0x%08x v1 = 0x%08x" % (zr, at, v0, v1) | |
print " a0 = 0x%08x a1 = 0x%08x a2 = 0x%08x a3 = 0x%08x" % (a0, a1, a2, a3) | |
print " t0 = 0x%08x t1 = 0x%08x t2 = 0x%08x t3 = 0x%08x" % (t0, t1, t2, t3) | |
print " t4 = 0x%08x t5 = 0x%08x t6 = 0x%08x t7 = 0x%08x" % (t4, t5, t6, t7) | |
print " s0 = 0x%08x s1 = 0x%08x s2 = 0x%08x s3 = 0x%08x" % (s0, s1, s2, s3) | |
print " s4 = 0x%08x s5 = 0x%08x s6 = 0x%08x s7 = 0x%08x" % (s4, s5, s6, s7) | |
print " gp = 0x%08x sp = 0x%08x pc = 0x%08x ra = 0x%08x" % (gp, sp, pc, ra) | |
print " fp = 0x%08x" % (fp) | |
global current_start | |
current_start = uc.reg_read(UC_MIPS_REG_PC) | |
if current_start == end_address: | |
current_start = None | |
uc.emu_stop() | |
PAGE_SIZE = 0x1000 | |
def _align_address(address): | |
return address & 0xFFFFF000 #// PAGE_SIZE * PAGE_SIZE | |
# Test MIPS EB | |
def test_mips_eb(): | |
try: | |
global current_start | |
global uc | |
#print "Emulate MIPS code (big-endian)" | |
# Initialize emulator in MIPS32 + EB mode | |
uc = Uc(UC_ARCH_MIPS, UC_MODE_MIPS32 + UC_MODE_BIG_ENDIAN) | |
address_aligned = _align_address(ADDRESS) | |
# map 2MB memory for this euclation | |
uc.mem_map(address_aligned, 2 * 1024 * 1024) | |
# write machine code to be euclated to memory | |
uc.mem_write(ADDRESS, MIPS_CODE_EB) | |
# tracing all instructions with customized callback | |
uc.hook_add(UC_HOOK_CODE, hook_code) | |
while current_start != None: | |
uc.emu_start(current_start, end_address+4, timeout=0, count=1) | |
# update current_start because single-step does not update | |
# the PC | |
if current_start is not None: | |
if current_start == 0x40079c: | |
current_start = 0x400790 | |
elif current_start == 0x400794: | |
current_start = 0x4007a4 | |
else: | |
current_start += 4 | |
# now print out some registers | |
print ">>> Emulation done. Below is the CPU context" | |
v0 = uc.reg_read(UC_MIPS_REG_V0) | |
print ">>> v0 = 0x%x" % v0 | |
except UcError as e: | |
print format_exc() | |
print "ERROR: %s" % e | |
if __name__ == '__main__': | |
test_mips_eb() | |
print "=" * 27 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment