Regress python testcases must define expected value via unittest

This commit is contained in:
danghvu 2015-09-17 15:45:15 -05:00
parent 8c163706e4
commit cbb2cf3618
29 changed files with 501 additions and 471 deletions

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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
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()

View File

@ -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

View File

@ -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)
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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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"

View File

@ -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()

View File

@ -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).'

View File

@ -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

View File

@ -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()

View File

@ -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)

View File

@ -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()

View File

@ -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()

View File

@ -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()

29
regress/regress.py Normal file
View File

@ -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)

View File

@ -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()

View File

@ -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))

View File

@ -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)

View File

@ -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)

View File

@ -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()

View File

@ -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()

View File

@ -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)