fix merge conflict

This commit is contained in:
Nguyen Anh Quynh
2016-02-01 12:08:38 +08:00
83 changed files with 2074 additions and 1081 deletions

View File

@ -36,6 +36,7 @@ TESTS += emu_stop_in_hook_overrun
TESTS += mips_branch_likely_issue
TESTS += hook_extrainvoke
TESTS += sysenter_hook_x86
TESTS += emu_clear_errors
TESTS += memleak_x86
TESTS += memleak_arm

View File

@ -0,0 +1,18 @@
#!/usr/bin/python
from unicorn import *
from unicorn.arm_const import *
import regress
class VldrPcInsn(regress.RegressTest):
def runTest(self):
uc = Uc(UC_ARCH_ARM, UC_MODE_ARM)
uc.mem_map(0x1000, 0x1000)
uc.mem_write(0x1000, 'ed9f8a3d'.decode('hex')) # vldr s16, [pc, #244]
# this will raise invalid insn
uc.emu_start(0x1000, 0x1004)
if __name__ == '__main__':
regress.main()

View File

@ -0,0 +1,154 @@
#include <sys/types.h>
#include <stdint.h>
#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <unicorn/unicorn.h>
static int count = 1;
bool cb_hookunmapped(uc_engine *uc, uc_mem_type type, uint64_t address, uint32_t size, int64_t value, void *user_data) {
uint32_t pc = 0;
uc_reg_read(uc, UC_X86_REG_EIP, &pc);
fprintf(stderr, "mem unmapped: 0x%x type: %x address: 0x%"PRIx64" length: %x value: 0x%"PRIx64"\n",
pc, type, address, size, value);
uc_err err = UC_ERR_OK;
err = uc_emu_stop(uc);
if (err != UC_ERR_OK) {
fprintf(stderr, "stop not ok");
exit(0);
}
return true;
}
// move esi, dword ptr [ecx + eax + 0x28]
// add esi, eax
// lea eax, dword ptr [ebp - 4]
// push eax
// push 0x40
// push 0x10
// push esi
// call some address
#define CODE "\x8B\x74\x01\x28" \
"\x0C\xF0" \
"\x8D\x45\xFC" \
"\x50" \
"\x6A\x40" \
"\x6A\x10" \
"\x56" \
"\xFF\x15\x20\x20\x00\x10"
int main() {
uc_engine *uc;
uc_err err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc);
if (err != UC_ERR_OK) {
fprintf(stderr, "not ok %d - %s\n", count++, uc_strerror(err));
exit(0);
}
fprintf(stderr, "ok %d - uc_open\n", count++);
err = uc_mem_map(uc, 0x1000, 0x1000, UC_PROT_ALL);
if (err != UC_ERR_OK) {
fprintf(stderr, "not ok %d - %s\n", count++, uc_strerror(err));
exit(0);
}
fprintf(stderr, "ok %d - uc_mem_map: code\n", count++);
uint8_t code[0x1000];
memset(code, 0x0, sizeof(code));
memcpy(code, CODE, sizeof(CODE));
err = uc_mem_write(uc, 0x1000, code, sizeof(code));
if (err != UC_ERR_OK) {
fprintf(stderr, "not ok %d - %s\n", count++, uc_strerror(err));
exit(0);
}
fprintf(stderr, "ok %d - uc_mem_write: code\n", count++);
uint32_t eip = 0x1000;
err = uc_reg_write(uc, UC_X86_REG_EIP, &eip);
if (err != UC_ERR_OK) {
fprintf(stderr, "not ok %d - %s\n", count++, uc_strerror(err));
exit(0);
}
fprintf(stderr, "ok %d - uc_reg_write: eip\n", count++);
err = uc_mem_map(uc, 0x4000, 0x4000, UC_PROT_ALL);
if (err != UC_ERR_OK) {
fprintf(stderr, "not ok %d - %s\n", count++, uc_strerror(err));
exit(0);
}
fprintf(stderr, "ok %d - uc_mem_map: stack\n", count++);
uint8_t stack[0x4000];
memset(stack, 0x0, sizeof(stack));
err = uc_mem_write(uc, 0x4000, code, sizeof(code));
if (err != UC_ERR_OK) {
fprintf(stderr, "not ok %d - %s\n", count++, uc_strerror(err));
exit(0);
}
fprintf(stderr, "ok %d - uc_mem_write: stack\n", count++);
uint32_t esp = 0x6000;
err = uc_reg_write(uc, UC_X86_REG_ESP, &esp);
if (err != UC_ERR_OK) {
fprintf(stderr, "not ok %d - %s\n", count++, uc_strerror(err));
exit(0);
}
fprintf(stderr, "ok %d - uc_reg_write: esp\n", count++);
uint32_t ebp = 0x6000;
err = uc_reg_write(uc, UC_X86_REG_EBP, &ebp);
if (err != UC_ERR_OK) {
fprintf(stderr, "not ok %d - %s\n", count++, uc_strerror(err));
exit(0);
}
fprintf(stderr, "ok %d - uc_reg_write: ebp\n", count++);
uc_hook h1;
err = uc_hook_add(uc, &h1, UC_HOOK_MEM_UNMAPPED, cb_hookunmapped, NULL);
if (err != UC_ERR_OK) {
fprintf(stderr, "not ok %d - %s\n", count++, uc_strerror(err));
exit(0);
}
fprintf(stderr, "ok %d - uc_hook_add\n", count++);
// this should execute only a single instruction at 0x1000, because
// that instruction accesses invalid memory.
err = uc_emu_start(uc, 0x1000, 0x100F, 0, 0);
if (err != UC_ERR_OK) {
fprintf(stderr, "not ok %d - %s\n", count++, uc_strerror(err));
exit(0);
}
fprintf(stderr, "ok %d - uc_emu_start\n", count++);
// yes, not necessary, but to demonstrate the UC API is working as expected
eip = 0x1004;
err = uc_reg_write(uc, UC_X86_REG_EIP, &eip);
if (err != UC_ERR_OK) {
fprintf(stderr, "not ok %d - %s\n", count++, uc_strerror(err));
exit(0);
}
fprintf(stderr, "ok %d - uc_reg_write: eip\n", count++);
// this should execute the remaining instructions up to (but not includign) 0x100F.
// currently, it returns an error about an unmapped read.
// seems that this error should have been returned in the previous call
// to emu_start.
err = uc_emu_start(uc, 0x1004, 0x100F, 0, 0);
if (err != UC_ERR_OK) {
fprintf(stderr, "not ok %d - %s\n", count++, uc_strerror(err));
exit(0);
}
fprintf(stderr, "ok %d - uc_emu_start\n", count++);
fprintf(stderr, "ok %d - Done", count++);
return 0;
}

View File

@ -0,0 +1,80 @@
#!/usr/bin/python
from __future__ import print_function
import binascii
import regress
from unicorn import *
from unicorn.x86_const import *
CODE = binascii.unhexlify(b"".join([
b"8B 74 01 28", # mov esi, dword ptr [ecx + eax + 0x28] mapped: 0x1000
b"03 F0", # add esi, eax 0x1004
b"8D 45 FC", # lea eax, dword ptr [ebp - 4] 0x1006
b"50", # push eax 0x1009
b"6A 40", # push 0x40 0x100A
b"6A 10", # push 0x10 0x100C
b"56", # push esi 0x100E
b"FF 15 20 20 00 10" # call some address 0x100F
]).replace(" ", ""))
def showpc(mu):
pc = mu.reg_read(UC_X86_REG_EIP)
print("pc: 0x%x" % (pc))
class HookCodeStopEmuTest(regress.RegressTest):
def test_hook_code_stop_emu(self):
mu = Uc(UC_ARCH_X86, UC_MODE_32)
# base of CODE
mu.mem_map(0x1000, 0x1000)
mu.mem_write(0x1000, CODE)
mu.reg_write(UC_X86_REG_EIP, 0x1000)
# base of STACK
mu.mem_map(0x4000, 0x4000)
mu.mem_write(0x4000, "\x00" * 0x4000)
mu.reg_write(UC_X86_REG_ESP, 0x6000)
mu.reg_write(UC_X86_REG_EBP, 0x6000)
mu.reg_write(UC_X86_REG_ECX, 0x0)
mu.reg_write(UC_X86_REG_EAX, 0x0)
def _hook(_, access, address, length, value, context):
pc = mu.reg_read(UC_X86_REG_EIP)
print("mem unmapped: pc: %x access: %x address: %x length: %x value: %x" % (
pc, access, address, length, value))
mu.emu_stop()
return True
mu.hook_add(UC_HOOK_MEM_UNMAPPED, _hook)
# we only expect the following instruction to execute,
# and it will fail, because it accesses unmapped memory.
# mov esi, dword ptr [ecx + eax + 0x28] mapped: 0x1000
mu.emu_start(0x1000, 0x100F)
showpc(mu)
# now, we want to reuse the emulator, and keep executing
# from the next instruction
mu.reg_write(UC_X86_REG_EIP, 0x1004)
self.assertEqual(0x1004, mu.reg_read(UC_X86_REG_EIP))
# we expect the following instructions to execute
# add esi, eax 0x1004
# lea eax, dword ptr [ebp - 4] 0x1006
# push eax 0x1009
# push 0x40 0x100A
# push 0x10 0x100C
# push esi 0x100E
#
# currently, a UC_ERR_READ_UNMAPPED exception is raised here
mu.emu_start(0x1004, 0x100F)
showpc(mu)
if __name__ == '__main__':
regress.main()

47
tests/regress/invalid_write.py Executable file
View File

@ -0,0 +1,47 @@
#!/usr/bin/env python
# Test callback that returns False to cancel emulation
from __future__ import print_function
from unicorn import *
from unicorn.x86_const import *
import regress
X86_CODE32_MEM_WRITE = b"\x89\x0D\xAA\xAA\xAA\xAA\x41\x4a" # mov [0xaaaaaaaa], ecx; INC ecx; DEC edx
# callback for tracing invalid memory access (READ or WRITE)
def hook_mem_invalid(uc, access, address, size, value, user_data):
return False
class InvalidWrite(regress.RegressTest):
def test(self):
# Initialize emulator in X86-32bit mode
mu = Uc(UC_ARCH_X86, UC_MODE_32)
# memory address where emulation starts
ADDRESS = 0x1000000
# map 2MB memory for this emulation
mu.mem_map(ADDRESS, 2 * 1024 * 1024)
# write machine code to be emulated to memory
mu.mem_write(ADDRESS, X86_CODE32_MEM_WRITE)
# initialize machine registers
mu.reg_write(UC_X86_REG_ECX, 0x1234)
mu.reg_write(UC_X86_REG_EDX, 0x7890)
# intercept invalid memory events
mu.hook_add(UC_HOOK_MEM_READ_UNMAPPED | UC_HOOK_MEM_WRITE_UNMAPPED, hook_mem_invalid)
try:
# emulation should return with error UC_ERR_WRITE_UNMAPPED
mu.emu_start(ADDRESS, ADDRESS + len(X86_CODE32_MEM_WRITE))
except UcError as e:
self.assertEqual(e.errno, UC_ERR_WRITE_UNMAPPED)
if __name__ == '__main__':
regress.main()

View File

@ -5,7 +5,7 @@ from unicorn.sparc_const import *
PAGE_SIZE = 1 * 1024 * 1024
uc = Uc(UC_ARCH_SPARC, UC_MODE_64)
uc = Uc(UC_ARCH_SPARC, UC_MODE_SPARC64|UC_MODE_BIG_ENDIAN)
uc.reg_write(UC_SPARC_REG_SP, 100)
print 'writing sp = 100'

View File

@ -1,7 +1,7 @@
#include <unicorn/unicorn.h>
#define HARDWARE_ARCHITECTURE UC_ARCH_SPARC
#define HARDWARE_MODE UC_MODE_32
#define HARDWARE_MODE UC_MODE_SPARC32|UC_MODE_BIG_ENDIAN
#define MEMORY_STARTING_ADDRESS 0x1000000
#define MEMORY_SIZE 2 * 1024 * 1024

View File

@ -5,7 +5,7 @@ from unicorn.sparc_const import *
PAGE_SIZE = 1 * 1024 * 1024
uc = Uc(UC_ARCH_SPARC, UC_MODE_32)
uc = Uc(UC_ARCH_SPARC, UC_MODE_SPARC32|UC_MODE_BIG_ENDIAN)
uc.reg_write(UC_SPARC_REG_SP, 100)
uc.reg_write(UC_SPARC_REG_FP, 200)