From b1d41d414bc69bea5b645da997319119a84741be Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Sat, 10 Oct 2015 18:01:47 +0800 Subject: [PATCH] on some hook events, uc_hook_add() should not allow more than 1 handler. this add UC_ERR_HOOK_EXIST error type --- bindings/go/unicorn/unicorn_const.go | 1 + bindings/java/unicorn/UnicornConst.java | 1 + bindings/python/unicorn/unicorn_const.py | 1 + include/unicorn/unicorn.h | 1 + tests/regress/hook_add_crash.py | 7 ++-- uc.c | 45 +++++++++++++++++++----- 6 files changed, 46 insertions(+), 10 deletions(-) diff --git a/bindings/go/unicorn/unicorn_const.go b/bindings/go/unicorn/unicorn_const.go index d9ba286b..2f80dea3 100644 --- a/bindings/go/unicorn/unicorn_const.go +++ b/bindings/go/unicorn/unicorn_const.go @@ -52,6 +52,7 @@ const ( ERR_READ_UNALIGNED = 16 ERR_WRITE_UNALIGNED = 17 ERR_FETCH_UNALIGNED = 18 + ERR_HOOK_EXIST = 19 MEM_READ = 16 MEM_WRITE = 17 MEM_FETCH = 18 diff --git a/bindings/java/unicorn/UnicornConst.java b/bindings/java/unicorn/UnicornConst.java index a18dcfe9..6139ecf5 100644 --- a/bindings/java/unicorn/UnicornConst.java +++ b/bindings/java/unicorn/UnicornConst.java @@ -54,6 +54,7 @@ public interface UnicornConst { public static final int UC_ERR_READ_UNALIGNED = 16; public static final int UC_ERR_WRITE_UNALIGNED = 17; public static final int UC_ERR_FETCH_UNALIGNED = 18; + public static final int UC_ERR_HOOK_EXIST = 19; public static final int UC_MEM_READ = 16; public static final int UC_MEM_WRITE = 17; public static final int UC_MEM_FETCH = 18; diff --git a/bindings/python/unicorn/unicorn_const.py b/bindings/python/unicorn/unicorn_const.py index 36706e7e..48162807 100644 --- a/bindings/python/unicorn/unicorn_const.py +++ b/bindings/python/unicorn/unicorn_const.py @@ -50,6 +50,7 @@ UC_ERR_ARG = 15 UC_ERR_READ_UNALIGNED = 16 UC_ERR_WRITE_UNALIGNED = 17 UC_ERR_FETCH_UNALIGNED = 18 +UC_ERR_HOOK_EXIST = 19 UC_MEM_READ = 16 UC_MEM_WRITE = 17 UC_MEM_FETCH = 18 diff --git a/include/unicorn/unicorn.h b/include/unicorn/unicorn.h index bc4edd40..b812b473 100644 --- a/include/unicorn/unicorn.h +++ b/include/unicorn/unicorn.h @@ -124,6 +124,7 @@ typedef enum uc_err { UC_ERR_READ_UNALIGNED, // Unaligned read UC_ERR_WRITE_UNALIGNED, // Unaligned write UC_ERR_FETCH_UNALIGNED, // Unaligned fetch + UC_ERR_HOOK_EXIST, // hook for this event already existed } uc_err; diff --git a/tests/regress/hook_add_crash.py b/tests/regress/hook_add_crash.py index 64b6f51b..342e7faa 100755 --- a/tests/regress/hook_add_crash.py +++ b/tests/regress/hook_add_crash.py @@ -9,5 +9,8 @@ def hook_mem_read_unmapped(mu, access, address, size, value, user_data): mu = unicorn.Uc(unicorn.UC_ARCH_X86, unicorn.UC_MODE_32) -for x in range(0, 1000): - mu.hook_add(unicorn.UC_HOOK_MEM_READ_UNMAPPED, hook_mem_read_unmapped, None) +try: + for x in range(0, 1000): + mu.hook_add(unicorn.UC_HOOK_MEM_READ_UNMAPPED, hook_mem_read_unmapped, None) +except unicorn.UcError as e: + print("ERROR: %s" % e) diff --git a/uc.c b/uc.c index b87d1a63..bb45fa5e 100644 --- a/uc.c +++ b/uc.c @@ -89,13 +89,14 @@ const char *uc_strerror(uc_err code) return "Fetch from non-executable memory (UC_ERR_FETCH_PROT)"; case UC_ERR_ARG: return "Invalid argumet (UC_ERR_ARG)"; - case UC_ERR_READ_UNALIGNED: return "Read from unaligned memory (UC_ERR_READ_UNALIGNED)"; case UC_ERR_WRITE_UNALIGNED: return "Write to unaligned memory (UC_ERR_WRITE_UNALIGNED)"; case UC_ERR_FETCH_UNALIGNED: return "Fetch from unaligned memory (UC_ERR_FETCH_UNALIGNED)"; + case UC_ERR_HOOK_EXIST: + return "Hook for this type event already existed (UC_ERR_HOOK_EXIST)"; } } @@ -538,7 +539,7 @@ static int _hook_code(uc_engine *uc, int type, uint64_t begin, uint64_t end, i = hook_add(uc, type, begin, end, callback, user_data); if (i == 0) - return UC_ERR_NOMEM; // FIXME + return UC_ERR_NOMEM; *hh = i; @@ -554,7 +555,7 @@ static uc_err _hook_mem_access(uc_engine *uc, uc_hook_type type, i = hook_add(uc, type, begin, end, callback, user_data); if (i == 0) - return UC_ERR_NOMEM; // FIXME + return UC_ERR_NOMEM; *hh = i; @@ -833,7 +834,24 @@ static uc_err _hook_mem_invalid(struct uc_struct* uc, int type, uc_cb_eventmem_t { size_t i; - // FIXME: only one event handler at the same time + // only one event handler at the same time + if ((type & UC_HOOK_MEM_READ_UNMAPPED) != 0 && (uc->hook_mem_read_idx != 0)) + return UC_ERR_HOOK_EXIST; + + if ((type & UC_HOOK_MEM_READ_PROT) != 0 && (uc->hook_mem_read_prot_idx != 0)) + return UC_ERR_HOOK_EXIST; + + if ((type & UC_HOOK_MEM_WRITE_UNMAPPED) != 0 && (uc->hook_mem_write_idx != 0)) + return UC_ERR_HOOK_EXIST; + + if ((type & UC_HOOK_MEM_WRITE_PROT) != 0 && (uc->hook_mem_write_prot_idx != 0)) + return UC_ERR_HOOK_EXIST; + + if ((type & UC_HOOK_MEM_FETCH_UNMAPPED) != 0 && (uc->hook_mem_fetch_idx != 0)) + return UC_ERR_HOOK_EXIST; + + if ((type & UC_HOOK_MEM_FETCH_PROT) != 0 && (uc->hook_mem_fetch_prot_idx != 0)) + return UC_ERR_HOOK_EXIST; i = hook_find_new(uc); if (i) { @@ -863,7 +881,9 @@ static uc_err _hook_intr(struct uc_struct* uc, void *callback, { size_t i; - // FIXME: only one event handler at the same time + // only one event handler at the same time + if (uc->hook_intr_idx) + return UC_ERR_HOOK_EXIST; i = hook_find_new(uc); if (i) { @@ -888,7 +908,10 @@ static uc_err _hook_insn(struct uc_struct *uc, unsigned int insn_id, void *callb switch(insn_id) { default: break; case UC_X86_INS_OUT: - // FIXME: only one event handler at the same time + // only one event handler at the same time + if (uc->hook_out_idx) + return UC_ERR_HOOK_EXIST; + i = hook_find_new(uc); if (i) { uc->hook_callbacks[i].callback = callback; @@ -899,7 +922,10 @@ static uc_err _hook_insn(struct uc_struct *uc, unsigned int insn_id, void *callb } else return UC_ERR_NOMEM; case UC_X86_INS_IN: - // FIXME: only one event handler at the same time + // only one event handler at the same time + if (uc->hook_in_idx) + return UC_ERR_HOOK_EXIST; + i = hook_find_new(uc); if (i) { uc->hook_callbacks[i].callback = callback; @@ -911,7 +937,10 @@ static uc_err _hook_insn(struct uc_struct *uc, unsigned int insn_id, void *callb return UC_ERR_NOMEM; case UC_X86_INS_SYSCALL: case UC_X86_INS_SYSENTER: - // FIXME: only one event handler at the same time + // only one event handler at the same time + if (uc->hook_syscall_idx) + return UC_ERR_HOOK_EXIST; + i = hook_find_new(uc); if (i) { uc->hook_callbacks[i].callback = callback;