Allow user to instrument cpuid instruction
This commit is contained in:
parent
af60b4dfab
commit
9d8a309fbf
|
@ -105,6 +105,7 @@ void helper_into(CPUX86State *env, int next_eip_addend)
|
||||||
void helper_cpuid(CPUX86State *env)
|
void helper_cpuid(CPUX86State *env)
|
||||||
{
|
{
|
||||||
uint32_t eax, ebx, ecx, edx;
|
uint32_t eax, ebx, ecx, edx;
|
||||||
|
struct hook *hook;
|
||||||
|
|
||||||
cpu_svm_check_intercept_param(env, SVM_EXIT_CPUID, 0, GETPC());
|
cpu_svm_check_intercept_param(env, SVM_EXIT_CPUID, 0, GETPC());
|
||||||
|
|
||||||
|
@ -114,6 +115,21 @@ void helper_cpuid(CPUX86State *env)
|
||||||
env->regs[R_EBX] = ebx;
|
env->regs[R_EBX] = ebx;
|
||||||
env->regs[R_ECX] = ecx;
|
env->regs[R_ECX] = ecx;
|
||||||
env->regs[R_EDX] = edx;
|
env->regs[R_EDX] = edx;
|
||||||
|
|
||||||
|
// Unicorn: call registered CPUID hooks
|
||||||
|
HOOK_FOREACH_VAR_DECLARE;
|
||||||
|
HOOK_FOREACH(env->uc, hook, UC_HOOK_INSN) {
|
||||||
|
if (hook->to_delete)
|
||||||
|
continue;
|
||||||
|
if (!HOOK_BOUND_CHECK(hook, env->eip))
|
||||||
|
continue;
|
||||||
|
if (hook->insn == UC_X86_INS_CPUID)
|
||||||
|
((uc_cb_insn_syscall_t)hook->callback)(env->uc, hook->user_data);
|
||||||
|
|
||||||
|
// the last callback may already asked to stop emulation
|
||||||
|
if (env->uc->stop_request)
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
target_ulong helper_read_crN(CPUX86State *env, int reg)
|
target_ulong helper_read_crN(CPUX86State *env, int reg)
|
||||||
|
|
|
@ -1564,7 +1564,8 @@ static bool x86_insn_hook_validate(uint32_t insn_enum)
|
||||||
if (insn_enum != UC_X86_INS_IN
|
if (insn_enum != UC_X86_INS_IN
|
||||||
&& insn_enum != UC_X86_INS_OUT
|
&& insn_enum != UC_X86_INS_OUT
|
||||||
&& insn_enum != UC_X86_INS_SYSCALL
|
&& insn_enum != UC_X86_INS_SYSCALL
|
||||||
&& insn_enum != UC_X86_INS_SYSENTER) {
|
&& insn_enum != UC_X86_INS_SYSENTER
|
||||||
|
&& insn_enum != UC_X86_INS_CPUID) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -525,6 +525,31 @@ static void test_x86_sysenter() {
|
||||||
OK(uc_close(uc));
|
OK(uc_close(uc));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_x86_hook_cpuid_callback(uc_engine* uc, void* data) {
|
||||||
|
int reg = 7;
|
||||||
|
|
||||||
|
OK(uc_reg_write(uc, UC_X86_REG_EAX, ®));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_x86_hook_cpuid() {
|
||||||
|
uc_engine* uc;
|
||||||
|
char code[] = "\x40\x0F\xA2"; // INC EAX; CPUID
|
||||||
|
uc_hook h;
|
||||||
|
int reg;
|
||||||
|
|
||||||
|
uc_common_setup(&uc, UC_ARCH_X86, UC_MODE_32, code, sizeof(code) - 1);
|
||||||
|
|
||||||
|
OK(uc_hook_add(uc, &h, UC_HOOK_INSN, test_x86_hook_cpuid_callback, NULL, 1, 0, UC_X86_INS_CPUID));
|
||||||
|
|
||||||
|
OK(uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 0, 0));
|
||||||
|
|
||||||
|
OK(uc_reg_read(uc, UC_X86_REG_EAX, ®));
|
||||||
|
|
||||||
|
TEST_CHECK(reg == 7);
|
||||||
|
|
||||||
|
OK(uc_close(uc));
|
||||||
|
}
|
||||||
|
|
||||||
TEST_LIST = {
|
TEST_LIST = {
|
||||||
{ "test_x86_in", test_x86_in },
|
{ "test_x86_in", test_x86_in },
|
||||||
{ "test_x86_out", test_x86_out },
|
{ "test_x86_out", test_x86_out },
|
||||||
|
@ -545,5 +570,6 @@ TEST_LIST = {
|
||||||
{ "test_x86_smc_xor", test_x86_smc_xor},
|
{ "test_x86_smc_xor", test_x86_smc_xor},
|
||||||
{ "test_x86_mmio_uc_mem_rw", test_x86_mmio_uc_mem_rw},
|
{ "test_x86_mmio_uc_mem_rw", test_x86_mmio_uc_mem_rw},
|
||||||
{ "test_x86_sysenter", test_x86_sysenter},
|
{ "test_x86_sysenter", test_x86_sysenter},
|
||||||
|
{ "test_x86_hook_cpuid", test_x86_hook_cpuid},
|
||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
};
|
};
|
Loading…
Reference in New Issue