mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2024-12-23 00:35:34 +00:00
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
This commit is contained in:
parent
4b50ca5cec
commit
4b9efdc986
|
@ -78,6 +78,9 @@ typedef bool (*uc_args_int_t)(int intno);
|
||||||
// some architecture redirect virtual memory to physical memory like Mips
|
// some architecture redirect virtual memory to physical memory like Mips
|
||||||
typedef uint64_t (*uc_mem_redirect_t)(uint64_t address);
|
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 {
|
struct hook {
|
||||||
int type; // UC_HOOK_*
|
int type; // UC_HOOK_*
|
||||||
int insn; // instruction for HOOK_INSN
|
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"?)
|
// TODO: remove current_cpu, as it's a flag for something else ("cpu running"?)
|
||||||
CPUState *cpu, *current_cpu;
|
CPUState *cpu, *current_cpu;
|
||||||
|
|
||||||
|
uc_insn_hook_validate insn_hook_validate;
|
||||||
|
|
||||||
MemoryRegion *system_memory; // qemu/exec.c
|
MemoryRegion *system_memory; // qemu/exec.c
|
||||||
MemoryRegion io_mem_rom; // qemu/exec.c
|
MemoryRegion io_mem_rom; // qemu/exec.c
|
||||||
MemoryRegion io_mem_notdirty; // qemu/exec.c
|
MemoryRegion io_mem_notdirty; // qemu/exec.c
|
||||||
|
|
|
@ -171,7 +171,7 @@ static int x86_msr_read(struct uc_struct *uc, uc_x86_msr *msr)
|
||||||
helper_rdmsr(env);
|
helper_rdmsr(env);
|
||||||
|
|
||||||
msr->value = ((uint32_t)env->regs[R_EAX]) |
|
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_EAX] = eax;
|
||||||
env->regs[R_ECX] = ecx;
|
env->regs[R_ECX] = ecx;
|
||||||
|
@ -1335,6 +1335,17 @@ static bool x86_stop_interrupt(int intno)
|
||||||
|
|
||||||
void pc_machine_init(struct uc_struct *uc);
|
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
|
DEFAULT_VISIBILITY
|
||||||
void x86_uc_init(struct uc_struct* uc)
|
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->release = x86_release;
|
||||||
uc->set_pc = x86_set_pc;
|
uc->set_pc = x86_set_pc;
|
||||||
uc->stop_interrupt = x86_stop_interrupt;
|
uc->stop_interrupt = x86_stop_interrupt;
|
||||||
|
uc->insn_hook_validate = x86_insn_hook_validate;
|
||||||
uc_common_init(uc);
|
uc_common_init(uc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
7
uc.c
7
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);
|
hook->insn = va_arg(valist, int);
|
||||||
va_end(valist);
|
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) {
|
if (list_append(&uc->hook[UC_HOOK_INSN_IDX], hook) == NULL) {
|
||||||
free(hook);
|
free(hook);
|
||||||
return UC_ERR_NOMEM;
|
return UC_ERR_NOMEM;
|
||||||
|
|
Loading…
Reference in a new issue