From cbb2cf361824a82f1ab3f6eec1ceaa9ff09345b9 Mon Sep 17 00:00:00 2001 From: danghvu Date: Thu, 17 Sep 2015 15:45:15 -0500 Subject: [PATCH] Regress python testcases must define expected value via unittest --- regress/arm_bxeq_hang.py | 30 +++++++++---- regress/arm_movr12_hang.py | 37 +++++++++++----- regress/callback-pc.py | 54 +++++++++++++---------- regress/crash_tb.py | 33 ++++++++------ regress/deadlock_1.py | 17 ++++++-- regress/emu_stop_segfault.py | 21 ++++++--- regress/fpu_ip.py | 54 +++++++++++++---------- regress/fpu_ip64.py | 62 -------------------------- regress/fpu_mem_write.py | 37 +++++++++------- regress/hang.py | 36 +++++++++------- regress/jmp_ebx_hang.py | 56 ++++++++++++------------ regress/memmap.py | 38 +++++++++++++--- regress/memmap_assert.py | 8 ---- regress/memmap_segfault.py | 46 ++++++++++++-------- regress/memmap_segfault2.py | 8 ---- regress/memmap_weirdness.py | 12 ------ regress/mips_branch_delay.py | 44 +++++++++++-------- regress/mips_except.py | 53 ++++++++++++----------- regress/movsd.py | 19 +++++--- regress/pshufb.py | 19 +++++--- regress/reg_write_sign_extension.py | 22 +++++++--- regress/regress.py | 29 +++++++++++++ regress/wrong_rip.py | 67 +++++++++++++++++++++++------ regress/wrong_rip2.py | 32 -------------- regress/wrong_rip3.py | 23 ---------- regress/wrong_rip4.py | 32 -------------- regress/wrong_rip_arm.py | 35 ++++++++------- regress/wrong_sp_arm.py | 36 +++++++++------- regress/wrong_sp_arm64.py | 12 ------ 29 files changed, 501 insertions(+), 471 deletions(-) delete mode 100755 regress/fpu_ip64.py delete mode 100755 regress/memmap_assert.py delete mode 100755 regress/memmap_segfault2.py delete mode 100755 regress/memmap_weirdness.py create mode 100644 regress/regress.py delete mode 100755 regress/wrong_rip2.py delete mode 100755 regress/wrong_rip3.py delete mode 100755 regress/wrong_rip4.py delete mode 100755 regress/wrong_sp_arm64.py diff --git a/regress/arm_bxeq_hang.py b/regress/arm_bxeq_hang.py index 0e4a6116..b696112a 100755 --- a/regress/arm_bxeq_hang.py +++ b/regress/arm_bxeq_hang.py @@ -3,13 +3,25 @@ from unicorn import * from unicorn.arm_const import * -uc = Uc(UC_ARCH_ARM, UC_MODE_ARM) -uc.mem_map(0x1000, 0x1000) -uc.mem_write(0x1000, '1eff2f010000a0e1'.decode('hex')) -def hook_block(uc, addr, *args): - print 'enter block 0x%04x' % addr +import regress -uc.reg_write(UC_ARM_REG_LR, 0x1004) -uc.hook_add(UC_HOOK_BLOCK, hook_block) -print 'block should only run once' -uc.emu_start(0x1000, 0x1004, timeout=250) +class BxHang(regress.RegressTest): + + def runTest(self): + uc = Uc(UC_ARCH_ARM, UC_MODE_ARM) + uc.mem_map(0x1000, 0x1000) + uc.mem_write(0x1000, '1eff2f010000a0e1'.decode('hex')) + uc.count = 0 + def hook_block(uc, addr, *args): + print 'enter block 0x%04x' % addr + uc.count += 1 + + uc.reg_write(UC_ARM_REG_LR, 0x1004) + uc.hook_add(UC_HOOK_BLOCK, hook_block) + print 'block should only run once' + uc.emu_start(0x1000, 0x1004, timeout=500) + + self.assertEqual(uc.count, 1) + +if __name__ == '__main__': + regress.main() diff --git a/regress/arm_movr12_hang.py b/regress/arm_movr12_hang.py index befa4889..1bb276e0 100755 --- a/regress/arm_movr12_hang.py +++ b/regress/arm_movr12_hang.py @@ -3,15 +3,30 @@ from unicorn import * from unicorn.arm_const import * -uc = Uc(UC_ARCH_ARM, UC_MODE_ARM) -uc.mem_map(0x1000, 0x1000) -uc.mem_write(0x1000, '00c000e3'.decode('hex')) # movw r12, #0 -def hook_block(uc, addr, *args): - print 'enter block 0x%04x' % addr +import regress -uc.reg_write(UC_ARM_REG_R12, 0x123) -print 'r12 =', uc.reg_read(UC_ARM_REG_R12) -uc.hook_add(UC_HOOK_BLOCK, hook_block) -print 'block should only run once' -uc.emu_start(0x1000, 0x1004, timeout=250) -print 'r12 =', uc.reg_read(UC_ARM_REG_R12) +class MovHang(regress.RegressTest): + + def runTest(self): + uc = Uc(UC_ARCH_ARM, UC_MODE_ARM) + uc.mem_map(0x1000, 0x1000) + uc.mem_write(0x1000, '00c000e3'.decode('hex')) # movw r12, #0 + + def hook_block(uc, addr, *args): + print 'enter block 0x%04x' % addr + uc.count += 1 + + uc.reg_write(UC_ARM_REG_R12, 0x123) + self.assertEquals(uc.reg_read(UC_ARM_REG_R12), 0x123) + + uc.hook_add(UC_HOOK_BLOCK, hook_block) + uc.count = 0 + + #print 'block should only run once' + uc.emu_start(0x1000, 0x1004, timeout=500) + + self.assertEquals(uc.reg_read(UC_ARM_REG_R12), 0x0) + self.assertEquals(uc.count, 1) + +if __name__ == '__main__': + regress.main() diff --git a/regress/callback-pc.py b/regress/callback-pc.py index be35a244..3edc67e6 100755 --- a/regress/callback-pc.py +++ b/regress/callback-pc.py @@ -1,56 +1,64 @@ #!/usr/bin/env python # reg_write() can't modify PC from within trace callbacks +# Pull Request #4 from __future__ import print_function from unicorn import * from unicorn.arm_const import * +import regress + BASE_ADDRESS = 0x10000000 # sub sp, #0xc -THUMB_CODE = "\x83\xb0" * 5 +THUMB_CODE = "\x83\xb0" * 5 # callback for tracing instructions def hook_code(uc, address, size, user_data): print(">>> Tracing instruction at 0x%x, instruction size = %u" % (address, size)) mu = user_data print(">>> Setting PC to 0xffffffff") - mu.reg_write(ARM_REG_PC, 0xffffffff) + mu.reg_write(UC_ARM_REG_PC, 0xffffffff) # callback for tracing basic blocks def hook_block(uc, address, size, user_data): print(">>> Tracing basic block at 0x%x, block size = 0x%x" %(address, size)) mu = user_data print(">>> Setting PC to 0xffffffff") - mu.reg_write(ARM_REG_PC, 0xffffffff) + mu.reg_write(UC_ARM_REG_PC, 0xffffffff) -# set up emulation -def instruction_trace_test(): - try: - # initialize emulator in ARM's Thumb mode - mu = Uc(UC_ARCH_ARM, UC_MODE_THUMB) +class CallBackPCTest(regress.RegressTest): - # map some memory - mu.mem_map(BASE_ADDRESS, 2 * 1024 * 1024) + def runTest(self): + self.instruction_trace_test() - # write machine code to be emulated to memory - mu.mem_write(BASE_ADDRESS, THUMB_CODE) + # set up emulation + def instruction_trace_test(self): + try: + # initialize emulator in ARM's Thumb mode + mu = Uc(UC_ARCH_ARM, UC_MODE_THUMB) - # setup stack - mu.reg_write(UC_ARM_REG_SP, BASE_ADDRESS + 2 * 1024 * 1024) + # map some memory + mu.mem_map(BASE_ADDRESS, 2 * 1024 * 1024) - # tracing all instructions with customized callback - mu.hook_add(UC_HOOK_CODE, hook_code, user_data=mu) + # write machine code to be emulated to memory + mu.mem_write(BASE_ADDRESS, THUMB_CODE) - # tracing all basic blocks with customized callback - mu.hook_add(UC_HOOK_BLOCK, hook_block, user_data=mu) + # setup stack + mu.reg_write(UC_ARM_REG_SP, BASE_ADDRESS + 2 * 1024 * 1024) - # emulate machine code in infinite time - mu.emu_start(BASE_ADDRESS, BASE_ADDRESS + len(THUMB_CODE)) + # tracing all instructions with customized callback + mu.hook_add(UC_HOOK_CODE, hook_code, user_data=mu) - except UcError as e: - print("ERROR: %s" % e) + # tracing all basic blocks with customized callback + mu.hook_add(UC_HOOK_BLOCK, hook_block, user_data=mu) + + # emulate machine code in infinite time + mu.emu_start(BASE_ADDRESS, BASE_ADDRESS + len(THUMB_CODE)) + + except UcError as e: + assertFalse(0, "ERROR: %s" % e) if __name__ == '__main__': - instruction_trace_test() + regress.main() diff --git a/regress/crash_tb.py b/regress/crash_tb.py index d4f99723..9ecf61cd 100755 --- a/regress/crash_tb.py +++ b/regress/crash_tb.py @@ -3,30 +3,35 @@ from unicorn import * from unicorn.x86_const import * +import regress CODE_ADDR = 0x0 - - binary1 = b'\xb8\x02\x00\x00\x00' binary2 = b'\xb8\x01\x00\x00\x00' -mu = Uc(UC_ARCH_X86, UC_MODE_64) +class CrashTB(regress.RegressTest): -mu.mem_map(CODE_ADDR, 2 * 1024 * 1024) + def runTest(self): + mu = Uc(UC_ARCH_X86, UC_MODE_64) -# write machine code to be emulated to memory -mu.mem_write(CODE_ADDR, binary1) + mu.mem_map(CODE_ADDR, 2 * 1024 * 1024) -# emu for maximum 1 sec. -mu.emu_start(CODE_ADDR, len(binary1), UC_SECOND_SCALE) + # write machine code to be emulated to memory + mu.mem_write(CODE_ADDR, binary1) -print("RAX = %x" %mu.reg_read(UC_X86_REG_RAX)) + # emu for maximum 1 sec. + mu.emu_start(CODE_ADDR, len(binary1), UC_SECOND_SCALE) -# write machine code to be emulated to memory -mu.mem_write(CODE_ADDR, binary2) + self.assertEqual(0x2, mu.reg_read(UC_X86_REG_RAX)) -# emu for maximum 1 sec. -mu.emu_start(CODE_ADDR, len(binary2), UC_SECOND_SCALE) + # write machine code to be emulated to memory + mu.mem_write(CODE_ADDR, binary2) -print("RAX = %x" %mu.reg_read(UC_X86_REG_RAX)) + # emu for maximum 1 sec. + mu.emu_start(CODE_ADDR, len(binary2), UC_SECOND_SCALE) + + self.assertEqual(0x1, mu.reg_read(UC_X86_REG_RAX)) + +if __name__ == '__main__': + regress.main() diff --git a/regress/deadlock_1.py b/regress/deadlock_1.py index 702376a3..269a573f 100755 --- a/regress/deadlock_1.py +++ b/regress/deadlock_1.py @@ -2,10 +2,19 @@ # From issue #1 of Ryan Hileman from unicorn import * +import regress CODE = b"\x90\x91\x92" -mu = Uc(UC_ARCH_X86, UC_MODE_64) -mu.mem_map(0x100000, 4 * 1024) -mu.mem_write(0x100000, CODE) -mu.emu_start(0x100000, 0x1000 + len(CODE)) +class DeadLock(regress.RegressTest): + + def runTest(self): + mu = Uc(UC_ARCH_X86, UC_MODE_64) + mu.mem_map(0x100000, 4 * 1024) + mu.mem_write(0x100000, CODE) + + with self.assertRaises(UcError): + mu.emu_start(0x100000, 0x1000 + len(CODE)) + +if __name__ == '__main__': + regress.main() diff --git a/regress/emu_stop_segfault.py b/regress/emu_stop_segfault.py index 8021d86d..8c22e9de 100755 --- a/regress/emu_stop_segfault.py +++ b/regress/emu_stop_segfault.py @@ -3,11 +3,18 @@ """See https://github.com/unicorn-engine/unicorn/issues/65""" import unicorn -ADDR = 0x10101000 -mu = unicorn.Uc(unicorn.UC_ARCH_X86, unicorn.UC_MODE_32) -mu.mem_map(ADDR, 1024 * 4) -mu.mem_write(ADDR, b'\x41') -mu.emu_start(ADDR, ADDR + 1, count=1) -# The following should not trigger a null pointer dereference -mu.emu_stop() +import regress +class EmuStopSegFault(regress.RegressTest): + + def runTest(self): + ADDR = 0x10101000 + mu = unicorn.Uc(unicorn.UC_ARCH_X86, unicorn.UC_MODE_32) + mu.mem_map(ADDR, 1024 * 4) + mu.mem_write(ADDR, b'\x41') + mu.emu_start(ADDR, ADDR + 1, count=1) + # The following should not trigger a null pointer dereference + self.assertEqual(None, mu.emu_stop()) + +if __name__ == '__main__': + regress.main() diff --git a/regress/fpu_ip.py b/regress/fpu_ip.py index 77efa21b..3db6a8b5 100755 --- a/regress/fpu_ip.py +++ b/regress/fpu_ip.py @@ -2,6 +2,7 @@ from unicorn import * from unicorn.x86_const import * from capstone import * +import regress ESP = 0x2000 PAGE_SIZE = 2 * 1024 * 1024 @@ -29,33 +30,40 @@ def hook_code(uc, addr, size, user_data): print(" 0x%X:" % (addr)), disasm.disas_single(str(mem)) -def mem_reader(addr, size): - tmp = mu.mem_read(addr, size) +class FpuIP(regress.RegressTest): - for i in tmp: - print(" 0x%x" % i), - print("") + def mem_reader(self, mu, addr, size, expected): + tmp = mu.mem_read(addr, size) + for out, exp in zip(tmp, expected): + self.assertEqual(exp, out) + def test_32(self): + mu = Uc(UC_ARCH_X86, UC_MODE_32) -mu = Uc(UC_ARCH_X86, UC_MODE_32) + mu.mem_map(0x0, PAGE_SIZE) + mu.mem_write(0x4000, CODE) + mu.reg_write(UC_X86_REG_ESP, ESP) + mu.hook_add(UC_HOOK_CODE, hook_code) -mu.mem_map(0x0, PAGE_SIZE) -mu.mem_write(0x4000, CODE) -mu.reg_write(UC_X86_REG_ESP, ESP) -mu.hook_add(UC_HOOK_CODE, hook_code) + mu.emu_start(0x4000, 0, 0, 5) + esp = mu.reg_read(UC_X86_REG_ESP) + self.assertEqual(0x2004, esp) + expected = [0x0, 0x0, 0xa, 0x40] + self.mem_reader(mu, esp + 14, 4, expected) + def test_64(self): + mu = Uc(UC_ARCH_X86, UC_MODE_64) -mu.emu_start(0x4000, 0, 0, 5) -esp = mu.reg_read(UC_X86_REG_ESP) -print("value at ESP [0x%X - 4]: " % esp) -mem_reader(esp + 14, 4) + mu.mem_map(0x0, PAGE_SIZE) + mu.mem_write(0x4000, CODE) + mu.reg_write(UC_X86_REG_ESP, ESP) + mu.hook_add(UC_HOOK_CODE, hook_code) -# EXPECTED OUTPUT: -# 0x4000: mov dword ptr [esp], 0x37f -# 0x4007: fldcw word ptr [esp] -# 0x400A: fnop -# 0x400C: fnstenv dword ptr [esp + 8] -# 0x4010: pop ecx -# value at ESP [0x2004 - 4]: -# 0x0 0x0 0xa 0x40 -# ^ this value should match the fnop instuction addr \ No newline at end of file + mu.emu_start(0x4000, 0, 0, 5) + rsp = mu.reg_read(UC_X86_REG_RSP) + self.assertEqual(0x2012, rsp + 10) + expected = [0x0, 0x0, 0xa, 0x40, 0x0, 0x0, 0x0, 0x0] + self.mem_reader(mu, rsp + 10, 4, expected) + +if __name__ == '__main__': + regress.main() diff --git a/regress/fpu_ip64.py b/regress/fpu_ip64.py deleted file mode 100755 index dd0b5c1c..00000000 --- a/regress/fpu_ip64.py +++ /dev/null @@ -1,62 +0,0 @@ -#!/usr/bin/python -from unicorn import * -from unicorn.x86_const import * -from capstone import * - -ESP = 0x2000 -PAGE_SIZE = 2 * 1024 * 1024 - -# mov [esp], DWORD 0x37f -# fldcw [esp] -# fnop -# fnstenv [esp + 8] -# pop ecx -CODE = "C704247F030000D92C24D9D0D974240859".decode('hex') - -class SimpleEngine: - def __init__(self): - self.capmd = Cs(CS_ARCH_X86, CS_MODE_64) - - def disas_single(self, data): - for i in self.capmd.disasm(data, 16): - print("\t%s\t%s" % (i.mnemonic, i.op_str)) - break - -disasm = SimpleEngine() - -def hook_code(uc, addr, size, user_data): - mem = uc.mem_read(addr, size) - print(" 0x%X:" % (addr)), - disasm.disas_single(str(mem)) - -def mem_reader(addr, size): - tmp = mu.mem_read(addr, size) - - for i in tmp: - print(" 0x%x" % i), - print("") - - -mu = Uc(UC_ARCH_X86, UC_MODE_64) - -mu.mem_map(0x0, PAGE_SIZE) -mu.mem_write(0x4000, CODE) -mu.reg_write(UC_X86_REG_RSP, ESP) -mu.hook_add(UC_HOOK_CODE, hook_code) - - -mu.emu_start(0x4000, 0, 0, 5) -rsp = mu.reg_read(UC_X86_REG_RSP) -print("Value of FPIP: [0x%X]" % (rsp + 10)) -mem_reader(rsp + 10, 8) -# EXPECTED OUTPUT: - -# 0x4000: mov dword ptr [rsp], 0x37f -# 0x4007: fldcw word ptr [rsp] -# 0x400A: fnop -# 0x400C: fnstenv dword ptr [rsp + 8] -# 0x4010: pop rcx -# Value of FPIP: [0x2012] -# 0x0 0x0 0xa 0x40 0x0 0x0 0x0 0x0 - -# WHERE: the value of FPIP should be the address of fnop \ No newline at end of file diff --git a/regress/fpu_mem_write.py b/regress/fpu_mem_write.py index 730914a6..226a139e 100755 --- a/regress/fpu_mem_write.py +++ b/regress/fpu_mem_write.py @@ -2,6 +2,8 @@ from unicorn import * from unicorn.x86_const import * +import regress + ESP = 0x2000 PAGE_SIZE = 1 * 1024 * 1024 @@ -9,24 +11,27 @@ PAGE_SIZE = 1 * 1024 * 1024 # pop ecx CODE = b'\x9B\xD9\x3C\x24\x59' -def mem_reader(addr, size): - tmp = mu.mem_read(addr, size) - - for i in tmp: - print(" 0x%x" % i), - print("") - def hook_mem_write(uc, access, address, size, value, user_data): print("mem WRITE: 0x%x, data size = %u, data value = 0x%x" % (address, size, value)) return True -mu = Uc(UC_ARCH_X86, UC_MODE_32) -mu.mem_map(0, PAGE_SIZE) -mu.mem_write(0, CODE) -mu.reg_write(UC_X86_REG_ESP, ESP) -mu.hook_add(UC_HOOK_MEM_WRITE, hook_mem_write) +class FpuWrite(regress.RegressTest): -mu.emu_start(0x0, 0, 0, 2) -esp = mu.reg_read(UC_X86_REG_ESP) -print("value at ESP [0x%X]: " % esp) -mem_reader(esp, 10) \ No newline at end of file + def mem_reader(self, mu, addr, size, expected): + tmp = mu.mem_read(addr, size) + for i, e in zip(tmp, expected): + self.assertEquals(e, i) + + def runTest(self): + mu = Uc(UC_ARCH_X86, UC_MODE_32) + mu.mem_map(0, PAGE_SIZE) + mu.mem_write(0, CODE) + mu.reg_write(UC_X86_REG_ESP, ESP) + + mu.hook_add(UC_HOOK_MEM_WRITE, hook_mem_write) + mu.emu_start(0x0, 0, 0, 2) + esp = mu.reg_read(UC_X86_REG_ESP) + self.mem_reader(mu, esp, 10, [0] * 10) + +if __name__ == '__main__': + regress.main() diff --git a/regress/hang.py b/regress/hang.py index 50edaf2c..9c8a3775 100755 --- a/regress/hang.py +++ b/regress/hang.py @@ -4,6 +4,7 @@ from __future__ import print_function from unicorn import * from unicorn.x86_const import * +import regress # callback for tracing instructions def hook_code(uc, address, size, user_data): @@ -13,7 +14,6 @@ def hook_code(uc, address, size, user_data): print(" %02x" %i, end="") print("") - # callback for tracing Linux interrupt def hook_intr(uc, intno, user_data): # only handle Linux syscall @@ -26,28 +26,32 @@ def hook_intr(uc, intno, user_data): eax = uc.reg_read(UC_X86_REG_EAX) print(">>> 0x%x: interrupt 0x%x, EAX = 0x%x" %(rip, intno, eax)) +class Hang(regress.RegressTest): -binary1 = b'\xeb\x1c\x5a\x89\xd6\x8b\x02\x66\x3d\xca\x7d\x75\x06\x66\x05\x03\x03\x89\x02\xfe\xc2\x3d\x41\x41\x41\x41\x75\xe9\xff\xe6\xe8\xdf\xff\xff\xff\x31\xd2\x6a\x0b\x58\x99\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xca\x7d\x41\x41\x41\x41\x41\x41\x41\x41' + def runTest(self): + binary1 = b'\xeb\x1c\x5a\x89\xd6\x8b\x02\x66\x3d\xca\x7d\x75\x06\x66\x05\x03\x03\x89\x02\xfe\xc2\x3d\x41\x41\x41\x41\x75\xe9\xff\xe6\xe8\xdf\xff\xff\xff\x31\xd2\x6a\x0b\x58\x99\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xca\x7d\x41\x41\x41\x41\x41\x41\x41\x41' -mu = Uc(UC_ARCH_X86, UC_MODE_64) + mu = Uc(UC_ARCH_X86, UC_MODE_64) -mu.mem_map(0, 2 * 1024 * 1024) + mu.mem_map(0, 2 * 1024 * 1024) -# tracing all instructions with customized callback -mu.hook_add(UC_HOOK_CODE, hook_code) + # tracing all instructions with customized callback + mu.hook_add(UC_HOOK_CODE, hook_code) -# handle interrupt ourself -mu.hook_add(UC_HOOK_INTR, hook_intr) + # handle interrupt ourself + mu.hook_add(UC_HOOK_INTR, hook_intr) -# setup stack -mu.reg_write(UC_X86_REG_RSP, 1024 * 1024) + # setup stack + mu.reg_write(UC_X86_REG_RSP, 1024 * 1024) -# fill in memory with 0xCC (software breakpoint int 3) -for i in xrange(1 * 1024): - mu.mem_write(0 + i, b'\xcc') + # fill in memory with 0xCC (software breakpoint int 3) + for i in xrange(1 * 1024): + mu.mem_write(0 + i, b'\xcc') -# write machine code to be emulated to memory -mu.mem_write(0, binary1) + # write machine code to be emulated to memory + mu.mem_write(0, binary1) -mu.emu_start(0, len(binary1)) + self.assertEqual(mu.emu_start(0, len(binary1)), None) +if __name__ == '__main__': + regress.main() diff --git a/regress/jmp_ebx_hang.py b/regress/jmp_ebx_hang.py index 5683de89..602c594f 100755 --- a/regress/jmp_ebx_hang.py +++ b/regress/jmp_ebx_hang.py @@ -3,35 +3,37 @@ """See https://github.com/unicorn-engine/unicorn/issues/82""" import unicorn +from unicorn import * +import regress + CODE_ADDR = 0x10101000 CODE = b'\xff\xe3' # jmp ebx -mu = unicorn.Uc(unicorn.UC_ARCH_X86, unicorn.UC_MODE_32) -mu.mem_map(CODE_ADDR, 1024 * 4) -mu.mem_write(CODE_ADDR, CODE) -# If EBX is zero then an exception is raised, as expected -mu.reg_write(unicorn.x86_const.UC_X86_REG_EBX, 0x0) -print(">>> jmp ebx (ebx = 0)"); -try: - mu.emu_start(CODE_ADDR, CODE_ADDR + 2, count=1) -except unicorn.UcError as e: - print("ERROR: %s" % e) - assert(e.errno == unicorn.UC_ERR_CODE_INVALID) -else: - assert(False) +class JumEbxHang(regress.RegressTest): -print(">>> jmp ebx (ebx = 0xaa96a47f)"); -mu = unicorn.Uc(unicorn.UC_ARCH_X86, unicorn.UC_MODE_32) -mu.mem_map(CODE_ADDR, 1024 * 4) -# If we write this address to EBX then the emulator hangs on emu_start -mu.reg_write(unicorn.x86_const.UC_X86_REG_EBX, 0xaa96a47f) -mu.mem_write(CODE_ADDR, CODE) -try: - mu.emu_start(CODE_ADDR, CODE_ADDR + 2, count=1) -except unicorn.UcError as e: - print("ERROR: %s" % e) - assert(e.errno == unicorn.UC_ERR_CODE_INVALID) -else: - assert(False) + def runTest(self): + mu = unicorn.Uc(unicorn.UC_ARCH_X86, unicorn.UC_MODE_32) + mu.mem_map(CODE_ADDR, 1024 * 4) + mu.mem_write(CODE_ADDR, CODE) + # If EBX is zero then an exception is raised, as expected + mu.reg_write(unicorn.x86_const.UC_X86_REG_EBX, 0x0) -print "Success" + print(">>> jmp ebx (ebx = 0)"); + with self.assertRaises(UcError) as m: + mu.emu_start(CODE_ADDR, CODE_ADDR + 2, count=1) + + self.assertEqual(m.exception.errno, unicorn.UC_ERR_CODE_INVALID) + + print(">>> jmp ebx (ebx = 0xaa96a47f)"); + mu = unicorn.Uc(unicorn.UC_ARCH_X86, unicorn.UC_MODE_32) + mu.mem_map(CODE_ADDR, 1024 * 4) + # If we write this address to EBX then the emulator hangs on emu_start + mu.reg_write(unicorn.x86_const.UC_X86_REG_EBX, 0xaa96a47f) + mu.mem_write(CODE_ADDR, CODE) + with self.assertRaises(UcError) as m: + mu.emu_start(CODE_ADDR, CODE_ADDR + 2, count=1) + + self.assertEqual(m.exception.errno, unicorn.UC_ERR_CODE_INVALID) + +if __name__ == '__main__': + regress.main() diff --git a/regress/memmap.py b/regress/memmap.py index 2ac3508e..3252d51f 100755 --- a/regress/memmap.py +++ b/regress/memmap.py @@ -4,11 +4,37 @@ # this prints out 2 lines and the contents must be the same from unicorn import * -uc = Uc(UC_ARCH_X86, UC_MODE_64) +import regress -uc.mem_map(0x8048000, 0x2000) -uc.mem_write(0x8048000, 'test') -print 1, str(uc.mem_read(0x8048000, 4)).encode('hex') +class MemMap(regress.RegressTest): -uc.mem_map(0x804a000, 0x8000) -print 2, str(uc.mem_read(0x8048000, 4)).encode('hex') + def test_mmap_write(self): + uc = Uc(UC_ARCH_X86, UC_MODE_64) + + uc.mem_map(0x8048000, 0x2000) + uc.mem_write(0x8048000, 'test') + s1 = str(uc.mem_read(0x8048000, 4)).encode('hex') + + self.assertEqual('test'.encode('hex'), s1) + + uc.mem_map(0x804a000, 0x8000) + s2 = str(uc.mem_read(0x8048000, 4)).encode('hex') + self.assertEqual(s1, s2) + + def test_mmap_invalid(self): + u = unicorn.Uc(unicorn.UC_ARCH_X86, unicorn.UC_MODE_32) + with self.assertRaises(UcError): + u.mem_map(0x2000, 0) + with self.assertRaises(UcError): + u.mem_map(0x4000, 1) + + def test_mmap_weird(self): + u = unicorn.Uc(unicorn.UC_ARCH_X86, unicorn.UC_MODE_32) + + for i in xrange(20): + with self.assertRaises(UcError): + u.mem_map(i*0x1000, 5) + u.mem_read(i*0x1000+6, 1) + +if __name__ == '__main__': + regress.main() diff --git a/regress/memmap_assert.py b/regress/memmap_assert.py deleted file mode 100755 index cebdb8e1..00000000 --- a/regress/memmap_assert.py +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env python - -import unicorn - -u = unicorn.Uc(unicorn.UC_ARCH_X86, unicorn.UC_MODE_32) -u.mem_map(0x2000, 0) -u.mem_map(0x4000, 1) -print "I am never reached" diff --git a/regress/memmap_segfault.py b/regress/memmap_segfault.py index 83aea625..5d012b8b 100755 --- a/regress/memmap_segfault.py +++ b/regress/memmap_segfault.py @@ -1,25 +1,35 @@ #!/usr/bin/env python import unicorn +from unicorn import * -u = unicorn.Uc(unicorn.UC_ARCH_X86, unicorn.UC_MODE_32) -u.mem_map(0x2000, 0x1000) -u.mem_read(0x2000, 1) +import regress -for i in range(20): - try: +class MmapSeg(regress.RegressTest): + + def test_seg1(self): u = unicorn.Uc(unicorn.UC_ARCH_X86, unicorn.UC_MODE_32) - u.mem_map(i*0x1000, 5) - u.mem_read(i*0x1000, 1) - print hex(i*0x1000) + " succeeeded" - except unicorn.UcError: - print hex(i*0x1000) + " failed" + u.mem_map(0x2000, 0x1000) + u.mem_read(0x2000, 1) -for i in range(20): - try: - u = unicorn.Uc(unicorn.UC_ARCH_X86, unicorn.UC_MODE_32) - u.mem_map(i*0x1000, 5) - u.mem_read(i*0x1000, 1) - print hex(i*0x1000) + " succeeeded" - except unicorn.UcError: - print hex(i*0x1000) + " failed" + for i in range(50): + u = unicorn.Uc(unicorn.UC_ARCH_X86, unicorn.UC_MODE_32) + u.mem_map(i*0x1000, 0x1000) + u.mem_read(i*0x1000, 1) + + for i in range(20): + with self.assertRaises(UcError): + u = unicorn.Uc(unicorn.UC_ARCH_X86, unicorn.UC_MODE_32) + u.mem_map(i*0x1000, 5) + u.mem_read(i*0x1000, 1) + + def test_seg2(self): + uc = Uc(UC_ARCH_X86, UC_MODE_32) + uc.mem_map(0x0000, 0x2000) + uc.mem_map(0x2000, 0x4000) + uc.mem_write(0x1000, 0x1004 * ' ') + self.assertTrue(1, + 'If not reached, then we have BUG (crash on x86_64 Linux).') + +if __name__ == '__main__': + regress.main() diff --git a/regress/memmap_segfault2.py b/regress/memmap_segfault2.py deleted file mode 100755 index bd3845b7..00000000 --- a/regress/memmap_segfault2.py +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/python - -from unicorn import * -uc = Uc(UC_ARCH_X86, UC_MODE_32) -uc.mem_map(0x0000, 0x2000) -uc.mem_map(0x2000, 0x4000) -uc.mem_write(0x1000, 0x1004 * ' ') -print 'If not reached, then we have BUG (crash on x86_64 Linux).' diff --git a/regress/memmap_weirdness.py b/regress/memmap_weirdness.py deleted file mode 100755 index d81eccd6..00000000 --- a/regress/memmap_weirdness.py +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env python - -import unicorn - -for i in range(20): - #try: - u = unicorn.Uc(unicorn.UC_ARCH_X86, unicorn.UC_MODE_32) - u.mem_map(i*0x1000, 5) - u.mem_read(i*0x1000+6, 1) - print hex(i*0x1000) + " succeeeded" - #except unicorn.UcError as e: - # print hex(i*0x1000) + " failed:",e diff --git a/regress/mips_branch_delay.py b/regress/mips_branch_delay.py index 50a71a6f..db1bc2ac 100755 --- a/regress/mips_branch_delay.py +++ b/regress/mips_branch_delay.py @@ -3,27 +3,35 @@ from capstone import * from unicorn import * from unicorn.mips_const import * -md = Cs(CS_ARCH_MIPS, CS_MODE_MIPS32 + CS_MODE_LITTLE_ENDIAN) +import regress -def disas(code, addr): - for i in md.disasm(code, addr): - print '0x%x: %s %s' % (i.address, str(i.bytes).encode('hex'), i.op_str) +class MipsBranchDelay(regress.RegressTest): -def hook_code(uc, addr, size, _): - mem = str(uc.mem_read(addr, size)) - disas(mem, addr) + def runTest(self): + md = Cs(CS_ARCH_MIPS, CS_MODE_MIPS32 + CS_MODE_LITTLE_ENDIAN) -CODE = 0x400000 -asm = '0000a4126a00822800000000'.decode('hex') + def disas(code, addr): + for i in md.disasm(code, addr): + print '0x%x: %s %s' % (i.address, str(i.bytes).encode('hex'), i.op_str) -print 'Input instructions:' -disas(asm, CODE) -print + def hook_code(uc, addr, size, _): + mem = str(uc.mem_read(addr, size)) + disas(mem, addr) -print 'Hooked instructions:' + CODE = 0x400000 + asm = '0000a4126a00822800000000'.decode('hex') -uc = Uc(UC_ARCH_MIPS, UC_MODE_MIPS32 + UC_MODE_LITTLE_ENDIAN) -uc.hook_add(UC_HOOK_CODE, hook_code) -uc.mem_map(CODE, 0x1000) -uc.mem_write(CODE, asm) -uc.emu_start(CODE, CODE + len(asm)) + print 'Input instructions:' + disas(asm, CODE) + print + + print 'Hooked instructions:' + + uc = Uc(UC_ARCH_MIPS, UC_MODE_MIPS32 + UC_MODE_LITTLE_ENDIAN) + uc.hook_add(UC_HOOK_CODE, hook_code) + uc.mem_map(CODE, 0x1000) + uc.mem_write(CODE, asm) + self.assertEqual(None, uc.emu_start(CODE, CODE + len(asm))) + +if __name__ == '__main__': + regress.main() diff --git a/regress/mips_except.py b/regress/mips_except.py index 28c8001e..23969e9e 100755 --- a/regress/mips_except.py +++ b/regress/mips_except.py @@ -2,37 +2,40 @@ from unicorn import * from unicorn.mips_const import * +import regress + def hook_intr(uc, intno, _): print 'interrupt', intno CODE = 0x400000 asm = '0000a48f'.decode('hex') # lw $a0, ($sp) -uc = Uc(UC_ARCH_MIPS, UC_MODE_MIPS32 + UC_MODE_LITTLE_ENDIAN) -uc.hook_add(UC_HOOK_INTR, hook_intr) -uc.mem_map(CODE, 0x1000) -uc.mem_write(CODE, asm) +class MipsExcept(regress.RegressTest): -try: - print 'unaligned access (exc 12)' - uc.reg_write(UC_MIPS_REG_SP, 0x400001) - uc.emu_start(CODE, CODE + len(asm), 300) - print -except UcError as e: - print("ERROR: %s" % e) + def runTest(self): + uc = Uc(UC_ARCH_MIPS, UC_MODE_MIPS32 + UC_MODE_LITTLE_ENDIAN) + uc.hook_add(UC_HOOK_INTR, hook_intr) + uc.mem_map(CODE, 0x1000) + uc.mem_write(CODE, asm) -try: - print 'dunno (exc 26)' - uc.reg_write(UC_MIPS_REG_SP, 0xFFFFFFF0) - uc.emu_start(CODE, CODE + len(asm), 200) - print -except UcError as e: - print("ERROR: %s" % e) + with self.assertRaises(UcError) as m: + uc.reg_write(UC_MIPS_REG_SP, 0x400001) + uc.emu_start(CODE, CODE + len(asm), 300) + + self.assertEqual(UC_ERR_READ_UNALIGNED, m.exception.errno) + + with self.assertRaises(UcError) as m: + uc.reg_write(UC_MIPS_REG_SP, 0xFFFFFFF0) + uc.emu_start(CODE, CODE + len(asm), 200) + + self.assertEqual(UC_ERR_READ_INVALID, m.exception.errno) + + with self.assertRaises(UcError) as m: + uc.reg_write(UC_MIPS_REG_SP, 0x80000000) + uc.emu_start(CODE, CODE + len(asm), 100) + + self.assertEqual(UC_ERR_READ_INVALID, m.exception.errno) + +if __name__ == '__main__': + regress.main() -try: - print 'unassigned access (exc 28)' - uc.reg_write(UC_MIPS_REG_SP, 0x80000000) - uc.emu_start(CODE, CODE + len(asm), 100) - print -except UcError as e: - print("ERROR: %s" % e) diff --git a/regress/movsd.py b/regress/movsd.py index e873b1cd..28766139 100755 --- a/regress/movsd.py +++ b/regress/movsd.py @@ -5,6 +5,7 @@ from capstone import * from unicorn import * from unicorn.x86_const import * +import regress code = 'f20f1005aa120000'.decode('hex') def dis(mem, addr): @@ -20,9 +21,15 @@ def hook_code(uc, addr, size, user_data): print 'instruction:', str(mem).encode('hex'), dis(mem, addr) print 'reference: ', code.encode('hex'), dis(code, addr) -addr = 0x400000 -mu = Uc(UC_ARCH_X86, UC_MODE_64) -mu.hook_add(UC_HOOK_CODE, hook_code) -mu.mem_map(addr, 8 * 1024 * 1024) -mu.mem_write(addr, code) -mu.emu_start(addr, addr + len(code)) +class Movsd(regress.RegressTest): + + def runTest(self): + addr = 0x400000 + mu = Uc(UC_ARCH_X86, UC_MODE_64) + mu.hook_add(UC_HOOK_CODE, hook_code) + mu.mem_map(addr, 8 * 1024 * 1024) + mu.mem_write(addr, code) + mu.emu_start(addr, addr + len(code)) + +if __name__ == '__main__': + regress.main() diff --git a/regress/pshufb.py b/regress/pshufb.py index 432a2300..4e60b7dc 100755 --- a/regress/pshufb.py +++ b/regress/pshufb.py @@ -5,8 +5,17 @@ from unicorn import * from unicorn.x86_const import * -uc = Uc(UC_ARCH_X86, UC_MODE_64) -uc.mem_map(0x2000, 0x1000) -# pshufb xmm0, xmm1 -uc.mem_write(0x2000, '660f3800c1'.decode('hex')) -uc.emu_start(0x2000, 0x2005) + +import regress + +class Pshufb(regress.RegressTest): + + def runTest(self): + uc = Uc(UC_ARCH_X86, UC_MODE_64) + uc.mem_map(0x2000, 0x1000) + # pshufb xmm0, xmm1 + uc.mem_write(0x2000, '660f3800c1'.decode('hex')) + uc.emu_start(0x2000, 0x2005) + +if __name__ == '__main__': + regress.main() diff --git a/regress/reg_write_sign_extension.py b/regress/reg_write_sign_extension.py index 582e3ee5..e2838da2 100755 --- a/regress/reg_write_sign_extension.py +++ b/regress/reg_write_sign_extension.py @@ -3,6 +3,8 @@ """See https://github.com/unicorn-engine/unicorn/issues/98""" import unicorn +import regress + ADDR = 0xffaabbcc def hook_mem_invalid(mu, access, address, size, value, user_data): @@ -12,12 +14,18 @@ def hook_mem_invalid(mu, access, address, size, value, user_data): mu.mem_write(address, b'\xcc') return True -mu = unicorn.Uc(unicorn.UC_ARCH_X86, unicorn.UC_MODE_32) -mu.reg_write(unicorn.x86_const.UC_X86_REG_EBX, ADDR) +class RegWriteSignExt(regress.RegressTest): -mu.mem_map(0x10000000, 1024 * 4) -# jmp ebx -mu.mem_write(0x10000000, b'\xff\xe3') + def runTest(self): + mu = unicorn.Uc(unicorn.UC_ARCH_X86, unicorn.UC_MODE_32) + mu.reg_write(unicorn.x86_const.UC_X86_REG_EBX, ADDR) -mu.hook_add(unicorn.UC_HOOK_MEM_INVALID, hook_mem_invalid) -mu.emu_start(0x10000000, 0x10000000 + 2, count=1) + mu.mem_map(0x10000000, 1024 * 4) + # jmp ebx + mu.mem_write(0x10000000, b'\xff\xe3') + + mu.hook_add(unicorn.UC_HOOK_MEM_INVALID, hook_mem_invalid) + mu.emu_start(0x10000000, 0x10000000 + 2, count=1) + +if __name__ == '__main__': + regress.main() diff --git a/regress/regress.py b/regress/regress.py new file mode 100644 index 00000000..89aeef65 --- /dev/null +++ b/regress/regress.py @@ -0,0 +1,29 @@ +import unittest + +from os.path import dirname, basename, isfile +import glob + +# Find all unittest type in this directory and run it. + +class RegressTest(unittest.TestCase): + pass + +def main(): + unittest.main() + +if __name__ == '__main__': + modules = glob.glob(dirname(__file__)+"./*.py") + __all__ = [ basename(f)[:-3] for f in modules if isfile(f)] + suite = unittest.TestSuite() + + for module in __all__: + m = __import__(module) + for cl in dir(m): + try: + realcl = getattr(m,cl) + if issubclass(realcl, unittest.TestCase): + suite.addTest(realcl()) + except Exception as e: + pass + + unittest.TextTestRunner().run(suite) diff --git a/regress/wrong_rip.py b/regress/wrong_rip.py index 8c0b4c1f..87549806 100755 --- a/regress/wrong_rip.py +++ b/regress/wrong_rip.py @@ -3,30 +3,69 @@ from unicorn import * from unicorn.x86_const import * +import regress + binary1 = b'\xb8\x02\x00\x00\x00' # mov eax, 2 binary2 = b'\xb8\x01\x00\x00\x00' # mov eax, 1 -mu = Uc(UC_ARCH_X86, UC_MODE_64) +class WrongRIP(regress.RegressTest): -mu.mem_map(0, 2 * 1024 * 1024) + def test_step(self): + mu = Uc(UC_ARCH_X86, UC_MODE_64) + mu.mem_map(0, 2 * 1024 * 1024) + # write machine code to be emulated to memory + mu.mem_write(0, binary1 + binary2) + # emu for maximum 1 instruction. + mu.emu_start(0, 5, 0, 1) -# write machine code to be emulated to memory -mu.mem_write(0, binary1 + binary2) + self.assertEqual(0x2, mu.reg_read(UC_X86_REG_RAX)) + self.assertEqual(0x5, mu.reg_read(UC_X86_REG_RIP)) -# emu for maximum 1 instruction. -mu.emu_start(0, 5, 0, 1) + mu.emu_start(5, 10, 0, 1) + self.assertEqual(0xa, mu.reg_read(UC_X86_REG_RIP)) + self.assertEqual(0x1, mu.reg_read(UC_X86_REG_RAX)) -print("RAX = %u" %mu.reg_read(UC_X86_REG_RAX)) + def test_step2(self): + mu = Uc(UC_ARCH_X86, UC_MODE_64) + mu.mem_map(0, 2 * 1024 * 1024) + # write machine code to be emulated to memory + mu.mem_write(0, binary1 + binary2) + # emu for maximum 1 instruction. + mu.emu_start(0, 10, 0, 1) + self.assertEqual(0x2, mu.reg_read(UC_X86_REG_RAX)) + self.assertEqual(0x5, mu.reg_read(UC_X86_REG_RIP)) -pos = mu.reg_read(UC_X86_REG_RIP) + mu.emu_start(5, 10, 0, 1) + self.assertEqual(0x1, mu.reg_read(UC_X86_REG_RAX)) + self.assertEqual(0xa, mu.reg_read(UC_X86_REG_RIP)) -print("RIP = %x" %pos) + def test_step3(self): + bin3 = b'\x40\x01\xc1\x31\xf6' # inc eax; add ecx, eax; xor esi, esi + mu = Uc(UC_ARCH_X86, UC_MODE_32) + mu.mem_map(0, 2 * 1024 * 1024) + # write machine code to be emulated to memory + mu.mem_write(0, bin3) + # emu for maximum 1 instruction. + mu.emu_start(0, 10, 0, 1) + self.assertEqual(0x1, mu.reg_read(UC_X86_REG_EAX)) + self.assertEqual(0x1, mu.reg_read(UC_X86_REG_EIP)) -mu.emu_start(5, 10, 0, 1) + def test_step_then_fin(self): + bin4 = b'\x40\x01\xc1\x31\xf6\x90\x90\x90' # inc eax; add ecx, eax; xor esi, esi + mu = Uc(UC_ARCH_X86, UC_MODE_32) + mu.mem_map(0, 2 * 1024 * 1024) + # write machine code to be emulated to memory + mu.mem_write(0, bin4) + # emu for maximum 1 instruction. + mu.emu_start(0, len(binary1), 0, 1) -pos = mu.reg_read(UC_X86_REG_RIP) + self.assertEqual(0x1, mu.reg_read(UC_X86_REG_EAX)) + self.assertEqual(0x1, mu.reg_read(UC_X86_REG_EIP)) + # emu to the end + mu.emu_start(1, len(bin4)) + self.assertEqual(0x1, mu.reg_read(UC_X86_REG_EAX)) + self.assertEqual(len(bin4), mu.reg_read(UC_X86_REG_EIP)) -print("RIP = %x" %pos) - -print("RAX = %u" %mu.reg_read(UC_X86_REG_RAX)) +if __name__ == '__main__': + regress.main() diff --git a/regress/wrong_rip2.py b/regress/wrong_rip2.py deleted file mode 100755 index 24d028ce..00000000 --- a/regress/wrong_rip2.py +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/python - -from unicorn import * -from unicorn.x86_const import * - -binary1 = b'\xb8\x02\x00\x00\x00' # mov eax, 2 -binary2 = b'\xb8\x01\x00\x00\x00' # mov eax, 1 - -mu = Uc(UC_ARCH_X86, UC_MODE_64) - -mu.mem_map(0, 2 * 1024 * 1024) - -# write machine code to be emulated to memory -mu.mem_write(0, binary1 + binary2) - -# emu for maximum 1 instruction. -mu.emu_start(0, 10, 0, 1) - -print("RAX = %u" %mu.reg_read(UC_X86_REG_RAX)) - -pos = mu.reg_read(UC_X86_REG_RIP) - -print("RIP = %x" %pos) - -mu.emu_start(5, 10, 0, 1) - -pos = mu.reg_read(UC_X86_REG_RIP) - -print("RIP = %x" %pos) - -print("RAX = %u" %mu.reg_read(UC_X86_REG_RAX)) - diff --git a/regress/wrong_rip3.py b/regress/wrong_rip3.py deleted file mode 100755 index 77c90eef..00000000 --- a/regress/wrong_rip3.py +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/python - -from unicorn import * -from unicorn.x86_const import * - -binary1 = b'\x40\x01\xc1\x31\xf6' # inc eax; add ecx, eax; xor esi, esi - -mu = Uc(UC_ARCH_X86, UC_MODE_32) - -mu.mem_map(0, 2 * 1024 * 1024) - -# write machine code to be emulated to memory -mu.mem_write(0, binary1) - -# emu for maximum 1 instruction. -mu.emu_start(0, 10, 0, 1) - -print("EAX = %u" %mu.reg_read(UC_X86_REG_EAX)) - -pos = mu.reg_read(UC_X86_REG_EIP) - -print("EIP = %x" %pos) - diff --git a/regress/wrong_rip4.py b/regress/wrong_rip4.py deleted file mode 100755 index 9937483b..00000000 --- a/regress/wrong_rip4.py +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/python - -from unicorn import * -from unicorn.x86_const import * - -binary1 = b'\x40\x01\xc1\x31\xf6\x90\x90\x90' # inc eax; add ecx, eax; xor esi, esi - -mu = Uc(UC_ARCH_X86, UC_MODE_32) - -mu.mem_map(0, 2 * 1024 * 1024) - -# write machine code to be emulated to memory -mu.mem_write(0, binary1) - -pos = 0 -# emu for maximum 1 instruction. -mu.emu_start(pos, len(binary1), 0, 1) - -print("EAX = %u" %mu.reg_read(UC_X86_REG_EAX)) - -pos = mu.reg_read(UC_X86_REG_EIP) - -print("EIP = %x" %pos) - -# emu to the end -mu.emu_start(pos, len(binary1)) - -print("EAX = %u" %mu.reg_read(UC_X86_REG_EAX)) - -pos = mu.reg_read(UC_X86_REG_EIP) - -print("EIP = %x" %pos) diff --git a/regress/wrong_rip_arm.py b/regress/wrong_rip_arm.py index d10a47f3..de710d85 100755 --- a/regress/wrong_rip_arm.py +++ b/regress/wrong_rip_arm.py @@ -4,6 +4,8 @@ from unicorn import * from unicorn.x86_const import * from unicorn.arm_const import * +import regress + # adds r1, #0x48 # ldrsb r7, [r7, r7] # ldrsh r7, [r2, r1] @@ -14,26 +16,23 @@ from unicorn.arm_const import * # strb r7, [r5, #0xc] # ldr r0, [pc, #0x1a0] binary1 = b'\x48\x31\xff\x57\x57\x5e\x5a\x48\xbf\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xef\x08\x57\x54\x5f\x6a\x3b\x58\x0f\x05' -binary1 = b'\x48\x31\xff\x57' +# binary1 = b'\x48\x31\xff\x57' #adds r1, #0x48 #ldrsb r7, [r7, r7] -mu = Uc(UC_ARCH_ARM, UC_MODE_THUMB) +class WrongRIPArm(regress.RegressTest): -mu.mem_map(0, 2 * 1024 * 1024) + def runTest(self): + mu = Uc(UC_ARCH_ARM, UC_MODE_THUMB) + mu.mem_map(0, 2 * 1024 * 1024) + # write machine code to be emulated to memory + mu.mem_write(0, binary1) + mu.reg_write(UC_ARM_REG_R13, 1 * 1024 * 1024) + # emu for maximum 1 instruction. + mu.emu_start(0, len(binary1), 0, 1) + self.assertEqual(0x48, mu.reg_read(UC_ARM_REG_R1)) + pos = mu.reg_read(UC_ARM_REG_R15) + self.assertEqual(0x2, pos) -# write machine code to be emulated to memory -mu.mem_write(0, binary1) - -mu.reg_write(ARM_REG_R13, 1*1024*1024) - -pos = 0 - -# emu for maximum 1 instruction. -mu.emu_start(pos, len(binary1), 0, 1) - -print("R1 = %x" % mu.reg_read(ARM_REG_R1)) - -pos = mu.reg_read(ARM_REG_R15) - -print("RIP = %x" %pos) +if __name__ == '__main__': + regress.main() diff --git a/regress/wrong_sp_arm.py b/regress/wrong_sp_arm.py index 762210f3..13dbd36c 100755 --- a/regress/wrong_sp_arm.py +++ b/regress/wrong_sp_arm.py @@ -3,20 +3,26 @@ from unicorn import * from unicorn.arm_const import * +from unicorn.arm64_const import * -try: - uc = Uc(UC_ARCH_ARM, UC_MODE_32) - uc.reg_write(UC_ARM_REG_SP, 4) - print 'Writing 4 to SP' - print 'SP =', uc.reg_read(UC_ARM_REG_SP) -except UcError as e: - print("ERROR: %s" % e) +import regress -try: - print "===========" - uc = Uc(UC_ARCH_ARM, UC_MODE_ARM) - uc.reg_write(UC_ARM_REG_SP, 4) - print 'Writing 4 to SP' - print 'SP =', uc.reg_read(UC_ARM_REG_SP) -except UcError as e: - print("ERROR: %s" % e) +class WrongSPArm(regress.RegressTest): + + def test_32(self): + with self.assertRaises(UcError): + uc = Uc(UC_ARCH_ARM, UC_MODE_32) + uc.reg_write(UC_ARM_REG_SP, 4) + + def test_64(self): + uc = Uc(UC_ARCH_ARM64, UC_MODE_ARM) + uc.reg_write(UC_ARM64_REG_SP, 4) + self.assertEqual(0x4, uc.reg_read(UC_ARM64_REG_SP)) + + def test_arm(self): + uc = Uc(UC_ARCH_ARM, UC_MODE_ARM) + uc.reg_write(UC_ARM_REG_SP, 4) + self.assertEqual(0x4, uc.reg_read(UC_ARM_REG_SP)) + +if __name__ == '__main__': + regress.main() diff --git a/regress/wrong_sp_arm64.py b/regress/wrong_sp_arm64.py deleted file mode 100755 index d63791e1..00000000 --- a/regress/wrong_sp_arm64.py +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/python - -from unicorn import * -from unicorn.arm64_const import * - -try: - uc = Uc(UC_ARCH_ARM64, UC_MODE_ARM) - uc.reg_write(UC_ARM64_REG_SP, 4) - print 'Writing 4 to SP' - print 'SP =', uc.reg_read(UC_ARM64_REG_SP) -except UcError as e: - print("ERROR: %s" % e)