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 import *
from unicorn.arm_const import * from unicorn.arm_const import *
import regress
class BxHang(regress.RegressTest):
def runTest(self):
uc = Uc(UC_ARCH_ARM, UC_MODE_ARM) uc = Uc(UC_ARCH_ARM, UC_MODE_ARM)
uc.mem_map(0x1000, 0x1000) uc.mem_map(0x1000, 0x1000)
uc.mem_write(0x1000, '1eff2f010000a0e1'.decode('hex')) uc.mem_write(0x1000, '1eff2f010000a0e1'.decode('hex'))
uc.count = 0
def hook_block(uc, addr, *args): def hook_block(uc, addr, *args):
print 'enter block 0x%04x' % addr print 'enter block 0x%04x' % addr
uc.count += 1
uc.reg_write(UC_ARM_REG_LR, 0x1004) uc.reg_write(UC_ARM_REG_LR, 0x1004)
uc.hook_add(UC_HOOK_BLOCK, hook_block) uc.hook_add(UC_HOOK_BLOCK, hook_block)
print 'block should only run once' print 'block should only run once'
uc.emu_start(0x1000, 0x1004, timeout=250) 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 import *
from unicorn.arm_const import * from unicorn.arm_const import *
import regress
class MovHang(regress.RegressTest):
def runTest(self):
uc = Uc(UC_ARCH_ARM, UC_MODE_ARM) uc = Uc(UC_ARCH_ARM, UC_MODE_ARM)
uc.mem_map(0x1000, 0x1000) uc.mem_map(0x1000, 0x1000)
uc.mem_write(0x1000, '00c000e3'.decode('hex')) # movw r12, #0 uc.mem_write(0x1000, '00c000e3'.decode('hex')) # movw r12, #0
def hook_block(uc, addr, *args): def hook_block(uc, addr, *args):
print 'enter block 0x%04x' % addr print 'enter block 0x%04x' % addr
uc.count += 1
uc.reg_write(UC_ARM_REG_R12, 0x123) uc.reg_write(UC_ARM_REG_R12, 0x123)
print 'r12 =', uc.reg_read(UC_ARM_REG_R12) self.assertEquals(uc.reg_read(UC_ARM_REG_R12), 0x123)
uc.hook_add(UC_HOOK_BLOCK, hook_block) uc.hook_add(UC_HOOK_BLOCK, hook_block)
print 'block should only run once' uc.count = 0
uc.emu_start(0x1000, 0x1004, timeout=250)
print 'r12 =', uc.reg_read(UC_ARM_REG_R12) #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,11 +1,14 @@
#!/usr/bin/env python #!/usr/bin/env python
# reg_write() can't modify PC from within trace callbacks # reg_write() can't modify PC from within trace callbacks
# Pull Request #4
from __future__ import print_function from __future__ import print_function
from unicorn import * from unicorn import *
from unicorn.arm_const import * from unicorn.arm_const import *
import regress
BASE_ADDRESS = 0x10000000 BASE_ADDRESS = 0x10000000
# sub sp, #0xc # sub sp, #0xc
@ -16,17 +19,22 @@ def hook_code(uc, address, size, user_data):
print(">>> Tracing instruction at 0x%x, instruction size = %u" % (address, size)) print(">>> Tracing instruction at 0x%x, instruction size = %u" % (address, size))
mu = user_data mu = user_data
print(">>> Setting PC to 0xffffffff") 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 # callback for tracing basic blocks
def hook_block(uc, address, size, user_data): def hook_block(uc, address, size, user_data):
print(">>> Tracing basic block at 0x%x, block size = 0x%x" %(address, size)) print(">>> Tracing basic block at 0x%x, block size = 0x%x" %(address, size))
mu = user_data mu = user_data
print(">>> Setting PC to 0xffffffff") print(">>> Setting PC to 0xffffffff")
mu.reg_write(ARM_REG_PC, 0xffffffff) mu.reg_write(UC_ARM_REG_PC, 0xffffffff)
class CallBackPCTest(regress.RegressTest):
def runTest(self):
self.instruction_trace_test()
# set up emulation # set up emulation
def instruction_trace_test(): def instruction_trace_test(self):
try: try:
# initialize emulator in ARM's Thumb mode # initialize emulator in ARM's Thumb mode
mu = Uc(UC_ARCH_ARM, UC_MODE_THUMB) mu = Uc(UC_ARCH_ARM, UC_MODE_THUMB)
@ -50,7 +58,7 @@ def instruction_trace_test():
mu.emu_start(BASE_ADDRESS, BASE_ADDRESS + len(THUMB_CODE)) mu.emu_start(BASE_ADDRESS, BASE_ADDRESS + len(THUMB_CODE))
except UcError as e: except UcError as e:
print("ERROR: %s" % e) assertFalse(0, "ERROR: %s" % e)
if __name__ == '__main__': if __name__ == '__main__':
instruction_trace_test() regress.main()

View File

@ -3,13 +3,15 @@
from unicorn import * from unicorn import *
from unicorn.x86_const import * from unicorn.x86_const import *
import regress
CODE_ADDR = 0x0 CODE_ADDR = 0x0
binary1 = b'\xb8\x02\x00\x00\x00' binary1 = b'\xb8\x02\x00\x00\x00'
binary2 = b'\xb8\x01\x00\x00\x00' binary2 = b'\xb8\x01\x00\x00\x00'
class CrashTB(regress.RegressTest):
def runTest(self):
mu = Uc(UC_ARCH_X86, UC_MODE_64) mu = Uc(UC_ARCH_X86, UC_MODE_64)
mu.mem_map(CODE_ADDR, 2 * 1024 * 1024) mu.mem_map(CODE_ADDR, 2 * 1024 * 1024)
@ -20,7 +22,7 @@ mu.mem_write(CODE_ADDR, binary1)
# emu for maximum 1 sec. # emu for maximum 1 sec.
mu.emu_start(CODE_ADDR, len(binary1), UC_SECOND_SCALE) mu.emu_start(CODE_ADDR, len(binary1), UC_SECOND_SCALE)
print("RAX = %x" %mu.reg_read(UC_X86_REG_RAX)) self.assertEqual(0x2, mu.reg_read(UC_X86_REG_RAX))
# write machine code to be emulated to memory # write machine code to be emulated to memory
mu.mem_write(CODE_ADDR, binary2) mu.mem_write(CODE_ADDR, binary2)
@ -28,5 +30,8 @@ mu.mem_write(CODE_ADDR, binary2)
# emu for maximum 1 sec. # emu for maximum 1 sec.
mu.emu_start(CODE_ADDR, len(binary2), UC_SECOND_SCALE) mu.emu_start(CODE_ADDR, len(binary2), UC_SECOND_SCALE)
print("RAX = %x" %mu.reg_read(UC_X86_REG_RAX)) 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 issue #1 of Ryan Hileman
from unicorn import * from unicorn import *
import regress
CODE = b"\x90\x91\x92" CODE = b"\x90\x91\x92"
class DeadLock(regress.RegressTest):
def runTest(self):
mu = Uc(UC_ARCH_X86, UC_MODE_64) mu = Uc(UC_ARCH_X86, UC_MODE_64)
mu.mem_map(0x100000, 4 * 1024) mu.mem_map(0x100000, 4 * 1024)
mu.mem_write(0x100000, CODE) mu.mem_write(0x100000, CODE)
with self.assertRaises(UcError):
mu.emu_start(0x100000, 0x1000 + len(CODE)) 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""" """See https://github.com/unicorn-engine/unicorn/issues/65"""
import unicorn import unicorn
import regress
class EmuStopSegFault(regress.RegressTest):
def runTest(self):
ADDR = 0x10101000 ADDR = 0x10101000
mu = unicorn.Uc(unicorn.UC_ARCH_X86, unicorn.UC_MODE_32) mu = unicorn.Uc(unicorn.UC_ARCH_X86, unicorn.UC_MODE_32)
mu.mem_map(ADDR, 1024 * 4) mu.mem_map(ADDR, 1024 * 4)
mu.mem_write(ADDR, b'\x41') mu.mem_write(ADDR, b'\x41')
mu.emu_start(ADDR, ADDR + 1, count=1) mu.emu_start(ADDR, ADDR + 1, count=1)
# The following should not trigger a null pointer dereference # The following should not trigger a null pointer dereference
mu.emu_stop() self.assertEqual(None, mu.emu_stop())
if __name__ == '__main__':
regress.main()

View File

@ -2,6 +2,7 @@
from unicorn import * from unicorn import *
from unicorn.x86_const import * from unicorn.x86_const import *
from capstone import * from capstone import *
import regress
ESP = 0x2000 ESP = 0x2000
PAGE_SIZE = 2 * 1024 * 1024 PAGE_SIZE = 2 * 1024 * 1024
@ -29,14 +30,14 @@ def hook_code(uc, addr, size, user_data):
print(" 0x%X:" % (addr)), print(" 0x%X:" % (addr)),
disasm.disas_single(str(mem)) disasm.disas_single(str(mem))
def mem_reader(addr, size): class FpuIP(regress.RegressTest):
def mem_reader(self, mu, addr, size, expected):
tmp = mu.mem_read(addr, size) tmp = mu.mem_read(addr, size)
for out, exp in zip(tmp, expected):
self.assertEqual(exp, out)
for i in tmp: def test_32(self):
print(" 0x%x" % i),
print("")
mu = Uc(UC_ARCH_X86, UC_MODE_32) mu = Uc(UC_ARCH_X86, UC_MODE_32)
mu.mem_map(0x0, PAGE_SIZE) mu.mem_map(0x0, PAGE_SIZE)
@ -44,18 +45,25 @@ mu.mem_write(0x4000, CODE)
mu.reg_write(UC_X86_REG_ESP, ESP) mu.reg_write(UC_X86_REG_ESP, ESP)
mu.hook_add(UC_HOOK_CODE, hook_code) mu.hook_add(UC_HOOK_CODE, hook_code)
mu.emu_start(0x4000, 0, 0, 5) mu.emu_start(0x4000, 0, 0, 5)
esp = mu.reg_read(UC_X86_REG_ESP) esp = mu.reg_read(UC_X86_REG_ESP)
print("value at ESP [0x%X - 4]: " % esp) self.assertEqual(0x2004, esp)
mem_reader(esp + 14, 4) expected = [0x0, 0x0, 0xa, 0x40]
self.mem_reader(mu, esp + 14, 4, expected)
# EXPECTED OUTPUT: def test_64(self):
# 0x4000: mov dword ptr [esp], 0x37f mu = Uc(UC_ARCH_X86, UC_MODE_64)
# 0x4007: fldcw word ptr [esp]
# 0x400A: fnop mu.mem_map(0x0, PAGE_SIZE)
# 0x400C: fnstenv dword ptr [esp + 8] mu.mem_write(0x4000, CODE)
# 0x4010: pop ecx mu.reg_write(UC_X86_REG_ESP, ESP)
# value at ESP [0x2004 - 4]: mu.hook_add(UC_HOOK_CODE, hook_code)
# 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 import *
from unicorn.x86_const import * from unicorn.x86_const import *
import regress
ESP = 0x2000 ESP = 0x2000
PAGE_SIZE = 1 * 1024 * 1024 PAGE_SIZE = 1 * 1024 * 1024
@ -9,24 +11,27 @@ PAGE_SIZE = 1 * 1024 * 1024
# pop ecx # pop ecx
CODE = b'\x9B\xD9\x3C\x24\x59' 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): 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)) print("mem WRITE: 0x%x, data size = %u, data value = 0x%x" % (address, size, value))
return True return True
class FpuWrite(regress.RegressTest):
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 = Uc(UC_ARCH_X86, UC_MODE_32)
mu.mem_map(0, PAGE_SIZE) mu.mem_map(0, PAGE_SIZE)
mu.mem_write(0, CODE) mu.mem_write(0, CODE)
mu.reg_write(UC_X86_REG_ESP, ESP) mu.reg_write(UC_X86_REG_ESP, ESP)
mu.hook_add(UC_HOOK_MEM_WRITE, hook_mem_write)
mu.hook_add(UC_HOOK_MEM_WRITE, hook_mem_write)
mu.emu_start(0x0, 0, 0, 2) mu.emu_start(0x0, 0, 0, 2)
esp = mu.reg_read(UC_X86_REG_ESP) esp = mu.reg_read(UC_X86_REG_ESP)
print("value at ESP [0x%X]: " % esp) self.mem_reader(mu, esp, 10, [0] * 10)
mem_reader(esp, 10)
if __name__ == '__main__':
regress.main()

View File

@ -4,6 +4,7 @@ from __future__ import print_function
from unicorn import * from unicorn import *
from unicorn.x86_const import * from unicorn.x86_const import *
import regress
# callback for tracing instructions # callback for tracing instructions
def hook_code(uc, address, size, user_data): 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(" %02x" %i, end="")
print("") print("")
# callback for tracing Linux interrupt # callback for tracing Linux interrupt
def hook_intr(uc, intno, user_data): def hook_intr(uc, intno, user_data):
# only handle Linux syscall # only handle Linux syscall
@ -26,7 +26,9 @@ def hook_intr(uc, intno, user_data):
eax = uc.reg_read(UC_X86_REG_EAX) eax = uc.reg_read(UC_X86_REG_EAX)
print(">>> 0x%x: interrupt 0x%x, EAX = 0x%x" %(rip, intno, eax)) print(">>> 0x%x: interrupt 0x%x, EAX = 0x%x" %(rip, intno, eax))
class Hang(regress.RegressTest):
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' 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)
@ -49,5 +51,7 @@ for i in xrange(1 * 1024):
# write machine code to be emulated to memory # write machine code to be emulated to memory
mu.mem_write(0, binary1) 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,8 +3,15 @@
"""See https://github.com/unicorn-engine/unicorn/issues/82""" """See https://github.com/unicorn-engine/unicorn/issues/82"""
import unicorn import unicorn
from unicorn import *
import regress
CODE_ADDR = 0x10101000 CODE_ADDR = 0x10101000
CODE = b'\xff\xe3' # jmp ebx CODE = b'\xff\xe3' # jmp ebx
class JumEbxHang(regress.RegressTest):
def runTest(self):
mu = unicorn.Uc(unicorn.UC_ARCH_X86, unicorn.UC_MODE_32) mu = unicorn.Uc(unicorn.UC_ARCH_X86, unicorn.UC_MODE_32)
mu.mem_map(CODE_ADDR, 1024 * 4) mu.mem_map(CODE_ADDR, 1024 * 4)
mu.mem_write(CODE_ADDR, CODE) mu.mem_write(CODE_ADDR, CODE)
@ -12,13 +19,10 @@ mu.mem_write(CODE_ADDR, CODE)
mu.reg_write(unicorn.x86_const.UC_X86_REG_EBX, 0x0) mu.reg_write(unicorn.x86_const.UC_X86_REG_EBX, 0x0)
print(">>> jmp ebx (ebx = 0)"); print(">>> jmp ebx (ebx = 0)");
try: with self.assertRaises(UcError) as m:
mu.emu_start(CODE_ADDR, CODE_ADDR + 2, count=1) mu.emu_start(CODE_ADDR, CODE_ADDR + 2, count=1)
except unicorn.UcError as e:
print("ERROR: %s" % e) self.assertEqual(m.exception.errno, unicorn.UC_ERR_CODE_INVALID)
assert(e.errno == unicorn.UC_ERR_CODE_INVALID)
else:
assert(False)
print(">>> jmp ebx (ebx = 0xaa96a47f)"); print(">>> jmp ebx (ebx = 0xaa96a47f)");
mu = unicorn.Uc(unicorn.UC_ARCH_X86, unicorn.UC_MODE_32) mu = unicorn.Uc(unicorn.UC_ARCH_X86, unicorn.UC_MODE_32)
@ -26,12 +30,10 @@ mu.mem_map(CODE_ADDR, 1024 * 4)
# If we write this address to EBX then the emulator hangs on emu_start # 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.reg_write(unicorn.x86_const.UC_X86_REG_EBX, 0xaa96a47f)
mu.mem_write(CODE_ADDR, CODE) mu.mem_write(CODE_ADDR, CODE)
try: with self.assertRaises(UcError) as m:
mu.emu_start(CODE_ADDR, CODE_ADDR + 2, count=1) 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)
print "Success" 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 # this prints out 2 lines and the contents must be the same
from unicorn import * from unicorn import *
import regress
class MemMap(regress.RegressTest):
def test_mmap_write(self):
uc = Uc(UC_ARCH_X86, UC_MODE_64) uc = Uc(UC_ARCH_X86, UC_MODE_64)
uc.mem_map(0x8048000, 0x2000) uc.mem_map(0x8048000, 0x2000)
uc.mem_write(0x8048000, 'test') uc.mem_write(0x8048000, 'test')
print 1, str(uc.mem_read(0x8048000, 4)).encode('hex') s1 = str(uc.mem_read(0x8048000, 4)).encode('hex')
self.assertEqual('test'.encode('hex'), s1)
uc.mem_map(0x804a000, 0x8000) uc.mem_map(0x804a000, 0x8000)
print 2, str(uc.mem_read(0x8048000, 4)).encode('hex') 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 #!/usr/bin/env python
import unicorn import unicorn
from unicorn import *
import regress
class MmapSeg(regress.RegressTest):
def test_seg1(self):
u = unicorn.Uc(unicorn.UC_ARCH_X86, unicorn.UC_MODE_32) u = unicorn.Uc(unicorn.UC_ARCH_X86, unicorn.UC_MODE_32)
u.mem_map(0x2000, 0x1000) u.mem_map(0x2000, 0x1000)
u.mem_read(0x2000, 1) u.mem_read(0x2000, 1)
for i in range(20): for i in range(50):
try:
u = unicorn.Uc(unicorn.UC_ARCH_X86, unicorn.UC_MODE_32) u = unicorn.Uc(unicorn.UC_ARCH_X86, unicorn.UC_MODE_32)
u.mem_map(i*0x1000, 5) u.mem_map(i*0x1000, 0x1000)
u.mem_read(i*0x1000, 1) u.mem_read(i*0x1000, 1)
print hex(i*0x1000) + " succeeeded"
except unicorn.UcError:
print hex(i*0x1000) + " failed"
for i in range(20): for i in range(20):
try: with self.assertRaises(UcError):
u = unicorn.Uc(unicorn.UC_ARCH_X86, unicorn.UC_MODE_32) u = unicorn.Uc(unicorn.UC_ARCH_X86, unicorn.UC_MODE_32)
u.mem_map(i*0x1000, 5) u.mem_map(i*0x1000, 5)
u.mem_read(i*0x1000, 1) u.mem_read(i*0x1000, 1)
print hex(i*0x1000) + " succeeeded"
except unicorn.UcError: def test_seg2(self):
print hex(i*0x1000) + " failed" 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,6 +3,11 @@ from capstone import *
from unicorn import * from unicorn import *
from unicorn.mips_const import * from unicorn.mips_const import *
import regress
class MipsBranchDelay(regress.RegressTest):
def runTest(self):
md = Cs(CS_ARCH_MIPS, CS_MODE_MIPS32 + CS_MODE_LITTLE_ENDIAN) md = Cs(CS_ARCH_MIPS, CS_MODE_MIPS32 + CS_MODE_LITTLE_ENDIAN)
def disas(code, addr): def disas(code, addr):
@ -26,4 +31,7 @@ uc = Uc(UC_ARCH_MIPS, UC_MODE_MIPS32 + UC_MODE_LITTLE_ENDIAN)
uc.hook_add(UC_HOOK_CODE, hook_code) uc.hook_add(UC_HOOK_CODE, hook_code)
uc.mem_map(CODE, 0x1000) uc.mem_map(CODE, 0x1000)
uc.mem_write(CODE, asm) uc.mem_write(CODE, asm)
uc.emu_start(CODE, CODE + len(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 import *
from unicorn.mips_const import * from unicorn.mips_const import *
import regress
def hook_intr(uc, intno, _): def hook_intr(uc, intno, _):
print 'interrupt', intno print 'interrupt', intno
CODE = 0x400000 CODE = 0x400000
asm = '0000a48f'.decode('hex') # lw $a0, ($sp) asm = '0000a48f'.decode('hex') # lw $a0, ($sp)
class MipsExcept(regress.RegressTest):
def runTest(self):
uc = Uc(UC_ARCH_MIPS, UC_MODE_MIPS32 + UC_MODE_LITTLE_ENDIAN) uc = Uc(UC_ARCH_MIPS, UC_MODE_MIPS32 + UC_MODE_LITTLE_ENDIAN)
uc.hook_add(UC_HOOK_INTR, hook_intr) uc.hook_add(UC_HOOK_INTR, hook_intr)
uc.mem_map(CODE, 0x1000) uc.mem_map(CODE, 0x1000)
uc.mem_write(CODE, asm) uc.mem_write(CODE, asm)
try: with self.assertRaises(UcError) as m:
print 'unaligned access (exc 12)'
uc.reg_write(UC_MIPS_REG_SP, 0x400001) uc.reg_write(UC_MIPS_REG_SP, 0x400001)
uc.emu_start(CODE, CODE + len(asm), 300) uc.emu_start(CODE, CODE + len(asm), 300)
print
except UcError as e:
print("ERROR: %s" % e)
try: self.assertEqual(UC_ERR_READ_UNALIGNED, m.exception.errno)
print 'dunno (exc 26)'
with self.assertRaises(UcError) as m:
uc.reg_write(UC_MIPS_REG_SP, 0xFFFFFFF0) uc.reg_write(UC_MIPS_REG_SP, 0xFFFFFFF0)
uc.emu_start(CODE, CODE + len(asm), 200) uc.emu_start(CODE, CODE + len(asm), 200)
print
except UcError as e:
print("ERROR: %s" % e)
try: self.assertEqual(UC_ERR_READ_INVALID, m.exception.errno)
print 'unassigned access (exc 28)'
with self.assertRaises(UcError) as m:
uc.reg_write(UC_MIPS_REG_SP, 0x80000000) uc.reg_write(UC_MIPS_REG_SP, 0x80000000)
uc.emu_start(CODE, CODE + len(asm), 100) uc.emu_start(CODE, CODE + len(asm), 100)
print
except UcError as e: self.assertEqual(UC_ERR_READ_INVALID, m.exception.errno)
print("ERROR: %s" % e)
if __name__ == '__main__':
regress.main()

View File

@ -5,6 +5,7 @@ from capstone import *
from unicorn import * from unicorn import *
from unicorn.x86_const import * from unicorn.x86_const import *
import regress
code = 'f20f1005aa120000'.decode('hex') code = 'f20f1005aa120000'.decode('hex')
def dis(mem, addr): 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 'instruction:', str(mem).encode('hex'), dis(mem, addr)
print 'reference: ', code.encode('hex'), dis(code, addr) print 'reference: ', code.encode('hex'), dis(code, addr)
class Movsd(regress.RegressTest):
def runTest(self):
addr = 0x400000 addr = 0x400000
mu = Uc(UC_ARCH_X86, UC_MODE_64) mu = Uc(UC_ARCH_X86, UC_MODE_64)
mu.hook_add(UC_HOOK_CODE, hook_code) mu.hook_add(UC_HOOK_CODE, hook_code)
mu.mem_map(addr, 8 * 1024 * 1024) mu.mem_map(addr, 8 * 1024 * 1024)
mu.mem_write(addr, code) mu.mem_write(addr, code)
mu.emu_start(addr, addr + len(code)) mu.emu_start(addr, addr + len(code))
if __name__ == '__main__':
regress.main()

View File

@ -5,8 +5,17 @@
from unicorn import * from unicorn import *
from unicorn.x86_const import * from unicorn.x86_const import *
import regress
class Pshufb(regress.RegressTest):
def runTest(self):
uc = Uc(UC_ARCH_X86, UC_MODE_64) uc = Uc(UC_ARCH_X86, UC_MODE_64)
uc.mem_map(0x2000, 0x1000) uc.mem_map(0x2000, 0x1000)
# pshufb xmm0, xmm1 # pshufb xmm0, xmm1
uc.mem_write(0x2000, '660f3800c1'.decode('hex')) uc.mem_write(0x2000, '660f3800c1'.decode('hex'))
uc.emu_start(0x2000, 0x2005) 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""" """See https://github.com/unicorn-engine/unicorn/issues/98"""
import unicorn import unicorn
import regress
ADDR = 0xffaabbcc ADDR = 0xffaabbcc
def hook_mem_invalid(mu, access, address, size, value, user_data): def hook_mem_invalid(mu, access, address, size, value, user_data):
@ -12,6 +14,9 @@ def hook_mem_invalid(mu, access, address, size, value, user_data):
mu.mem_write(address, b'\xcc') mu.mem_write(address, b'\xcc')
return True return True
class RegWriteSignExt(regress.RegressTest):
def runTest(self):
mu = unicorn.Uc(unicorn.UC_ARCH_X86, unicorn.UC_MODE_32) mu = unicorn.Uc(unicorn.UC_ARCH_X86, unicorn.UC_MODE_32)
mu.reg_write(unicorn.x86_const.UC_X86_REG_EBX, ADDR) mu.reg_write(unicorn.x86_const.UC_X86_REG_EBX, ADDR)
@ -21,3 +26,6 @@ mu.mem_write(0x10000000, b'\xff\xe3')
mu.hook_add(unicorn.UC_HOOK_MEM_INVALID, hook_mem_invalid) mu.hook_add(unicorn.UC_HOOK_MEM_INVALID, hook_mem_invalid)
mu.emu_start(0x10000000, 0x10000000 + 2, count=1) 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 import *
from unicorn.x86_const import * from unicorn.x86_const import *
import regress
binary1 = b'\xb8\x02\x00\x00\x00' # mov eax, 2 binary1 = b'\xb8\x02\x00\x00\x00' # mov eax, 2
binary2 = b'\xb8\x01\x00\x00\x00' # mov eax, 1 binary2 = b'\xb8\x01\x00\x00\x00' # mov eax, 1
class WrongRIP(regress.RegressTest):
def test_step(self):
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)
# write machine code to be emulated to memory # write machine code to be emulated to memory
mu.mem_write(0, binary1 + binary2) mu.mem_write(0, binary1 + binary2)
# emu for maximum 1 instruction. # emu for maximum 1 instruction.
mu.emu_start(0, 5, 0, 1) mu.emu_start(0, 5, 0, 1)
print("RAX = %u" %mu.reg_read(UC_X86_REG_RAX)) 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)
print("RIP = %x" %pos)
mu.emu_start(5, 10, 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))
pos = mu.reg_read(UC_X86_REG_RIP) 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))
print("RIP = %x" %pos) 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("RAX = %u" %mu.reg_read(UC_X86_REG_RAX)) 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))
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)
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))
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.x86_const import *
from unicorn.arm_const import * from unicorn.arm_const import *
import regress
# adds r1, #0x48 # adds r1, #0x48
# ldrsb r7, [r7, r7] # ldrsb r7, [r7, r7]
# ldrsh r7, [r2, r1] # ldrsh r7, [r2, r1]
@ -14,26 +16,23 @@ from unicorn.arm_const import *
# strb r7, [r5, #0xc] # strb r7, [r5, #0xc]
# ldr r0, [pc, #0x1a0] # 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\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 #adds r1, #0x48
#ldrsb r7, [r7, r7] #ldrsb r7, [r7, r7]
class WrongRIPArm(regress.RegressTest):
def runTest(self):
mu = Uc(UC_ARCH_ARM, UC_MODE_THUMB) mu = Uc(UC_ARCH_ARM, UC_MODE_THUMB)
mu.mem_map(0, 2 * 1024 * 1024) mu.mem_map(0, 2 * 1024 * 1024)
# write machine code to be emulated to memory # write machine code to be emulated to memory
mu.mem_write(0, binary1) mu.mem_write(0, binary1)
mu.reg_write(UC_ARM_REG_R13, 1 * 1024 * 1024)
mu.reg_write(ARM_REG_R13, 1*1024*1024)
pos = 0
# emu for maximum 1 instruction. # emu for maximum 1 instruction.
mu.emu_start(pos, len(binary1), 0, 1) 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)
print("R1 = %x" % mu.reg_read(ARM_REG_R1)) if __name__ == '__main__':
regress.main()
pos = mu.reg_read(ARM_REG_R15)
print("RIP = %x" %pos)

View File

@ -3,20 +3,26 @@
from unicorn import * from unicorn import *
from unicorn.arm_const import * from unicorn.arm_const import *
from unicorn.arm64_const import *
try: import regress
class WrongSPArm(regress.RegressTest):
def test_32(self):
with self.assertRaises(UcError):
uc = Uc(UC_ARCH_ARM, UC_MODE_32) uc = Uc(UC_ARCH_ARM, UC_MODE_32)
uc.reg_write(UC_ARM_REG_SP, 4) 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)
try: def test_64(self):
print "===========" 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 = Uc(UC_ARCH_ARM, UC_MODE_ARM)
uc.reg_write(UC_ARM_REG_SP, 4) uc.reg_write(UC_ARM_REG_SP, 4)
print 'Writing 4 to SP' self.assertEqual(0x4, uc.reg_read(UC_ARM_REG_SP))
print 'SP =', uc.reg_read(UC_ARM_REG_SP)
except UcError as e: if __name__ == '__main__':
print("ERROR: %s" % e) 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)