Merge branch 'change-handle-based-api' of https://github.com/JonathonReinhart/unicorn into JonathonReinhart-change-handle-based-api

This commit is contained in:
Nguyen Anh Quynh 2015-09-03 14:42:53 +08:00
commit dd13d821af
44 changed files with 649 additions and 784 deletions

59
hook.c
View file

@ -38,13 +38,9 @@ size_t hook_find_new(struct uc_struct *uc)
}
// return -1 on failure, index to hook_callbacks[] on success.
size_t hook_add(uch handle, int type, uint64_t begin, uint64_t end, void *callback, void *user_data)
size_t hook_add(struct uc_struct *uc, int type, uint64_t begin, uint64_t end, void *callback, void *user_data)
{
int i;
struct uc_struct *uc = (struct uc_struct *)(uintptr_t)handle;
if (handle == 0)
return -1;
// find the first free slot. skip slot 0, so index > 0
i = hook_find_new(uc);
@ -95,52 +91,45 @@ size_t hook_add(uch handle, int type, uint64_t begin, uint64_t end, void *callba
}
// return 0 on success, -1 on failure
uc_err hook_del(uch handle, uch *h2)
uc_err hook_del(struct uc_struct *uc, uc_hook_h hh)
{
struct uc_struct *uc = (struct uc_struct *)(uintptr_t)handle;
if (handle == 0)
return UC_ERR_UCH;
if (*h2 == uc->hook_block_idx) {
if (hh == uc->hook_block_idx) {
uc->hook_block_idx = 0;
}
if (*h2 == uc->hook_insn_idx) {
if (hh == uc->hook_insn_idx) {
uc->hook_insn_idx = 0;
}
if (*h2 == uc->hook_read_idx) {
if (hh == uc->hook_read_idx) {
uc->hook_read_idx = 0;
}
if (*h2 == uc->hook_write_idx) {
if (hh == uc->hook_write_idx) {
uc->hook_write_idx = 0;
}
if (*h2 == uc->hook_mem_idx) {
if (hh == uc->hook_mem_idx) {
uc->hook_mem_idx = 0;
}
if (*h2 == uc->hook_intr_idx) {
if (hh == uc->hook_intr_idx) {
uc->hook_intr_idx = 0;
}
if (*h2 == uc->hook_out_idx) {
if (hh == uc->hook_out_idx) {
uc->hook_out_idx = 0;
}
if (*h2 == uc->hook_in_idx) {
if (hh == uc->hook_in_idx) {
uc->hook_in_idx = 0;
}
uc->hook_callbacks[*h2].callback = NULL;
uc->hook_callbacks[*h2].user_data = NULL;
uc->hook_callbacks[*h2].hook_type = 0;
uc->hook_callbacks[*h2].begin = 0;
uc->hook_callbacks[*h2].end = 0;
*h2 = 0;
uc->hook_callbacks[hh].callback = NULL;
uc->hook_callbacks[hh].user_data = NULL;
uc->hook_callbacks[hh].hook_type = 0;
uc->hook_callbacks[hh].begin = 0;
uc->hook_callbacks[hh].end = 0;
return UC_ERR_OK;
}
@ -206,26 +195,19 @@ static struct hook_struct *_hook_find(struct uc_struct *uc, int type, uint64_t a
}
static void hook_count_cb(uch handle, uint64_t address, uint32_t size, void *user_data)
static void hook_count_cb(struct uc_struct *uc, uint64_t address, uint32_t size, void *user_data)
{
struct uc_struct *uc = (struct uc_struct *)(uintptr_t)handle;
// count this instruction
uc->emu_counter++;
if (uc->emu_counter > uc->emu_count)
uc_emu_stop(handle);
uc_emu_stop(uc);
else if (uc->hook_count_callback)
uc->hook_count_callback(handle, address, size, user_data);
uc->hook_count_callback(uc, address, size, user_data);
}
struct hook_struct *hook_find(uch handle, int type, uint64_t address)
struct hook_struct *hook_find(struct uc_struct *uc, int type, uint64_t address)
{
struct uc_struct *uc = (struct uc_struct *)(uintptr_t)handle;
if (handle == 0)
return NULL;
// stop executing callbacks if we already got stop request
if (uc->stop_request)
return NULL;
@ -270,6 +252,5 @@ void helper_uc_tracecode(int32_t size, void *callback, void *handle, int64_t add
uc->set_pc(uc, address);
}
((uc_cb_hookcode_t)callback)((uch)handle, address, size, user_data);
((uc_cb_hookcode_t)callback)(uc, address, size, user_data);
}

View file

@ -5,13 +5,13 @@
#define UC_HOOK_H
// return -1 on failure, index to traces[] on success.
size_t hook_add(uch handle, int type, uint64_t begin, uint64_t end, void *callback, void *user_data);
size_t hook_add(struct uc_struct *uc, int type, uint64_t begin, uint64_t end, void *callback, void *user_data);
// return 0 on success, -1 on failure
uc_err hook_del(uch handle, uch *traceh);
uc_err hook_del(struct uc_struct *uc, uc_hook_h hh);
// return NULL on failure
struct hook_struct *hook_find(uch handle, int type, uint64_t address);
struct hook_struct *hook_find(struct uc_struct *uc, int type, uint64_t address);
// return index of an free hook entry in hook_callbacks[] array.
// this realloc memory if needed.

View file

@ -24,10 +24,10 @@ typedef struct ModuleEntry {
typedef QTAILQ_HEAD(, ModuleEntry) ModuleTypeList;
// return 0 on success, -1 on failure
typedef int (*reg_read_t)(uch handle, unsigned int regid, void *value);
typedef int (*reg_write_t)(uch handle, unsigned int regid, const void *value);
typedef int (*reg_read_t)(struct uc_struct *uc, unsigned int regid, void *value);
typedef int (*reg_write_t)(struct uc_struct *uc, unsigned int regid, const void *value);
typedef void (*reg_reset_t)(uch handle);
typedef void (*reg_reset_t)(struct uc_struct *uc);
typedef bool (*uc_write_mem_t)(AddressSpace *as, hwaddr addr, const uint8_t *buf, int len);

View file

@ -19,8 +19,10 @@ extern "C" {
#include "platform.h"
// Handle to use with all APIs
typedef size_t uch;
struct uc_struct;
typedef struct uc_struct ucengine;
typedef size_t uc_hook_h;
#include "m68k.h"
#include "x86.h"
@ -107,7 +109,6 @@ typedef enum uc_err {
UC_ERR_OOM, // Out-Of-Memory error: uc_open(), uc_emulate()
UC_ERR_ARCH, // Unsupported architecture: uc_open()
UC_ERR_HANDLE, // Invalid handle
UC_ERR_UCH, // Invalid handle (uch)
UC_ERR_MODE, // Invalid/unsupported mode: uc_open()
UC_ERR_VERSION, // Unsupported version (bindings)
UC_ERR_MEM_READ, // Quit emulation due to invalid memory READ: uc_emu_start()
@ -125,24 +126,24 @@ typedef enum uc_err {
// @address: address where the code is being executed
// @size: size of machine instruction(s) being executed, or 0 when size is unknown
// @user_data: user data passed to tracing APIs.
typedef void (*uc_cb_hookcode_t)(uch handle, uint64_t address, uint32_t size, void *user_data);
typedef void (*uc_cb_hookcode_t)(ucengine *uc, uint64_t address, uint32_t size, void *user_data);
// Callback function for tracing interrupts (for uc_hook_intr())
// @intno: interrupt number
// @user_data: user data passed to tracing APIs.
typedef void (*uc_cb_hookintr_t)(uch handle, uint32_t intno, void *user_data);
typedef void (*uc_cb_hookintr_t)(ucengine *uc, uint32_t intno, void *user_data);
// Callback function for tracing IN instruction of X86
// @port: port number
// @size: data size (1/2/4) to be read from this port
// @user_data: user data passed to tracing APIs.
typedef uint32_t (*uc_cb_insn_in_t)(uch handle, uint32_t port, int size, void *user_data);
typedef uint32_t (*uc_cb_insn_in_t)(ucengine *uc, uint32_t port, int size, void *user_data);
// x86's handler for OUT
// @port: port number
// @size: data size (1/2/4) to be written to this port
// @value: data value to be written to this port
typedef void (*uc_cb_insn_out_t)(uch handle, uint32_t port, int size, uint32_t value, void *user_data);
typedef void (*uc_cb_insn_out_t)(ucengine *uc, uint32_t port, int size, uint32_t value, void *user_data);
// All type of memory accesses for UC_HOOK_MEM_*
typedef enum uc_mem_type {
@ -171,7 +172,7 @@ typedef enum uc_hook_t {
// @size: size of data being read or written
// @value: value of data being written to memory, or irrelevant if type = READ.
// @user_data: user data passed to tracing APIs
typedef void (*uc_cb_hookmem_t)(uch handle, uc_mem_type type,
typedef void (*uc_cb_hookmem_t)(ucengine *uc, uc_mem_type type,
uint64_t address, int size, int64_t value, void *user_data);
// Callback function for handling memory events (for UC_HOOK_MEM_INVALID)
@ -181,7 +182,7 @@ typedef void (*uc_cb_hookmem_t)(uch handle, uc_mem_type type,
// @value: value of data being written to memory, or irrelevant if type = READ.
// @user_data: user data passed to tracing APIs
// @return: return true to continue, or false to stop program (due to invalid memory).
typedef bool (*uc_cb_eventmem_t)(uch handle, uc_mem_type type,
typedef bool (*uc_cb_eventmem_t)(ucengine *uc, uc_mem_type type,
uint64_t address, int size, int64_t value, void *user_data);
@ -218,43 +219,43 @@ bool uc_arch_supported(uc_arch arch);
/*
Initialize UC handle: this must be done before any usage of UC.
Create new instance of unicorn engine.
@arch: architecture type (UC_ARCH_*)
@mode: hardware mode. This is combined of UC_MODE_*
@handle: pointer to handle, which will be updated at return time
@uc: pointer to ucengine, which will be updated at return time
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
for detailed error).
*/
UNICORN_EXPORT
uc_err uc_open(uc_arch arch, uc_mode mode, uch *handle);
uc_err uc_open(uc_arch arch, uc_mode mode, ucengine **uc);
/*
Close UC handle: MUST do to release the handle when it is not used anymore.
Close UC instance: MUST do to release the handle when it is not used anymore.
NOTE: this must be called only when there is no longer usage of Unicorn.
The reason is the this API releases some cached memory, thus access to any
Unicorn API after uc_close() might crash your application.
After this, @handle is invalid, and nolonger usable.
After this, @uc is invalid, and nolonger usable.
@handle: pointer to a handle returned by uc_open()
@uc: pointer to a handle returned by uc_open()
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
for detailed error).
*/
UNICORN_EXPORT
uc_err uc_close(uch *handle);
uc_err uc_close(ucengine *uc);
/*
Report the last error number when some API function fail.
Like glibc's errno, uc_errno might not retain its old value once accessed.
@handle: handle returned by uc_open()
@uc: handle returned by uc_open()
@return: error code of uc_err enum type (UC_ERR_*, see above)
*/
UNICORN_EXPORT
uc_err uc_errno(uch handle);
uc_err uc_errno(ucengine *uc);
/*
Return a string describing given error code.
@ -270,7 +271,7 @@ const char *uc_strerror(uc_err code);
/*
Write to register.
@handle: handle returned by uc_open()
@uc: handle returned by uc_open()
@regid: register ID that is to be modified.
@value: pointer to the value that will set to register @regid
@ -278,12 +279,12 @@ const char *uc_strerror(uc_err code);
for detailed error).
*/
UNICORN_EXPORT
uc_err uc_reg_write(uch handle, int regid, const void *value);
uc_err uc_reg_write(ucengine *uc, int regid, const void *value);
/*
Read register value.
@handle: handle returned by uc_open()
@uc: handle returned by uc_open()
@regid: register ID that is to be retrieved.
@value: pointer to a variable storing the register value.
@ -291,12 +292,12 @@ uc_err uc_reg_write(uch handle, int regid, const void *value);
for detailed error).
*/
UNICORN_EXPORT
uc_err uc_reg_read(uch handle, int regid, void *value);
uc_err uc_reg_read(ucengine *uc, int regid, void *value);
/*
Write to a range of bytes in memory.
@handle: handle returned by uc_open()
@uc: handle returned by uc_open()
@address: starting memory address of bytes to set.
@bytes: pointer to a variable containing data to be written to memory.
@size: size of memory to write to.
@ -307,12 +308,12 @@ uc_err uc_reg_read(uch handle, int regid, void *value);
for detailed error).
*/
UNICORN_EXPORT
uc_err uc_mem_write(uch handle, uint64_t address, const uint8_t *bytes, size_t size);
uc_err uc_mem_write(ucengine *uc, uint64_t address, const uint8_t *bytes, size_t size);
/*
Read a range of bytes in memory.
@handle: handle returned by uc_open()
@uc: handle returned by uc_open()
@address: starting memory address of bytes to get.
@bytes: pointer to a variable containing data copied from memory.
@size: size of memory to read.
@ -323,12 +324,12 @@ uc_err uc_mem_write(uch handle, uint64_t address, const uint8_t *bytes, size_t s
for detailed error).
*/
UNICORN_EXPORT
uc_err uc_mem_read(uch handle, uint64_t address, uint8_t *bytes, size_t size);
uc_err uc_mem_read(ucengine *uc, uint64_t address, uint8_t *bytes, size_t size);
/*
Emulate machine code in a specific duration of time.
@handle: handle returned by uc_open()
@uc: handle returned by uc_open()
@begin: address where emulation starts
@until: address where emulation stops (i.e when this address is hit)
@timeout: duration to emulate the code (in microseconds). When this value is 0,
@ -340,27 +341,27 @@ uc_err uc_mem_read(uch handle, uint64_t address, uint8_t *bytes, size_t size);
for detailed error).
*/
UNICORN_EXPORT
uc_err uc_emu_start(uch handle, uint64_t begin, uint64_t until, uint64_t timeout, size_t count);
uc_err uc_emu_start(ucengine *uc, uint64_t begin, uint64_t until, uint64_t timeout, size_t count);
/*
Stop emulation (which was started by uc_emu_start() API.
This is typically called from callback functions registered via tracing APIs.
NOTE: for now, this will stop the execution only after the current block.
@handle: handle returned by uc_open()
@uc: handle returned by uc_open()
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
for detailed error).
*/
UNICORN_EXPORT
uc_err uc_emu_stop(uch handle);
uc_err uc_emu_stop(ucengine *uc);
/*
Register callback for a hook event.
The callback will be run when the hook event is hit.
@handle: handle returned by uc_open()
@h2: hook handle returned from this registration. To be used in uc_hook_del() API
@uc: handle returned by uc_open()
@hh: hook handle returned from this registration. To be used in uc_hook_del() API
@type: hook type
@callback: callback to be run when instruction is hit
@user_data: user-defined data. This will be passed to callback function in its
@ -371,22 +372,22 @@ uc_err uc_emu_stop(uch handle);
for detailed error).
*/
UNICORN_EXPORT
uc_err uc_hook_add(uch handle, uch *h2, uc_hook_t type, void *callback, void *user_data, ...);
uc_err uc_hook_add(ucengine *uc, uc_hook_h *hh, uc_hook_t type, void *callback, void *user_data, ...);
/*
Unregister (remove) a hook callback.
This API removes the hook callback registered by uc_hook_add().
NOTE: this should be called only when you no longer want to trace.
After this, @hhandle is invalid, and nolonger usable.
After this, @hh is invalid, and nolonger usable.
@handle: handle returned by uc_open()
@h2: handle returned by uc_hook_add()
@uc: handle returned by uc_open()
@hh: handle returned by uc_hook_add()
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
for detailed error).
*/
UNICORN_EXPORT
uc_err uc_hook_del(uch handle, uch *h2);
uc_err uc_hook_del(ucengine *uc, uc_hook_h hh);
typedef enum uc_prot {
UC_PROT_NONE = 0,
@ -399,7 +400,7 @@ typedef enum uc_prot {
Map memory in for emulation.
This API adds a memory region that can be used by emulation.
@handle: handle returned by uc_open()
@uc: handle returned by uc_open()
@address: starting address of the new memory region to be mapped in.
This address must be aligned to 4KB, or this will return with UC_ERR_MAP error.
@size: size of the new memory region to be mapped in.
@ -412,7 +413,7 @@ typedef enum uc_prot {
for detailed error).
*/
UNICORN_EXPORT
uc_err uc_mem_map(uch handle, uint64_t address, size_t size, uint32_t perms);
uc_err uc_mem_map(ucengine *uc, uint64_t address, size_t size, uint32_t perms);
#ifdef __cplusplus
}

View file

@ -10,7 +10,7 @@ extern "C" {
// Callback function for tracing SYSCALL/SYSENTER (for uc_hook_intr())
// @user_data: user data passed to tracing APIs.
typedef void (*uc_cb_insn_syscall_t)(uch handle, void *user_data);
typedef void (*uc_cb_insn_syscall_t)(struct uc_struct *uc, void *user_data);
//> X86 registers
typedef enum uc_x86_reg {

View file

@ -141,7 +141,7 @@ int cpu_exec(struct uc_struct *uc, CPUArchState *env) // qq
// Unicorn: call interrupt callback if registered
if (uc->hook_intr_idx)
((uc_cb_hookintr_t)uc->hook_callbacks[uc->hook_intr_idx].callback)(
(uch)uc, cpu->exception_index,
uc, cpu->exception_index,
uc->hook_callbacks[uc->hook_intr_idx].user_data);
cpu->exception_index = -1;
#endif

View file

@ -69,7 +69,7 @@ void cpu_outb(struct uc_struct *uc, pio_addr_t addr, uint8_t val)
// Unicorn: call interrupt callback if registered
if (uc->hook_out_idx)
((uc_cb_insn_out_t)uc->hook_callbacks[uc->hook_out_idx].callback)(
(uch)uc, addr, 1, val,
uc, addr, 1, val,
uc->hook_callbacks[uc->hook_out_idx].user_data);
}
@ -79,7 +79,7 @@ void cpu_outw(struct uc_struct *uc, pio_addr_t addr, uint16_t val)
// Unicorn: call interrupt callback if registered
if (uc->hook_out_idx)
((uc_cb_insn_out_t)uc->hook_callbacks[uc->hook_out_idx].callback)(
(uch)uc, addr, 2, val,
uc, addr, 2, val,
uc->hook_callbacks[uc->hook_out_idx].user_data);
}
@ -88,7 +88,7 @@ void cpu_outl(struct uc_struct *uc, pio_addr_t addr, uint32_t val)
//LOG_IOPORT("outl: %04"FMT_pioaddr" %08"PRIx32"\n", addr, val);
if (uc->hook_out_idx)
((uc_cb_insn_out_t)uc->hook_callbacks[uc->hook_out_idx].callback)(
(uch)uc, addr, 4, val,
uc, addr, 4, val,
uc->hook_callbacks[uc->hook_out_idx].user_data);
}
@ -97,7 +97,7 @@ uint8_t cpu_inb(struct uc_struct *uc, pio_addr_t addr)
//LOG_IOPORT("inb : %04"FMT_pioaddr" %02"PRIx8"\n", addr, val);
if (uc->hook_in_idx)
return ((uc_cb_insn_in_t)uc->hook_callbacks[uc->hook_in_idx].callback)(
(uch)uc, addr, 1,
uc, addr, 1,
uc->hook_callbacks[uc->hook_in_idx].user_data);
return 0;
@ -108,7 +108,7 @@ uint16_t cpu_inw(struct uc_struct *uc, pio_addr_t addr)
//LOG_IOPORT("inw : %04"FMT_pioaddr" %04"PRIx16"\n", addr, val);
if (uc->hook_in_idx)
return ((uc_cb_insn_in_t)uc->hook_callbacks[uc->hook_in_idx].callback)(
(uch)uc, addr, 2,
uc, addr, 2,
uc->hook_callbacks[uc->hook_in_idx].user_data);
return 0;
@ -119,7 +119,7 @@ uint32_t cpu_inl(struct uc_struct *uc, pio_addr_t addr)
//LOG_IOPORT("inl : %04"FMT_pioaddr" %08"PRIx32"\n", addr, val);
if (uc->hook_in_idx)
return ((uc_cb_insn_in_t)uc->hook_callbacks[uc->hook_in_idx].callback)(
(uch)uc, addr, 4,
uc, addr, 4,
uc->hook_callbacks[uc->hook_in_idx].user_data);
return 0;

View file

@ -183,9 +183,9 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
// Unicorn: callback on memory read
if (env->uc->hook_mem_read && READ_ACCESS_TYPE == MMU_DATA_LOAD) {
struct hook_struct *trace = hook_find((uch)env->uc, UC_HOOK_MEM_READ, addr);
struct hook_struct *trace = hook_find(env->uc, UC_HOOK_MEM_READ, addr);
if (trace) {
((uc_cb_hookmem_t)trace->callback)((uch)env->uc, UC_MEM_READ,
((uc_cb_hookmem_t)trace->callback)(env->uc, UC_MEM_READ,
(uint64_t)addr, (int)DATA_SIZE, (int64_t)0, trace->user_data);
}
}
@ -193,7 +193,7 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
// Unicorn: callback on invalid memory
if (env->uc->hook_mem_idx && mr == NULL) {
if (!((uc_cb_eventmem_t)env->uc->hook_callbacks[env->uc->hook_mem_idx].callback)(
(uch)env->uc, UC_MEM_READ, addr, DATA_SIZE, 0,
env->uc, UC_MEM_READ, addr, DATA_SIZE, 0,
env->uc->hook_callbacks[env->uc->hook_mem_idx].user_data)) {
// save error & quit
env->invalid_addr = addr;
@ -211,7 +211,7 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
bool result = false;
if (uc->hook_mem_idx) {
result = ((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_idx].callback)(
(uch)uc, UC_MEM_READ_NR, addr, DATA_SIZE, 0,
uc, UC_MEM_READ_NR, addr, DATA_SIZE, 0,
uc->hook_callbacks[uc->hook_mem_idx].user_data);
}
if (result) {
@ -328,9 +328,9 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
// Unicorn: callback on memory read
if (env->uc->hook_mem_read && READ_ACCESS_TYPE == MMU_DATA_LOAD) {
struct hook_struct *trace = hook_find((uch)env->uc, UC_HOOK_MEM_READ, addr);
struct hook_struct *trace = hook_find(env->uc, UC_HOOK_MEM_READ, addr);
if (trace) {
((uc_cb_hookmem_t)trace->callback)((uch)env->uc, UC_MEM_READ,
((uc_cb_hookmem_t)trace->callback)(env->uc, UC_MEM_READ,
(uint64_t)addr, (int)DATA_SIZE, (int64_t)0, trace->user_data);
}
}
@ -338,7 +338,7 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
// Unicorn: callback on invalid memory
if (env->uc->hook_mem_idx && mr == NULL) {
if (!((uc_cb_eventmem_t)env->uc->hook_callbacks[env->uc->hook_mem_idx].callback)(
(uch)env->uc, UC_MEM_READ, addr, DATA_SIZE, 0,
env->uc, UC_MEM_READ, addr, DATA_SIZE, 0,
env->uc->hook_callbacks[env->uc->hook_mem_idx].user_data)) {
// save error & quit
env->invalid_addr = addr;
@ -356,7 +356,7 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
bool result = false;
if (uc->hook_mem_idx) {
result = ((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_idx].callback)(
(uch)uc, UC_MEM_READ_NR, addr, DATA_SIZE, 0,
uc, UC_MEM_READ_NR, addr, DATA_SIZE, 0,
uc->hook_callbacks[uc->hook_mem_idx].user_data);
}
if (result) {
@ -511,9 +511,9 @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
// Unicorn: callback on memory write
if (uc->hook_mem_write) {
struct hook_struct *trace = hook_find((uch)uc, UC_HOOK_MEM_WRITE, addr);
struct hook_struct *trace = hook_find(uc, UC_HOOK_MEM_WRITE, addr);
if (trace) {
((uc_cb_hookmem_t)trace->callback)((uch)uc, UC_MEM_WRITE,
((uc_cb_hookmem_t)trace->callback)(uc, UC_MEM_WRITE,
(uint64_t)addr, (int)DATA_SIZE, (int64_t)val, trace->user_data);
}
}
@ -521,7 +521,7 @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
// Unicorn: callback on invalid memory
if (uc->hook_mem_idx && mr == NULL) {
if (!((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_idx].callback)(
(uch)uc, UC_MEM_WRITE, addr, DATA_SIZE, (int64_t)val,
uc, UC_MEM_WRITE, addr, DATA_SIZE, (int64_t)val,
uc->hook_callbacks[uc->hook_mem_idx].user_data)) {
// save error & quit
env->invalid_addr = addr;
@ -539,7 +539,7 @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
bool result = false;
if (uc->hook_mem_idx) {
result = ((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_idx].callback)(
(uch)uc, UC_MEM_WRITE_NW, addr, DATA_SIZE, (int64_t)val,
uc, UC_MEM_WRITE_NW, addr, DATA_SIZE, (int64_t)val,
uc->hook_callbacks[uc->hook_mem_idx].user_data);
}
if (result) {
@ -649,9 +649,9 @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
// Unicorn: callback on memory write
if (uc->hook_mem_write) {
struct hook_struct *trace = hook_find((uch)uc, UC_HOOK_MEM_WRITE, addr);
struct hook_struct *trace = hook_find(uc, UC_HOOK_MEM_WRITE, addr);
if (trace) {
((uc_cb_hookmem_t)trace->callback)((uch)uc, UC_MEM_WRITE,
((uc_cb_hookmem_t)trace->callback)(uc, UC_MEM_WRITE,
(uint64_t)addr, (int)DATA_SIZE, (int64_t)val, trace->user_data);
}
}
@ -659,7 +659,7 @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
// Unicorn: callback on invalid memory
if (uc->hook_mem_idx && mr == NULL) {
if (!((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_idx].callback)(
(uch)uc, UC_MEM_WRITE, addr, DATA_SIZE, (int64_t)val,
uc, UC_MEM_WRITE, addr, DATA_SIZE, (int64_t)val,
uc->hook_callbacks[uc->hook_mem_idx].user_data)) {
// save error & quit
env->invalid_addr = addr;
@ -677,7 +677,7 @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
bool result = false;
if (uc->hook_mem_idx) {
result = ((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_idx].callback)(
(uch)uc, UC_MEM_WRITE_NW, addr, DATA_SIZE, (int64_t)val,
uc, UC_MEM_WRITE_NW, addr, DATA_SIZE, (int64_t)val,
uc->hook_callbacks[uc->hook_mem_idx].user_data);
}
if (result) {

View file

@ -10984,7 +10984,7 @@ static void disas_a64_insn(CPUARMState *env, DisasContext *s)
// Unicorn: trace this instruction on request
if (env->uc->hook_insn) {
struct hook_struct *trace = hook_find((uch)s->uc, UC_HOOK_CODE, s->pc - 4);
struct hook_struct *trace = hook_find(s->uc, UC_HOOK_CODE, s->pc - 4);
if (trace)
gen_uc_tracecode(tcg_ctx, 4, trace->callback, env->uc, s->pc - 4, trace->user_data);
// if requested to emulate only some instructions, check if
@ -11109,7 +11109,7 @@ void gen_intermediate_code_internal_a64(ARMCPU *cpu,
// Only hook this block if it is not broken from previous translation due to
// full translation cache
if (env->uc->hook_block && !env->uc->block_full) {
struct hook_struct *trace = hook_find((uch)env->uc, UC_HOOK_BLOCK, pc_start);
struct hook_struct *trace = hook_find(env->uc, UC_HOOK_BLOCK, pc_start);
if (trace) {
// save block address to see if we need to patch block size later
env->uc->block_addr = pc_start;

View file

@ -7688,7 +7688,7 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn) // qq
// Unicorn: trace this instruction on request
if (s->uc->hook_insn) {
struct hook_struct *trace = hook_find((uch)s->uc, UC_HOOK_CODE, s->pc - 4);
struct hook_struct *trace = hook_find(s->uc, UC_HOOK_CODE, s->pc - 4);
if (trace)
gen_uc_tracecode(tcg_ctx, 4, trace->callback, s->uc, s->pc - 4, trace->user_data);
// if requested to emulate only some instructions, check if
@ -10411,7 +10411,7 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s) // qq
// Unicorn: trace this instruction on request
if (env->uc->hook_insn) {
struct hook_struct *trace = hook_find((uch)s->uc, UC_HOOK_CODE, s->pc);
struct hook_struct *trace = hook_find(s->uc, UC_HOOK_CODE, s->pc);
if (trace)
gen_uc_tracecode(tcg_ctx, 2, trace->callback, env->uc, s->pc, trace->user_data);
// if requested to emulate only some instructions, check to see
@ -11232,7 +11232,7 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
// Only hook this block if it is not broken from previous translation due to
// full translation cache
if (env->uc->hook_block && !env->uc->block_full) {
struct hook_struct *trace = hook_find((uch)env->uc, UC_HOOK_BLOCK, pc_start);
struct hook_struct *trace = hook_find(env->uc, UC_HOOK_BLOCK, pc_start);
if (trace) {
// save block address to see if we need to patch block size later
env->uc->block_addr = pc_start;

View file

@ -5,13 +5,13 @@
#define UC_QEMU_TARGET_ARM_H
// functions to read & write registers
int arm_reg_read(uch handle, unsigned int regid, void *value);
int arm_reg_write(uch handle, unsigned int regid, const void *value);
int arm64_reg_read(uch handle, unsigned int regid, void *value);
int arm64_reg_write(uch handle, unsigned int regid, const void *value);
int arm_reg_read(struct uc_struct *uc, unsigned int regid, void *value);
int arm_reg_write(struct uc_struct *uc, unsigned int regid, const void *value);
int arm64_reg_read(struct uc_struct *uc, unsigned int regid, void *value);
int arm64_reg_write(struct uc_struct *uc, unsigned int regid, const void *value);
void arm_reg_reset(uch handle);
void arm64_reg_reset(uch handle);
void arm_reg_reset(struct uc_struct *uc);
void arm64_reg_reset(struct uc_struct *uc);
__attribute__ ((visibility ("default")))
void arm_uc_init(struct uc_struct* uc);

View file

@ -25,23 +25,17 @@ static void arm64_set_pc(struct uc_struct *uc, uint64_t address)
((CPUARMState *)uc->current_cpu->env_ptr)->pc = address;
}
void arm64_reg_reset(uch handle)
void arm64_reg_reset(struct uc_struct *uc)
{
struct uc_struct *uc = (struct uc_struct *) handle;
CPUArchState *env;
env = first_cpu->env_ptr;
CPUArchState *env = first_cpu->env_ptr;
memset(env->xregs, 0, sizeof(env->xregs));
env->pc = 0;
}
int arm64_reg_read(uch handle, unsigned int regid, void *value)
int arm64_reg_read(struct uc_struct *uc, unsigned int regid, void *value)
{
CPUState *mycpu;
struct uc_struct *uc = (struct uc_struct *) handle;
mycpu = first_cpu;
CPUState *mycpu = first_cpu;
if (regid >= UC_ARM64_REG_X0 && regid <= UC_ARM64_REG_X28)
*(int64_t *)value = ARM_CPU(uc, mycpu)->env.xregs[regid - UC_ARM64_REG_X0];
@ -68,12 +62,9 @@ int arm64_reg_read(uch handle, unsigned int regid, void *value)
#define WRITE_BYTE_H(x, b) (x = (x & ~0xff00) | (b & 0xff))
#define WRITE_BYTE_L(x, b) (x = (x & ~0xff) | (b & 0xff))
int arm64_reg_write(uch handle, unsigned int regid, const void *value)
int arm64_reg_write(struct uc_struct *uc, unsigned int regid, const void *value)
{
CPUState *mycpu;
struct uc_struct *uc = (struct uc_struct *) handle;
mycpu = first_cpu;
CPUState *mycpu = first_cpu;
if (regid >= UC_ARM64_REG_X0 && regid <= UC_ARM64_REG_X28)
ARM_CPU(uc, mycpu)->env.xregs[regid - UC_ARM64_REG_X0] = *(int64_t *)value;

View file

@ -25,9 +25,9 @@ static void arm_set_pc(struct uc_struct *uc, uint64_t address)
((CPUARMState *)uc->current_cpu->env_ptr)->regs[15] = address;
}
void arm_reg_reset(uch handle)
void arm_reg_reset(struct uc_struct *uc)
{
struct uc_struct *uc = (struct uc_struct *) handle;
(void)uc;
CPUArchState *env;
env = first_cpu->env_ptr;
@ -36,10 +36,9 @@ void arm_reg_reset(uch handle)
env->pc = 0;
}
int arm_reg_read(uch handle, unsigned int regid, void *value)
int arm_reg_read(struct uc_struct *uc, unsigned int regid, void *value)
{
CPUState *mycpu;
struct uc_struct *uc = (struct uc_struct *) handle;
mycpu = first_cpu;
@ -78,12 +77,9 @@ int arm_reg_read(uch handle, unsigned int regid, void *value)
#define WRITE_BYTE_H(x, b) (x = (x & ~0xff00) | (b & 0xff))
#define WRITE_BYTE_L(x, b) (x = (x & ~0xff) | (b & 0xff))
int arm_reg_write(uch handle, unsigned int regid, const void *value)
int arm_reg_write(struct uc_struct *uc, unsigned int regid, const void *value)
{
CPUState *mycpu;
struct uc_struct *uc = (struct uc_struct *) handle;
mycpu = first_cpu;
CPUState *mycpu = first_cpu;
switch(uc->mode) {
default:

View file

@ -949,7 +949,7 @@ void helper_syscall(CPUX86State *env, int next_eip_addend)
struct uc_struct *uc = env->uc;
if (uc->hook_syscall_idx) {
((uc_cb_insn_syscall_t)uc->hook_callbacks[uc->hook_syscall_idx].callback)(
(uch)uc, uc->hook_callbacks[uc->hook_syscall_idx].user_data);
uc, uc->hook_callbacks[uc->hook_syscall_idx].user_data);
env->eip += next_eip_addend;
}

View file

@ -4761,7 +4761,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
// Unicorn: trace this instruction on request
if (env->uc->hook_insn) {
trace = hook_find((uch)env->uc, UC_HOOK_CODE, pc_start);
trace = hook_find(env->uc, UC_HOOK_CODE, pc_start);
if (trace) {
if (s->last_cc_op != s->cc_op) {
sync_eflags(s, tcg_ctx);
@ -8379,7 +8379,7 @@ static inline void gen_intermediate_code_internal(uint8_t *gen_opc_cc_op,
// Only hook this block if it is not broken from previous translation due to
// full translation cache
if (env->uc->hook_block && !env->uc->block_full) {
struct hook_struct *trace = hook_find((uch)env->uc, UC_HOOK_BLOCK, pc_start);
struct hook_struct *trace = hook_find(env->uc, UC_HOOK_BLOCK, pc_start);
if (trace) {
env->uc->block_addr = pc_start;
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, trace->callback, env->uc, pc_start, trace->user_data);

View file

@ -48,12 +48,10 @@ void x86_release(void *ctx)
g_free(s->tb_ctx.tbs);
}
void x86_reg_reset(uch handle)
void x86_reg_reset(struct uc_struct *uc)
{
struct uc_struct *uc = (struct uc_struct *) handle;
CPUArchState *env;
CPUArchState *env = first_cpu->env_ptr;
env = first_cpu->env_ptr;
env->features[FEAT_1_EDX] = CPUID_CX8 | CPUID_CMOV | CPUID_SSE2 | CPUID_FXSR | CPUID_SSE | CPUID_CLFLUSH;
env->features[FEAT_1_ECX] = CPUID_EXT_SSSE3 | CPUID_EXT_SSE41 | CPUID_EXT_SSE42 | CPUID_EXT_AES;
env->features[FEAT_8000_0001_EDX] = CPUID_EXT2_3DNOW | CPUID_EXT2_RDTSCP;
@ -143,12 +141,9 @@ void x86_reg_reset(uch handle)
}
}
int x86_reg_read(uch handle, unsigned int regid, void *value)
int x86_reg_read(struct uc_struct *uc, unsigned int regid, void *value)
{
CPUState *mycpu;
struct uc_struct *uc = (struct uc_struct *) handle;
mycpu = first_cpu;
CPUState *mycpu = first_cpu;
switch(uc->mode) {
default:
@ -545,12 +540,9 @@ int x86_reg_read(uch handle, unsigned int regid, void *value)
#define WRITE_BYTE_H(x, b) (x = (x & ~0xff00) | (b & 0xff))
#define WRITE_BYTE_L(x, b) (x = (x & ~0xff) | (b & 0xff))
int x86_reg_write(uch handle, unsigned int regid, const void *value)
int x86_reg_write(struct uc_struct *uc, unsigned int regid, const void *value)
{
CPUState *mycpu;
struct uc_struct *uc = (struct uc_struct *) handle;
mycpu = first_cpu;
CPUState *mycpu = first_cpu;
switch(uc->mode) {
default:

View file

@ -5,10 +5,10 @@
#define UC_QEMU_TARGET_I386_H
// functions to read & write registers
int x86_reg_read(uch handle, unsigned int regid, void *value);
int x86_reg_write(uch handle, unsigned int regid, const void *value);
int x86_reg_read(struct uc_struct *uc, unsigned int regid, void *value);
int x86_reg_write(struct uc_struct *uc, unsigned int regid, const void *value);
void x86_reg_reset(uch handle);
void x86_reg_reset(struct uc_struct *uc);
void x86_uc_init(struct uc_struct* uc);
int x86_uc_machine_init(struct uc_struct *uc);

View file

@ -3044,7 +3044,7 @@ static void disas_m68k_insn(CPUM68KState * env, DisasContext *s)
// Unicorn: trace this instruction on request
if (env->uc->hook_insn) {
struct hook_struct *trace = hook_find((uch)env->uc, UC_HOOK_CODE, s->pc);
struct hook_struct *trace = hook_find(env->uc, UC_HOOK_CODE, s->pc);
if (trace)
gen_uc_tracecode(tcg_ctx, 2, trace->callback, env->uc, s->pc, trace->user_data);
// if requested to emulate only some instructions, check if
@ -3105,7 +3105,7 @@ gen_intermediate_code_internal(M68kCPU *cpu, TranslationBlock *tb,
// Only hook this block if it is not broken from previous translation due to
// full translation cache
if (env->uc->hook_block && !env->uc->block_full) {
struct hook_struct *trace = hook_find((uch)env->uc, UC_HOOK_BLOCK, pc_start);
struct hook_struct *trace = hook_find(env->uc, UC_HOOK_BLOCK, pc_start);
if (trace) {
// save block address to see if we need to patch block size later
env->uc->block_addr = pc_start;

View file

@ -21,21 +21,18 @@ static void m68k_set_pc(struct uc_struct *uc, uint64_t address)
((CPUM68KState *)uc->current_cpu->env_ptr)->pc = address;
}
void m68k_reg_reset(uch handle)
void m68k_reg_reset(struct uc_struct *uc)
{
struct uc_struct *uc = (struct uc_struct *) handle;
CPUArchState *env;
CPUArchState *env = first_cpu->env_ptr;
env = first_cpu->env_ptr;
memset(env->aregs, 0, sizeof(env->aregs));
memset(env->dregs, 0, sizeof(env->dregs));
env->pc = 0;
}
int m68k_reg_read(uch handle, unsigned int regid, void *value)
int m68k_reg_read(struct uc_struct *uc, unsigned int regid, void *value)
{
struct uc_struct *uc = (struct uc_struct *)handle;
CPUState *mycpu = first_cpu;
if (regid >= UC_M68K_REG_A0 && regid <= UC_M68K_REG_A7)
@ -60,9 +57,8 @@ int m68k_reg_read(uch handle, unsigned int regid, void *value)
#define WRITE_BYTE_H(x, b) (x = (x & ~0xff00) | (b & 0xff))
#define WRITE_BYTE_L(x, b) (x = (x & ~0xff) | (b & 0xff))
int m68k_reg_write(uch handle, unsigned int regid, const void *value)
int m68k_reg_write(struct uc_struct *uc, unsigned int regid, const void *value)
{
struct uc_struct *uc = (struct uc_struct *) handle;
CPUState *mycpu = first_cpu;
if (regid >= UC_M68K_REG_A0 && regid <= UC_M68K_REG_A7)

View file

@ -5,10 +5,10 @@
#define UC_QEMU_TARGET_M68K_H
// functions to read & write registers
int m68k_reg_read(uch handle, unsigned int regid, void *value);
int m68k_reg_write(uch handle, unsigned int regid, const void *value);
int m68k_reg_read(struct uc_struct *uc, unsigned int regid, void *value);
int m68k_reg_write(struct uc_struct *uc, unsigned int regid, const void *value);
void m68k_reg_reset(uch handle);
void m68k_reg_reset(struct uc_struct *uc);
void m68k_uc_init(struct uc_struct* uc);

View file

@ -11344,7 +11344,7 @@ static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
// Unicorn: trace this instruction on request
if (env->uc->hook_insn) {
struct hook_struct *trace = hook_find((uch)env->uc, UC_HOOK_CODE, ctx->pc);
struct hook_struct *trace = hook_find(env->uc, UC_HOOK_CODE, ctx->pc);
if (trace)
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, trace->callback, env->uc, ctx->pc, trace->user_data);
// if requested to emulate only some instructions, check if
@ -13944,7 +13944,7 @@ static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
// Unicorn: trace this instruction on request
if (env->uc->hook_insn) {
struct hook_struct *trace = hook_find((uch)env->uc, UC_HOOK_CODE, ctx->pc);
struct hook_struct *trace = hook_find(env->uc, UC_HOOK_CODE, ctx->pc);
if (trace)
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, trace->callback, env->uc, ctx->pc, trace->user_data);
// if requested to emulate only some instructions, check if
@ -18523,7 +18523,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx)
// Unicorn: trace this instruction on request
if (env->uc->hook_insn) {
struct hook_struct *trace = hook_find((uch)env->uc, UC_HOOK_CODE, ctx->pc);
struct hook_struct *trace = hook_find(env->uc, UC_HOOK_CODE, ctx->pc);
if (trace)
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, trace->callback, env->uc, ctx->pc, trace->user_data);
// if requested to emulate only some instructions, check if
@ -19211,7 +19211,7 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
// Only hook this block if it is not broken from previous translation due to
// full translation cache
if (env->uc->hook_block && !env->uc->block_full) {
struct hook_struct *trace = hook_find((uch)env->uc, UC_HOOK_BLOCK, pc_start);
struct hook_struct *trace = hook_find(env->uc, UC_HOOK_BLOCK, pc_start);
if (trace) {
// save block address to see if we need to patch block size later
env->uc->block_addr = pc_start;

View file

@ -22,19 +22,17 @@ static void mips_set_pc(struct uc_struct *uc, uint64_t address)
((CPUMIPSState *)uc->current_cpu->env_ptr)->active_tc.PC = address;
}
void mips_reg_reset(uch handle)
void mips_reg_reset(struct uc_struct *uc)
{
struct uc_struct *uc = (struct uc_struct *) handle;
CPUArchState *env;
env = first_cpu->env_ptr;
(void)uc;
CPUArchState *env = first_cpu->env_ptr;
memset(env->active_tc.gpr, 0, sizeof(env->active_tc.gpr));
env->active_tc.PC = 0; }
env->active_tc.PC = 0;
}
int mips_reg_read(uch handle, unsigned int regid, void *value)
int mips_reg_read(struct uc_struct *uc, unsigned int regid, void *value)
{
struct uc_struct *uc = (struct uc_struct *) handle;
CPUState *mycpu = first_cpu;
if (regid >= UC_MIPS_REG_0 && regid <= UC_MIPS_REG_31)
@ -57,9 +55,8 @@ int mips_reg_read(uch handle, unsigned int regid, void *value)
#define WRITE_BYTE_H(x, b) (x = (x & ~0xff00) | (b & 0xff))
#define WRITE_BYTE_L(x, b) (x = (x & ~0xff) | (b & 0xff))
int mips_reg_write(uch handle, unsigned int regid, const void *value)
int mips_reg_write(struct uc_struct *uc, unsigned int regid, const void *value)
{
struct uc_struct *uc = (struct uc_struct *) handle;
CPUState *mycpu = first_cpu;
if (regid >= UC_MIPS_REG_0 && regid <= UC_MIPS_REG_31)

View file

@ -5,10 +5,10 @@
#define UC_QEMU_TARGET_MIPS_H
// functions to read & write registers
int mips_reg_read(uch handle, unsigned int regid, void *value);
int mips_reg_write(uch handle, unsigned int regid, const void *value);
int mips_reg_read(struct uc_struct *uc, unsigned int regid, void *value);
int mips_reg_write(struct uc_struct *uc, unsigned int regid, const void *value);
void mips_reg_reset(uch handle);
void mips_reg_reset(struct uc_struct *uc);
void mips_uc_init(struct uc_struct* uc);
void mipsel_uc_init(struct uc_struct* uc);

View file

@ -2632,7 +2632,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
// Unicorn: trace this instruction on request
if (dc->uc->hook_insn) {
struct hook_struct *trace = hook_find((uch)dc->uc, UC_HOOK_CODE, dc->pc);
struct hook_struct *trace = hook_find(dc->uc, UC_HOOK_CODE, dc->pc);
if (trace)
gen_uc_tracecode(tcg_ctx, 4, trace->callback, dc->uc, dc->pc, trace->user_data);
// if requested to emulate only some instructions, check if
@ -5409,7 +5409,7 @@ static inline void gen_intermediate_code_internal(SPARCCPU *cpu,
// Only hook this block if it is not broken from previous translation due to
// full translation cache
if (env->uc->hook_block && !env->uc->block_full) {
struct hook_struct *trace = hook_find((uch)env->uc, UC_HOOK_BLOCK, pc_start);
struct hook_struct *trace = hook_find(env->uc, UC_HOOK_BLOCK, pc_start);
if (trace) {
// save block address to see if we need to patch block size later
env->uc->block_addr = pc_start;

View file

@ -32,12 +32,10 @@ static void sparc_set_pc(struct uc_struct *uc, uint64_t address)
((CPUSPARCState *)uc->current_cpu->env_ptr)->npc = address + 4;
}
void sparc_reg_reset(uch handle)
void sparc_reg_reset(struct uc_struct *uc)
{
struct uc_struct *uc = (struct uc_struct *) handle;
CPUArchState *env;
CPUArchState *env = first_cpu->env_ptr;
env = first_cpu->env_ptr;
memset(env->gregs, 0, sizeof(env->gregs));
memset(env->fpr, 0, sizeof(env->fpr));
memset(env->regbase, 0, sizeof(env->regbase));
@ -46,9 +44,8 @@ void sparc_reg_reset(uch handle)
env->npc = 0;
}
int sparc_reg_read(uch handle, unsigned int regid, void *value)
int sparc_reg_read(struct uc_struct *uc, unsigned int regid, void *value)
{
struct uc_struct *uc = (struct uc_struct *) handle;
CPUState *mycpu = first_cpu;
if (regid >= UC_SPARC_REG_G0 && regid <= UC_SPARC_REG_G7)
@ -71,9 +68,8 @@ int sparc_reg_read(uch handle, unsigned int regid, void *value)
#define WRITE_BYTE_H(x, b) (x = (x & ~0xff00) | (b & 0xff))
#define WRITE_BYTE_L(x, b) (x = (x & ~0xff) | (b & 0xff))
int sparc_reg_write(uch handle, unsigned int regid, const void *value)
int sparc_reg_write(struct uc_struct *uc, unsigned int regid, const void *value)
{
struct uc_struct *uc = (struct uc_struct *) handle;
CPUState *mycpu = first_cpu;
if (regid >= UC_SPARC_REG_G0 && regid <= UC_SPARC_REG_G7)

View file

@ -5,10 +5,10 @@
#define UC_QEMU_TARGET_SPARC_H
// functions to read & write registers
int sparc_reg_read(uch handle, unsigned int regid, void *value);
int sparc_reg_write(uch handle, unsigned int regid, const void *value);
int sparc_reg_read(struct uc_struct *uc, unsigned int regid, void *value);
int sparc_reg_write(struct uc_struct *uc, unsigned int regid, const void *value);
void sparc_reg_reset(uch handle);
void sparc_reg_reset(struct uc_struct *uc);
void sparc_uc_init(struct uc_struct* uc);
void sparc64_uc_init(struct uc_struct* uc);

View file

@ -15,12 +15,10 @@
#define READ_BYTE_L(x) (x & 0xff)
void sparc_reg_reset(uch handle)
void sparc_reg_reset(struct uc_struct *uc)
{
struct uc_struct *uc = (struct uc_struct *) handle;
CPUArchState *env;
CPUArchState *env = first_cpu->env_ptr;
env = first_cpu->env_ptr;
memset(env->gregs, 0, sizeof(env->gregs));
memset(env->fpr, 0, sizeof(env->fpr));
memset(env->regbase, 0, sizeof(env->regbase));
@ -29,9 +27,8 @@ void sparc_reg_reset(uch handle)
env->npc = 0;
}
int sparc_reg_read(uch handle, unsigned int regid, void *value)
int sparc_reg_read(struct uc_struct *uc, unsigned int regid, void *value)
{
struct uc_struct *uc = (struct uc_struct *) handle;
CPUState *mycpu = first_cpu;
if (regid >= UC_SPARC_REG_G0 && regid <= UC_SPARC_REG_G7)
@ -54,9 +51,8 @@ int sparc_reg_read(uch handle, unsigned int regid, void *value)
#define WRITE_BYTE_H(x, b) (x = (x & ~0xff00) | (b & 0xff))
#define WRITE_BYTE_L(x, b) (x = (x & ~0xff) | (b & 0xff))
int sparc_reg_write(uch handle, unsigned int regid, const void *value)
int sparc_reg_write(struct uc_struct *uc, unsigned int regid, const void *value)
{
struct uc_struct *uc = (struct uc_struct *) handle;
CPUState *mycpu = first_cpu;
if (regid >= UC_SPARC_REG_G0 && regid <= UC_SPARC_REG_G7)

View file

@ -12,7 +12,7 @@ static int count = 1;
// @address: address where the code is being executed
// @size: size of machine instruction being executed
// @user_data: user data passed to tracing APIs.
void cb_hookblock(uch handle, uint64_t address, uint32_t size, void *user_data) {
void cb_hookblock(ucengine *uc, uint64_t address, uint32_t size, void *user_data) {
fprintf(stderr, "# >>> Tracing basic block at 0x%llx, block size = 0x%x\n", address, size);
if (address != 0x1000000 && address != 0x1000200) {
fprintf(stderr, "not ok %d - address != 0x1000000 && address != 0x1000200\n", count++);
@ -27,19 +27,19 @@ void cb_hookblock(uch handle, uint64_t address, uint32_t size, void *user_data)
}
int main() {
uch u;
ucengine *uc;
fprintf(stderr, "# basic block callback test\n");
fprintf(stderr, "# there are only two basic blocks 0x1000000-0x10001ff and 0x1000200-0x10003ff\n");
uc_err err = uc_open(UC_ARCH_X86, UC_MODE_32, &u);
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(u, 0x1000000, 4096, UC_PROT_ALL);
err = uc_mem_map(uc, 0x1000000, 4096, UC_PROT_ALL);
if (err != UC_ERR_OK) {
fprintf(stderr, "not ok %d - %s\n", count++, uc_strerror(err));
exit(0);
@ -55,23 +55,23 @@ int main() {
memset(code, 0x90, sizeof(code));
memcpy(code + 1024 - 5, "\xe9\x00\xfe\xff\xff", 5);
err = uc_mem_write(u, 0x1000000, code, sizeof(code));
err = uc_mem_write(uc, 0x1000000, 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\n", count++);
uch h1, h2;
uc_hook_h h1, h2;
err = uc_hook_add(u, &h1, UC_HOOK_BLOCK, cb_hookblock, NULL, (uint64_t)1, (uint64_t)0);
err = uc_hook_add(uc, &h1, UC_HOOK_BLOCK, cb_hookblock, NULL, (uint64_t)1, (uint64_t)0);
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++);
err = uc_emu_start(u, 0x1000000, 0x1000000 + sizeof(code), 0, 1030);
err = uc_emu_start(uc, 0x1000000, 0x1000000 + sizeof(code), 0, 1030);
if (err != UC_ERR_OK) {
fprintf(stderr, "not ok %d - %s\n", count++, uc_strerror(err));
exit(0);

View file

@ -10,8 +10,8 @@ int main()
{
int size;
uint8_t *buf;
uch uh;
uc_err err = uc_open (UC_ARCH_X86, UC_MODE_64, &uh);
ucengine *uc;
uc_err err = uc_open (UC_ARCH_X86, UC_MODE_64, &uc);
if (err) {
fprintf (stderr, "Cannot initialize unicorn\n");
return 1;
@ -23,9 +23,9 @@ int main()
return 1;
}
memset (buf, 0, size);
if (!uc_mem_map (uh, UC_BUG_WRITE_ADDR, size, UC_PROT_ALL)) {
uc_mem_write (uh, UC_BUG_WRITE_ADDR, buf, size);
if (!uc_mem_map (uc, UC_BUG_WRITE_ADDR, size, UC_PROT_ALL)) {
uc_mem_write (uc, UC_BUG_WRITE_ADDR, buf, size);
}
uc_close (&uh);
uc_close(uc);
return 0;
}

View file

@ -8,17 +8,17 @@
int main()
{
uch uh;
ucengine *uc;
uint8_t *buf, *buf2;
int i;
uc_err err;
err = uc_open (UC_ARCH_X86, UC_MODE_64, &uh);
err = uc_open (UC_ARCH_X86, UC_MODE_64, &uc);
if (err) {
printf ("uc_open %d\n", err);
return 1;
}
err = uc_mem_map (uh, ADDR, SIZE, UC_PROT_ALL);
err = uc_mem_map (uc, ADDR, SIZE, UC_PROT_ALL);
if (err) {
printf ("uc_mem_map %d\n", err);
return 1;
@ -29,12 +29,12 @@ int main()
buf[i] = i & 0xff;
}
/* crash here */
err = uc_mem_write (uh, ADDR, buf, SIZE+OVERFLOW);
err = uc_mem_write (uc, ADDR, buf, SIZE+OVERFLOW);
if (err) {
printf ("uc_mem_map %d\n", err);
return 1;
}
err = uc_mem_read (uh, ADDR+10, buf2, 4);
err = uc_mem_read (uc, ADDR+10, buf2, 4);
if (err) {
printf ("uc_mem_map %d\n", err);
return 1;

View file

@ -36,7 +36,7 @@ bits 32
*/
// callback for tracing memory access (READ or WRITE)
static bool hook_mem_invalid(uch handle, uc_mem_type type,
static bool hook_mem_invalid(ucengine *uc, uc_mem_type type,
uint64_t address, int size, int64_t value, void *user_data)
{
@ -54,42 +54,43 @@ static bool hook_mem_invalid(uch handle, uc_mem_type type,
int main(int argc, char **argv, char **envp)
{
uch handle, trace1, trace2;
ucengine *uc;
uc_hook_h trace1, trace2;
uc_err err;
uint32_t eax, ebx;
printf("Memory protections test\n");
// Initialize emulator in X86-32bit mode
err = uc_open(UC_ARCH_X86, UC_MODE_32, &handle);
err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc);
if (err) {
printf("Failed on uc_open() with error returned: %u\n", err);
return 1;
}
uc_mem_map(handle, 0x100000, 0x1000, UC_PROT_READ);
uc_mem_map(handle, 0x300000, 0x1000, UC_PROT_READ | UC_PROT_WRITE);
uc_mem_map(handle, 0x400000, 0x1000, UC_PROT_WRITE);
uc_mem_map(uc, 0x100000, 0x1000, UC_PROT_READ);
uc_mem_map(uc, 0x300000, 0x1000, UC_PROT_READ | UC_PROT_WRITE);
uc_mem_map(uc, 0x400000, 0x1000, UC_PROT_WRITE);
// write machine code to be emulated to memory
if (uc_mem_write(handle, 0x100000, PROGRAM, sizeof(PROGRAM))) {
if (uc_mem_write(uc, 0x100000, PROGRAM, sizeof(PROGRAM))) {
printf("Failed to write emulation code to memory, quit!\n");
return 2;
} else {
printf("Allowed to write to read only memory via uc_mem_write\n");
}
uc_mem_write(handle, 0x300000, (const uint8_t*)"\x41\x41\x41\x41", 4);
uc_mem_write(handle, 0x400000, (const uint8_t*)"\x42\x42\x42\x42", 4);
uc_mem_write(uc, 0x300000, (const uint8_t*)"\x41\x41\x41\x41", 4);
uc_mem_write(uc, 0x400000, (const uint8_t*)"\x42\x42\x42\x42", 4);
//uc_hook_add(handle, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)0x400000, (uint64_t)0x400fff);
//uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)0x400000, (uint64_t)0x400fff);
// intercept invalid memory events
uc_hook_add(handle, &trace1, UC_HOOK_MEM_INVALID, hook_mem_invalid, NULL);
uc_hook_add(uc, &trace1, UC_HOOK_MEM_INVALID, hook_mem_invalid, NULL);
// emulate machine code in infinite time
printf("BEGIN execution\n");
err = uc_emu_start(handle, 0x100000, 0x100000 + sizeof(PROGRAM), 0, 2);
err = uc_emu_start(uc, 0x100000, 0x100000 + sizeof(PROGRAM), 0, 2);
if (err) {
printf("Expected failure on uc_emu_start() with error returned %u: %s\n",
err, uc_strerror(err));
@ -98,12 +99,12 @@ int main(int argc, char **argv, char **envp)
}
printf("END execution\n");
uc_reg_read(handle, UC_X86_REG_EAX, &eax);
uc_reg_read(uc, UC_X86_REG_EAX, &eax);
printf("Final eax = 0x%x\n", eax);
uc_reg_read(handle, UC_X86_REG_EBX, &ebx);
uc_reg_read(uc, UC_X86_REG_EBX, &ebx);
printf("Final ebx = 0x%x\n", ebx);
uc_close(&handle);
uc_close(uc);
return 0;
}

View file

@ -50,17 +50,17 @@ hlt
static int log_num = 1;
// callback for tracing instruction
static void hook_code(uch handle, uint64_t addr, uint32_t size, void *user_data)
static void hook_code(ucengine *uc, uint64_t addr, uint32_t size, void *user_data)
{
uint8_t opcode;
if (uc_mem_read(handle, addr, &opcode, 1) != UC_ERR_OK) {
if (uc_mem_read(uc, addr, &opcode, 1) != UC_ERR_OK) {
printf("not ok %d - uc_mem_read fail during hook_code callback, addr: 0x%" PRIx64 "\n", log_num++, addr);
_exit(-1);
}
switch (opcode) {
case 0xf4: //hlt
printf("# Handling HLT\n");
if (uc_emu_stop(handle) != UC_ERR_OK) {
if (uc_emu_stop(uc) != UC_ERR_OK) {
printf("not ok %d - uc_emu_stop fail during hook_code callback, addr: 0x%" PRIx64 "\n", log_num++, addr);
_exit(-1);
}
@ -74,7 +74,7 @@ static void hook_code(uch handle, uint64_t addr, uint32_t size, void *user_data)
}
// callback for tracing memory access (READ or WRITE)
static void hook_mem_write(uch handle, uc_mem_type type,
static void hook_mem_write(ucengine *uc, uc_mem_type type,
uint64_t addr, int size, int64_t value, void *user_data)
{
printf("# write to memory at 0x%"PRIx64 ", data size = %u, data value = 0x%"PRIx64 "\n", addr, size, value);
@ -89,7 +89,8 @@ static void hook_mem_write(uch handle, uc_mem_type type,
int main(int argc, char **argv, char **envp)
{
uch handle, trace1, trace2;
ucengine *uc;
uc_hook_h trace1, trace2;
uc_err err;
uint8_t buf1[100], readbuf[100];
@ -98,7 +99,7 @@ int main(int argc, char **argv, char **envp)
memset(buf1, 'A', 20);
// Initialize emulator in X86-32bit mode
err = uc_open(UC_ARCH_X86, UC_MODE_32, &handle);
err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc);
if (err) {
printf("not ok %d - Failed on uc_open() with error returned: %u\n", log_num++, err);
return 1;
@ -107,11 +108,11 @@ int main(int argc, char **argv, char **envp)
printf("ok %d - uc_open() success\n", log_num++);
}
uc_mem_map(handle, 0x100000, 0x1000, UC_PROT_READ);
uc_mem_map(handle, 0x200000, 0x2000, UC_PROT_READ | UC_PROT_WRITE);
uc_mem_map(uc, 0x100000, 0x1000, UC_PROT_READ);
uc_mem_map(uc, 0x200000, 0x2000, UC_PROT_READ | UC_PROT_WRITE);
// fill in the data that we want to copy
if (uc_mem_write(handle, 0x200000, (uint8_t*)buf1, 20)) {
if (uc_mem_write(uc, 0x200000, (uint8_t*)buf1, 20)) {
printf("not ok %d - Failed to write read buffer to memory, quit!\n", log_num++);
return 2;
}
@ -120,7 +121,7 @@ int main(int argc, char **argv, char **envp)
}
// write machine code to be emulated to memory
if (uc_mem_write(handle, 0x100000, PROGRAM, sizeof(PROGRAM))) {
if (uc_mem_write(uc, 0x100000, PROGRAM, sizeof(PROGRAM))) {
printf("not ok %d - Failed to write emulation code to memory, quit!\n", log_num++);
return 4;
}
@ -128,7 +129,7 @@ int main(int argc, char **argv, char **envp)
printf("ok %d - Program written to memory\n", log_num++);
}
if (uc_hook_add(handle, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)1, (uint64_t)0) != UC_ERR_OK) {
if (uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)1, (uint64_t)0) != UC_ERR_OK) {
printf("not ok %d - Failed to install UC_HOOK_CODE handler\n", log_num++);
return 5;
}
@ -137,7 +138,7 @@ int main(int argc, char **argv, char **envp)
}
// intercept memory write events only, NOT read events
if (uc_hook_add(handle, &trace1, UC_HOOK_MEM_WRITE, hook_mem_write, NULL, (uint64_t)1, (uint64_t)0) != UC_ERR_OK) {
if (uc_hook_add(uc, &trace1, UC_HOOK_MEM_WRITE, hook_mem_write, NULL, (uint64_t)1, (uint64_t)0) != UC_ERR_OK) {
printf("not ok %d - Failed to install UC_HOOK_MEM_WRITE handler\n", log_num++);
return 6;
}
@ -147,7 +148,7 @@ int main(int argc, char **argv, char **envp)
// emulate machine code until told to stop by hook_code
printf("# BEGIN execution\n");
err = uc_emu_start(handle, 0x100000, 0x101000, 0, 0);
err = uc_emu_start(uc, 0x100000, 0x101000, 0, 0);
if (err != UC_ERR_OK) {
printf("not ok %d - Failure on uc_emu_start() with error %u:%s\n", log_num++, err, uc_strerror(err));
return 8;
@ -159,7 +160,7 @@ int main(int argc, char **argv, char **envp)
//make sure that data got copied
// fill in sections that shouldn't get touched
if (uc_mem_read(handle, 0x201000, (uint8_t*)readbuf, 20)) {
if (uc_mem_read(uc, 0x201000, (uint8_t*)readbuf, 20)) {
printf("not ok %d - Failed to read random buffer 1 from memory\n", log_num++);
}
else {
@ -172,7 +173,7 @@ int main(int argc, char **argv, char **envp)
}
}
if (uc_close(&handle) == UC_ERR_OK) {
if (uc_close(uc) == UC_ERR_OK) {
printf("ok %d - uc_close complete\n", log_num++);
}
else {

View file

@ -46,22 +46,22 @@ bottom:
*/
// callback for tracing instruction
static void hook_code(uch handle, uint64_t address, uint32_t size, void *user_data)
static void hook_code(ucengine *uc, uint64_t address, uint32_t size, void *user_data)
{
uint32_t esp;
printf(">>> Tracing instruction at 0x%"PRIx64 ", instruction size = 0x%x\n", address, size);
uc_reg_read(handle, UC_X86_REG_ESP, &esp);
uc_reg_read(uc, UC_X86_REG_ESP, &esp);
printf(">>> --- ESP is 0x%x\n", esp);
}
// callback for tracing memory access (READ or WRITE)
static bool hook_mem_invalid(uch handle, uc_mem_type type,
static bool hook_mem_invalid(ucengine *uc, uc_mem_type type,
uint64_t address, int size, int64_t value, void *user_data)
{
uint32_t esp;
uc_reg_read(handle, UC_X86_REG_ESP, &esp);
uc_reg_read(uc, UC_X86_REG_ESP, &esp);
switch(type) {
default:
@ -74,7 +74,7 @@ static bool hook_mem_invalid(uch handle, uc_mem_type type,
upper = (esp + 0xfff) & ~0xfff;
printf(">>> Stack appears to be missing at 0x%"PRIx64 ", allocating now\n", address);
// map this memory in with 2MB in size
uc_mem_map(handle, upper - 0x8000, 0x8000, UC_PROT_READ | UC_PROT_WRITE);
uc_mem_map(uc, upper - 0x8000, 0x8000, UC_PROT_READ | UC_PROT_WRITE);
// return true to indicate we want to continue
return true;
}
@ -94,7 +94,8 @@ static bool hook_mem_invalid(uch handle, uc_mem_type type,
int main(int argc, char **argv, char **envp)
{
uch handle, trace1, trace2;
ucengine *uc;
uc_hook_h trace1, trace2;
uc_err err;
uint8_t bytes[8];
uint32_t esp;
@ -108,44 +109,44 @@ int main(int argc, char **argv, char **envp)
printf("Memory mapping test\n");
// Initialize emulator in X86-32bit mode
err = uc_open(UC_ARCH_X86, UC_MODE_32, &handle);
err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc);
if (err) {
printf("Failed on uc_open() with error returned: %u\n", err);
return 1;
}
uc_mem_map(handle, 0x100000, 0x1000, UC_PROT_ALL);
uc_mem_map(handle, 0x200000, 0x2000, UC_PROT_ALL);
uc_mem_map(handle, 0x300000, 0x3000, UC_PROT_ALL);
uc_mem_map(handle, 0x400000, 0x4000, UC_PROT_READ);
uc_mem_map(uc, 0x100000, 0x1000, UC_PROT_ALL);
uc_mem_map(uc, 0x200000, 0x2000, UC_PROT_ALL);
uc_mem_map(uc, 0x300000, 0x3000, UC_PROT_ALL);
uc_mem_map(uc, 0x400000, 0x4000, UC_PROT_READ);
if (map_stack) {
printf("Pre-mapping stack\n");
uc_mem_map(handle, STACK, STACK_SIZE, UC_PROT_READ | UC_PROT_WRITE);
uc_mem_map(uc, STACK, STACK_SIZE, UC_PROT_READ | UC_PROT_WRITE);
} else {
printf("Mapping stack on first invalid memory access\n");
}
esp = STACK + STACK_SIZE;
uc_reg_write(handle, UC_X86_REG_ESP, &esp);
uc_reg_write(uc, UC_X86_REG_ESP, &esp);
// write machine code to be emulated to memory
if (uc_mem_write(handle, 0x400000, PROGRAM, sizeof(PROGRAM))) {
if (uc_mem_write(uc, 0x400000, PROGRAM, sizeof(PROGRAM))) {
printf("Failed to write emulation code to memory, quit!\n");
return 2;
} else {
printf("Allowed to write to read only memory via uc_mem_write\n");
}
//uc_hook_add(handle, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)0x400000, (uint64_t)0x400fff);
//uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)0x400000, (uint64_t)0x400fff);
// intercept invalid memory events
uc_hook_add(handle, &trace1, UC_HOOK_MEM_INVALID, hook_mem_invalid, NULL);
uc_hook_add(uc, &trace1, UC_HOOK_MEM_INVALID, hook_mem_invalid, NULL);
// emulate machine code in infinite time
printf("BEGIN execution - 1\n");
err = uc_emu_start(handle, 0x400000, 0x400000 + sizeof(PROGRAM), 0, 10);
err = uc_emu_start(uc, 0x400000, 0x400000 + sizeof(PROGRAM), 0, 10);
if (err) {
printf("Expected failue on uc_emu_start() with error returned %u: %s\n",
err, uc_strerror(err));
@ -157,8 +158,8 @@ int main(int argc, char **argv, char **envp)
// emulate machine code in infinite time
printf("BEGIN execution - 2\n");
uint32_t eax = 0x40002C;
uc_reg_write(handle, UC_X86_REG_EAX, &eax);
err = uc_emu_start(handle, 0x400015, 0x400000 + sizeof(PROGRAM), 0, 2);
uc_reg_write(uc, UC_X86_REG_EAX, &eax);
err = uc_emu_start(uc, 0x400015, 0x400000 + sizeof(PROGRAM), 0, 2);
if (err) {
printf("Expected failure on uc_emu_start() with error returned %u: %s\n",
err, uc_strerror(err));
@ -168,7 +169,7 @@ int main(int argc, char **argv, char **envp)
printf("END execution - 2\n");
printf("Verifying content at 0x400025 is unchanged\n");
if (!uc_mem_read(handle, 0x400025, bytes, 4)) {
if (!uc_mem_read(uc, 0x400025, bytes, 4)) {
printf(">>> Read 4 bytes from [0x%x] = 0x%x\n", (uint32_t)0x400025, *(uint32_t*) bytes);
if (0x41414141 != *(uint32_t*) bytes) {
printf("ERROR content in read only memory changed\n");
@ -181,7 +182,7 @@ int main(int argc, char **argv, char **envp)
}
printf("Verifying content at 0x40002C is unchanged\n");
if (!uc_mem_read(handle, 0x40002C, bytes, 4)) {
if (!uc_mem_read(uc, 0x40002C, bytes, 4)) {
printf(">>> Read 4 bytes from [0x%x] = 0x%x\n", (uint32_t)0x40002C, *(uint32_t*) bytes);
if (0x42424242 != *(uint32_t*) bytes) {
printf("ERROR content in read only memory changed\n");
@ -194,14 +195,14 @@ int main(int argc, char **argv, char **envp)
}
printf("Verifying content at bottom of stack is readable and correct\n");
if (!uc_mem_read(handle, esp - 4, bytes, 4)) {
if (!uc_mem_read(uc, esp - 4, bytes, 4)) {
printf(">>> Read 4 bytes from [0x%x] = 0x%x\n", (uint32_t)(esp - 4), *(uint32_t*) bytes);
} else {
printf(">>> Failed to read 4 bytes from [0x%x]\n", (uint32_t)(esp - 4));
return 4;
}
uc_close(&handle);
uc_close(uc);
return 0;
}

View file

@ -8,10 +8,10 @@
int got_sigill = 0;
void _interrupt(uch handle, uint32_t intno, void *user_data)
void _interrupt(ucengine *uc, uint32_t intno, void *user_data)
{
if (intno == 6) {
uc_emu_stop (handle);
uc_emu_stop(uc);
got_sigill = 1;
}
}
@ -20,9 +20,9 @@ int main()
{
int size;
uint8_t *buf;
uch uh;
uch uh_trap;
uc_err err = uc_open (UC_ARCH_X86, UC_MODE_64, &uh);
ucengine *uc;
uc_hook_h uh_trap;
uc_err err = uc_open (UC_ARCH_X86, UC_MODE_64, &uc);
if (err) {
fprintf (stderr, "Cannot initialize unicorn\n");
return 1;
@ -34,13 +34,13 @@ int main()
return 1;
}
memset (buf, 0, size);
if (!uc_mem_map (uh, UC_BUG_WRITE_ADDR, size, UC_PROT_ALL)) {
uc_mem_write (uh, UC_BUG_WRITE_ADDR,
if (!uc_mem_map(uc, UC_BUG_WRITE_ADDR, size, UC_PROT_ALL)) {
uc_mem_write(uc, UC_BUG_WRITE_ADDR,
(const uint8_t*)"\xff\xff\xff\xff\xff\xff\xff\xff", 8);
}
uc_hook_add (uh, &uh_trap, UC_HOOK_INTR, _interrupt, NULL);
uc_emu_start (uh, UC_BUG_WRITE_ADDR, UC_BUG_WRITE_ADDR+8, 0, 1);
uc_close (&uh);
uc_hook_add(uc, &uh_trap, UC_HOOK_INTR, _interrupt, NULL);
uc_emu_start(uc, UC_BUG_WRITE_ADDR, UC_BUG_WRITE_ADDR+8, 0, 1);
uc_close(uc);
printf ("Correct: %s\n", got_sigill? "YES": "NO");
return got_sigill? 0: 1;
}

View file

@ -10,20 +10,20 @@ int main()
{
int size;
uint8_t *buf;
uch uh;
uch uh_trap;
uc_err err = uc_open (UC_ARCH_X86, UC_MODE_64, &uh);
ucengine *uc;
uc_err err = uc_open (UC_ARCH_X86, UC_MODE_64, &uc);
if (err) {
fprintf (stderr, "Cannot initialize unicorn\n");
return 1;
}
size = UC_BUG_WRITE_SIZE;
if (!uc_mem_map (uh, UC_BUG_WRITE_ADDR, size, UC_PROT_ALL)) {
uc_mem_write (uh, UC_BUG_WRITE_ADDR,
if (!uc_mem_map (uc, UC_BUG_WRITE_ADDR, size, UC_PROT_ALL)) {
uc_mem_write (uc, UC_BUG_WRITE_ADDR,
(const uint8_t*)"\xff\xff\xff\xff\xff\xff\xff\xff", 8);
}
err = uc_emu_start (uh, UC_BUG_WRITE_ADDR, UC_BUG_WRITE_ADDR+8, 0, 1);
uc_close (&uh);
err = uc_emu_start(uc, UC_BUG_WRITE_ADDR, UC_BUG_WRITE_ADDR+8, 0, 1);
uc_close(uc);
printf ("Error = %u (%s)\n", err, uc_strerror(err));
return err? -1: 0;
}

View file

@ -24,21 +24,21 @@ https://github.com/unicorn-engine/unicorn/issues/78
// number of seconds to wait before timeout
#define TIMEOUT 5
static void hook_block(uch handle, uint64_t address, uint32_t size, void *user_data)
static void hook_block(ucengine *uc, uint64_t address, uint32_t size, void *user_data)
{
printf(">>> Tracing basic block at 0x%"PRIx64 ", block size = 0x%x\n", address, size);
}
static void hook_code(uch handle, uint64_t address, uint32_t size, void *user_data)
static void hook_code(ucengine *uc, uint64_t address, uint32_t size, void *user_data)
{
printf(">>> Tracing instruction at 0x%"PRIx64 ", instruction size = 0x%x\n", address, size);
}
static void test_arm(void)
{
uch handle;
ucengine *uc;
uc_err err;
uch trace1, trace2;
uc_hook_h trace1, trace2;
int r0 = 0x1234; // R0 register
int r2 = 0x6789; // R1 register
@ -48,7 +48,7 @@ static void test_arm(void)
printf("Emulate ARM code\n");
// Initialize emulator in ARM mode
err = uc_open(UC_ARCH_ARM, UC_MODE_ARM, &handle);
err = uc_open(UC_ARCH_ARM, UC_MODE_ARM, &uc);
if (err) {
printf("Failed on uc_open() with error returned: %u (%s)\n",
err, uc_strerror(err));
@ -56,25 +56,25 @@ static void test_arm(void)
}
// map 2MB memory for this emulation
uc_mem_map(handle, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
uc_mem_map(uc, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
// write machine code to be emulated to memory
uc_mem_write(handle, ADDRESS, (uint8_t *)ARM_CODE, sizeof(ARM_CODE) - 1);
uc_mem_write(uc, ADDRESS, (uint8_t *)ARM_CODE, sizeof(ARM_CODE) - 1);
// initialize machine registers
uc_reg_write(handle, UC_ARM_REG_R0, &r0);
uc_reg_write(handle, UC_ARM_REG_R2, &r2);
uc_reg_write(handle, UC_ARM_REG_R3, &r3);
uc_reg_write(uc, UC_ARM_REG_R0, &r0);
uc_reg_write(uc, UC_ARM_REG_R2, &r2);
uc_reg_write(uc, UC_ARM_REG_R3, &r3);
// tracing all basic blocks with customized callback
uc_hook_add(handle, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
// tracing one instruction at ADDRESS with customized callback
uc_hook_add(handle, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)ADDRESS, (uint64_t)ADDRESS);
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)ADDRESS, (uint64_t)ADDRESS);
// emulate machine code in infinite time (last param = 0), or when
// finishing all the code.
err = uc_emu_start(handle, ADDRESS, ADDRESS + sizeof(ARM_CODE) -1, UC_SECOND_SCALE * TIMEOUT, 0);
err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(ARM_CODE) -1, UC_SECOND_SCALE * TIMEOUT, 0);
if (err) {
printf("Failed on uc_emu_start() with error returned: %u\n", err);
}
@ -82,26 +82,26 @@ static void test_arm(void)
// now print out some registers
printf(">>> Emulation done. Below is the CPU context\n");
uc_reg_read(handle, UC_ARM_REG_R0, &r0);
uc_reg_read(handle, UC_ARM_REG_R1, &r1);
uc_reg_read(uc, UC_ARM_REG_R0, &r0);
uc_reg_read(uc, UC_ARM_REG_R1, &r1);
printf(">>> R0 = 0x%x\n", r0);
printf(">>> R1 = 0x%x\n", r1);
uc_close(&handle);
uc_close(uc);
}
static void test_thumb(void)
{
uch handle;
ucengine *uc;
uc_err err;
uch trace1, trace2;
uc_hook_h trace1, trace2;
int sp = 0x1234; // R0 register
printf("Emulate THUMB code\n");
// Initialize emulator in ARM mode
err = uc_open(UC_ARCH_ARM, UC_MODE_THUMB, &handle);
err = uc_open(UC_ARCH_ARM, UC_MODE_THUMB, &uc);
if (err) {
printf("Failed on uc_open() with error returned: %u (%s)\n",
err, uc_strerror(err));
@ -109,23 +109,23 @@ static void test_thumb(void)
}
// map 2MB memory for this emulation
uc_mem_map(handle, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
uc_mem_map(uc, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
// write machine code to be emulated to memory
uc_mem_write(handle, ADDRESS, (uint8_t *)THUMB_CODE, sizeof(THUMB_CODE) - 1);
uc_mem_write(uc, ADDRESS, (uint8_t *)THUMB_CODE, sizeof(THUMB_CODE) - 1);
// initialize machine registers
uc_reg_write(handle, UC_ARM_REG_SP, &sp);
uc_reg_write(uc, UC_ARM_REG_SP, &sp);
// tracing all basic blocks with customized callback
uc_hook_add(handle, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
// tracing one instruction at ADDRESS with customized callback
uc_hook_add(handle, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)ADDRESS, (uint64_t)ADDRESS);
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)ADDRESS, (uint64_t)ADDRESS);
// emulate machine code in infinite time (last param = 0), or when
// finishing all the code.
err = uc_emu_start(handle, ADDRESS, ADDRESS + sizeof(THUMB_CODE) -1, UC_SECOND_SCALE * TIMEOUT, 0);
err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(THUMB_CODE) -1, UC_SECOND_SCALE * TIMEOUT, 0);
if (err) {
printf("Failed on uc_emu_start() with error returned: %u\n", err);
}
@ -133,10 +133,10 @@ static void test_thumb(void)
// now print out some registers
printf(">>> Emulation done. Below is the CPU context\n");
uc_reg_read(handle, UC_ARM_REG_SP, &sp);
uc_reg_read(uc, UC_ARM_REG_SP, &sp);
printf(">>> SP = 0x%x\n", sp);
uc_close(&handle);
uc_close(uc);
}
int main(int argc, char **argv, char **envp)

View file

@ -15,21 +15,21 @@
// memory address where emulation starts
#define ADDRESS 0x10000
static void hook_block(uch handle, uint64_t address, uint32_t size, void *user_data)
static void hook_block(ucengine *uc, uint64_t address, uint32_t size, void *user_data)
{
printf(">>> Tracing basic block at 0x%"PRIx64 ", block size = 0x%x\n", address, size);
}
static void hook_code(uch handle, uint64_t address, uint32_t size, void *user_data)
static void hook_code(ucengine *uc, uint64_t address, uint32_t size, void *user_data)
{
printf(">>> Tracing instruction at 0x%"PRIx64 ", instruction size = 0x%x\n", address, size);
}
static void test_arm(void)
{
uch handle;
ucengine *uc;
uc_err err;
uch trace1, trace2;
uc_hook_h trace1, trace2;
int r0 = 0x1234; // R0 register
int r2 = 0x6789; // R1 register
@ -39,7 +39,7 @@ static void test_arm(void)
printf("Emulate ARM code\n");
// Initialize emulator in ARM mode
err = uc_open(UC_ARCH_ARM, UC_MODE_ARM, &handle);
err = uc_open(UC_ARCH_ARM, UC_MODE_ARM, &uc);
if (err) {
printf("Failed on uc_open() with error returned: %u (%s)\n",
err, uc_strerror(err));
@ -47,25 +47,25 @@ static void test_arm(void)
}
// map 2MB memory for this emulation
uc_mem_map(handle, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
uc_mem_map(uc, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
// write machine code to be emulated to memory
uc_mem_write(handle, ADDRESS, (uint8_t *)ARM_CODE, sizeof(ARM_CODE) - 1);
uc_mem_write(uc, ADDRESS, (uint8_t *)ARM_CODE, sizeof(ARM_CODE) - 1);
// initialize machine registers
uc_reg_write(handle, UC_ARM_REG_R0, &r0);
uc_reg_write(handle, UC_ARM_REG_R2, &r2);
uc_reg_write(handle, UC_ARM_REG_R3, &r3);
uc_reg_write(uc, UC_ARM_REG_R0, &r0);
uc_reg_write(uc, UC_ARM_REG_R2, &r2);
uc_reg_write(uc, UC_ARM_REG_R3, &r3);
// tracing all basic blocks with customized callback
uc_hook_add(handle, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
// tracing one instruction at ADDRESS with customized callback
uc_hook_add(handle, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)ADDRESS, (uint64_t)ADDRESS);
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)ADDRESS, (uint64_t)ADDRESS);
// emulate machine code in infinite time (last param = 0), or when
// finishing all the code.
err = uc_emu_start(handle, ADDRESS, ADDRESS + sizeof(ARM_CODE) -1, 0, 0);
err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(ARM_CODE) -1, 0, 0);
if (err) {
printf("Failed on uc_emu_start() with error returned: %u\n", err);
}
@ -73,26 +73,26 @@ static void test_arm(void)
// now print out some registers
printf(">>> Emulation done. Below is the CPU context\n");
uc_reg_read(handle, UC_ARM_REG_R0, &r0);
uc_reg_read(handle, UC_ARM_REG_R1, &r1);
uc_reg_read(uc, UC_ARM_REG_R0, &r0);
uc_reg_read(uc, UC_ARM_REG_R1, &r1);
printf(">>> R0 = 0x%x\n", r0);
printf(">>> R1 = 0x%x\n", r1);
uc_close(&handle);
uc_close(uc);
}
static void test_thumb(void)
{
uch handle;
ucengine *uc;
uc_err err;
uch trace1, trace2;
uc_hook_h trace1, trace2;
int sp = 0x1234; // R0 register
printf("Emulate THUMB code\n");
// Initialize emulator in ARM mode
err = uc_open(UC_ARCH_ARM, UC_MODE_THUMB, &handle);
err = uc_open(UC_ARCH_ARM, UC_MODE_THUMB, &uc);
if (err) {
printf("Failed on uc_open() with error returned: %u (%s)\n",
err, uc_strerror(err));
@ -100,23 +100,23 @@ static void test_thumb(void)
}
// map 2MB memory for this emulation
uc_mem_map(handle, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
uc_mem_map(uc, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
// write machine code to be emulated to memory
uc_mem_write(handle, ADDRESS, (uint8_t *)THUMB_CODE, sizeof(THUMB_CODE) - 1);
uc_mem_write(uc, ADDRESS, (uint8_t *)THUMB_CODE, sizeof(THUMB_CODE) - 1);
// initialize machine registers
uc_reg_write(handle, UC_ARM_REG_SP, &sp);
uc_reg_write(uc, UC_ARM_REG_SP, &sp);
// tracing all basic blocks with customized callback
uc_hook_add(handle, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
// tracing one instruction at ADDRESS with customized callback
uc_hook_add(handle, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)ADDRESS, (uint64_t)ADDRESS);
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)ADDRESS, (uint64_t)ADDRESS);
// emulate machine code in infinite time (last param = 0), or when
// finishing all the code.
err = uc_emu_start(handle, ADDRESS, ADDRESS + sizeof(THUMB_CODE) -1, 0, 0);
err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(THUMB_CODE) -1, 0, 0);
if (err) {
printf("Failed on uc_emu_start() with error returned: %u\n", err);
}
@ -124,10 +124,10 @@ static void test_thumb(void)
// now print out some registers
printf(">>> Emulation done. Below is the CPU context\n");
uc_reg_read(handle, UC_ARM_REG_SP, &sp);
uc_reg_read(uc, UC_ARM_REG_SP, &sp);
printf(">>> SP = 0x%x\n", sp);
uc_close(&handle);
uc_close(uc);
}
int main(int argc, char **argv, char **envp)

View file

@ -14,21 +14,21 @@
// memory address where emulation starts
#define ADDRESS 0x10000
static void hook_block(uch handle, uint64_t address, uint32_t size, void *user_data)
static void hook_block(ucengine *uc, uint64_t address, uint32_t size, void *user_data)
{
printf(">>> Tracing basic block at 0x%"PRIx64 ", block size = 0x%x\n", address, size);
}
static void hook_code(uch handle, uint64_t address, uint32_t size, void *user_data)
static void hook_code(ucengine *uc, uint64_t address, uint32_t size, void *user_data)
{
printf(">>> Tracing instruction at 0x%"PRIx64 ", instruction size = 0x%x\n", address, size);
}
static void test_arm64(void)
{
uch handle;
ucengine *uc;
uc_err err;
uch trace1, trace2;
uc_hook_h trace1, trace2;
int64_t x11 = 0x1234; // X11 register
int64_t x13 = 0x6789; // X13 register
@ -37,7 +37,7 @@ static void test_arm64(void)
printf("Emulate ARM64 code\n");
// Initialize emulator in ARM mode
err = uc_open(UC_ARCH_ARM64, UC_MODE_ARM, &handle);
err = uc_open(UC_ARCH_ARM64, UC_MODE_ARM, &uc);
if (err) {
printf("Failed on uc_open() with error returned: %u (%s)\n",
err, uc_strerror(err));
@ -45,25 +45,25 @@ static void test_arm64(void)
}
// map 2MB memory for this emulation
uc_mem_map(handle, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
uc_mem_map(uc, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
// write machine code to be emulated to memory
uc_mem_write(handle, ADDRESS, (uint8_t *)ARM_CODE, sizeof(ARM_CODE) - 1);
uc_mem_write(uc, ADDRESS, (uint8_t *)ARM_CODE, sizeof(ARM_CODE) - 1);
// initialize machine registers
uc_reg_write(handle, UC_ARM64_REG_X11, &x11);
uc_reg_write(handle, UC_ARM64_REG_X13, &x13);
uc_reg_write(handle, UC_ARM64_REG_X15, &x15);
uc_reg_write(uc, UC_ARM64_REG_X11, &x11);
uc_reg_write(uc, UC_ARM64_REG_X13, &x13);
uc_reg_write(uc, UC_ARM64_REG_X15, &x15);
// tracing all basic blocks with customized callback
uc_hook_add(handle, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
// tracing one instruction at ADDRESS with customized callback
uc_hook_add(handle, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)ADDRESS, (uint64_t)ADDRESS);
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)ADDRESS, (uint64_t)ADDRESS);
// emulate machine code in infinite time (last param = 0), or when
// finishing all the code.
err = uc_emu_start(handle, ADDRESS, ADDRESS + sizeof(ARM_CODE) -1, 0, 0);
err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(ARM_CODE) -1, 0, 0);
if (err) {
printf("Failed on uc_emu_start() with error returned: %u\n", err);
}
@ -71,10 +71,10 @@ static void test_arm64(void)
// now print out some registers
printf(">>> Emulation done. Below is the CPU context\n");
uc_reg_read(handle, UC_ARM64_REG_X11, &x11);
uc_reg_read(uc, UC_ARM64_REG_X11, &x11);
printf(">>> X11 = 0x%" PRIx64 "\n", x11);
uc_close(&handle);
uc_close(uc);
}
int main(int argc, char **argv, char **envp)

View file

@ -12,20 +12,20 @@
// memory address where emulation starts
#define ADDRESS 0x10000
static void hook_block(uch handle, uint64_t address, uint32_t size, void *user_data)
static void hook_block(ucengine *uc, uint64_t address, uint32_t size, void *user_data)
{
printf(">>> Tracing basic block at 0x%"PRIx64 ", block size = 0x%x\n", address, size);
}
static void hook_code(uch handle, uint64_t address, uint32_t size, void *user_data)
static void hook_code(ucengine *uc, uint64_t address, uint32_t size, void *user_data)
{
printf(">>> Tracing instruction at 0x%"PRIx64 ", instruction size = 0x%x\n", address, size);
}
static void test_m68k(void)
{
uch handle;
uch trace1, trace2;
ucengine *uc;
uc_hook_h trace1, trace2;
uc_err err;
int d0 = 0x0000; // d0 data register
@ -52,7 +52,7 @@ static void test_m68k(void)
printf("Emulate M68K code\n");
// Initialize emulator in M68K mode
err = uc_open(UC_ARCH_M68K, UC_MODE_BIG_ENDIAN, &handle);
err = uc_open(UC_ARCH_M68K, UC_MODE_BIG_ENDIAN, &uc);
if (err) {
printf("Failed on uc_open() with error returned: %u (%s)\n",
err, uc_strerror(err));
@ -60,42 +60,42 @@ static void test_m68k(void)
}
// map 2MB memory for this emulation
uc_mem_map(handle, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
uc_mem_map(uc, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
// write machine code to be emulated to memory
uc_mem_write(handle, ADDRESS, (uint8_t *)M68K_CODE, sizeof(M68K_CODE) - 1);
uc_mem_write(uc, ADDRESS, (uint8_t *)M68K_CODE, sizeof(M68K_CODE) - 1);
// initialize machine registers
uc_reg_write(handle, UC_M68K_REG_D0, &d0);
uc_reg_write(handle, UC_M68K_REG_D1, &d1);
uc_reg_write(handle, UC_M68K_REG_D2, &d2);
uc_reg_write(handle, UC_M68K_REG_D3, &d3);
uc_reg_write(handle, UC_M68K_REG_D4, &d4);
uc_reg_write(handle, UC_M68K_REG_D5, &d5);
uc_reg_write(handle, UC_M68K_REG_D6, &d6);
uc_reg_write(handle, UC_M68K_REG_D7, &d7);
uc_reg_write(uc, UC_M68K_REG_D0, &d0);
uc_reg_write(uc, UC_M68K_REG_D1, &d1);
uc_reg_write(uc, UC_M68K_REG_D2, &d2);
uc_reg_write(uc, UC_M68K_REG_D3, &d3);
uc_reg_write(uc, UC_M68K_REG_D4, &d4);
uc_reg_write(uc, UC_M68K_REG_D5, &d5);
uc_reg_write(uc, UC_M68K_REG_D6, &d6);
uc_reg_write(uc, UC_M68K_REG_D7, &d7);
uc_reg_write(handle, UC_M68K_REG_A0, &a0);
uc_reg_write(handle, UC_M68K_REG_A1, &a1);
uc_reg_write(handle, UC_M68K_REG_A2, &a2);
uc_reg_write(handle, UC_M68K_REG_A3, &a3);
uc_reg_write(handle, UC_M68K_REG_A4, &a4);
uc_reg_write(handle, UC_M68K_REG_A5, &a5);
uc_reg_write(handle, UC_M68K_REG_A6, &a6);
uc_reg_write(handle, UC_M68K_REG_A7, &a7);
uc_reg_write(uc, UC_M68K_REG_A0, &a0);
uc_reg_write(uc, UC_M68K_REG_A1, &a1);
uc_reg_write(uc, UC_M68K_REG_A2, &a2);
uc_reg_write(uc, UC_M68K_REG_A3, &a3);
uc_reg_write(uc, UC_M68K_REG_A4, &a4);
uc_reg_write(uc, UC_M68K_REG_A5, &a5);
uc_reg_write(uc, UC_M68K_REG_A6, &a6);
uc_reg_write(uc, UC_M68K_REG_A7, &a7);
uc_reg_write(handle, UC_M68K_REG_PC, &pc);
uc_reg_write(handle, UC_M68K_REG_SR, &sr);
uc_reg_write(uc, UC_M68K_REG_PC, &pc);
uc_reg_write(uc, UC_M68K_REG_SR, &sr);
// tracing all basic blocks with customized callback
uc_hook_add(handle, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
// tracing all instruction
uc_hook_add(handle, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)1, (uint64_t)0);
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)1, (uint64_t)0);
// emulate machine code in infinite time (last param = 0), or when
// finishing all the code.
err = uc_emu_start(handle, ADDRESS, ADDRESS + sizeof(M68K_CODE)-1, 0, 0);
err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(M68K_CODE)-1, 0, 0);
if (err) {
printf("Failed on uc_emu_start() with error returned: %u\n", err);
}
@ -103,26 +103,26 @@ static void test_m68k(void)
// now print out some registers
printf(">>> Emulation done. Below is the CPU context\n");
uc_reg_read(handle, UC_M68K_REG_D0, &d0);
uc_reg_read(handle, UC_M68K_REG_D1, &d1);
uc_reg_read(handle, UC_M68K_REG_D2, &d2);
uc_reg_read(handle, UC_M68K_REG_D3, &d3);
uc_reg_read(handle, UC_M68K_REG_D4, &d4);
uc_reg_read(handle, UC_M68K_REG_D5, &d5);
uc_reg_read(handle, UC_M68K_REG_D6, &d6);
uc_reg_read(handle, UC_M68K_REG_D7, &d7);
uc_reg_read(uc, UC_M68K_REG_D0, &d0);
uc_reg_read(uc, UC_M68K_REG_D1, &d1);
uc_reg_read(uc, UC_M68K_REG_D2, &d2);
uc_reg_read(uc, UC_M68K_REG_D3, &d3);
uc_reg_read(uc, UC_M68K_REG_D4, &d4);
uc_reg_read(uc, UC_M68K_REG_D5, &d5);
uc_reg_read(uc, UC_M68K_REG_D6, &d6);
uc_reg_read(uc, UC_M68K_REG_D7, &d7);
uc_reg_read(handle, UC_M68K_REG_A0, &a0);
uc_reg_read(handle, UC_M68K_REG_A1, &a1);
uc_reg_read(handle, UC_M68K_REG_A2, &a2);
uc_reg_read(handle, UC_M68K_REG_A3, &a3);
uc_reg_read(handle, UC_M68K_REG_A4, &a4);
uc_reg_read(handle, UC_M68K_REG_A5, &a5);
uc_reg_read(handle, UC_M68K_REG_A6, &a6);
uc_reg_read(handle, UC_M68K_REG_A7, &a7);
uc_reg_read(uc, UC_M68K_REG_A0, &a0);
uc_reg_read(uc, UC_M68K_REG_A1, &a1);
uc_reg_read(uc, UC_M68K_REG_A2, &a2);
uc_reg_read(uc, UC_M68K_REG_A3, &a3);
uc_reg_read(uc, UC_M68K_REG_A4, &a4);
uc_reg_read(uc, UC_M68K_REG_A5, &a5);
uc_reg_read(uc, UC_M68K_REG_A6, &a6);
uc_reg_read(uc, UC_M68K_REG_A7, &a7);
uc_reg_read(handle, UC_M68K_REG_PC, &pc);
uc_reg_read(handle, UC_M68K_REG_SR, &sr);
uc_reg_read(uc, UC_M68K_REG_PC, &pc);
uc_reg_read(uc, UC_M68K_REG_SR, &sr);
printf(">>> A0 = 0x%x\t\t>>> D0 = 0x%x\n", a0, d0);
printf(">>> A1 = 0x%x\t\t>>> D1 = 0x%x\n", a1, d1);
@ -135,7 +135,7 @@ static void test_m68k(void)
printf(">>> PC = 0x%x\n", pc);
printf(">>> SR = 0x%x\n", sr);
uc_close(&handle);
uc_close(uc);
}
int main(int argc, char **argv, char **envp)

View file

@ -15,28 +15,28 @@
// memory address where emulation starts
#define ADDRESS 0x10000
static void hook_block(uch handle, uint64_t address, uint32_t size, void *user_data)
static void hook_block(ucengine *uc, uint64_t address, uint32_t size, void *user_data)
{
printf(">>> Tracing basic block at 0x%"PRIx64 ", block size = 0x%x\n", address, size);
}
static void hook_code(uch handle, uint64_t address, uint32_t size, void *user_data)
static void hook_code(ucengine *uc, uint64_t address, uint32_t size, void *user_data)
{
printf(">>> Tracing instruction at 0x%"PRIx64 ", instruction size = 0x%x\n", address, size);
}
static void test_mips_eb(void)
{
uch handle;
ucengine *uc;
uc_err err;
uch trace1, trace2;
uc_hook_h trace1, trace2;
int r1 = 0x6789; // R1 register
printf("Emulate MIPS code (big-endian)\n");
// Initialize emulator in MIPS mode
err = uc_open(UC_ARCH_MIPS, UC_MODE_MIPS32 + UC_MODE_BIG_ENDIAN, &handle);
err = uc_open(UC_ARCH_MIPS, UC_MODE_MIPS32 + UC_MODE_BIG_ENDIAN, &uc);
if (err) {
printf("Failed on uc_open() with error returned: %u (%s)\n",
err, uc_strerror(err));
@ -44,23 +44,23 @@ static void test_mips_eb(void)
}
// map 2MB memory for this emulation
uc_mem_map(handle, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
uc_mem_map(uc, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
// write machine code to be emulated to memory
uc_mem_write(handle, ADDRESS, (uint8_t *)MIPS_CODE_EB, sizeof(MIPS_CODE_EB) - 1);
uc_mem_write(uc, ADDRESS, (uint8_t *)MIPS_CODE_EB, sizeof(MIPS_CODE_EB) - 1);
// initialize machine registers
uc_reg_write(handle, UC_MIPS_REG_1, &r1);
uc_reg_write(uc, UC_MIPS_REG_1, &r1);
// tracing all basic blocks with customized callback
uc_hook_add(handle, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
// tracing one instruction at ADDRESS with customized callback
uc_hook_add(handle, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)ADDRESS, (uint64_t)ADDRESS);
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)ADDRESS, (uint64_t)ADDRESS);
// emulate machine code in infinite time (last param = 0), or when
// finishing all the code.
err = uc_emu_start(handle, ADDRESS, ADDRESS + sizeof(MIPS_CODE_EB) - 1, 0, 0);
err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(MIPS_CODE_EB) - 1, 0, 0);
if (err) {
printf("Failed on uc_emu_start() with error returned: %u (%s)\n", err, uc_strerror(err));
}
@ -68,17 +68,17 @@ static void test_mips_eb(void)
// now print out some registers
printf(">>> Emulation done. Below is the CPU context\n");
uc_reg_read(handle, UC_MIPS_REG_1, &r1);
uc_reg_read(uc, UC_MIPS_REG_1, &r1);
printf(">>> R1 = 0x%x\n", r1);
uc_close(&handle);
uc_close(uc);
}
static void test_mips_el(void)
{
uch handle;
ucengine *uc;
uc_err err;
uch trace1, trace2;
uc_hook_h trace1, trace2;
int r1 = 0x6789; // R1 register
@ -86,7 +86,7 @@ static void test_mips_el(void)
printf("Emulate MIPS code (little-endian)\n");
// Initialize emulator in MIPS mode
err = uc_open(UC_ARCH_MIPS, UC_MODE_MIPS32, &handle);
err = uc_open(UC_ARCH_MIPS, UC_MODE_MIPS32, &uc);
if (err) {
printf("Failed on uc_open() with error returned: %u (%s)\n",
err, uc_strerror(err));
@ -94,23 +94,23 @@ static void test_mips_el(void)
}
// map 2MB memory for this emulation
uc_mem_map(handle, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
uc_mem_map(uc, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
// write machine code to be emulated to memory
uc_mem_write(handle, ADDRESS, (uint8_t *)MIPS_CODE_EL, sizeof(MIPS_CODE_EL) - 1);
uc_mem_write(uc, ADDRESS, (uint8_t *)MIPS_CODE_EL, sizeof(MIPS_CODE_EL) - 1);
// initialize machine registers
uc_reg_write(handle, UC_MIPS_REG_1, &r1);
uc_reg_write(uc, UC_MIPS_REG_1, &r1);
// tracing all basic blocks with customized callback
uc_hook_add(handle, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
// tracing one instruction at ADDRESS with customized callback
uc_hook_add(handle, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)ADDRESS, (uint64_t)ADDRESS);
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)ADDRESS, (uint64_t)ADDRESS);
// emulate machine code in infinite time (last param = 0), or when
// finishing all the code.
err = uc_emu_start(handle, ADDRESS, ADDRESS + sizeof(MIPS_CODE_EL) - 1, 0, 0);
err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(MIPS_CODE_EL) - 1, 0, 0);
if (err) {
printf("Failed on uc_emu_start() with error returned: %u (%s)\n", err, uc_strerror(err));
}
@ -118,10 +118,10 @@ static void test_mips_el(void)
// now print out some registers
printf(">>> Emulation done. Below is the CPU context\n");
uc_reg_read(handle, UC_MIPS_REG_1, &r1);
uc_reg_read(uc, UC_MIPS_REG_1, &r1);
printf(">>> R1 = 0x%x\n", r1);
uc_close(&handle);
uc_close(uc);
}
int main(int argc, char **argv, char **envp)

View file

@ -15,21 +15,21 @@
// memory address where emulation starts
#define ADDRESS 0x10000
static void hook_block(uch handle, uint64_t address, uint32_t size, void *user_data)
static void hook_block(ucengine *uc, uint64_t address, uint32_t size, void *user_data)
{
printf(">>> Tracing basic block at 0x%"PRIx64 ", block size = 0x%x\n", address, size);
}
static void hook_code(uch handle, uint64_t address, uint32_t size, void *user_data)
static void hook_code(ucengine *uc, uint64_t address, uint32_t size, void *user_data)
{
printf(">>> Tracing instruction at 0x%"PRIx64 ", instruction size = 0x%x\n", address, size);
}
static void test_sparc(void)
{
uch handle;
ucengine *uc;
uc_err err;
uch trace1, trace2;
uc_hook_h trace1, trace2;
int g1 = 0x1230; // G1 register
int g2 = 0x6789; // G2 register
@ -38,7 +38,7 @@ static void test_sparc(void)
printf("Emulate SPARC code\n");
// Initialize emulator in Sparc mode
err = uc_open(UC_ARCH_SPARC, UC_MODE_BIG_ENDIAN, &handle);
err = uc_open(UC_ARCH_SPARC, UC_MODE_BIG_ENDIAN, &uc);
if (err) {
printf("Failed on uc_open() with error returned: %u (%s)\n",
err, uc_strerror(err));
@ -46,25 +46,25 @@ static void test_sparc(void)
}
// map 2MB memory for this emulation
uc_mem_map(handle, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
uc_mem_map(uc, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
// write machine code to be emulated to memory
uc_mem_write(handle, ADDRESS, (uint8_t *)SPARC_CODE, sizeof(SPARC_CODE) - 1);
uc_mem_write(uc, ADDRESS, (uint8_t *)SPARC_CODE, sizeof(SPARC_CODE) - 1);
// initialize machine registers
uc_reg_write(handle, UC_SPARC_REG_G1, &g1);
uc_reg_write(handle, UC_SPARC_REG_G2, &g2);
uc_reg_write(handle, UC_SPARC_REG_G3, &g3);
uc_reg_write(uc, UC_SPARC_REG_G1, &g1);
uc_reg_write(uc, UC_SPARC_REG_G2, &g2);
uc_reg_write(uc, UC_SPARC_REG_G3, &g3);
// tracing all basic blocks with customized callback
uc_hook_add(handle, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
// tracing one instruction at ADDRESS with customized callback
uc_hook_add(handle, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)ADDRESS, (uint64_t)ADDRESS);
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)ADDRESS, (uint64_t)ADDRESS);
// emulate machine code in infinite time (last param = 0), or when
// finishing all the code.
err = uc_emu_start(handle, ADDRESS, ADDRESS + sizeof(SPARC_CODE) -1, 0, 0);
err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(SPARC_CODE) -1, 0, 0);
if (err) {
printf("Failed on uc_emu_start() with error returned: %u (%s)\n",
err, uc_strerror(err));
@ -73,10 +73,10 @@ static void test_sparc(void)
// now print out some registers
printf(">>> Emulation done. Below is the CPU context\n");
uc_reg_read(handle, UC_SPARC_REG_G3, &g3);
uc_reg_read(uc, UC_SPARC_REG_G3, &g3);
printf(">>> G3 = 0x%x\n", g3);
uc_close(&handle);
uc_close(uc);
}
int main(int argc, char **argv, char **envp)

View file

@ -32,41 +32,41 @@
#define ADDRESS 0x1000000
// callback for tracing basic blocks
static void hook_block(uch handle, uint64_t address, uint32_t size, void *user_data)
static void hook_block(ucengine *uc, uint64_t address, uint32_t size, void *user_data)
{
printf(">>> Tracing basic block at 0x%"PRIx64 ", block size = 0x%x\n", address, size);
}
// callback for tracing instruction
static void hook_code(uch handle, uint64_t address, uint32_t size, void *user_data)
static void hook_code(ucengine *uc, uint64_t address, uint32_t size, void *user_data)
{
int eflags;
printf(">>> Tracing instruction at 0x%"PRIx64 ", instruction size = 0x%x\n", address, size);
uc_reg_read(handle, UC_X86_REG_EFLAGS, &eflags);
uc_reg_read(uc, UC_X86_REG_EFLAGS, &eflags);
printf(">>> --- EFLAGS is 0x%x\n", eflags);
// Uncomment below code to stop the emulation using uc_emu_stop()
// if (address == 0x1000009)
// uc_emu_stop(handle);
// uc_emu_stop(uc);
}
// callback for tracing instruction
static void hook_code64(uch handle, uint64_t address, uint32_t size, void *user_data)
static void hook_code64(ucengine *uc, uint64_t address, uint32_t size, void *user_data)
{
uint64_t rip;
uc_reg_read(handle, UC_X86_REG_RIP, &rip);
uc_reg_read(uc, UC_X86_REG_RIP, &rip);
printf(">>> Tracing instruction at 0x%"PRIx64 ", instruction size = 0x%x\n", address, size);
printf(">>> RIP is 0x%"PRIx64 "\n", rip);
// Uncomment below code to stop the emulation using uc_emu_stop()
// if (address == 0x1000009)
// uc_emu_stop(handle);
// uc_emu_stop(uc);
}
// callback for tracing memory access (READ or WRITE)
static bool hook_mem_invalid(uch handle, uc_mem_type type,
static bool hook_mem_invalid(ucengine *uc, uc_mem_type type,
uint64_t address, int size, int64_t value, void *user_data)
{
switch(type) {
@ -77,13 +77,13 @@ static bool hook_mem_invalid(uch handle, uc_mem_type type,
printf(">>> Missing memory is being WRITE at 0x%"PRIx64 ", data size = %u, data value = 0x%"PRIx64 "\n",
address, size, value);
// map this memory in with 2MB in size
uc_mem_map(handle, 0xaaaa0000, 2 * 1024*1024, UC_PROT_ALL);
uc_mem_map(uc, 0xaaaa0000, 2 * 1024*1024, UC_PROT_ALL);
// return true to indicate we want to continue
return true;
}
}
static void hook_mem64(uch handle, uc_mem_type type,
static void hook_mem64(ucengine *uc, uc_mem_type type,
uint64_t address, int size, int64_t value, void *user_data)
{
switch(type) {
@ -101,11 +101,11 @@ static void hook_mem64(uch handle, uc_mem_type type,
// callback for IN instruction (X86).
// this returns the data read from the port
static uint32_t hook_in(uch handle, uint32_t port, int size, void *user_data)
static uint32_t hook_in(ucengine *uc, uint32_t port, int size, void *user_data)
{
uint32_t eip;
uc_reg_read(handle, UC_X86_REG_EIP, &eip);
uc_reg_read(uc, UC_X86_REG_EIP, &eip);
printf("--- reading from port 0x%x, size: %u, address: 0x%x\n", port, size, eip);
@ -126,12 +126,12 @@ static uint32_t hook_in(uch handle, uint32_t port, int size, void *user_data)
}
// callback for OUT instruction (X86).
static void hook_out(uch handle, uint32_t port, int size, uint32_t value, void *user_data)
static void hook_out(ucengine *uc, uint32_t port, int size, uint32_t value, void *user_data)
{
uint32_t tmp;
uint32_t eip;
uc_reg_read(handle, UC_X86_REG_EIP, &eip);
uc_reg_read(uc, UC_X86_REG_EIP, &eip);
printf("--- writing to port 0x%x, size: %u, value: 0x%x, address: 0x%x\n", port, size, value, eip);
@ -140,13 +140,13 @@ static void hook_out(uch handle, uint32_t port, int size, uint32_t value, void *
default:
return; // should never reach this
case 1:
uc_reg_read(handle, UC_X86_REG_AL, &tmp);
uc_reg_read(uc, UC_X86_REG_AL, &tmp);
break;
case 2:
uc_reg_read(handle, UC_X86_REG_AX, &tmp);
uc_reg_read(uc, UC_X86_REG_AX, &tmp);
break;
case 4:
uc_reg_read(handle, UC_X86_REG_EAX, &tmp);
uc_reg_read(uc, UC_X86_REG_EAX, &tmp);
break;
}
@ -154,24 +154,24 @@ static void hook_out(uch handle, uint32_t port, int size, uint32_t value, void *
}
// callback for SYSCALL instruction (X86).
static void hook_syscall(uch handle, void *user_data)
static void hook_syscall(ucengine *uc, void *user_data)
{
uint64_t rax;
uc_reg_read(handle, UC_X86_REG_RAX, &rax);
uc_reg_read(uc, UC_X86_REG_RAX, &rax);
if (rax == 0x100) {
rax = 0x200;
uc_reg_write(handle, UC_X86_REG_RAX, &rax);
uc_reg_write(uc, UC_X86_REG_RAX, &rax);
} else
printf("ERROR: was not expecting rax=0x%"PRIx64 " in syscall\n", rax);
}
static void test_i386(void)
{
uch handle;
ucengine *uc;
uc_err err;
uint32_t tmp;
uch trace1, trace2;
uc_hook_h trace1, trace2;
int r_ecx = 0x1234; // ECX register
int r_edx = 0x7890; // EDX register
@ -179,33 +179,33 @@ static void test_i386(void)
printf("Emulate i386 code\n");
// Initialize emulator in X86-32bit mode
err = uc_open(UC_ARCH_X86, UC_MODE_32, &handle);
err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc);
if (err) {
printf("Failed on uc_open() with error returned: %u\n", err);
return;
}
// map 2MB memory for this emulation
uc_mem_map(handle, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
uc_mem_map(uc, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
// write machine code to be emulated to memory
if (uc_mem_write(handle, ADDRESS, (uint8_t *)X86_CODE32, sizeof(X86_CODE32) - 1)) {
if (uc_mem_write(uc, ADDRESS, (uint8_t *)X86_CODE32, sizeof(X86_CODE32) - 1)) {
printf("Failed to write emulation code to memory, quit!\n");
return;
}
// initialize machine registers
uc_reg_write(handle, UC_X86_REG_ECX, &r_ecx);
uc_reg_write(handle, UC_X86_REG_EDX, &r_edx);
uc_reg_write(uc, UC_X86_REG_ECX, &r_ecx);
uc_reg_write(uc, UC_X86_REG_EDX, &r_edx);
// tracing all basic blocks with customized callback
uc_hook_add(handle, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
// tracing all instruction by having @begin > @end
uc_hook_add(handle, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)1, (uint64_t)0);
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)1, (uint64_t)0);
// emulate machine code in infinite time
err = uc_emu_start(handle, ADDRESS, ADDRESS + sizeof(X86_CODE32) - 1, 0, 0);
err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(X86_CODE32) - 1, 0, 0);
if (err) {
printf("Failed on uc_emu_start() with error returned %u: %s\n",
err, uc_strerror(err));
@ -214,54 +214,54 @@ static void test_i386(void)
// now print out some registers
printf(">>> Emulation done. Below is the CPU context\n");
uc_reg_read(handle, UC_X86_REG_ECX, &r_ecx);
uc_reg_read(handle, UC_X86_REG_EDX, &r_edx);
uc_reg_read(uc, UC_X86_REG_ECX, &r_ecx);
uc_reg_read(uc, UC_X86_REG_EDX, &r_edx);
printf(">>> ECX = 0x%x\n", r_ecx);
printf(">>> EDX = 0x%x\n", r_edx);
// read from memory
if (!uc_mem_read(handle, ADDRESS, (uint8_t *)&tmp, 4))
if (!uc_mem_read(uc, ADDRESS, (uint8_t *)&tmp, 4))
printf(">>> Read 4 bytes from [0x%x] = 0x%x\n", ADDRESS, tmp);
else
printf(">>> Failed to read 4 bytes from [0x%x]\n", ADDRESS);
uc_close(&handle);
uc_close(uc);
}
static void test_i386_jump(void)
{
uch handle;
ucengine *uc;
uc_err err;
uch trace1, trace2;
uc_hook_h trace1, trace2;
printf("===================================\n");
printf("Emulate i386 code with jump\n");
// Initialize emulator in X86-32bit mode
err = uc_open(UC_ARCH_X86, UC_MODE_32, &handle);
err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc);
if (err) {
printf("Failed on uc_open() with error returned: %u\n", err);
return;
}
// map 2MB memory for this emulation
uc_mem_map(handle, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
uc_mem_map(uc, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
// write machine code to be emulated to memory
if (uc_mem_write(handle, ADDRESS, (uint8_t *)X86_CODE32_JUMP,
if (uc_mem_write(uc, ADDRESS, (uint8_t *)X86_CODE32_JUMP,
sizeof(X86_CODE32_JUMP) - 1)) {
printf("Failed to write emulation code to memory, quit!\n");
return;
}
// tracing 1 basic block with customized callback
uc_hook_add(handle, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)ADDRESS, (uint64_t)ADDRESS);
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)ADDRESS, (uint64_t)ADDRESS);
// tracing 1 instruction at ADDRESS
uc_hook_add(handle, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)ADDRESS, (uint64_t)ADDRESS);
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)ADDRESS, (uint64_t)ADDRESS);
// emulate machine code in infinite time
err = uc_emu_start(handle, ADDRESS, ADDRESS + sizeof(X86_CODE32_JUMP) - 1, 0, 0);
err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(X86_CODE32_JUMP) - 1, 0, 0);
if (err) {
printf("Failed on uc_emu_start() with error returned %u: %s\n",
err, uc_strerror(err));
@ -269,13 +269,13 @@ static void test_i386_jump(void)
printf(">>> Emulation done. Below is the CPU context\n");
uc_close(&handle);
uc_close(uc);
}
// emulate code that loop forever
static void test_i386_loop(void)
{
uch handle;
ucengine *uc;
uc_err err;
int r_ecx = 0x1234; // ECX register
@ -285,28 +285,28 @@ static void test_i386_loop(void)
printf("Emulate i386 code that loop forever\n");
// Initialize emulator in X86-32bit mode
err = uc_open(UC_ARCH_X86, UC_MODE_32, &handle);
err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc);
if (err) {
printf("Failed on uc_open() with error returned: %u\n", err);
return;
}
// map 2MB memory for this emulation
uc_mem_map(handle, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
uc_mem_map(uc, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
// write machine code to be emulated to memory
if (uc_mem_write(handle, ADDRESS, (uint8_t *)X86_CODE32_LOOP, sizeof(X86_CODE32_LOOP) - 1)) {
if (uc_mem_write(uc, ADDRESS, (uint8_t *)X86_CODE32_LOOP, sizeof(X86_CODE32_LOOP) - 1)) {
printf("Failed to write emulation code to memory, quit!\n");
return;
}
// initialize machine registers
uc_reg_write(handle, UC_X86_REG_ECX, &r_ecx);
uc_reg_write(handle, UC_X86_REG_EDX, &r_edx);
uc_reg_write(uc, UC_X86_REG_ECX, &r_ecx);
uc_reg_write(uc, UC_X86_REG_EDX, &r_edx);
// emulate machine code in 2 seconds, so we can quit even
// if the code loops
err = uc_emu_start(handle, ADDRESS, ADDRESS + sizeof(X86_CODE32_LOOP) - 1, 2 * UC_SECOND_SCALE, 0);
err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(X86_CODE32_LOOP) - 1, 2 * UC_SECOND_SCALE, 0);
if (err) {
printf("Failed on uc_emu_start() with error returned %u: %s\n",
err, uc_strerror(err));
@ -315,20 +315,20 @@ static void test_i386_loop(void)
// now print out some registers
printf(">>> Emulation done. Below is the CPU context\n");
uc_reg_read(handle, UC_X86_REG_ECX, &r_ecx);
uc_reg_read(handle, UC_X86_REG_EDX, &r_edx);
uc_reg_read(uc, UC_X86_REG_ECX, &r_ecx);
uc_reg_read(uc, UC_X86_REG_EDX, &r_edx);
printf(">>> ECX = 0x%x\n", r_ecx);
printf(">>> EDX = 0x%x\n", r_edx);
uc_close(&handle);
uc_close(uc);
}
// emulate code that read invalid memory
static void test_i386_invalid_mem_read(void)
{
uch handle;
ucengine *uc;
uc_err err;
uch trace1, trace2;
uc_hook_h trace1, trace2;
int r_ecx = 0x1234; // ECX register
int r_edx = 0x7890; // EDX register
@ -337,33 +337,33 @@ static void test_i386_invalid_mem_read(void)
printf("Emulate i386 code that read from invalid memory\n");
// Initialize emulator in X86-32bit mode
err = uc_open(UC_ARCH_X86, UC_MODE_32, &handle);
err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc);
if (err) {
printf("Failed on uc_open() with error returned: %u\n", err);
return;
}
// map 2MB memory for this emulation
uc_mem_map(handle, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
uc_mem_map(uc, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
// write machine code to be emulated to memory
if (uc_mem_write(handle, ADDRESS, (uint8_t *)X86_CODE32_MEM_READ, sizeof(X86_CODE32_MEM_READ) - 1)) {
if (uc_mem_write(uc, ADDRESS, (uint8_t *)X86_CODE32_MEM_READ, sizeof(X86_CODE32_MEM_READ) - 1)) {
printf("Failed to write emulation code to memory, quit!\n");
return;
}
// initialize machine registers
uc_reg_write(handle, UC_X86_REG_ECX, &r_ecx);
uc_reg_write(handle, UC_X86_REG_EDX, &r_edx);
uc_reg_write(uc, UC_X86_REG_ECX, &r_ecx);
uc_reg_write(uc, UC_X86_REG_EDX, &r_edx);
// tracing all basic blocks with customized callback
uc_hook_add(handle, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
// tracing all instruction by having @begin > @end
uc_hook_add(handle, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)1, (uint64_t)0);
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)1, (uint64_t)0);
// emulate machine code in infinite time
err = uc_emu_start(handle, ADDRESS, ADDRESS + sizeof(X86_CODE32_MEM_READ) - 1, 0, 0);
err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(X86_CODE32_MEM_READ) - 1, 0, 0);
if (err) {
printf("Failed on uc_emu_start() with error returned %u: %s\n",
err, uc_strerror(err));
@ -372,20 +372,20 @@ static void test_i386_invalid_mem_read(void)
// now print out some registers
printf(">>> Emulation done. Below is the CPU context\n");
uc_reg_read(handle, UC_X86_REG_ECX, &r_ecx);
uc_reg_read(handle, UC_X86_REG_EDX, &r_edx);
uc_reg_read(uc, UC_X86_REG_ECX, &r_ecx);
uc_reg_read(uc, UC_X86_REG_EDX, &r_edx);
printf(">>> ECX = 0x%x\n", r_ecx);
printf(">>> EDX = 0x%x\n", r_edx);
uc_close(&handle);
uc_close(uc);
}
// emulate code that read invalid memory
static void test_i386_invalid_mem_write(void)
{
uch handle, evh;
ucengine *uc;
uc_err err;
uch trace1, trace2; //, trace3;
uc_hook_h trace1, trace2, trace3;
uint32_t tmp;
int r_ecx = 0x1234; // ECX register
@ -395,36 +395,36 @@ static void test_i386_invalid_mem_write(void)
printf("Emulate i386 code that write to invalid memory\n");
// Initialize emulator in X86-32bit mode
err = uc_open(UC_ARCH_X86, UC_MODE_32, &handle);
err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc);
if (err) {
printf("Failed on uc_open() with error returned: %u\n", err);
return;
}
// map 2MB memory for this emulation
uc_mem_map(handle, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
uc_mem_map(uc, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
// write machine code to be emulated to memory
if (uc_mem_write(handle, ADDRESS, (uint8_t *)X86_CODE32_MEM_WRITE, sizeof(X86_CODE32_MEM_WRITE) - 1)) {
if (uc_mem_write(uc, ADDRESS, (uint8_t *)X86_CODE32_MEM_WRITE, sizeof(X86_CODE32_MEM_WRITE) - 1)) {
printf("Failed to write emulation code to memory, quit!\n");
return;
}
// initialize machine registers
uc_reg_write(handle, UC_X86_REG_ECX, &r_ecx);
uc_reg_write(handle, UC_X86_REG_EDX, &r_edx);
uc_reg_write(uc, UC_X86_REG_ECX, &r_ecx);
uc_reg_write(uc, UC_X86_REG_EDX, &r_edx);
// tracing all basic blocks with customized callback
uc_hook_add(handle, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
// tracing all instruction by having @begin > @end
uc_hook_add(handle, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)1, (uint64_t)0);
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)1, (uint64_t)0);
// intercept invalid memory events
uc_hook_add(handle, &evh, UC_HOOK_MEM_INVALID, hook_mem_invalid, NULL);
uc_hook_add(uc, &trace3, UC_HOOK_MEM_INVALID, hook_mem_invalid, NULL);
// emulate machine code in infinite time
err = uc_emu_start(handle, ADDRESS, ADDRESS + sizeof(X86_CODE32_MEM_WRITE) - 1, 0, 0);
err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(X86_CODE32_MEM_WRITE) - 1, 0, 0);
if (err) {
printf("Failed on uc_emu_start() with error returned %u: %s\n",
err, uc_strerror(err));
@ -433,31 +433,31 @@ static void test_i386_invalid_mem_write(void)
// now print out some registers
printf(">>> Emulation done. Below is the CPU context\n");
uc_reg_read(handle, UC_X86_REG_ECX, &r_ecx);
uc_reg_read(handle, UC_X86_REG_EDX, &r_edx);
uc_reg_read(uc, UC_X86_REG_ECX, &r_ecx);
uc_reg_read(uc, UC_X86_REG_EDX, &r_edx);
printf(">>> ECX = 0x%x\n", r_ecx);
printf(">>> EDX = 0x%x\n", r_edx);
// read from memory
if (!uc_mem_read(handle, 0xaaaaaaaa, (uint8_t *)&tmp, 4))
if (!uc_mem_read(uc, 0xaaaaaaaa, (uint8_t *)&tmp, 4))
printf(">>> Read 4 bytes from [0x%x] = 0x%x\n", 0xaaaaaaaa, tmp);
else
printf(">>> Failed to read 4 bytes from [0x%x]\n", 0xffffffaa);
if (!uc_mem_read(handle, 0xffffffaa, (uint8_t *)&tmp, 4))
if (!uc_mem_read(uc, 0xffffffaa, (uint8_t *)&tmp, 4))
printf(">>> Read 4 bytes from [0x%x] = 0x%x\n", 0xffffffaa, tmp);
else
printf(">>> Failed to read 4 bytes from [0x%x]\n", 0xffffffaa);
uc_close(&handle);
uc_close(uc);
}
// emulate code that jump to invalid memory
static void test_i386_jump_invalid(void)
{
uch handle;
ucengine *uc;
uc_err err;
uch trace1, trace2;
uc_hook_h trace1, trace2;
int r_ecx = 0x1234; // ECX register
int r_edx = 0x7890; // EDX register
@ -466,33 +466,33 @@ static void test_i386_jump_invalid(void)
printf("Emulate i386 code that jumps to invalid memory\n");
// Initialize emulator in X86-32bit mode
err = uc_open(UC_ARCH_X86, UC_MODE_32, &handle);
err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc);
if (err) {
printf("Failed on uc_open() with error returned: %u\n", err);
return;
}
// map 2MB memory for this emulation
uc_mem_map(handle, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
uc_mem_map(uc, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
// write machine code to be emulated to memory
if (uc_mem_write(handle, ADDRESS, (uint8_t *)X86_CODE32_JMP_INVALID, sizeof(X86_CODE32_JMP_INVALID) - 1)) {
if (uc_mem_write(uc, ADDRESS, (uint8_t *)X86_CODE32_JMP_INVALID, sizeof(X86_CODE32_JMP_INVALID) - 1)) {
printf("Failed to write emulation code to memory, quit!\n");
return;
}
// initialize machine registers
uc_reg_write(handle, UC_X86_REG_ECX, &r_ecx);
uc_reg_write(handle, UC_X86_REG_EDX, &r_edx);
uc_reg_write(uc, UC_X86_REG_ECX, &r_ecx);
uc_reg_write(uc, UC_X86_REG_EDX, &r_edx);
// tracing all basic blocks with customized callback
uc_hook_add(handle, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
// tracing all instructions by having @begin > @end
uc_hook_add(handle, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)1, (uint64_t)0);
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)1, (uint64_t)0);
// emulate machine code in infinite time
err = uc_emu_start(handle, ADDRESS, ADDRESS + sizeof(X86_CODE32_JMP_INVALID) - 1, 0, 0);
err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(X86_CODE32_JMP_INVALID) - 1, 0, 0);
if (err) {
printf("Failed on uc_emu_start() with error returned %u: %s\n",
err, uc_strerror(err));
@ -501,20 +501,19 @@ static void test_i386_jump_invalid(void)
// now print out some registers
printf(">>> Emulation done. Below is the CPU context\n");
uc_reg_read(handle, UC_X86_REG_ECX, &r_ecx);
uc_reg_read(handle, UC_X86_REG_EDX, &r_edx);
uc_reg_read(uc, UC_X86_REG_ECX, &r_ecx);
uc_reg_read(uc, UC_X86_REG_EDX, &r_edx);
printf(">>> ECX = 0x%x\n", r_ecx);
printf(">>> EDX = 0x%x\n", r_edx);
uc_close(&handle);
uc_close(uc);
}
static void test_i386_inout(void)
{
uch handle;
ucengine *uc;
uc_err err;
uch trace1, trace2;
uch trace3, trace4;
uc_hook_h trace1, trace2, trace3, trace4;
int r_eax = 0x1234; // EAX register
int r_ecx = 0x6789; // ECX register
@ -523,38 +522,38 @@ static void test_i386_inout(void)
printf("Emulate i386 code with IN/OUT instructions\n");
// Initialize emulator in X86-32bit mode
err = uc_open(UC_ARCH_X86, UC_MODE_32, &handle);
err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc);
if (err) {
printf("Failed on uc_open() with error returned: %u\n", err);
return;
}
// map 2MB memory for this emulation
uc_mem_map(handle, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
uc_mem_map(uc, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
// write machine code to be emulated to memory
if (uc_mem_write(handle, ADDRESS, (uint8_t *)X86_CODE32_INOUT, sizeof(X86_CODE32_INOUT) - 1)) {
if (uc_mem_write(uc, ADDRESS, (uint8_t *)X86_CODE32_INOUT, sizeof(X86_CODE32_INOUT) - 1)) {
printf("Failed to write emulation code to memory, quit!\n");
return;
}
// initialize machine registers
uc_reg_write(handle, UC_X86_REG_EAX, &r_eax);
uc_reg_write(handle, UC_X86_REG_ECX, &r_ecx);
uc_reg_write(uc, UC_X86_REG_EAX, &r_eax);
uc_reg_write(uc, UC_X86_REG_ECX, &r_ecx);
// tracing all basic blocks with customized callback
uc_hook_add(handle, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
// tracing all instructions
uc_hook_add(handle, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)1, (uint64_t)0);
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)1, (uint64_t)0);
// handle IN instruction
uc_hook_add(handle, &trace3, UC_HOOK_INSN, hook_in, NULL, UC_X86_INS_IN);
// handle OUT instruction
uc_hook_add(handle, &trace4, UC_HOOK_INSN, hook_out, NULL, UC_X86_INS_OUT);
// uc IN instruction
uc_hook_add(uc, &trace3, UC_HOOK_INSN, hook_in, NULL, UC_X86_INS_IN);
// uc OUT instruction
uc_hook_add(uc, &trace4, UC_HOOK_INSN, hook_out, NULL, UC_X86_INS_OUT);
// emulate machine code in infinite time
err = uc_emu_start(handle, ADDRESS, ADDRESS + sizeof(X86_CODE32_INOUT) - 1, 0, 0);
err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(X86_CODE32_INOUT) - 1, 0, 0);
if (err) {
printf("Failed on uc_emu_start() with error returned %u: %s\n",
err, uc_strerror(err));
@ -563,19 +562,19 @@ static void test_i386_inout(void)
// now print out some registers
printf(">>> Emulation done. Below is the CPU context\n");
uc_reg_read(handle, UC_X86_REG_EAX, &r_eax);
uc_reg_read(handle, UC_X86_REG_ECX, &r_ecx);
uc_reg_read(uc, UC_X86_REG_EAX, &r_eax);
uc_reg_read(uc, UC_X86_REG_ECX, &r_ecx);
printf(">>> EAX = 0x%x\n", r_eax);
printf(">>> ECX = 0x%x\n", r_ecx);
uc_close(&handle);
uc_close(uc);
}
static void test_x86_64(void)
{
uch handle;
ucengine *uc;
uc_err err;
uch trace1, trace2, trace3, trace4;
uc_hook_h trace1, trace2, trace3, trace4;
int64_t rax = 0x71f3029efd49d41d;
int64_t rbx = 0xd87b45277f133ddb;
@ -598,54 +597,54 @@ static void test_x86_64(void)
printf("Emulate x86_64 code\n");
// Initialize emulator in X86-64bit mode
err = uc_open(UC_ARCH_X86, UC_MODE_64, &handle);
err = uc_open(UC_ARCH_X86, UC_MODE_64, &uc);
if (err) {
printf("Failed on uc_open() with error returned: %u\n", err);
return;
}
// map 2MB memory for this emulation
uc_mem_map(handle, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
uc_mem_map(uc, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
// write machine code to be emulated to memory
if (uc_mem_write(handle, ADDRESS, (uint8_t *)X86_CODE64, sizeof(X86_CODE64) - 1)) {
if (uc_mem_write(uc, ADDRESS, (uint8_t *)X86_CODE64, sizeof(X86_CODE64) - 1)) {
printf("Failed to write emulation code to memory, quit!\n");
return;
}
// initialize machine registers
uc_reg_write(handle, UC_X86_REG_RSP, &rsp);
uc_reg_write(uc, UC_X86_REG_RSP, &rsp);
uc_reg_write(handle, UC_X86_REG_RAX, &rax);
uc_reg_write(handle, UC_X86_REG_RBX, &rbx);
uc_reg_write(handle, UC_X86_REG_RCX, &rcx);
uc_reg_write(handle, UC_X86_REG_RDX, &rdx);
uc_reg_write(handle, UC_X86_REG_RSI, &rsi);
uc_reg_write(handle, UC_X86_REG_RDI, &rdi);
uc_reg_write(handle, UC_X86_REG_R8, &r8);
uc_reg_write(handle, UC_X86_REG_R9, &r9);
uc_reg_write(handle, UC_X86_REG_R10, &r10);
uc_reg_write(handle, UC_X86_REG_R11, &r11);
uc_reg_write(handle, UC_X86_REG_R12, &r12);
uc_reg_write(handle, UC_X86_REG_R13, &r13);
uc_reg_write(handle, UC_X86_REG_R14, &r14);
uc_reg_write(handle, UC_X86_REG_R15, &r15);
uc_reg_write(uc, UC_X86_REG_RAX, &rax);
uc_reg_write(uc, UC_X86_REG_RBX, &rbx);
uc_reg_write(uc, UC_X86_REG_RCX, &rcx);
uc_reg_write(uc, UC_X86_REG_RDX, &rdx);
uc_reg_write(uc, UC_X86_REG_RSI, &rsi);
uc_reg_write(uc, UC_X86_REG_RDI, &rdi);
uc_reg_write(uc, UC_X86_REG_R8, &r8);
uc_reg_write(uc, UC_X86_REG_R9, &r9);
uc_reg_write(uc, UC_X86_REG_R10, &r10);
uc_reg_write(uc, UC_X86_REG_R11, &r11);
uc_reg_write(uc, UC_X86_REG_R12, &r12);
uc_reg_write(uc, UC_X86_REG_R13, &r13);
uc_reg_write(uc, UC_X86_REG_R14, &r14);
uc_reg_write(uc, UC_X86_REG_R15, &r15);
// tracing all basic blocks with customized callback
uc_hook_add(handle, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
// tracing all instructions in the range [ADDRESS, ADDRESS+20]
uc_hook_add(handle, &trace2, UC_HOOK_CODE, hook_code64, NULL, (uint64_t)ADDRESS, (uint64_t)(ADDRESS+20));
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code64, NULL, (uint64_t)ADDRESS, (uint64_t)(ADDRESS+20));
// tracing all memory WRITE access (with @begin > @end)
uc_hook_add(handle, &trace3, UC_HOOK_MEM_WRITE, hook_mem64, NULL, (uint64_t)1, (uint64_t)0);
uc_hook_add(uc, &trace3, UC_HOOK_MEM_WRITE, hook_mem64, NULL, (uint64_t)1, (uint64_t)0);
// tracing all memory READ access (with @begin > @end)
uc_hook_add(handle, &trace4, UC_HOOK_MEM_READ, hook_mem64, NULL, (uint64_t)1, (uint64_t)0);
uc_hook_add(uc, &trace4, UC_HOOK_MEM_READ, hook_mem64, NULL, (uint64_t)1, (uint64_t)0);
// emulate machine code in infinite time (last param = 0), or when
// finishing all the code.
err = uc_emu_start(handle, ADDRESS, ADDRESS + sizeof(X86_CODE64) - 1, 0, 0);
err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(X86_CODE64) - 1, 0, 0);
if (err) {
printf("Failed on uc_emu_start() with error returned %u: %s\n",
err, uc_strerror(err));
@ -654,20 +653,20 @@ static void test_x86_64(void)
// now print out some registers
printf(">>> Emulation done. Below is the CPU context\n");
uc_reg_read(handle, UC_X86_REG_RAX, &rax);
uc_reg_read(handle, UC_X86_REG_RBX, &rbx);
uc_reg_read(handle, UC_X86_REG_RCX, &rcx);
uc_reg_read(handle, UC_X86_REG_RDX, &rdx);
uc_reg_read(handle, UC_X86_REG_RSI, &rsi);
uc_reg_read(handle, UC_X86_REG_RDI, &rdi);
uc_reg_read(handle, UC_X86_REG_R8, &r8);
uc_reg_read(handle, UC_X86_REG_R9, &r9);
uc_reg_read(handle, UC_X86_REG_R10, &r10);
uc_reg_read(handle, UC_X86_REG_R11, &r11);
uc_reg_read(handle, UC_X86_REG_R12, &r12);
uc_reg_read(handle, UC_X86_REG_R13, &r13);
uc_reg_read(handle, UC_X86_REG_R14, &r14);
uc_reg_read(handle, UC_X86_REG_R15, &r15);
uc_reg_read(uc, UC_X86_REG_RAX, &rax);
uc_reg_read(uc, UC_X86_REG_RBX, &rbx);
uc_reg_read(uc, UC_X86_REG_RCX, &rcx);
uc_reg_read(uc, UC_X86_REG_RDX, &rdx);
uc_reg_read(uc, UC_X86_REG_RSI, &rsi);
uc_reg_read(uc, UC_X86_REG_RDI, &rdi);
uc_reg_read(uc, UC_X86_REG_R8, &r8);
uc_reg_read(uc, UC_X86_REG_R9, &r9);
uc_reg_read(uc, UC_X86_REG_R10, &r10);
uc_reg_read(uc, UC_X86_REG_R11, &r11);
uc_reg_read(uc, UC_X86_REG_R12, &r12);
uc_reg_read(uc, UC_X86_REG_R13, &r13);
uc_reg_read(uc, UC_X86_REG_R14, &r14);
uc_reg_read(uc, UC_X86_REG_R15, &r15);
printf(">>> RAX = 0x%" PRIx64 "\n", rax);
printf(">>> RBX = 0x%" PRIx64 "\n", rbx);
@ -684,13 +683,13 @@ static void test_x86_64(void)
printf(">>> R14 = 0x%" PRIx64 "\n", r14);
printf(">>> R15 = 0x%" PRIx64 "\n", r15);
uc_close(&handle);
uc_close(uc);
}
static void test_x86_64_syscall(void)
{
uch handle;
uch trace1;
ucengine *uc;
uc_hook_h trace1;
uc_err err;
int64_t rax = 0x100;
@ -699,30 +698,30 @@ static void test_x86_64_syscall(void)
printf("Emulate x86_64 code with 'syscall' instruction\n");
// Initialize emulator in X86-64bit mode
err = uc_open(UC_ARCH_X86, UC_MODE_64, &handle);
err = uc_open(UC_ARCH_X86, UC_MODE_64, &uc);
if (err) {
printf("Failed on uc_open() with error returned: %u\n", err);
return;
}
// map 2MB memory for this emulation
uc_mem_map(handle, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
uc_mem_map(uc, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
// write machine code to be emulated to memory
if (uc_mem_write(handle, ADDRESS, (uint8_t *)X86_CODE64_SYSCALL, sizeof(X86_CODE64_SYSCALL) - 1)) {
if (uc_mem_write(uc, ADDRESS, (uint8_t *)X86_CODE64_SYSCALL, sizeof(X86_CODE64_SYSCALL) - 1)) {
printf("Failed to write emulation code to memory, quit!\n");
return;
}
// hook interrupts for syscall
uc_hook_add(handle, &trace1, UC_HOOK_INSN, hook_syscall, NULL, UC_X86_INS_SYSCALL);
uc_hook_add(uc, &trace1, UC_HOOK_INSN, hook_syscall, NULL, UC_X86_INS_SYSCALL);
// initialize machine registers
uc_reg_write(handle, UC_X86_REG_RAX, &rax);
uc_reg_write(uc, UC_X86_REG_RAX, &rax);
// emulate machine code in infinite time (last param = 0), or when
// finishing all the code.
err = uc_emu_start(handle, ADDRESS, ADDRESS + sizeof(X86_CODE64_SYSCALL) - 1, 0, 0);
err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(X86_CODE64_SYSCALL) - 1, 0, 0);
if (err) {
printf("Failed on uc_emu_start() with error returned %u: %s\n",
err, uc_strerror(err));
@ -731,16 +730,16 @@ static void test_x86_64_syscall(void)
// now print out some registers
printf(">>> Emulation done. Below is the CPU context\n");
uc_reg_read(handle, UC_X86_REG_RAX, &rax);
uc_reg_read(uc, UC_X86_REG_RAX, &rax);
printf(">>> RAX = 0x%" PRIx64 "\n", rax);
uc_close(&handle);
uc_close(uc);
}
static void test_x86_16(void)
{
uch handle;
ucengine *uc;
uc_err err;
uint8_t tmp;
@ -751,29 +750,29 @@ static void test_x86_16(void)
printf("Emulate x86 16-bit code\n");
// Initialize emulator in X86-16bit mode
err = uc_open(UC_ARCH_X86, UC_MODE_16, &handle);
err = uc_open(UC_ARCH_X86, UC_MODE_16, &uc);
if (err) {
printf("Failed on uc_open() with error returned: %u\n", err);
return;
}
// map 8KB memory for this emulation
uc_mem_map(handle, 0, 8 * 1024, UC_PROT_ALL);
uc_mem_map(uc, 0, 8 * 1024, UC_PROT_ALL);
// write machine code to be emulated to memory
if (uc_mem_write(handle, 0, (uint8_t *)X86_CODE16, sizeof(X86_CODE64) - 1)) {
if (uc_mem_write(uc, 0, (uint8_t *)X86_CODE16, sizeof(X86_CODE64) - 1)) {
printf("Failed to write emulation code to memory, quit!\n");
return;
}
// initialize machine registers
uc_reg_write(handle, UC_X86_REG_EAX, &eax);
uc_reg_write(handle, UC_X86_REG_EBX, &ebx);
uc_reg_write(handle, UC_X86_REG_ESI, &esi);
uc_reg_write(uc, UC_X86_REG_EAX, &eax);
uc_reg_write(uc, UC_X86_REG_EBX, &ebx);
uc_reg_write(uc, UC_X86_REG_ESI, &esi);
// emulate machine code in infinite time (last param = 0), or when
// finishing all the code.
err = uc_emu_start(handle, 0, sizeof(X86_CODE16) - 1, 0, 0);
err = uc_emu_start(uc, 0, sizeof(X86_CODE16) - 1, 0, 0);
if (err) {
printf("Failed on uc_emu_start() with error returned %u: %s\n",
err, uc_strerror(err));
@ -783,12 +782,12 @@ static void test_x86_16(void)
printf(">>> Emulation done. Below is the CPU context\n");
// read from memory
if (!uc_mem_read(handle, 11, &tmp, 1))
if (!uc_mem_read(uc, 11, &tmp, 1))
printf(">>> Read 1 bytes from [0x%x] = 0x%x\n", 11, tmp);
else
printf(">>> Failed to read 1 bytes from [0x%x]\n", 11);
uc_close(&handle);
uc_close(uc);
}
int main(int argc, char **argv, char **envp)

View file

@ -20,18 +20,18 @@
#define MIN(a, b) (a < b? a : b)
// callback for tracing instruction
static void hook_code(uch handle, uint64_t address, uint32_t size, void *user_data)
static void hook_code(ucengine *uc, uint64_t address, uint32_t size, void *user_data)
{
int r_eip;
char tmp[16];
printf("Tracing instruction at 0x%"PRIx64 ", instruction size = 0x%x\n", address, size);
uc_reg_read(handle, UC_X86_REG_EIP, &r_eip);
uc_reg_read(uc, UC_X86_REG_EIP, &r_eip);
printf("*** EIP = %x ***: ", r_eip);
size = MIN(sizeof(tmp), size);
if (!uc_mem_read(handle, address, (uint8_t *)tmp, size)) {
if (!uc_mem_read(uc, address, (uint8_t *)tmp, size)) {
int i;
for (i=0; i<size; i++) {
printf("%x ", ((uint8_t*)tmp)[i]);
@ -43,7 +43,7 @@ static void hook_code(uch handle, uint64_t address, uint32_t size, void *user_da
#define MIN(a, b) (a < b? a : b)
// callback for handling interrupt
// ref: http://syscalls.kernelgrok.com/
static void hook_intr(uch handle, uint32_t intno, void *user_data)
static void hook_intr(ucengine *uc, uint32_t intno, void *user_data)
{
int32_t r_eax, r_ecx, r_eip;
uint32_t r_edx, size;
@ -53,8 +53,8 @@ static void hook_intr(uch handle, uint32_t intno, void *user_data)
if (intno != 0x80)
return;
uc_reg_read(handle, UC_X86_REG_EAX, &r_eax);
uc_reg_read(handle, UC_X86_REG_EIP, &r_eip);
uc_reg_read(uc, UC_X86_REG_EAX, &r_eax);
uc_reg_read(uc, UC_X86_REG_EIP, &r_eip);
switch(r_eax) {
default:
@ -62,19 +62,19 @@ static void hook_intr(uch handle, uint32_t intno, void *user_data)
break;
case 1: // sys_exit
printf(">>> 0x%x: interrupt 0x%x, SYS_EXIT. quit!\n\n", r_eip, intno);
uc_emu_stop(handle);
uc_emu_stop(uc);
break;
case 4: // sys_write
// ECX = buffer address
uc_reg_read(handle, UC_X86_REG_ECX, &r_ecx);
uc_reg_read(uc, UC_X86_REG_ECX, &r_ecx);
// EDX = buffer size
uc_reg_read(handle, UC_X86_REG_EDX, &r_edx);
uc_reg_read(uc, UC_X86_REG_EDX, &r_edx);
// read the buffer in
size = MIN(sizeof(buffer)-1, r_edx);
if (!uc_mem_read(handle, r_ecx, buffer, size)) {
if (!uc_mem_read(uc, r_ecx, buffer, size)) {
buffer[size] = '\0';
printf(">>> 0x%x: interrupt 0x%x, SYS_WRITE. buffer = 0x%x, size = %u, content = '%s'\n",
r_eip, intno, r_ecx, r_edx, buffer);
@ -88,44 +88,44 @@ static void hook_intr(uch handle, uint32_t intno, void *user_data)
static void test_i386(void)
{
uch handle, evh;
ucengine *uc;
uc_err err;
uch trace1;
uc_hook_h trace1, trace2;
int r_esp = ADDRESS + 0x200000; // ESP register
printf("Emulate i386 code\n");
// Initialize emulator in X86-32bit mode
err = uc_open(UC_ARCH_X86, UC_MODE_32, &handle);
err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc);
if (err) {
printf("Failed on uc_open() with error returned: %u\n", err);
return;
}
// map 2MB memory for this emulation
uc_mem_map(handle, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
uc_mem_map(uc, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
// write machine code to be emulated to memory
if (uc_mem_write(handle, ADDRESS, (uint8_t *)X86_CODE32_SELF, sizeof(X86_CODE32_SELF) - 1)) {
if (uc_mem_write(uc, ADDRESS, (uint8_t *)X86_CODE32_SELF, sizeof(X86_CODE32_SELF) - 1)) {
printf("Failed to write emulation code to memory, quit!\n");
return;
}
// initialize machine registers
uc_reg_write(handle, UC_X86_REG_ESP, &r_esp);
uc_reg_write(uc, UC_X86_REG_ESP, &r_esp);
// tracing all instructions by having @begin > @end
uc_hook_add(handle, &trace1, UC_HOOK_CODE, hook_code, NULL, 1, 0);
uc_hook_add(uc, &trace1, UC_HOOK_CODE, hook_code, NULL, 1, 0);
// handle interrupt ourself
uc_hook_add(handle, &evh, UC_HOOK_INTR, hook_intr, NULL);
uc_hook_add(uc, &trace2, UC_HOOK_INTR, hook_intr, NULL);
printf("\n>>> Start tracing this Linux code\n");
// emulate machine code in infinite time
// err = uc_emu_start(handle, ADDRESS, ADDRESS + sizeof(X86_CODE32_SELF), 0, 12); <--- emulate only 12 instructions
err = uc_emu_start(handle, ADDRESS, ADDRESS + sizeof(X86_CODE32_SELF) - 1, 0, 0);
// err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(X86_CODE32_SELF), 0, 12); <--- emulate only 12 instructions
err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(X86_CODE32_SELF) - 1, 0, 0);
if (err) {
printf("Failed on uc_emu_start() with error returned %u: %s\n",
err, uc_strerror(err));
@ -133,7 +133,7 @@ static void test_i386(void)
printf("\n>>> Emulation done.\n");
uc_close(&handle);
uc_close(uc);
}
int main(int argc, char **argv, char **envp)

183
uc.c
View file

@ -44,15 +44,8 @@ unsigned int uc_version(unsigned int *major, unsigned int *minor)
UNICORN_EXPORT
uc_err uc_errno(uch handle)
uc_err uc_errno(ucengine *uc)
{
struct uc_struct *uc;
if (!handle)
return UC_ERR_UCH;
uc = (struct uc_struct *)(uintptr_t)handle;
return uc->errnum;
}
@ -71,8 +64,6 @@ const char *uc_strerror(uc_err code)
return "Invalid/unsupported architecture(UC_ERR_ARCH)";
case UC_ERR_HANDLE:
return "Invalid handle (UC_ERR_HANDLE)";
case UC_ERR_UCH:
return "Invalid uch (UC_ERR_UCH)";
case UC_ERR_MODE:
return "Invalid mode (UC_ERR_MODE)";
case UC_ERR_VERSION:
@ -130,7 +121,7 @@ bool uc_arch_supported(uc_arch arch)
UNICORN_EXPORT
uc_err uc_open(uc_arch arch, uc_mode mode, uch *handle)
uc_err uc_open(uc_arch arch, uc_mode mode, ucengine **result)
{
struct uc_struct *uc;
@ -179,7 +170,6 @@ uc_err uc_open(uc_arch arch, uc_mode mode, uch *handle)
// verify mode
if (mode != UC_MODE_ARM && mode != UC_MODE_THUMB) {
*handle = 0;
free(uc);
return UC_ERR_MODE;
}
@ -229,38 +219,29 @@ uc_err uc_open(uc_arch arch, uc_mode mode, uch *handle)
}
if (uc->init_arch == NULL) {
*handle = 0;
return UC_ERR_ARCH;
}
machine_initialize(uc);
*handle = (uintptr_t)uc;
*result = uc;
if (uc->reg_reset)
uc->reg_reset(*handle);
uc->reg_reset(uc);
uc->hook_size = HOOK_SIZE;
uc->hook_callbacks = calloc(1, sizeof(uc->hook_callbacks[0]) * HOOK_SIZE);
return UC_ERR_OK;
} else {
*handle = 0;
return UC_ERR_ARCH;
}
}
UNICORN_EXPORT
uc_err uc_close(uch *handle)
uc_err uc_close(ucengine *uc)
{
struct uc_struct *uc;
// invalid handle ?
if (*handle == 0)
return UC_ERR_UCH;
uc = (struct uc_struct *)(*handle);
if (uc->release)
uc->release(uc->tcg_ctx);
@ -294,26 +275,15 @@ uc_err uc_close(uch *handle)
memset(uc, 0, sizeof(*uc));
free(uc);
// invalidate this handle by ZERO out its value.
// this is to make sure it is unusable after uc_close()
*handle = 0;
return UC_ERR_OK;
}
UNICORN_EXPORT
uc_err uc_reg_read(uch handle, int regid, void *value)
uc_err uc_reg_read(ucengine *uc, int regid, void *value)
{
struct uc_struct *uc;
if (handle == 0)
// invalid handle
return UC_ERR_UCH;
uc = (struct uc_struct *)handle;
if (uc->reg_read)
uc->reg_read(handle, regid, value);
uc->reg_read(uc, regid, value);
else
return -1; // FIXME: need a proper uc_err
@ -322,17 +292,10 @@ uc_err uc_reg_read(uch handle, int regid, void *value)
UNICORN_EXPORT
uc_err uc_reg_write(uch handle, int regid, const void *value)
uc_err uc_reg_write(ucengine *uc, int regid, const void *value)
{
struct uc_struct *uc;
if (handle == 0)
// invalid handle
return UC_ERR_UCH;
uc = (struct uc_struct *)handle;
if (uc->reg_write)
uc->reg_write(handle, regid, value);
uc->reg_write(uc, regid, value);
else
return -1; // FIXME: need a proper uc_err
@ -342,7 +305,7 @@ uc_err uc_reg_write(uch handle, int regid, const void *value)
// check if a memory area is mapped
// this is complicated because an area can overlap adjacent blocks
static bool check_mem_area(struct uc_struct *uc, uint64_t address, size_t size)
static bool check_mem_area(ucengine *uc, uint64_t address, size_t size)
{
size_t count = 0, len;
@ -361,14 +324,8 @@ static bool check_mem_area(struct uc_struct *uc, uint64_t address, size_t size)
UNICORN_EXPORT
uc_err uc_mem_read(uch handle, uint64_t address, uint8_t *bytes, size_t size)
uc_err uc_mem_read(ucengine *uc, uint64_t address, uint8_t *bytes, size_t size)
{
struct uc_struct *uc = (struct uc_struct *)(uintptr_t)handle;
if (handle == 0)
// invalid handle
return UC_ERR_UCH;
if (!check_mem_area(uc, address, size))
return UC_ERR_MEM_READ;
@ -395,14 +352,8 @@ uc_err uc_mem_read(uch handle, uint64_t address, uint8_t *bytes, size_t size)
}
UNICORN_EXPORT
uc_err uc_mem_write(uch handle, uint64_t address, const uint8_t *bytes, size_t size)
uc_err uc_mem_write(ucengine *uc, uint64_t address, const uint8_t *bytes, size_t size)
{
struct uc_struct *uc = (struct uc_struct *)(uintptr_t)handle;
if (handle == 0)
// invalid handle
return UC_ERR_UCH;
if (!check_mem_area(uc, address, size))
return UC_ERR_MEM_WRITE;
@ -441,7 +392,7 @@ uc_err uc_mem_write(uch handle, uint64_t address, const uint8_t *bytes, size_t s
#define TIMEOUT_STEP 2 // microseconds
static void *_timeout_fn(void *arg)
{
struct uc_struct *uc = (struct uc_struct *)arg;
struct uc_struct *uc = arg;
int64_t current_time = get_clock();
do {
@ -454,30 +405,22 @@ static void *_timeout_fn(void *arg)
// timeout before emulation is done?
if (!uc->emulation_done) {
// force emulation to stop
uc_emu_stop((uch)uc);
uc_emu_stop(uc);
}
return NULL;
}
static void enable_emu_timer(uch handle, uint64_t timeout)
static void enable_emu_timer(ucengine *uc, uint64_t timeout)
{
struct uc_struct *uc = (struct uc_struct *)handle;
uc->timeout = timeout;
qemu_thread_create(uc, &uc->timer, "timeout", _timeout_fn,
uc, QEMU_THREAD_JOINABLE);
}
UNICORN_EXPORT
uc_err uc_emu_start(uch handle, uint64_t begin, uint64_t until, uint64_t timeout, size_t count)
uc_err uc_emu_start(ucengine* uc, uint64_t begin, uint64_t until, uint64_t timeout, size_t count)
{
struct uc_struct* uc = (struct uc_struct *)handle;
if (handle == 0)
// invalid handle
return UC_ERR_UCH;
// reset the counter
uc->emu_counter = 0;
uc->stop_request = false;
@ -490,7 +433,7 @@ uc_err uc_emu_start(uch handle, uint64_t begin, uint64_t until, uint64_t timeout
break;
case UC_ARCH_M68K:
uc_reg_write(handle, UC_M68K_REG_PC, &begin);
uc_reg_write(uc, UC_M68K_REG_PC, &begin);
break;
case UC_ARCH_X86:
@ -498,13 +441,13 @@ uc_err uc_emu_start(uch handle, uint64_t begin, uint64_t until, uint64_t timeout
default:
break;
case UC_MODE_16:
uc_reg_write(handle, UC_X86_REG_IP, &begin);
uc_reg_write(uc, UC_X86_REG_IP, &begin);
break;
case UC_MODE_32:
uc_reg_write(handle, UC_X86_REG_EIP, &begin);
uc_reg_write(uc, UC_X86_REG_EIP, &begin);
break;
case UC_MODE_64:
uc_reg_write(handle, UC_X86_REG_RIP, &begin);
uc_reg_write(uc, UC_X86_REG_RIP, &begin);
break;
}
break;
@ -515,23 +458,23 @@ uc_err uc_emu_start(uch handle, uint64_t begin, uint64_t until, uint64_t timeout
break;
case UC_MODE_THUMB:
case UC_MODE_ARM:
uc_reg_write(handle, UC_ARM_REG_R15, &begin);
uc_reg_write(uc, UC_ARM_REG_R15, &begin);
break;
}
break;
case UC_ARCH_ARM64:
uc_reg_write(handle, UC_ARM64_REG_PC, &begin);
uc_reg_write(uc, UC_ARM64_REG_PC, &begin);
break;
case UC_ARCH_MIPS:
// TODO: MIPS32/MIPS64/BIGENDIAN etc
uc_reg_write(handle, UC_MIPS_REG_PC, &begin);
uc_reg_write(uc, UC_MIPS_REG_PC, &begin);
break;
case UC_ARCH_SPARC:
// TODO: Sparc/Sparc64
uc_reg_write(handle, UC_SPARC_REG_PC, &begin);
uc_reg_write(uc, UC_SPARC_REG_PC, &begin);
break;
}
@ -544,7 +487,7 @@ uc_err uc_emu_start(uch handle, uint64_t begin, uint64_t until, uint64_t timeout
uc->vm_start(uc);
if (timeout)
enable_emu_timer(handle, timeout * 1000); // microseconds -> nanoseconds
enable_emu_timer(uc, timeout * 1000); // microseconds -> nanoseconds
uc->pause_all_vcpus(uc);
// emulation is done
uc->emulation_done = true;
@ -559,14 +502,8 @@ uc_err uc_emu_start(uch handle, uint64_t begin, uint64_t until, uint64_t timeout
UNICORN_EXPORT
uc_err uc_emu_stop(uch handle)
uc_err uc_emu_stop(ucengine *uc)
{
struct uc_struct* uc = (struct uc_struct *)handle;
if (handle == 0)
// invalid handle
return UC_ERR_UCH;
if (uc->emulation_done)
return UC_ERR_OK;
@ -578,45 +515,40 @@ uc_err uc_emu_stop(uch handle)
}
static int _hook_code(uch handle, int type, uint64_t begin, uint64_t end,
void *callback, void *user_data, uch *h2)
static int _hook_code(ucengine *uc, int type, uint64_t begin, uint64_t end,
void *callback, void *user_data, uc_hook_h *hh)
{
int i;
i = hook_add(handle, type, begin, end, callback, user_data);
i = hook_add(uc, type, begin, end, callback, user_data);
if (i == 0)
return UC_ERR_OOM; // FIXME
*h2 = i;
*hh = i;
return UC_ERR_OK;
}
static uc_err _hook_mem_access(uch handle, uc_hook_t type,
static uc_err _hook_mem_access(ucengine *uc, uc_hook_t type,
uint64_t begin, uint64_t end,
void *callback, void *user_data, uch *h2)
void *callback, void *user_data, uc_hook_h *hh)
{
int i;
i = hook_add(handle, type, begin, end, callback, user_data);
i = hook_add(uc, type, begin, end, callback, user_data);
if (i == 0)
return UC_ERR_OOM; // FIXME
*h2 = i;
*hh = i;
return UC_ERR_OK;
}
UNICORN_EXPORT
uc_err uc_mem_map(uch handle, uint64_t address, size_t size, uint32_t perms)
uc_err uc_mem_map(ucengine *uc, uint64_t address, size_t size, uint32_t perms)
{
MemoryRegion **regions;
struct uc_struct* uc = (struct uc_struct *)handle;
if (handle == 0)
// invalid handle
return UC_ERR_UCH;
if (size == 0)
// invalid memory mapping
@ -647,7 +579,7 @@ uc_err uc_mem_map(uch handle, uint64_t address, size_t size, uint32_t perms)
return UC_ERR_OK;
}
MemoryRegion *memory_mapping(struct uc_struct* uc, uint64_t address)
MemoryRegion *memory_mapping(ucengine* uc, uint64_t address)
{
unsigned int i;
@ -661,7 +593,7 @@ MemoryRegion *memory_mapping(struct uc_struct* uc, uint64_t address)
}
static uc_err _hook_mem_invalid(struct uc_struct* uc, uc_cb_eventmem_t callback,
void *user_data, uch *evh)
void *user_data, uc_hook_h *evh)
{
size_t i;
@ -680,7 +612,7 @@ static uc_err _hook_mem_invalid(struct uc_struct* uc, uc_cb_eventmem_t callback,
static uc_err _hook_intr(struct uc_struct* uc, void *callback,
void *user_data, uch *evh)
void *user_data, uc_hook_h *evh)
{
size_t i;
@ -699,7 +631,7 @@ static uc_err _hook_intr(struct uc_struct* uc, void *callback,
static uc_err _hook_insn(struct uc_struct *uc, unsigned int insn_id, void *callback,
void *user_data, uch *evh)
void *user_data, uc_hook_h *evh)
{
size_t i;
@ -750,18 +682,13 @@ static uc_err _hook_insn(struct uc_struct *uc, unsigned int insn_id, void *callb
}
UNICORN_EXPORT
uc_err uc_hook_add(uch handle, uch *h2, uc_hook_t type, void *callback, void *user_data, ...)
uc_err uc_hook_add(ucengine *uc, uc_hook_h *hh, uc_hook_t type, void *callback, void *user_data, ...)
{
struct uc_struct* uc = (struct uc_struct *)handle;
va_list valist;
int ret = UC_ERR_OK;
int id;
uint64_t begin, end;
if (handle == 0)
// invalid handle
return UC_ERR_UCH;
va_start(valist, user_data);
switch(type) {
@ -769,39 +696,39 @@ uc_err uc_hook_add(uch handle, uch *h2, uc_hook_t type, void *callback, void *us
ret = UC_ERR_HOOK;
break;
case UC_HOOK_INTR:
ret = _hook_intr(uc, callback, user_data, h2);
ret = _hook_intr(uc, callback, user_data, hh);
break;
case UC_HOOK_INSN:
id = va_arg(valist, int);
ret = _hook_insn(uc, id, callback, user_data, h2);
ret = _hook_insn(uc, id, callback, user_data, hh);
break;
case UC_HOOK_CODE:
begin = va_arg(valist, uint64_t);
end = va_arg(valist, uint64_t);
ret = _hook_code(handle, UC_HOOK_CODE, begin, end, callback, user_data, h2);
ret = _hook_code(uc, UC_HOOK_CODE, begin, end, callback, user_data, hh);
break;
case UC_HOOK_BLOCK:
begin = va_arg(valist, uint64_t);
end = va_arg(valist, uint64_t);
ret = _hook_code(handle, UC_HOOK_BLOCK, begin, end, callback, user_data, h2);
ret = _hook_code(uc, UC_HOOK_BLOCK, begin, end, callback, user_data, hh);
break;
case UC_HOOK_MEM_INVALID:
ret = _hook_mem_invalid(uc, callback, user_data, h2);
ret = _hook_mem_invalid(uc, callback, user_data, hh);
break;
case UC_HOOK_MEM_READ:
begin = va_arg(valist, uint64_t);
end = va_arg(valist, uint64_t);
ret = _hook_mem_access(handle, UC_HOOK_MEM_READ, begin, end, callback, user_data, h2);
ret = _hook_mem_access(uc, UC_HOOK_MEM_READ, begin, end, callback, user_data, hh);
break;
case UC_HOOK_MEM_WRITE:
begin = va_arg(valist, uint64_t);
end = va_arg(valist, uint64_t);
ret = _hook_mem_access(handle, UC_HOOK_MEM_WRITE, begin, end, callback, user_data, h2);
ret = _hook_mem_access(uc, UC_HOOK_MEM_WRITE, begin, end, callback, user_data, hh);
break;
case UC_HOOK_MEM_READ_WRITE:
begin = va_arg(valist, uint64_t);
end = va_arg(valist, uint64_t);
ret = _hook_mem_access(handle, UC_HOOK_MEM_READ_WRITE, begin, end, callback, user_data, h2);
ret = _hook_mem_access(uc, UC_HOOK_MEM_READ_WRITE, begin, end, callback, user_data, hh);
break;
}
@ -811,17 +738,7 @@ uc_err uc_hook_add(uch handle, uch *h2, uc_hook_t type, void *callback, void *us
}
UNICORN_EXPORT
uc_err uc_hook_del(uch handle, uch *h2)
uc_err uc_hook_del(ucengine *uc, uc_hook_h hh)
{
//struct uc_struct* uc = (struct uc_struct *)handle;
if (handle == 0)
// invalid handle
return UC_ERR_UCH;
if (*h2 == 0)
// invalid handle
return UC_ERR_HANDLE;
return hook_del(handle, h2);
return hook_del(uc, hh);
}