more PC sync for HOOK_INSN
This commit is contained in:
@@ -217,6 +217,7 @@ void helper_rdtsc(CPUX86State *env)
|
|||||||
uc_engine *uc = env->uc;
|
uc_engine *uc = env->uc;
|
||||||
struct hook *hook;
|
struct hook *hook;
|
||||||
int skip_rdtsc = 0;
|
int skip_rdtsc = 0;
|
||||||
|
bool synced = false;
|
||||||
|
|
||||||
if ((env->cr[4] & CR4_TSD_MASK) && ((env->hflags & HF_CPL_MASK) != 0)) {
|
if ((env->cr[4] & CR4_TSD_MASK) && ((env->hflags & HF_CPL_MASK) != 0)) {
|
||||||
raise_exception_ra(env, EXCP0D_GPF, GETPC());
|
raise_exception_ra(env, EXCP0D_GPF, GETPC());
|
||||||
@@ -234,6 +235,11 @@ void helper_rdtsc(CPUX86State *env)
|
|||||||
// Multiple rdtsc callbacks returning different values is undefined.
|
// Multiple rdtsc callbacks returning different values is undefined.
|
||||||
// true -> skip the rdtsc instruction
|
// true -> skip the rdtsc instruction
|
||||||
if (hook->insn == UC_X86_INS_RDTSC) {
|
if (hook->insn == UC_X86_INS_RDTSC) {
|
||||||
|
uintptr_t pc = GETPC();
|
||||||
|
if (!synced && !uc->skip_sync_pc_on_exit && pc) {
|
||||||
|
cpu_restore_state(uc->cpu, pc, false);
|
||||||
|
synced = true;
|
||||||
|
}
|
||||||
JIT_CALLBACK_GUARD_VAR(skip_rdtsc, ((uc_cb_insn_cpuid_t)hook->callback)(env->uc, hook->user_data));
|
JIT_CALLBACK_GUARD_VAR(skip_rdtsc, ((uc_cb_insn_cpuid_t)hook->callback)(env->uc, hook->user_data));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -255,6 +261,7 @@ void helper_rdtscp(CPUX86State *env)
|
|||||||
uc_engine *uc = env->uc;
|
uc_engine *uc = env->uc;
|
||||||
struct hook *hook;
|
struct hook *hook;
|
||||||
int skip_rdtscp = 0;
|
int skip_rdtscp = 0;
|
||||||
|
bool synced = false;
|
||||||
|
|
||||||
if ((env->cr[4] & CR4_TSD_MASK) && ((env->hflags & HF_CPL_MASK) != 0)) {
|
if ((env->cr[4] & CR4_TSD_MASK) && ((env->hflags & HF_CPL_MASK) != 0)) {
|
||||||
raise_exception_ra(env, EXCP0D_GPF, GETPC());
|
raise_exception_ra(env, EXCP0D_GPF, GETPC());
|
||||||
@@ -272,6 +279,11 @@ void helper_rdtscp(CPUX86State *env)
|
|||||||
// Multiple rdtscp callbacks returning different values is undefined.
|
// Multiple rdtscp callbacks returning different values is undefined.
|
||||||
// true -> skip the rdtscp instruction
|
// true -> skip the rdtscp instruction
|
||||||
if (hook->insn == UC_X86_INS_RDTSCP) {
|
if (hook->insn == UC_X86_INS_RDTSCP) {
|
||||||
|
uintptr_t pc = GETPC();
|
||||||
|
if (!synced && !uc->skip_sync_pc_on_exit && pc) {
|
||||||
|
cpu_restore_state(uc->cpu, pc, false);
|
||||||
|
synced = true;
|
||||||
|
}
|
||||||
JIT_CALLBACK_GUARD_VAR(skip_rdtscp, ((uc_cb_insn_cpuid_t)hook->callback)(env->uc, hook->user_data));
|
JIT_CALLBACK_GUARD_VAR(skip_rdtscp, ((uc_cb_insn_cpuid_t)hook->callback)(env->uc, hook->user_data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -974,6 +974,7 @@ void helper_syscall(CPUX86State *env, int next_eip_addend)
|
|||||||
// Unicorn: call registered syscall hooks
|
// Unicorn: call registered syscall hooks
|
||||||
struct hook *hook;
|
struct hook *hook;
|
||||||
uc_engine *uc = env->uc;
|
uc_engine *uc = env->uc;
|
||||||
|
bool synced = false;
|
||||||
|
|
||||||
HOOK_FOREACH_VAR_DECLARE;
|
HOOK_FOREACH_VAR_DECLARE;
|
||||||
HOOK_FOREACH(env->uc, hook, UC_HOOK_INSN) {
|
HOOK_FOREACH(env->uc, hook, UC_HOOK_INSN) {
|
||||||
@@ -982,6 +983,11 @@ void helper_syscall(CPUX86State *env, int next_eip_addend)
|
|||||||
if (!HOOK_BOUND_CHECK(hook, env->eip))
|
if (!HOOK_BOUND_CHECK(hook, env->eip))
|
||||||
continue;
|
continue;
|
||||||
if (hook->insn == UC_X86_INS_SYSCALL) {
|
if (hook->insn == UC_X86_INS_SYSCALL) {
|
||||||
|
uintptr_t pc = GETPC();
|
||||||
|
if (!synced && !uc->skip_sync_pc_on_exit && pc) {
|
||||||
|
cpu_restore_state(uc->cpu, pc, false);
|
||||||
|
synced = true;
|
||||||
|
}
|
||||||
JIT_CALLBACK_GUARD(((uc_cb_insn_syscall_t)hook->callback)(env->uc, hook->user_data));
|
JIT_CALLBACK_GUARD(((uc_cb_insn_syscall_t)hook->callback)(env->uc, hook->user_data));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2352,6 +2358,7 @@ void helper_sysenter(CPUX86State *env, int next_eip_addend)
|
|||||||
// Unicorn: call registered SYSENTER hooks
|
// Unicorn: call registered SYSENTER hooks
|
||||||
struct hook *hook;
|
struct hook *hook;
|
||||||
uc_engine *uc = env->uc;
|
uc_engine *uc = env->uc;
|
||||||
|
bool synced = false;
|
||||||
|
|
||||||
HOOK_FOREACH_VAR_DECLARE;
|
HOOK_FOREACH_VAR_DECLARE;
|
||||||
HOOK_FOREACH(env->uc, hook, UC_HOOK_INSN) {
|
HOOK_FOREACH(env->uc, hook, UC_HOOK_INSN) {
|
||||||
@@ -2360,6 +2367,11 @@ void helper_sysenter(CPUX86State *env, int next_eip_addend)
|
|||||||
if (!HOOK_BOUND_CHECK(hook, env->eip))
|
if (!HOOK_BOUND_CHECK(hook, env->eip))
|
||||||
continue;
|
continue;
|
||||||
if (hook->insn == UC_X86_INS_SYSENTER) {
|
if (hook->insn == UC_X86_INS_SYSENTER) {
|
||||||
|
uintptr_t pc = GETPC();
|
||||||
|
if (!synced && !uc->skip_sync_pc_on_exit && pc) {
|
||||||
|
cpu_restore_state(uc->cpu, pc, false);
|
||||||
|
synced = true;
|
||||||
|
}
|
||||||
JIT_CALLBACK_GUARD(((uc_cb_insn_syscall_t)hook->callback)(env->uc, hook->user_data));
|
JIT_CALLBACK_GUARD(((uc_cb_insn_syscall_t)hook->callback)(env->uc, hook->user_data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user