diff --git a/include/unicorn/unicorn.h b/include/unicorn/unicorn.h index ad2d551e..4947d199 100644 --- a/include/unicorn/unicorn.h +++ b/include/unicorn/unicorn.h @@ -184,6 +184,16 @@ typedef enum uc_hook_type { typedef void (*uc_cb_hookmem_t)(uc_engine *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) +// @type: this memory is being READ, or WRITE +// @address: address where the code is being executed +// @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 +// @return: return true to continue, or false to stop program (due to invalid memory). +typedef bool (*uc_cb_eventmem_t)(uc_engine *uc, uc_mem_type type, + uint64_t address, int size, int64_t value, void *user_data); + /* Return combined API version & major and minor version numbers. diff --git a/qemu/softmmu_template.h b/qemu/softmmu_template.h index 19addf35..9e8afd46 100644 --- a/qemu/softmmu_template.h +++ b/qemu/softmmu_template.h @@ -191,7 +191,7 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx, mem_access = UC_MEM_READ; error_code = UC_ERR_READ_INVALID; #endif - if (uc->hook_mem_idx != 0 && ((uc_cb_hookmem_t)uc->hook_callbacks[uc->hook_mem_idx].callback)( + if (uc->hook_mem_idx != 0 && ((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_idx].callback)( uc, mem_access, addr, DATA_SIZE, 0, uc->hook_callbacks[uc->hook_mem_idx].user_data)) { env->invalid_error = UC_ERR_OK; @@ -208,7 +208,7 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx, #if defined(SOFTMMU_CODE_ACCESS) // Unicorn: callback on fetch from NX if (mr != NULL && !(mr->perms & UC_PROT_EXEC)) { // non-executable - if (uc->hook_mem_idx != 0 && ((uc_cb_hookmem_t)uc->hook_callbacks[uc->hook_mem_idx].callback)( + if (uc->hook_mem_idx != 0 && ((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_idx].callback)( uc, UC_MEM_EXEC_PROT, addr, DATA_SIZE, 0, uc->hook_callbacks[uc->hook_mem_idx].user_data)) { env->invalid_error = UC_ERR_OK; @@ -233,7 +233,7 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx, // Unicorn: callback on non-readable memory if (READ_ACCESS_TYPE == MMU_DATA_LOAD && mr != NULL && !(mr->perms & UC_PROT_READ)) { //non-readable - if (uc->hook_mem_idx != 0 && ((uc_cb_hookmem_t)uc->hook_callbacks[uc->hook_mem_idx].callback)( + if (uc->hook_mem_idx != 0 && ((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_idx].callback)( uc, UC_MEM_READ_PROT, addr, DATA_SIZE, 0, uc->hook_callbacks[uc->hook_mem_idx].user_data)) { env->invalid_error = UC_ERR_OK; @@ -381,7 +381,7 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx, mem_access = UC_MEM_READ; error_code = UC_ERR_READ_INVALID; #endif - if (uc->hook_mem_idx != 0 && ((uc_cb_hookmem_t)uc->hook_callbacks[uc->hook_mem_idx].callback)( + if (uc->hook_mem_idx != 0 && ((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_idx].callback)( uc, mem_access, addr, DATA_SIZE, 0, uc->hook_callbacks[uc->hook_mem_idx].user_data)) { env->invalid_error = UC_ERR_OK; @@ -398,7 +398,7 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx, #if defined(SOFTMMU_CODE_ACCESS) // Unicorn: callback on fetch from NX if (mr != NULL && !(mr->perms & UC_PROT_EXEC)) { // non-executable - if (uc->hook_mem_idx != 0 && ((uc_cb_hookmem_t)uc->hook_callbacks[uc->hook_mem_idx].callback)( + if (uc->hook_mem_idx != 0 && ((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_idx].callback)( uc, UC_MEM_EXEC_PROT, addr, DATA_SIZE, 0, uc->hook_callbacks[uc->hook_mem_idx].user_data)) { env->invalid_error = UC_ERR_OK; @@ -423,7 +423,7 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx, // Unicorn: callback on non-readable memory if (READ_ACCESS_TYPE == MMU_DATA_LOAD && mr != NULL && !(mr->perms & UC_PROT_READ)) { //non-readable - if (uc->hook_mem_idx != 0 && ((uc_cb_hookmem_t)uc->hook_callbacks[uc->hook_mem_idx].callback)( + if (uc->hook_mem_idx != 0 && ((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_idx].callback)( uc, UC_MEM_READ_PROT, addr, DATA_SIZE, 0, uc->hook_callbacks[uc->hook_mem_idx].user_data)) { env->invalid_error = UC_ERR_OK; @@ -609,7 +609,7 @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val, // Unicorn: callback on invalid memory if (uc->hook_mem_idx && mr == NULL) { - if (!((uc_cb_hookmem_t)uc->hook_callbacks[uc->hook_mem_idx].callback)( + if (!((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_idx].callback)( uc, UC_MEM_WRITE, addr, DATA_SIZE, (int64_t)val, uc->hook_callbacks[uc->hook_mem_idx].user_data)) { // save error & quit @@ -625,7 +625,7 @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val, // Unicorn: callback on non-writable memory if (mr != NULL && !(mr->perms & UC_PROT_WRITE)) { //non-writable - if (uc->hook_mem_idx != 0 && ((uc_cb_hookmem_t)uc->hook_callbacks[uc->hook_mem_idx].callback)( + if (uc->hook_mem_idx != 0 && ((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_idx].callback)( uc, UC_MEM_WRITE_PROT, addr, DATA_SIZE, (int64_t)val, uc->hook_callbacks[uc->hook_mem_idx].user_data)) { env->invalid_error = UC_ERR_OK; @@ -755,7 +755,7 @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val, // Unicorn: callback on invalid memory if (uc->hook_mem_idx && mr == NULL) { - if (!((uc_cb_hookmem_t)uc->hook_callbacks[uc->hook_mem_idx].callback)( + if (!((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_idx].callback)( uc, UC_MEM_WRITE, addr, DATA_SIZE, (int64_t)val, uc->hook_callbacks[uc->hook_mem_idx].user_data)) { // save error & quit @@ -771,7 +771,7 @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val, // Unicorn: callback on non-writable memory if (mr != NULL && !(mr->perms & UC_PROT_WRITE)) { //non-writable - if (uc->hook_mem_idx != 0 && ((uc_cb_hookmem_t)uc->hook_callbacks[uc->hook_mem_idx].callback)( + if (uc->hook_mem_idx != 0 && ((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_idx].callback)( uc, UC_MEM_WRITE_PROT, addr, DATA_SIZE, (int64_t)val, uc->hook_callbacks[uc->hook_mem_idx].user_data)) { env->invalid_error = UC_ERR_OK; diff --git a/uc.c b/uc.c index 4f34a6b4..2d97b7c9 100644 --- a/uc.c +++ b/uc.c @@ -830,7 +830,7 @@ MemoryRegion *memory_mapping(struct uc_struct* uc, uint64_t address) return NULL; } -static uc_err _hook_mem_invalid(struct uc_struct* uc, uc_cb_hookmem_t callback, +static uc_err _hook_mem_invalid(struct uc_struct* uc, uc_cb_eventmem_t callback, void *user_data, uc_hook *evh) { size_t i;