From 4ea3a3ebbf3d633952309d7a939c05b710b77aa2 Mon Sep 17 00:00:00 2001 From: Jonathon Reinhart Date: Wed, 26 Aug 2015 08:00:00 -0400 Subject: [PATCH 01/23] change uch to uc_struct (header files) --- include/uc_priv.h | 6 ++-- include/unicorn/unicorn.h | 70 ++++++++++++++++++++------------------- include/unicorn/x86.h | 2 +- 3 files changed, 40 insertions(+), 38 deletions(-) diff --git a/include/uc_priv.h b/include/uc_priv.h index 2703627c..2d075267 100644 --- a/include/uc_priv.h +++ b/include/uc_priv.h @@ -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); diff --git a/include/unicorn/unicorn.h b/include/unicorn/unicorn.h index 66de81eb..9fd38435 100644 --- a/include/unicorn/unicorn.h +++ b/include/unicorn/unicorn.h @@ -19,6 +19,8 @@ extern "C" { #include "platform.h" +struct uc_struct; + // Handle to use with all APIs typedef size_t uch; @@ -123,24 +125,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)(struct uc_struct *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)(struct uc_struct *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)(struct uc_struct *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)(struct uc_struct *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 { @@ -167,7 +169,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)(struct uc_struct *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) @@ -177,7 +179,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)(struct uc_struct *uc, uc_mem_type type, uint64_t address, int size, int64_t value, void *user_data); @@ -214,43 +216,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 struct uc_struct, 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, struct uc_struct **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(struct uc_struct *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(struct uc_struct *uc); /* Return a string describing given error code. @@ -266,7 +268,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 @@ -274,12 +276,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(struct uc_struct *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. @@ -287,12 +289,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(struct uc_struct *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. @@ -303,12 +305,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(struct uc_struct *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. @@ -319,12 +321,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(struct uc_struct *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, @@ -336,26 +338,26 @@ 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(struct uc_struct *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(struct uc_struct *uc); /* Register callback for a hook event. The callback will be run when the hook event is hit. - @handle: handle returned by uc_open() + @uc: handle returned by uc_open() @h2: 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 @@ -367,28 +369,28 @@ 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(struct uc_struct *uc, uch *h2, 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, @h2 is invalid, and nolonger usable. - @handle: handle returned by uc_open() + @uc: handle returned by uc_open() @h2: 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(struct uc_struct *uc, uch *h2); /* 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. @@ -398,7 +400,7 @@ uc_err uc_hook_del(uch handle, uch *h2); for detailed error). */ UNICORN_EXPORT -uc_err uc_mem_map(uch handle, uint64_t address, size_t size); +uc_err uc_mem_map(struct uc_struct *uc, uint64_t address, size_t size); #ifdef __cplusplus } diff --git a/include/unicorn/x86.h b/include/unicorn/x86.h index 4ee6945e..b279de58 100644 --- a/include/unicorn/x86.h +++ b/include/unicorn/x86.h @@ -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 { From 5f89f9884ebbde38d5067bd4d529b9a88679c589 Mon Sep 17 00:00:00 2001 From: Jonathon Reinhart Date: Wed, 26 Aug 2015 06:39:51 -0400 Subject: [PATCH 02/23] change uch to uc_struct (uc.c) --- uc.c | 150 ++++++++++++++--------------------------------------------- 1 file changed, 36 insertions(+), 114 deletions(-) diff --git a/uc.c b/uc.c index 5a798f57..2a808ce8 100644 --- a/uc.c +++ b/uc.c @@ -49,15 +49,8 @@ unsigned int uc_version(unsigned int *major, unsigned int *minor) UNICORN_EXPORT -uc_err uc_errno(uch handle) +uc_err uc_errno(struct uc_struct *uc) { - struct uc_struct *uc; - - if (!handle) - return UC_ERR_UCH; - - uc = (struct uc_struct *)(uintptr_t)handle; - return uc->errnum; } @@ -131,7 +124,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, struct uc_struct **result) { struct uc_struct *uc; @@ -180,7 +173,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; } @@ -230,38 +222,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(struct uc_struct *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); @@ -293,26 +276,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(struct uc_struct *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 @@ -321,17 +293,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(struct uc_struct *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 @@ -340,14 +305,8 @@ uc_err uc_reg_write(uch handle, int regid, const void *value) UNICORN_EXPORT -uc_err uc_mem_read(uch handle, uint64_t address, uint8_t *bytes, size_t size) +uc_err uc_mem_read(struct uc_struct *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 (uc->read_mem(&uc->as, address, bytes, size) == false) return UC_ERR_MEM_READ; @@ -356,14 +315,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(struct uc_struct *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 (uc->write_mem(&uc->as, address, bytes, size) == false) return UC_ERR_MEM_WRITE; @@ -392,24 +345,16 @@ static void *_timeout_fn(void *arg) return NULL; } -static void enable_emu_timer(uch handle, uint64_t timeout) +static void enable_emu_timer(struct uc_struct *uc, uint64_t timeout) { - struct uc_struct *uc = (struct uc_struct *)handle; - uc->timeout = timeout; qemu_thread_create(&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(struct uc_struct* 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; @@ -421,7 +366,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: @@ -429,13 +374,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; @@ -446,23 +391,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; } @@ -475,7 +420,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; @@ -485,14 +430,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(struct uc_struct *uc) { - struct uc_struct* uc = (struct uc_struct *)handle; - - if (handle == 0) - // invalid handle - return UC_ERR_UCH; - uc->stop_request = true; // exit the current TB cpu_exit(uc->current_cpu); @@ -501,12 +440,12 @@ uc_err uc_emu_stop(uch handle) } -static int _hook_code(uch handle, int type, uint64_t begin, uint64_t end, +static int _hook_code(struct uc_struct *uc, int type, uint64_t begin, uint64_t end, void *callback, void *user_data, uch *h2) { 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 @@ -516,13 +455,13 @@ static int _hook_code(uch handle, int type, uint64_t begin, uint64_t end, } -static uc_err _hook_mem_access(uch handle, uc_mem_type type, +static uc_err _hook_mem_access(struct uc_struct *uc, uc_mem_type type, uint64_t begin, uint64_t end, void *callback, void *user_data, uch *h2) { 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 @@ -532,14 +471,8 @@ static uc_err _hook_mem_access(uch handle, uc_mem_type type, } UNICORN_EXPORT -uc_err uc_mem_map(uch handle, uint64_t address, size_t size) +uc_err uc_mem_map(struct uc_struct *uc, uint64_t address, size_t size) { - struct uc_struct* uc = (struct uc_struct *)handle; - - if (handle == 0) - // invalid handle - return UC_ERR_UCH; - if (size == 0) // invalid memory mapping return UC_ERR_MAP; @@ -663,18 +596,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(struct uc_struct *uc, uch *h2, 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) { @@ -691,12 +619,12 @@ uc_err uc_hook_add(uch handle, uch *h2, uc_hook_t type, void *callback, void *us 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, h2); 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, h2); break; case UC_HOOK_MEM_INVALID: ret = _hook_mem_invalid(uc, callback, user_data, h2); @@ -704,16 +632,16 @@ uc_err uc_hook_add(uch handle, uch *h2, uc_hook_t type, void *callback, void *us case UC_HOOK_MEM_READ: begin = va_arg(valist, uint64_t); end = va_arg(valist, uint64_t); - ret = _hook_mem_access(handle, UC_MEM_READ, begin, end, callback, user_data, h2); + ret = _hook_mem_access(uc, UC_MEM_READ, begin, end, callback, user_data, h2); break; case UC_HOOK_MEM_WRITE: begin = va_arg(valist, uint64_t); end = va_arg(valist, uint64_t); - ret = _hook_mem_access(handle, UC_MEM_WRITE, begin, end, callback, user_data, h2); + ret = _hook_mem_access(uc, UC_MEM_WRITE, begin, end, callback, user_data, h2); case UC_HOOK_MEM_READ_WRITE: begin = va_arg(valist, uint64_t); end = va_arg(valist, uint64_t); - ret = _hook_mem_access(handle, UC_MEM_READ_WRITE, begin, end, callback, user_data, h2); + ret = _hook_mem_access(uc, UC_MEM_READ_WRITE, begin, end, callback, user_data, h2); break; } @@ -723,18 +651,12 @@ 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(struct uc_struct *uc, uch *h2) { - //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, h2); } From b9f7850efb00e0115958b5cd9061e4e03e7a5679 Mon Sep 17 00:00:00 2001 From: Jonathon Reinhart Date: Wed, 26 Aug 2015 06:11:39 -0400 Subject: [PATCH 03/23] change uch to uc_struct (hook) --- hook.c | 31 +++++++------------------------ include/hook.h | 6 +++--- 2 files changed, 10 insertions(+), 27 deletions(-) diff --git a/hook.c b/hook.c index 6a26d70d..468d79b7 100644 --- a/hook.c +++ b/hook.c @@ -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,13 +91,8 @@ 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, uch *h2) { - struct uc_struct *uc = (struct uc_struct *)(uintptr_t)handle; - - if (handle == 0) - return UC_ERR_UCH; - if (*h2 == uc->hook_block_idx) { uc->hook_block_idx = 0; } @@ -205,26 +196,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; @@ -269,6 +253,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); } - diff --git a/include/hook.h b/include/hook.h index 5441071f..72e255a7 100644 --- a/include/hook.h +++ b/include/hook.h @@ -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, uch *traceh); // 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. From 6c4726c88eb0d784b4f751bd38e1467b8756985d Mon Sep 17 00:00:00 2001 From: Jonathon Reinhart Date: Wed, 26 Aug 2015 06:19:28 -0400 Subject: [PATCH 04/23] change uch to uc_struct (ioport.c) --- qemu/ioport.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/qemu/ioport.c b/qemu/ioport.c index f4e56510..338a296a 100644 --- a/qemu/ioport.c +++ b/qemu/ioport.c @@ -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; From 622d5cd5f9669ab98cb58200938254f6422b1967 Mon Sep 17 00:00:00 2001 From: Jonathon Reinhart Date: Wed, 26 Aug 2015 06:30:58 -0400 Subject: [PATCH 05/23] change uch to uc_struct (target-arm) --- qemu/target-arm/translate-a64.c | 4 ++-- qemu/target-arm/translate.c | 6 +++--- qemu/target-arm/unicorn.h | 12 ++++++------ qemu/target-arm/unicorn_aarch64.c | 21 ++++++--------------- qemu/target-arm/unicorn_arm.c | 14 +++++--------- 5 files changed, 22 insertions(+), 35 deletions(-) diff --git a/qemu/target-arm/translate-a64.c b/qemu/target-arm/translate-a64.c index 2e159f21..deeebabe 100644 --- a/qemu/target-arm/translate-a64.c +++ b/qemu/target-arm/translate-a64.c @@ -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 @@ -11106,7 +11106,7 @@ void gen_intermediate_code_internal_a64(ARMCPU *cpu, // Unicorn: trace this block on request if (env->uc->hook_block) { - 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; diff --git a/qemu/target-arm/translate.c b/qemu/target-arm/translate.c index 9a1b7914..e3aa07f7 100644 --- a/qemu/target-arm/translate.c +++ b/qemu/target-arm/translate.c @@ -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 @@ -11229,7 +11229,7 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu, // Unicorn: trace this block on request if (env->uc->hook_block) { - 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; diff --git a/qemu/target-arm/unicorn.h b/qemu/target-arm/unicorn.h index 0c355a71..797ef979 100644 --- a/qemu/target-arm/unicorn.h +++ b/qemu/target-arm/unicorn.h @@ -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); diff --git a/qemu/target-arm/unicorn_aarch64.c b/qemu/target-arm/unicorn_aarch64.c index b9474155..a8a674b0 100644 --- a/qemu/target-arm/unicorn_aarch64.c +++ b/qemu/target-arm/unicorn_aarch64.c @@ -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; diff --git a/qemu/target-arm/unicorn_arm.c b/qemu/target-arm/unicorn_arm.c index 9737906c..dcb2a65f 100644 --- a/qemu/target-arm/unicorn_arm.c +++ b/qemu/target-arm/unicorn_arm.c @@ -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: From 15a774ac904ca8f834c2f2c2dbd0510ce53ca662 Mon Sep 17 00:00:00 2001 From: Jonathon Reinhart Date: Wed, 26 Aug 2015 06:34:47 -0400 Subject: [PATCH 06/23] change uch to uc_struct (target-mips) --- qemu/target-mips/translate.c | 8 ++++---- qemu/target-mips/unicorn.c | 17 +++++++---------- qemu/target-mips/unicorn.h | 6 +++--- 3 files changed, 14 insertions(+), 17 deletions(-) diff --git a/qemu/target-mips/translate.c b/qemu/target-mips/translate.c index 4dbad582..6ffd0d79 100644 --- a/qemu/target-mips/translate.c +++ b/qemu/target-mips/translate.c @@ -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 @@ -19208,7 +19208,7 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb, // Unicorn: trace this block on request if (env->uc->hook_block) { - 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; diff --git a/qemu/target-mips/unicorn.c b/qemu/target-mips/unicorn.c index a66efdaf..33f1d6c0 100644 --- a/qemu/target-mips/unicorn.c +++ b/qemu/target-mips/unicorn.c @@ -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) diff --git a/qemu/target-mips/unicorn.h b/qemu/target-mips/unicorn.h index 29d36a7d..874b82f1 100644 --- a/qemu/target-mips/unicorn.h +++ b/qemu/target-mips/unicorn.h @@ -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); From e7a8eb89761949fce230e4c9bc85c81e541b165d Mon Sep 17 00:00:00 2001 From: Jonathon Reinhart Date: Wed, 26 Aug 2015 06:59:01 -0400 Subject: [PATCH 07/23] change uch to uc_struct (target-sparc) --- qemu/target-sparc/translate.c | 4 ++-- qemu/target-sparc/unicorn.c | 12 ++++-------- qemu/target-sparc/unicorn.h | 6 +++--- qemu/target-sparc/unicorn64.c | 12 ++++-------- 4 files changed, 13 insertions(+), 21 deletions(-) diff --git a/qemu/target-sparc/translate.c b/qemu/target-sparc/translate.c index 60c7ba20..f0ad799f 100644 --- a/qemu/target-sparc/translate.c +++ b/qemu/target-sparc/translate.c @@ -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 @@ -5406,7 +5406,7 @@ static inline void gen_intermediate_code_internal(SPARCCPU *cpu, // Unicorn: trace this block on request if (env->uc->hook_block) { - 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; diff --git a/qemu/target-sparc/unicorn.c b/qemu/target-sparc/unicorn.c index 31c79cd7..2ca74743 100644 --- a/qemu/target-sparc/unicorn.c +++ b/qemu/target-sparc/unicorn.c @@ -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) diff --git a/qemu/target-sparc/unicorn.h b/qemu/target-sparc/unicorn.h index 492a7ffb..89771827 100644 --- a/qemu/target-sparc/unicorn.h +++ b/qemu/target-sparc/unicorn.h @@ -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); diff --git a/qemu/target-sparc/unicorn64.c b/qemu/target-sparc/unicorn64.c index f9baef0c..20a3928e 100644 --- a/qemu/target-sparc/unicorn64.c +++ b/qemu/target-sparc/unicorn64.c @@ -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) From b57662e43d03e17a2514941c9280fecc812fd728 Mon Sep 17 00:00:00 2001 From: Jonathon Reinhart Date: Wed, 26 Aug 2015 07:06:12 -0400 Subject: [PATCH 08/23] change uch to uc_struct (target-i386) --- qemu/target-i386/seg_helper.c | 2 +- qemu/target-i386/translate.c | 4 ++-- qemu/target-i386/unicorn.c | 21 ++++++--------------- qemu/target-i386/unicorn.h | 6 +++--- 4 files changed, 12 insertions(+), 21 deletions(-) diff --git a/qemu/target-i386/seg_helper.c b/qemu/target-i386/seg_helper.c index 0bae3caa..2111ac7c 100644 --- a/qemu/target-i386/seg_helper.c +++ b/qemu/target-i386/seg_helper.c @@ -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; } diff --git a/qemu/target-i386/translate.c b/qemu/target-i386/translate.c index 7ce37ef8..776f73c6 100644 --- a/qemu/target-i386/translate.c +++ b/qemu/target-i386/translate.c @@ -4756,7 +4756,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); @@ -8353,7 +8353,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); diff --git a/qemu/target-i386/unicorn.c b/qemu/target-i386/unicorn.c index c6350213..9db3fb6d 100644 --- a/qemu/target-i386/unicorn.c +++ b/qemu/target-i386/unicorn.c @@ -48,12 +48,9 @@ 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; - - env = first_cpu->env_ptr; + CPUArchState *env = first_cpu->env_ptr; env->invalid_error = UC_ERR_OK; // no error memset(env->regs, 0, sizeof(env->regs)); @@ -138,12 +135,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: @@ -540,12 +534,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: diff --git a/qemu/target-i386/unicorn.h b/qemu/target-i386/unicorn.h index b710236b..a4dda81e 100644 --- a/qemu/target-i386/unicorn.h +++ b/qemu/target-i386/unicorn.h @@ -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); From fcb099805fd414269f9c2d992fcb9bbc02b12663 Mon Sep 17 00:00:00 2001 From: Jonathon Reinhart Date: Wed, 26 Aug 2015 07:08:24 -0400 Subject: [PATCH 09/23] change uch to uc_struct (qemu) --- qemu/cpu-exec.c | 2 +- qemu/softmmu_template.h | 24 ++++++++++++------------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/qemu/cpu-exec.c b/qemu/cpu-exec.c index 7d23caac..d491aacd 100644 --- a/qemu/cpu-exec.c +++ b/qemu/cpu-exec.c @@ -148,7 +148,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 diff --git a/qemu/softmmu_template.h b/qemu/softmmu_template.h index 5ae4a73f..6c968676 100644 --- a/qemu/softmmu_template.h +++ b/qemu/softmmu_template.h @@ -180,9 +180,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_MEM_READ, addr); + struct hook_struct *trace = hook_find(env->uc, UC_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); } } @@ -190,7 +190,7 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx, // Unicorn: callback on invalid memory if (!memory_mapping(addr) && env->uc->hook_mem_idx) { 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; @@ -302,9 +302,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_MEM_READ, addr); + struct hook_struct *trace = hook_find(env->uc, UC_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); } } @@ -312,7 +312,7 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx, // Unicorn: callback on invalid memory if (!memory_mapping(addr) && env->uc->hook_mem_idx) { 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; @@ -462,9 +462,9 @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val, // Unicorn: callback on memory write if (env->uc->hook_mem_write) { - struct hook_struct *trace = hook_find((uch)env->uc, UC_MEM_WRITE, addr); + struct hook_struct *trace = hook_find(env->uc, UC_MEM_WRITE, addr); if (trace) { - ((uc_cb_hookmem_t)trace->callback)((uch)env->uc, UC_MEM_WRITE, + ((uc_cb_hookmem_t)trace->callback)(env->uc, UC_MEM_WRITE, (uint64_t)addr, (int)DATA_SIZE, (int64_t)val, trace->user_data); } } @@ -472,7 +472,7 @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val, // Unicorn: callback on invalid memory if (!memory_mapping(addr) && env->uc->hook_mem_idx) { if (!((uc_cb_eventmem_t)env->uc->hook_callbacks[env->uc->hook_mem_idx].callback)( - (uch)env->uc, UC_MEM_WRITE, addr, DATA_SIZE, (int64_t)val, + env->uc, UC_MEM_WRITE, addr, DATA_SIZE, (int64_t)val, env->uc->hook_callbacks[env->uc->hook_mem_idx].user_data)) { // save error & quit env->invalid_addr = addr; @@ -576,9 +576,9 @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val, // Unicorn: callback on memory write if (env->uc->hook_mem_write) { - struct hook_struct *trace = hook_find((uch)env->uc, UC_MEM_WRITE, addr); + struct hook_struct *trace = hook_find(env->uc, UC_MEM_WRITE, addr); if (trace) { - ((uc_cb_hookmem_t)trace->callback)((uch)env->uc, UC_MEM_WRITE, + ((uc_cb_hookmem_t)trace->callback)(env->uc, UC_MEM_WRITE, (uint64_t)addr, (int)DATA_SIZE, (int64_t)val, trace->user_data); } } @@ -586,7 +586,7 @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val, // Unicorn: callback on invalid memory if (!memory_mapping(addr) && env->uc->hook_mem_idx) { if (!((uc_cb_eventmem_t)env->uc->hook_callbacks[env->uc->hook_mem_idx].callback)( - (uch)env->uc, UC_MEM_WRITE, addr, DATA_SIZE, (int64_t)val, + env->uc, UC_MEM_WRITE, addr, DATA_SIZE, (int64_t)val, env->uc->hook_callbacks[env->uc->hook_mem_idx].user_data)) { // save error & quit env->invalid_addr = addr; From 8918deb1b2796d6f1a312905c89b904f72746218 Mon Sep 17 00:00:00 2001 From: Jonathon Reinhart Date: Wed, 26 Aug 2015 07:11:49 -0400 Subject: [PATCH 10/23] change uch to uc_struct (target-m68k) --- qemu/target-m68k/translate.c | 4 ++-- qemu/target-m68k/unicorn.c | 12 ++++-------- qemu/target-m68k/unicorn.h | 6 +++--- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/qemu/target-m68k/translate.c b/qemu/target-m68k/translate.c index ce630d7d..0751445c 100644 --- a/qemu/target-m68k/translate.c +++ b/qemu/target-m68k/translate.c @@ -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 @@ -3102,7 +3102,7 @@ gen_intermediate_code_internal(M68kCPU *cpu, TranslationBlock *tb, // Unicorn: trace this block on request if (env->uc->hook_block) { - 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; diff --git a/qemu/target-m68k/unicorn.c b/qemu/target-m68k/unicorn.c index f085b53c..d8403c63 100644 --- a/qemu/target-m68k/unicorn.c +++ b/qemu/target-m68k/unicorn.c @@ -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) diff --git a/qemu/target-m68k/unicorn.h b/qemu/target-m68k/unicorn.h index 5fcca5f3..37ea828f 100644 --- a/qemu/target-m68k/unicorn.h +++ b/qemu/target-m68k/unicorn.h @@ -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); From 24caaa07debc8e1660d4efe84dce29164a353836 Mon Sep 17 00:00:00 2001 From: Jonathon Reinhart Date: Wed, 26 Aug 2015 07:32:05 -0400 Subject: [PATCH 11/23] change uch to uc_hook_h for hook handles --- hook.c | 30 ++++++++++++++--------------- include/hook.h | 2 +- include/unicorn/unicorn.h | 13 ++++++------- uc.c | 40 +++++++++++++++++++-------------------- 4 files changed, 41 insertions(+), 44 deletions(-) diff --git a/hook.c b/hook.c index 468d79b7..31fcaabf 100644 --- a/hook.c +++ b/hook.c @@ -91,47 +91,45 @@ size_t hook_add(struct uc_struct *uc, int type, uint64_t begin, uint64_t end, vo } // return 0 on success, -1 on failure -uc_err hook_del(struct uc_struct *uc, uch *h2) +uc_err hook_del(struct uc_struct *uc, uc_hook_h hh) { - 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; } diff --git a/include/hook.h b/include/hook.h index 72e255a7..8c095b28 100644 --- a/include/hook.h +++ b/include/hook.h @@ -8,7 +8,7 @@ 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(struct uc_struct *uc, uch *traceh); +uc_err hook_del(struct uc_struct *uc, uc_hook_h hh); // return NULL on failure struct hook_struct *hook_find(struct uc_struct *uc, int type, uint64_t address); diff --git a/include/unicorn/unicorn.h b/include/unicorn/unicorn.h index 9fd38435..d7ac2a33 100644 --- a/include/unicorn/unicorn.h +++ b/include/unicorn/unicorn.h @@ -21,8 +21,7 @@ extern "C" { struct uc_struct; -// Handle to use with all APIs -typedef size_t uch; +typedef size_t uc_hook_h; #include "m68k.h" #include "x86.h" @@ -358,7 +357,7 @@ uc_err uc_emu_stop(struct uc_struct *uc); The callback will be run when the hook event is hit. @uc: handle returned by uc_open() - @h2: hook handle returned from this registration. To be used in uc_hook_del() API + @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 @@ -369,22 +368,22 @@ uc_err uc_emu_stop(struct uc_struct *uc); for detailed error). */ UNICORN_EXPORT -uc_err uc_hook_add(struct uc_struct *uc, uch *h2, uc_hook_t type, void *callback, void *user_data, ...); +uc_err uc_hook_add(struct uc_struct *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, @h2 is invalid, and nolonger usable. + After this, @hh is invalid, and nolonger usable. @uc: handle returned by uc_open() - @h2: handle returned by uc_hook_add() + @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(struct uc_struct *uc, uch *h2); +uc_err uc_hook_del(struct uc_struct *uc, uc_hook_h *hh); /* Map memory in for emulation. diff --git a/uc.c b/uc.c index 2a808ce8..7bb690c7 100644 --- a/uc.c +++ b/uc.c @@ -339,7 +339,7 @@ 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; @@ -441,7 +441,7 @@ uc_err uc_emu_stop(struct uc_struct *uc) static int _hook_code(struct uc_struct *uc, int 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; @@ -449,7 +449,7 @@ static int _hook_code(struct uc_struct *uc, int type, uint64_t begin, uint64_t e if (i == 0) return UC_ERR_OOM; // FIXME - *h2 = i; + *hh = i; return UC_ERR_OK; } @@ -457,7 +457,7 @@ static int _hook_code(struct uc_struct *uc, int type, uint64_t begin, uint64_t e static uc_err _hook_mem_access(struct uc_struct *uc, uc_mem_type 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; @@ -465,7 +465,7 @@ static uc_err _hook_mem_access(struct uc_struct *uc, uc_mem_type type, if (i == 0) return UC_ERR_OOM; // FIXME - *h2 = i; + *hh = i; return UC_ERR_OK; } @@ -507,7 +507,7 @@ bool memory_mapping(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; @@ -526,7 +526,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; @@ -545,7 +545,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; @@ -596,7 +596,7 @@ static uc_err _hook_insn(struct uc_struct *uc, unsigned int insn_id, void *callb } UNICORN_EXPORT -uc_err uc_hook_add(struct uc_struct *uc, uch *h2, uc_hook_t type, void *callback, void *user_data, ...) +uc_err uc_hook_add(struct uc_struct *uc, uc_hook_h *hh, uc_hook_t type, void *callback, void *user_data, ...) { va_list valist; int ret = UC_ERR_OK; @@ -610,38 +610,38 @@ uc_err uc_hook_add(struct uc_struct *uc, uch *h2, uc_hook_t type, void *callback 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(uc, 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(uc, 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(uc, UC_MEM_READ, begin, end, callback, user_data, h2); + ret = _hook_mem_access(uc, UC_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(uc, UC_MEM_WRITE, begin, end, callback, user_data, h2); + ret = _hook_mem_access(uc, UC_MEM_WRITE, begin, end, callback, user_data, hh); case UC_HOOK_MEM_READ_WRITE: begin = va_arg(valist, uint64_t); end = va_arg(valist, uint64_t); - ret = _hook_mem_access(uc, UC_MEM_READ_WRITE, begin, end, callback, user_data, h2); + ret = _hook_mem_access(uc, UC_MEM_READ_WRITE, begin, end, callback, user_data, hh); break; } @@ -651,12 +651,12 @@ uc_err uc_hook_add(struct uc_struct *uc, uch *h2, uc_hook_t type, void *callback } UNICORN_EXPORT -uc_err uc_hook_del(struct uc_struct *uc, uch *h2) +uc_err uc_hook_del(struct uc_struct *uc, uc_hook_h *hh) { - if (*h2 == 0) + if (*hh == 0) // invalid handle return UC_ERR_HANDLE; - return hook_del(uc, h2); + return hook_del(uc, hh); } From ad59de2b5132ab87d9759930f084ae61ed492ad1 Mon Sep 17 00:00:00 2001 From: Jonathon Reinhart Date: Wed, 26 Aug 2015 07:35:42 -0400 Subject: [PATCH 12/23] remove UC_ERR_UCH not used anymore --- include/unicorn/unicorn.h | 1 - uc.c | 2 -- 2 files changed, 3 deletions(-) diff --git a/include/unicorn/unicorn.h b/include/unicorn/unicorn.h index d7ac2a33..714feaae 100644 --- a/include/unicorn/unicorn.h +++ b/include/unicorn/unicorn.h @@ -108,7 +108,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() diff --git a/uc.c b/uc.c index 7bb690c7..3db2778f 100644 --- a/uc.c +++ b/uc.c @@ -69,8 +69,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: From 20bdbf638d1d9312676f4d3ec96d0f52fb8508cd Mon Sep 17 00:00:00 2001 From: Jonathon Reinhart Date: Wed, 26 Aug 2015 07:36:20 -0400 Subject: [PATCH 13/23] change uc_hook_del() to take hook handle by value --- include/unicorn/unicorn.h | 2 +- uc.c | 6 +----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/include/unicorn/unicorn.h b/include/unicorn/unicorn.h index 714feaae..14102c97 100644 --- a/include/unicorn/unicorn.h +++ b/include/unicorn/unicorn.h @@ -382,7 +382,7 @@ uc_err uc_hook_add(struct uc_struct *uc, uc_hook_h *hh, uc_hook_t type, void *ca for detailed error). */ UNICORN_EXPORT -uc_err uc_hook_del(struct uc_struct *uc, uc_hook_h *hh); +uc_err uc_hook_del(struct uc_struct *uc, uc_hook_h hh); /* Map memory in for emulation. diff --git a/uc.c b/uc.c index 3db2778f..3effa782 100644 --- a/uc.c +++ b/uc.c @@ -649,12 +649,8 @@ uc_err uc_hook_add(struct uc_struct *uc, uc_hook_h *hh, uc_hook_t type, void *ca } UNICORN_EXPORT -uc_err uc_hook_del(struct uc_struct *uc, uc_hook_h *hh) +uc_err uc_hook_del(struct uc_struct *uc, uc_hook_h hh) { - if (*hh == 0) - // invalid handle - return UC_ERR_HANDLE; - return hook_del(uc, hh); } From 7ac92ac50a76f9a0562390adfbf6b62c0ff75876 Mon Sep 17 00:00:00 2001 From: Jonathon Reinhart Date: Wed, 26 Aug 2015 08:24:17 -0400 Subject: [PATCH 14/23] samples: update sample_mips to use new API --- samples/sample_mips.c | 48 +++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/samples/sample_mips.c b/samples/sample_mips.c index 43d0682e..5b921257 100644 --- a/samples/sample_mips.c +++ b/samples/sample_mips.c @@ -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(struct uc_struct *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(struct uc_struct *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; + struct uc_struct *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_mem_map(uc, ADDRESS, 2 * 1024 * 1024); // 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; + struct uc_struct *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_mem_map(uc, ADDRESS, 2 * 1024 * 1024); // 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) From 7406367a3462ee30231774e6a6ae174020bcf88f Mon Sep 17 00:00:00 2001 From: Jonathon Reinhart Date: Wed, 26 Aug 2015 08:28:04 -0400 Subject: [PATCH 15/23] samples: update sample_arm to use new API --- samples/sample_arm.c | 54 ++++++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/samples/sample_arm.c b/samples/sample_arm.c index cb5cc6b3..78476e03 100644 --- a/samples/sample_arm.c +++ b/samples/sample_arm.c @@ -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(struct uc_struct *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(struct uc_struct *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; + struct uc_struct *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_mem_map(uc, ADDRESS, 2 * 1024 * 1024); // 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; + struct uc_struct *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_mem_map(uc, ADDRESS, 2 * 1024 * 1024); // 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) From 0d69d81c2ece9782c18a86f56a174cd8e481f757 Mon Sep 17 00:00:00 2001 From: Jonathon Reinhart Date: Wed, 26 Aug 2015 08:30:49 -0400 Subject: [PATCH 16/23] samples: update sample_arm64 to use new API --- samples/sample_arm64.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/samples/sample_arm64.c b/samples/sample_arm64.c index f1c5ffbc..1626f20b 100644 --- a/samples/sample_arm64.c +++ b/samples/sample_arm64.c @@ -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(struct uc_struct *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(struct uc_struct *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; + struct uc_struct *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_mem_map(uc, ADDRESS, 2 * 1024 * 1024); // 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) From fa11e9dddb3e395da0ab50b6c5664810aa94cf84 Mon Sep 17 00:00:00 2001 From: Jonathon Reinhart Date: Wed, 26 Aug 2015 08:31:53 -0400 Subject: [PATCH 17/23] samples: update sample_sparc to use new API --- samples/sample_sparc.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/samples/sample_sparc.c b/samples/sample_sparc.c index 52bb373d..c74b31f3 100644 --- a/samples/sample_sparc.c +++ b/samples/sample_sparc.c @@ -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(struct uc_struct *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(struct uc_struct *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; + struct uc_struct *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_mem_map(uc, ADDRESS, 2 * 1024 * 1024); // 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) From 4c9e78d2f97df38545e475cefc2001943f472860 Mon Sep 17 00:00:00 2001 From: Jonathon Reinhart Date: Wed, 26 Aug 2015 08:35:03 -0400 Subject: [PATCH 18/23] samples: update sample_x86 to use new API --- samples/sample_x86.c | 319 +++++++++++++++++++++---------------------- 1 file changed, 159 insertions(+), 160 deletions(-) diff --git a/samples/sample_x86.c b/samples/sample_x86.c index 4e4a736d..14c6b234 100644 --- a/samples/sample_x86.c +++ b/samples/sample_x86.c @@ -31,41 +31,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(struct uc_struct *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(struct uc_struct *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(struct uc_struct *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(struct uc_struct *uc, uc_mem_type type, uint64_t address, int size, int64_t value, void *user_data) { switch(type) { @@ -76,13 +76,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_mem_map(uc, 0xaaaa0000, 2 * 1024*1024); // return true to indicate we want to continue return true; } } -static void hook_mem64(uch handle, uc_mem_type type, +static void hook_mem64(struct uc_struct *uc, uc_mem_type type, uint64_t address, int size, int64_t value, void *user_data) { switch(type) { @@ -100,11 +100,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(struct uc_struct *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); @@ -125,12 +125,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(struct uc_struct *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); @@ -139,13 +139,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,10 +154,10 @@ static void hook_out(uch handle, uint32_t port, int size, uint32_t value, void * static void test_i386(void) { - uch handle; + struct uc_struct *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 @@ -165,33 +165,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_mem_map(uc, ADDRESS, 2 * 1024 * 1024); // 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)); @@ -200,54 +200,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; + struct uc_struct *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_mem_map(uc, ADDRESS, 2 * 1024 * 1024); // 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)); @@ -255,13 +255,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; + struct uc_struct *uc; uc_err err; int r_ecx = 0x1234; // ECX register @@ -271,28 +271,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_mem_map(uc, ADDRESS, 2 * 1024 * 1024); // 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)); @@ -301,20 +301,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; + struct uc_struct *uc; uc_err err; - uch trace1, trace2; + uc_hook_h trace1, trace2; int r_ecx = 0x1234; // ECX register int r_edx = 0x7890; // EDX register @@ -323,33 +323,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_mem_map(uc, ADDRESS, 2 * 1024 * 1024); // 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)); @@ -358,20 +358,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; + struct uc_struct *uc; uc_err err; - uch trace1, trace2; //, trace3; + uc_hook_h trace1, trace2, trace3; uint32_t tmp; int r_ecx = 0x1234; // ECX register @@ -381,36 +381,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_mem_map(uc, ADDRESS, 2 * 1024 * 1024); // 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)); @@ -419,31 +419,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; + struct uc_struct *uc; uc_err err; - uch trace1, trace2; + uc_hook_h trace1, trace2; int r_ecx = 0x1234; // ECX register int r_edx = 0x7890; // EDX register @@ -452,33 +452,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_mem_map(uc, ADDRESS, 2 * 1024 * 1024); // 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)); @@ -487,20 +487,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; + struct uc_struct *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 @@ -509,38 +508,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_mem_map(uc, ADDRESS, 2 * 1024 * 1024); // 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)); @@ -549,19 +548,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; + struct uc_struct *uc; uc_err err; - uch trace1, trace2, trace3, trace4; + uc_hook_h trace1, trace2, trace3, trace4; int64_t rax = 0x71f3029efd49d41d; int64_t rbx = 0xd87b45277f133ddb; @@ -584,54 +583,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_mem_map(uc, ADDRESS, 2 * 1024 * 1024); // 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)); @@ -640,20 +639,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); @@ -670,12 +669,12 @@ 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_16(void) { - uch handle; + struct uc_struct *uc; uc_err err; uint8_t tmp; @@ -686,29 +685,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_mem_map(uc, 0, 8 * 1024); // 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)); @@ -718,12 +717,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) From 0202a57d32c142679f8a3565c4f86395d280402f Mon Sep 17 00:00:00 2001 From: Jonathon Reinhart Date: Wed, 26 Aug 2015 08:37:45 -0400 Subject: [PATCH 19/23] samples: update shellcode.c to use new API --- samples/shellcode.c | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/samples/shellcode.c b/samples/shellcode.c index 51dfb481..bd336882 100644 --- a/samples/shellcode.c +++ b/samples/shellcode.c @@ -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(struct uc_struct *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>> 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; + struct uc_struct *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_mem_map(uc, ADDRESS, 2 * 1024 * 1024); // 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) From db563bfcdba55facef6ee66d84a3629cbc820f0f Mon Sep 17 00:00:00 2001 From: Jonathon Reinhart Date: Wed, 26 Aug 2015 08:38:50 -0400 Subject: [PATCH 20/23] samples: update sample_m68k to use new API --- samples/sample_m68k.c | 94 +++++++++++++++++++++---------------------- 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/samples/sample_m68k.c b/samples/sample_m68k.c index 02452e5d..f482a786 100644 --- a/samples/sample_m68k.c +++ b/samples/sample_m68k.c @@ -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(struct uc_struct *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(struct uc_struct *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; + struct uc_struct *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_mem_map(uc, ADDRESS, 2 * 1024 * 1024); // 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) From e74bc0db88e13db4ecd3b5454e0aba633353a14e Mon Sep 17 00:00:00 2001 From: Jonathon Reinhart Date: Wed, 26 Aug 2015 09:29:28 -0400 Subject: [PATCH 21/23] regress: update C programs to use new API --- regress/block_test.c | 16 ++++++++-------- regress/map_crash.c | 10 +++++----- regress/sigill.c | 20 ++++++++++---------- regress/sigill2.c | 14 +++++++------- 4 files changed, 30 insertions(+), 30 deletions(-) diff --git a/regress/block_test.c b/regress/block_test.c index cc372fed..0d778222 100644 --- a/regress/block_test.c +++ b/regress/block_test.c @@ -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(struct uc_struct *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; + struct uc_struct *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); + err = uc_mem_map(uc, 0x1000000, 4096); 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); diff --git a/regress/map_crash.c b/regress/map_crash.c index 4d6bc8fe..9da92447 100644 --- a/regress/map_crash.c +++ b/regress/map_crash.c @@ -9,8 +9,8 @@ int main() { int size; uint8_t *buf; - uch uh; - uc_err err = uc_open (UC_ARCH_X86, UC_MODE_64, &uh); + struct uc_struct *uc; + uc_err err = uc_open (UC_ARCH_X86, UC_MODE_64, &uc); if (err) { fprintf (stderr, "Cannot initialize unicorn\n"); return 1; @@ -22,9 +22,9 @@ int main() { return 1; } memset (buf, 0, size); - if (!uc_mem_map (uh, UC_BUG_WRITE_ADDR, size)) { - uc_mem_write (uh, UC_BUG_WRITE_ADDR, buf, size); + if (!uc_mem_map(uc, UC_BUG_WRITE_ADDR, size)) { + uc_mem_write(uc, UC_BUG_WRITE_ADDR, buf, size); } - uc_close (&uh); + uc_close(uc); return 0; } diff --git a/regress/sigill.c b/regress/sigill.c index 099bbec3..151ad8ec 100644 --- a/regress/sigill.c +++ b/regress/sigill.c @@ -8,9 +8,9 @@ int got_sigill = 0; -void _interrupt(uch handle, uint32_t intno, void *user_data) { +void _interrupt(struct uc_struct *uc, uint32_t intno, void *user_data) { if (intno == 6) { - uc_emu_stop (handle); + uc_emu_stop(uc); got_sigill = 1; } } @@ -18,9 +18,9 @@ void _interrupt(uch handle, uint32_t intno, void *user_data) { int main() { int size; uint8_t *buf; - uch uh; - uch uh_trap; - uc_err err = uc_open (UC_ARCH_X86, UC_MODE_64, &uh); + struct uc_struct *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; @@ -32,13 +32,13 @@ int main() { return 1; } memset (buf, 0, size); - if (!uc_mem_map (uh, UC_BUG_WRITE_ADDR, size)) { - uc_mem_write (uh, UC_BUG_WRITE_ADDR, + if (!uc_mem_map(uc, UC_BUG_WRITE_ADDR, size)) { + 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; } diff --git a/regress/sigill2.c b/regress/sigill2.c index 97cd7199..2985c836 100644 --- a/regress/sigill2.c +++ b/regress/sigill2.c @@ -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); + struct uc_struct *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_mem_write (uh, UC_BUG_WRITE_ADDR, + if (!uc_mem_map(uc, UC_BUG_WRITE_ADDR, size)) { + 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; } From 0feab69a6138c6202ba4845f775dd7dd578a6cee Mon Sep 17 00:00:00 2001 From: Jonathon Reinhart Date: Wed, 2 Sep 2015 21:25:59 -0400 Subject: [PATCH 22/23] update samples to conform to uc API changes --- regress/map_write.c | 10 +++---- regress/nr_mem_test.c | 31 +++++++++++----------- regress/rep_movsb.c | 31 +++++++++++----------- regress/ro_mem_test.c | 47 +++++++++++++++++---------------- regress/timeout_segfault.c | 54 +++++++++++++++++++------------------- 5 files changed, 88 insertions(+), 85 deletions(-) diff --git a/regress/map_write.c b/regress/map_write.c index e5b94366..400b4719 100644 --- a/regress/map_write.c +++ b/regress/map_write.c @@ -8,17 +8,17 @@ int main() { - uch uh; + struct uc_struct *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; diff --git a/regress/nr_mem_test.c b/regress/nr_mem_test.c index 37c344de..1f45cb1d 100644 --- a/regress/nr_mem_test.c +++ b/regress/nr_mem_test.c @@ -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(struct uc_struct *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; + struct uc_struct *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; } diff --git a/regress/rep_movsb.c b/regress/rep_movsb.c index c9fb6f15..0b36e07c 100644 --- a/regress/rep_movsb.c +++ b/regress/rep_movsb.c @@ -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(struct uc_struct *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(struct uc_struct *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; + struct uc_struct *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 { diff --git a/regress/ro_mem_test.c b/regress/ro_mem_test.c index 06edf068..75b0d9bf 100644 --- a/regress/ro_mem_test.c +++ b/regress/ro_mem_test.c @@ -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(struct uc_struct *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(struct uc_struct *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; + struct uc_struct *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; } diff --git a/regress/timeout_segfault.c b/regress/timeout_segfault.c index a1378e6a..5c31483a 100644 --- a/regress/timeout_segfault.c +++ b/regress/timeout_segfault.c @@ -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(struct uc_struct *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(struct uc_struct *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; + struct uc_struct *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; + struct uc_struct *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) From 5b62d436a9dad171c495f7dac3a00b6ee26eee2e Mon Sep 17 00:00:00 2001 From: Jonathon Reinhart Date: Wed, 2 Sep 2015 21:44:43 -0400 Subject: [PATCH 23/23] change public APIs to use `ucengine` See #52. --- include/unicorn/unicorn.h | 39 +++++++++++++++++++------------------- regress/block_test.c | 4 ++-- regress/map_crash.c | 2 +- regress/map_write.c | 2 +- regress/nr_mem_test.c | 4 ++-- regress/rep_movsb.c | 6 +++--- regress/ro_mem_test.c | 6 +++--- regress/sigill.c | 4 ++-- regress/sigill2.c | 2 +- regress/timeout_segfault.c | 8 ++++---- samples/sample_arm.c | 8 ++++---- samples/sample_arm64.c | 6 +++--- samples/sample_m68k.c | 6 +++--- samples/sample_mips.c | 8 ++++---- samples/sample_sparc.c | 6 +++--- samples/sample_x86.c | 36 +++++++++++++++++------------------ samples/shellcode.c | 6 +++--- uc.c | 36 +++++++++++++++++------------------ 18 files changed, 95 insertions(+), 94 deletions(-) diff --git a/include/unicorn/unicorn.h b/include/unicorn/unicorn.h index e72399a7..40a32e0e 100644 --- a/include/unicorn/unicorn.h +++ b/include/unicorn/unicorn.h @@ -20,6 +20,7 @@ extern "C" { #include "platform.h" struct uc_struct; +typedef struct uc_struct ucengine; typedef size_t uc_hook_h; @@ -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)(struct uc_struct *uc, 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)(struct uc_struct *uc, 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)(struct uc_struct *uc, 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)(struct uc_struct *uc, 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)(struct uc_struct *uc, 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)(struct uc_struct *uc, 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)(struct uc_struct *uc, 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); @@ -222,13 +223,13 @@ bool uc_arch_supported(uc_arch arch); @arch: architecture type (UC_ARCH_*) @mode: hardware mode. This is combined of UC_MODE_* - @uc: pointer to struct uc_struct, 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, struct uc_struct **uc); +uc_err uc_open(uc_arch arch, uc_mode mode, ucengine **uc); /* Close UC instance: MUST do to release the handle when it is not used anymore. @@ -243,7 +244,7 @@ uc_err uc_open(uc_arch arch, uc_mode mode, struct uc_struct **uc); for detailed error). */ UNICORN_EXPORT -uc_err uc_close(struct uc_struct *uc); +uc_err uc_close(ucengine *uc); /* Report the last error number when some API function fail. @@ -254,7 +255,7 @@ uc_err uc_close(struct uc_struct *uc); @return: error code of uc_err enum type (UC_ERR_*, see above) */ UNICORN_EXPORT -uc_err uc_errno(struct uc_struct *uc); +uc_err uc_errno(ucengine *uc); /* Return a string describing given error code. @@ -278,7 +279,7 @@ const char *uc_strerror(uc_err code); for detailed error). */ UNICORN_EXPORT -uc_err uc_reg_write(struct uc_struct *uc, int regid, const void *value); +uc_err uc_reg_write(ucengine *uc, int regid, const void *value); /* Read register value. @@ -291,7 +292,7 @@ uc_err uc_reg_write(struct uc_struct *uc, int regid, const void *value); for detailed error). */ UNICORN_EXPORT -uc_err uc_reg_read(struct uc_struct *uc, int regid, void *value); +uc_err uc_reg_read(ucengine *uc, int regid, void *value); /* Write to a range of bytes in memory. @@ -307,7 +308,7 @@ uc_err uc_reg_read(struct uc_struct *uc, int regid, void *value); for detailed error). */ UNICORN_EXPORT -uc_err uc_mem_write(struct uc_struct *uc, 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. @@ -323,7 +324,7 @@ uc_err uc_mem_write(struct uc_struct *uc, uint64_t address, const uint8_t *bytes for detailed error). */ UNICORN_EXPORT -uc_err uc_mem_read(struct uc_struct *uc, 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. @@ -340,7 +341,7 @@ uc_err uc_mem_read(struct uc_struct *uc, uint64_t address, uint8_t *bytes, size_ for detailed error). */ UNICORN_EXPORT -uc_err uc_emu_start(struct uc_struct *uc, 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. @@ -353,7 +354,7 @@ uc_err uc_emu_start(struct uc_struct *uc, uint64_t begin, uint64_t until, uint64 for detailed error). */ UNICORN_EXPORT -uc_err uc_emu_stop(struct uc_struct *uc); +uc_err uc_emu_stop(ucengine *uc); /* Register callback for a hook event. @@ -371,7 +372,7 @@ uc_err uc_emu_stop(struct uc_struct *uc); for detailed error). */ UNICORN_EXPORT -uc_err uc_hook_add(struct uc_struct *uc, uc_hook_h *hh, 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. @@ -386,7 +387,7 @@ uc_err uc_hook_add(struct uc_struct *uc, uc_hook_h *hh, uc_hook_t type, void *ca for detailed error). */ UNICORN_EXPORT -uc_err uc_hook_del(struct uc_struct *uc, uc_hook_h hh); +uc_err uc_hook_del(ucengine *uc, uc_hook_h hh); typedef enum uc_prot { UC_PROT_NONE = 0, @@ -412,7 +413,7 @@ typedef enum uc_prot { for detailed error). */ UNICORN_EXPORT -uc_err uc_mem_map(struct uc_struct *uc, 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 } diff --git a/regress/block_test.c b/regress/block_test.c index 0d1ddf9f..06a0fa21 100644 --- a/regress/block_test.c +++ b/regress/block_test.c @@ -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(struct uc_struct *uc, 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,7 +27,7 @@ void cb_hookblock(struct uc_struct *uc, uint64_t address, uint32_t size, void *u } int main() { - struct uc_struct *uc; + ucengine *uc; fprintf(stderr, "# basic block callback test\n"); fprintf(stderr, "# there are only two basic blocks 0x1000000-0x10001ff and 0x1000200-0x10003ff\n"); diff --git a/regress/map_crash.c b/regress/map_crash.c index b25c2b00..e7fbf38c 100644 --- a/regress/map_crash.c +++ b/regress/map_crash.c @@ -10,7 +10,7 @@ int main() { int size; uint8_t *buf; - struct uc_struct *uc; + ucengine *uc; uc_err err = uc_open (UC_ARCH_X86, UC_MODE_64, &uc); if (err) { fprintf (stderr, "Cannot initialize unicorn\n"); diff --git a/regress/map_write.c b/regress/map_write.c index 400b4719..40fada8d 100644 --- a/regress/map_write.c +++ b/regress/map_write.c @@ -8,7 +8,7 @@ int main() { - struct uc_struct *uc; + ucengine *uc; uint8_t *buf, *buf2; int i; uc_err err; diff --git a/regress/nr_mem_test.c b/regress/nr_mem_test.c index 1f45cb1d..0e70829b 100644 --- a/regress/nr_mem_test.c +++ b/regress/nr_mem_test.c @@ -36,7 +36,7 @@ bits 32 */ // callback for tracing memory access (READ or WRITE) -static bool hook_mem_invalid(struct uc_struct *uc, 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,7 +54,7 @@ static bool hook_mem_invalid(struct uc_struct *uc, uc_mem_type type, int main(int argc, char **argv, char **envp) { - struct uc_struct *uc; + ucengine *uc; uc_hook_h trace1, trace2; uc_err err; uint32_t eax, ebx; diff --git a/regress/rep_movsb.c b/regress/rep_movsb.c index 0b36e07c..97b00c15 100644 --- a/regress/rep_movsb.c +++ b/regress/rep_movsb.c @@ -50,7 +50,7 @@ hlt static int log_num = 1; // callback for tracing instruction -static void hook_code(struct uc_struct *uc, 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(uc, addr, &opcode, 1) != UC_ERR_OK) { @@ -74,7 +74,7 @@ static void hook_code(struct uc_struct *uc, uint64_t addr, uint32_t size, void * } // callback for tracing memory access (READ or WRITE) -static void hook_mem_write(struct uc_struct *uc, 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,7 @@ static void hook_mem_write(struct uc_struct *uc, uc_mem_type type, int main(int argc, char **argv, char **envp) { - struct uc_struct *uc; + ucengine *uc; uc_hook_h trace1, trace2; uc_err err; uint8_t buf1[100], readbuf[100]; diff --git a/regress/ro_mem_test.c b/regress/ro_mem_test.c index 75b0d9bf..51b94b2f 100644 --- a/regress/ro_mem_test.c +++ b/regress/ro_mem_test.c @@ -46,7 +46,7 @@ bottom: */ // callback for tracing instruction -static void hook_code(struct uc_struct *uc, 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); @@ -57,7 +57,7 @@ static void hook_code(struct uc_struct *uc, uint64_t address, uint32_t size, voi } // callback for tracing memory access (READ or WRITE) -static bool hook_mem_invalid(struct uc_struct *uc, 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; @@ -94,7 +94,7 @@ static bool hook_mem_invalid(struct uc_struct *uc, uc_mem_type type, int main(int argc, char **argv, char **envp) { - struct uc_struct *uc; + ucengine *uc; uc_hook_h trace1, trace2; uc_err err; uint8_t bytes[8]; diff --git a/regress/sigill.c b/regress/sigill.c index 72e3be49..ad7af47f 100644 --- a/regress/sigill.c +++ b/regress/sigill.c @@ -8,7 +8,7 @@ int got_sigill = 0; -void _interrupt(struct uc_struct *uc, uint32_t intno, void *user_data) +void _interrupt(ucengine *uc, uint32_t intno, void *user_data) { if (intno == 6) { uc_emu_stop(uc); @@ -20,7 +20,7 @@ int main() { int size; uint8_t *buf; - struct uc_struct *uc; + ucengine *uc; uc_hook_h uh_trap; uc_err err = uc_open (UC_ARCH_X86, UC_MODE_64, &uc); if (err) { diff --git a/regress/sigill2.c b/regress/sigill2.c index 406dd750..1d955144 100644 --- a/regress/sigill2.c +++ b/regress/sigill2.c @@ -10,7 +10,7 @@ int main() { int size; uint8_t *buf; - struct uc_struct *uc; + ucengine *uc; uc_err err = uc_open (UC_ARCH_X86, UC_MODE_64, &uc); if (err) { diff --git a/regress/timeout_segfault.c b/regress/timeout_segfault.c index 5c31483a..2632a51f 100644 --- a/regress/timeout_segfault.c +++ b/regress/timeout_segfault.c @@ -24,19 +24,19 @@ https://github.com/unicorn-engine/unicorn/issues/78 // number of seconds to wait before timeout #define TIMEOUT 5 -static void hook_block(struct uc_struct *uc, 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(struct uc_struct *uc, 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) { - struct uc_struct *uc; + ucengine *uc; uc_err err; uc_hook_h trace1, trace2; @@ -92,7 +92,7 @@ static void test_arm(void) static void test_thumb(void) { - struct uc_struct *uc; + ucengine *uc; uc_err err; uc_hook_h trace1, trace2; diff --git a/samples/sample_arm.c b/samples/sample_arm.c index 1da06fc8..38e8590a 100644 --- a/samples/sample_arm.c +++ b/samples/sample_arm.c @@ -15,19 +15,19 @@ // memory address where emulation starts #define ADDRESS 0x10000 -static void hook_block(struct uc_struct *uc, 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(struct uc_struct *uc, 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) { - struct uc_struct *uc; + ucengine *uc; uc_err err; uc_hook_h trace1, trace2; @@ -83,7 +83,7 @@ static void test_arm(void) static void test_thumb(void) { - struct uc_struct *uc; + ucengine *uc; uc_err err; uc_hook_h trace1, trace2; diff --git a/samples/sample_arm64.c b/samples/sample_arm64.c index de24ab37..61a58f20 100644 --- a/samples/sample_arm64.c +++ b/samples/sample_arm64.c @@ -14,19 +14,19 @@ // memory address where emulation starts #define ADDRESS 0x10000 -static void hook_block(struct uc_struct *uc, 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(struct uc_struct *uc, 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) { - struct uc_struct *uc; + ucengine *uc; uc_err err; uc_hook_h trace1, trace2; diff --git a/samples/sample_m68k.c b/samples/sample_m68k.c index a640da72..049041cb 100644 --- a/samples/sample_m68k.c +++ b/samples/sample_m68k.c @@ -12,19 +12,19 @@ // memory address where emulation starts #define ADDRESS 0x10000 -static void hook_block(struct uc_struct *uc, 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(struct uc_struct *uc, 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) { - struct uc_struct *uc; + ucengine *uc; uc_hook_h trace1, trace2; uc_err err; diff --git a/samples/sample_mips.c b/samples/sample_mips.c index 6fc13229..0806f60e 100644 --- a/samples/sample_mips.c +++ b/samples/sample_mips.c @@ -15,19 +15,19 @@ // memory address where emulation starts #define ADDRESS 0x10000 -static void hook_block(struct uc_struct *uc, 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(struct uc_struct *uc, 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) { - struct uc_struct *uc; + ucengine *uc; uc_err err; uc_hook_h trace1, trace2; @@ -76,7 +76,7 @@ static void test_mips_eb(void) static void test_mips_el(void) { - struct uc_struct *uc; + ucengine *uc; uc_err err; uc_hook_h trace1, trace2; diff --git a/samples/sample_sparc.c b/samples/sample_sparc.c index b9c2404e..36536680 100644 --- a/samples/sample_sparc.c +++ b/samples/sample_sparc.c @@ -15,19 +15,19 @@ // memory address where emulation starts #define ADDRESS 0x10000 -static void hook_block(struct uc_struct *uc, 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(struct uc_struct *uc, 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) { - struct uc_struct *uc; + ucengine *uc; uc_err err; uc_hook_h trace1, trace2; diff --git a/samples/sample_x86.c b/samples/sample_x86.c index af99075b..9bdd8232 100644 --- a/samples/sample_x86.c +++ b/samples/sample_x86.c @@ -32,13 +32,13 @@ #define ADDRESS 0x1000000 // callback for tracing basic blocks -static void hook_block(struct uc_struct *uc, 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(struct uc_struct *uc, 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); @@ -52,7 +52,7 @@ static void hook_code(struct uc_struct *uc, uint64_t address, uint32_t size, voi } // callback for tracing instruction -static void hook_code64(struct uc_struct *uc, 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; @@ -66,7 +66,7 @@ static void hook_code64(struct uc_struct *uc, uint64_t address, uint32_t size, v } // callback for tracing memory access (READ or WRITE) -static bool hook_mem_invalid(struct uc_struct *uc, 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) { @@ -83,7 +83,7 @@ static bool hook_mem_invalid(struct uc_struct *uc, uc_mem_type type, } } -static void hook_mem64(struct uc_struct *uc, 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,7 +101,7 @@ static void hook_mem64(struct uc_struct *uc, uc_mem_type type, // callback for IN instruction (X86). // this returns the data read from the port -static uint32_t hook_in(struct uc_struct *uc, 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; @@ -126,7 +126,7 @@ static uint32_t hook_in(struct uc_struct *uc, uint32_t port, int size, void *use } // callback for OUT instruction (X86). -static void hook_out(struct uc_struct *uc, 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; @@ -154,7 +154,7 @@ static void hook_out(struct uc_struct *uc, uint32_t port, int size, uint32_t val } // callback for SYSCALL instruction (X86). -static void hook_syscall(struct uc_struct *uc, void *user_data) +static void hook_syscall(ucengine *uc, void *user_data) { uint64_t rax; @@ -168,7 +168,7 @@ static void hook_syscall(struct uc_struct *uc, void *user_data) static void test_i386(void) { - struct uc_struct *uc; + ucengine *uc; uc_err err; uint32_t tmp; uc_hook_h trace1, trace2; @@ -230,7 +230,7 @@ static void test_i386(void) static void test_i386_jump(void) { - struct uc_struct *uc; + ucengine *uc; uc_err err; uc_hook_h trace1, trace2; @@ -275,7 +275,7 @@ static void test_i386_jump(void) // emulate code that loop forever static void test_i386_loop(void) { - struct uc_struct *uc; + ucengine *uc; uc_err err; int r_ecx = 0x1234; // ECX register @@ -326,7 +326,7 @@ static void test_i386_loop(void) // emulate code that read invalid memory static void test_i386_invalid_mem_read(void) { - struct uc_struct *uc; + ucengine *uc; uc_err err; uc_hook_h trace1, trace2; @@ -383,7 +383,7 @@ static void test_i386_invalid_mem_read(void) // emulate code that read invalid memory static void test_i386_invalid_mem_write(void) { - struct uc_struct *uc; + ucengine *uc; uc_err err; uc_hook_h trace1, trace2, trace3; uint32_t tmp; @@ -455,7 +455,7 @@ static void test_i386_invalid_mem_write(void) // emulate code that jump to invalid memory static void test_i386_jump_invalid(void) { - struct uc_struct *uc; + ucengine *uc; uc_err err; uc_hook_h trace1, trace2; @@ -511,7 +511,7 @@ static void test_i386_jump_invalid(void) static void test_i386_inout(void) { - struct uc_struct *uc; + ucengine *uc; uc_err err; uc_hook_h trace1, trace2, trace3, trace4; @@ -572,7 +572,7 @@ static void test_i386_inout(void) static void test_x86_64(void) { - struct uc_struct *uc; + ucengine *uc; uc_err err; uc_hook_h trace1, trace2, trace3, trace4; @@ -688,7 +688,7 @@ static void test_x86_64(void) static void test_x86_64_syscall(void) { - struct uc_struct *uc; + ucengine *uc; uc_hook_h trace1; uc_err err; @@ -739,7 +739,7 @@ static void test_x86_64_syscall(void) static void test_x86_16(void) { - struct uc_struct *uc; + ucengine *uc; uc_err err; uint8_t tmp; diff --git a/samples/shellcode.c b/samples/shellcode.c index 62fe30e5..f185db97 100644 --- a/samples/shellcode.c +++ b/samples/shellcode.c @@ -20,7 +20,7 @@ #define MIN(a, b) (a < b? a : b) // callback for tracing instruction -static void hook_code(struct uc_struct *uc, 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]; @@ -43,7 +43,7 @@ static void hook_code(struct uc_struct *uc, uint64_t address, uint32_t size, voi #define MIN(a, b) (a < b? a : b) // callback for handling interrupt // ref: http://syscalls.kernelgrok.com/ -static void hook_intr(struct uc_struct *uc, 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; @@ -88,7 +88,7 @@ static void hook_intr(struct uc_struct *uc, uint32_t intno, void *user_data) static void test_i386(void) { - struct uc_struct *uc; + ucengine *uc; uc_err err; uc_hook_h trace1, trace2; diff --git a/uc.c b/uc.c index efe02622..cc25918a 100644 --- a/uc.c +++ b/uc.c @@ -44,7 +44,7 @@ unsigned int uc_version(unsigned int *major, unsigned int *minor) UNICORN_EXPORT -uc_err uc_errno(struct uc_struct *uc) +uc_err uc_errno(ucengine *uc) { return uc->errnum; } @@ -121,7 +121,7 @@ bool uc_arch_supported(uc_arch arch) UNICORN_EXPORT -uc_err uc_open(uc_arch arch, uc_mode mode, struct uc_struct **result) +uc_err uc_open(uc_arch arch, uc_mode mode, ucengine **result) { struct uc_struct *uc; @@ -240,7 +240,7 @@ uc_err uc_open(uc_arch arch, uc_mode mode, struct uc_struct **result) UNICORN_EXPORT -uc_err uc_close(struct uc_struct *uc) +uc_err uc_close(ucengine *uc) { if (uc->release) uc->release(uc->tcg_ctx); @@ -280,7 +280,7 @@ uc_err uc_close(struct uc_struct *uc) UNICORN_EXPORT -uc_err uc_reg_read(struct uc_struct *uc, int regid, void *value) +uc_err uc_reg_read(ucengine *uc, int regid, void *value) { if (uc->reg_read) uc->reg_read(uc, regid, value); @@ -292,7 +292,7 @@ uc_err uc_reg_read(struct uc_struct *uc, int regid, void *value) UNICORN_EXPORT -uc_err uc_reg_write(struct uc_struct *uc, int regid, const void *value) +uc_err uc_reg_write(ucengine *uc, int regid, const void *value) { if (uc->reg_write) uc->reg_write(uc, regid, value); @@ -305,7 +305,7 @@ uc_err uc_reg_write(struct uc_struct *uc, 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; @@ -324,7 +324,7 @@ static bool check_mem_area(struct uc_struct *uc, uint64_t address, size_t size) UNICORN_EXPORT -uc_err uc_mem_read(struct uc_struct *uc, 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) { if (!check_mem_area(uc, address, size)) return UC_ERR_MEM_READ; @@ -352,7 +352,7 @@ uc_err uc_mem_read(struct uc_struct *uc, uint64_t address, uint8_t *bytes, size_ } UNICORN_EXPORT -uc_err uc_mem_write(struct uc_struct *uc, 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) { if (!check_mem_area(uc, address, size)) return UC_ERR_MEM_WRITE; @@ -392,7 +392,7 @@ uc_err uc_mem_write(struct uc_struct *uc, uint64_t address, const uint8_t *bytes #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 { @@ -411,7 +411,7 @@ static void *_timeout_fn(void *arg) return NULL; } -static void enable_emu_timer(struct uc_struct *uc, uint64_t timeout) +static void enable_emu_timer(ucengine *uc, uint64_t timeout) { uc->timeout = timeout; qemu_thread_create(uc, &uc->timer, "timeout", _timeout_fn, @@ -419,7 +419,7 @@ static void enable_emu_timer(struct uc_struct *uc, uint64_t timeout) } UNICORN_EXPORT -uc_err uc_emu_start(struct uc_struct* uc, 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) { // reset the counter uc->emu_counter = 0; @@ -502,7 +502,7 @@ uc_err uc_emu_start(struct uc_struct* uc, uint64_t begin, uint64_t until, uint64 UNICORN_EXPORT -uc_err uc_emu_stop(struct uc_struct *uc) +uc_err uc_emu_stop(ucengine *uc) { if (uc->emulation_done) return UC_ERR_OK; @@ -515,7 +515,7 @@ uc_err uc_emu_stop(struct uc_struct *uc) } -static int _hook_code(struct uc_struct *uc, int type, uint64_t begin, uint64_t end, +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; @@ -530,7 +530,7 @@ static int _hook_code(struct uc_struct *uc, int type, uint64_t begin, uint64_t e } -static uc_err _hook_mem_access(struct uc_struct *uc, 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, uc_hook_h *hh) { @@ -546,7 +546,7 @@ static uc_err _hook_mem_access(struct uc_struct *uc, uc_hook_t type, } UNICORN_EXPORT -uc_err uc_mem_map(struct uc_struct *uc, 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; @@ -579,7 +579,7 @@ uc_err uc_mem_map(struct uc_struct *uc, uint64_t address, size_t size, uint32_t 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; @@ -682,7 +682,7 @@ static uc_err _hook_insn(struct uc_struct *uc, unsigned int insn_id, void *callb } UNICORN_EXPORT -uc_err uc_hook_add(struct uc_struct *uc, uc_hook_h *hh, 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, ...) { va_list valist; int ret = UC_ERR_OK; @@ -738,7 +738,7 @@ uc_err uc_hook_add(struct uc_struct *uc, uc_hook_h *hh, uc_hook_t type, void *ca } UNICORN_EXPORT -uc_err uc_hook_del(struct uc_struct *uc, uc_hook_h hh) +uc_err uc_hook_del(ucengine *uc, uc_hook_h hh) { return hook_del(uc, hh); }