From 4b9efdc986616b6b7b70d7c188b267f95237931e Mon Sep 17 00:00:00 2001 From: bulaza Date: Sat, 13 May 2017 13:16:17 -0400 Subject: [PATCH] Adding INSN hook checks for x86 (#833) * adding INSN hook checking for x86 * tabs to spaces * need to return bool not uc_err * fixed conditional after switching to bool --- include/uc_priv.h | 5 +++++ qemu/target-i386/unicorn.c | 14 +++++++++++++- uc.c | 7 +++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/include/uc_priv.h b/include/uc_priv.h index 9b15bbfe..5c47fb91 100644 --- a/include/uc_priv.h +++ b/include/uc_priv.h @@ -78,6 +78,9 @@ typedef bool (*uc_args_int_t)(int intno); // some architecture redirect virtual memory to physical memory like Mips typedef uint64_t (*uc_mem_redirect_t)(uint64_t address); +// validate if Unicorn supports hooking a given instruction +typedef bool(*uc_insn_hook_validate)(uint32_t insn_enum); + struct hook { int type; // UC_HOOK_* int insn; // instruction for HOOK_INSN @@ -169,6 +172,8 @@ struct uc_struct { // TODO: remove current_cpu, as it's a flag for something else ("cpu running"?) CPUState *cpu, *current_cpu; + uc_insn_hook_validate insn_hook_validate; + MemoryRegion *system_memory; // qemu/exec.c MemoryRegion io_mem_rom; // qemu/exec.c MemoryRegion io_mem_notdirty; // qemu/exec.c diff --git a/qemu/target-i386/unicorn.c b/qemu/target-i386/unicorn.c index 08ea9a11..8fc8c410 100644 --- a/qemu/target-i386/unicorn.c +++ b/qemu/target-i386/unicorn.c @@ -171,7 +171,7 @@ static int x86_msr_read(struct uc_struct *uc, uc_x86_msr *msr) helper_rdmsr(env); msr->value = ((uint32_t)env->regs[R_EAX]) | - ((uint64_t)((uint32_t)env->regs[R_EDX]) << 32); + ((uint64_t)((uint32_t)env->regs[R_EDX]) << 32); env->regs[R_EAX] = eax; env->regs[R_ECX] = ecx; @@ -1335,6 +1335,17 @@ static bool x86_stop_interrupt(int intno) void pc_machine_init(struct uc_struct *uc); +static bool x86_insn_hook_validate(uint32_t insn_enum) +{ + //for x86 we can only hook IN, OUT, and SYSCALL + if (insn_enum != UC_X86_INS_IN + && insn_enum != UC_X86_INS_OUT + && insn_enum != UC_X86_INS_SYSCALL) { + return false; + } + return true; +} + DEFAULT_VISIBILITY void x86_uc_init(struct uc_struct* uc) { @@ -1350,6 +1361,7 @@ void x86_uc_init(struct uc_struct* uc) uc->release = x86_release; uc->set_pc = x86_set_pc; uc->stop_interrupt = x86_stop_interrupt; + uc->insn_hook_validate = x86_insn_hook_validate; uc_common_init(uc); } diff --git a/uc.c b/uc.c index 370f7b95..192b67d0 100644 --- a/uc.c +++ b/uc.c @@ -1036,6 +1036,13 @@ uc_err uc_hook_add(uc_engine *uc, uc_hook *hh, int type, void *callback, hook->insn = va_arg(valist, int); va_end(valist); + if (uc->insn_hook_validate) { + if (! uc->insn_hook_validate(hook->insn)) { + free(hook); + return UC_ERR_HOOK; + } + } + if (list_append(&uc->hook[UC_HOOK_INSN_IDX], hook) == NULL) { free(hook); return UC_ERR_NOMEM;