diff --git a/bindings/go/unicorn/hook.go b/bindings/go/unicorn/hook.go index bfa72c80..c286f08f 100644 --- a/bindings/go/unicorn/hook.go +++ b/bindings/go/unicorn/hook.go @@ -71,10 +71,7 @@ func (u *uc) HookAdd(htype int, cb interface{}, extra ...uint64) (Hook, error) { case HOOK_BLOCK, HOOK_CODE: rangeMode = true callback = C.hookCode_cgo - case HOOK_MEM_INVALID: - rangeMode = true - callback = C.hookMemInvalid_cgo - case HOOK_MEM_READ, HOOK_MEM_WRITE, HOOK_MEM_READ_WRITE: + case HOOK_MEM_READ, HOOK_MEM_WRITE, HOOK_MEM_READ | HOOK_MEM_WRITE: rangeMode = true callback = C.hookMemAccess_cgo case HOOK_INTR: @@ -92,7 +89,14 @@ func (u *uc) HookAdd(htype int, cb interface{}, extra ...uint64) (Hook, error) { return 0, errors.New("Unknown instruction type.") } default: - return 0, errors.New("Unknown hook type.") + // special case for mask + if htype&(HOOK_MEM_READ_INVALID|HOOK_MEM_WRITE_INVALID|HOOK_MEM_FETCH_INVALID| + HOOK_MEM_READ_PROT|HOOK_MEM_WRITE_PROT|HOOK_MEM_FETCH_PROT) != 0 { + rangeMode = true + callback = C.hookMemInvalid_cgo + } else { + return 0, errors.New("Unknown hook type.") + } } var h2 C.uc_hook data := &HookData{u, cb} diff --git a/include/unicorn/unicorn.h b/include/unicorn/unicorn.h index 21661f0c..75f47064 100644 --- a/include/unicorn/unicorn.h +++ b/include/unicorn/unicorn.h @@ -181,7 +181,20 @@ typedef enum uc_hook_type { UC_HOOK_MEM_FETCH = 1 << 12, // Hook memory fetch for execution events } uc_hook_type; -// Callback function for hooking memory (UC_HOOK_MEM_*) +// hook type for all events of unmapped memory access +#define UC_HOOK_MEM_INVALID (UC_HOOK_MEM_READ_INVALID + UC_HOOK_MEM_WRITE_INVALID + UC_HOOK_MEM_FETCH_INVALID) +// hook type for all events of illegal protected memory access +#define UC_HOOK_MEM_PROT (UC_HOOK_MEM_READ_PROT + UC_HOOK_MEM_WRITE_PROT + UC_HOOK_MEM_FETCH_PROT) +// hook type for all events of illegal read memory access +#define UC_HOOK_MEM_READ_ERR (UC_HOOK_MEM_READ_PROT + UC_HOOK_MEM_READ_INVALID) +// hook type for all events of illegal write memory access +#define UC_HOOK_MEM_WRITE_ERR (UC_HOOK_MEM_WRITE_PROT + UC_HOOK_MEM_WRITE_INVALID) +// hook type for all events of illegal fetch memory access +#define UC_HOOK_MEM_FETCH_ERR (UC_HOOK_MEM_FETCH_PROT + UC_HOOK_MEM_FETCH_INVALID) +// hook type for all events of illegal memory access +#define UC_HOOK_MEM_ERR (UC_HOOK_MEM_INVALID + UC_HOOK_MEM_PROT) + +// Callback function for hooking memory (UC_MEM_READ, UC_MEM_WRITE & UC_MEM_FETCH) // @type: this memory is being READ, or WRITE // @address: address where the code is being executed // @size: size of data being read or written @@ -190,7 +203,8 @@ 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) +// Callback function for handling invalid memory access events (UC_MEM_*_INVALID and +// UC_MEM_*PROT events) // @type: this memory is being READ, or WRITE // @address: address where the code is being executed // @size: size of data being read or written diff --git a/samples/mem_apis.c b/samples/mem_apis.c index fea1a834..28f2b60c 100644 --- a/samples/mem_apis.c +++ b/samples/mem_apis.c @@ -147,8 +147,7 @@ static void do_nx_demo(bool cause_fault) // intercept code and invalid memory events if (uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)1, (uint64_t)0) != UC_ERR_OK || - uc_hook_add(uc, &trace1, - UC_HOOK_MEM_READ_INVALID | UC_HOOK_MEM_WRITE_INVALID | UC_HOOK_MEM_FETCH_INVALID | UC_HOOK_MEM_FETCH_PROT | UC_HOOK_MEM_WRITE_PROT | UC_HOOK_MEM_READ_PROT, + uc_hook_add(uc, &trace1, UC_HOOK_MEM_ERR, hook_mem_invalid, NULL) != UC_ERR_OK) { printf("not ok - Failed to install hooks\n"); return;