* Handle the cpu context save in a more pythonic way, so the context can be serialized and reuse in an other process using the same emulator architecture and modes * Fix type error ; mistakes a size_t uint64_t ; breaks in 32bit... * Fix the UAF situation when deleting a hook while being in a hook callback. Added an attribute 'to_delete' to hooks, and a list hooks_to_del to delay the free of the hooks * Minor fixes ; forgot return type of clear_deleted_hooks ; do not declare variable in for predicate
This commit is contained in:
@ -135,6 +135,8 @@ int cpu_exec(struct uc_struct *uc, CPUArchState *env) // qq
|
||||
// Unicorn: call registered invalid instruction callbacks
|
||||
HOOK_FOREACH_VAR_DECLARE;
|
||||
HOOK_FOREACH(uc, hook, UC_HOOK_INSN_INVALID) {
|
||||
if (hook->to_delete)
|
||||
continue;
|
||||
catched = ((uc_cb_hookinsn_invalid_t)hook->callback)(uc, hook->user_data);
|
||||
if (catched)
|
||||
break;
|
||||
@ -145,6 +147,8 @@ int cpu_exec(struct uc_struct *uc, CPUArchState *env) // qq
|
||||
// Unicorn: call registered interrupt callbacks
|
||||
HOOK_FOREACH_VAR_DECLARE;
|
||||
HOOK_FOREACH(uc, hook, UC_HOOK_INTR) {
|
||||
if (hook->to_delete)
|
||||
continue;
|
||||
((uc_cb_hookintr_t)hook->callback)(uc, cpu->exception_index, hook->user_data);
|
||||
catched = true;
|
||||
}
|
||||
|
@ -70,6 +70,8 @@ void cpu_outb(struct uc_struct *uc, pio_addr_t addr, uint8_t val)
|
||||
struct hook *hook;
|
||||
HOOK_FOREACH_VAR_DECLARE;
|
||||
HOOK_FOREACH(uc, hook, UC_HOOK_INSN) {
|
||||
if (hook->to_delete)
|
||||
continue;
|
||||
if (hook->insn == UC_X86_INS_OUT)
|
||||
((uc_cb_insn_out_t)hook->callback)(uc, addr, 1, val, hook->user_data);
|
||||
}
|
||||
@ -82,6 +84,8 @@ void cpu_outw(struct uc_struct *uc, pio_addr_t addr, uint16_t val)
|
||||
struct hook *hook;
|
||||
HOOK_FOREACH_VAR_DECLARE;
|
||||
HOOK_FOREACH(uc, hook, UC_HOOK_INSN) {
|
||||
if (hook->to_delete)
|
||||
continue;
|
||||
if (hook->insn == UC_X86_INS_OUT)
|
||||
((uc_cb_insn_out_t)hook->callback)(uc, addr, 2, val, hook->user_data);
|
||||
}
|
||||
@ -94,6 +98,8 @@ void cpu_outl(struct uc_struct *uc, pio_addr_t addr, uint32_t val)
|
||||
struct hook *hook;
|
||||
HOOK_FOREACH_VAR_DECLARE;
|
||||
HOOK_FOREACH(uc, hook, UC_HOOK_INSN) {
|
||||
if (hook->to_delete)
|
||||
continue;
|
||||
if (hook->insn == UC_X86_INS_OUT)
|
||||
((uc_cb_insn_out_t)hook->callback)(uc, addr, 4, val, hook->user_data);
|
||||
}
|
||||
@ -106,6 +112,8 @@ uint8_t cpu_inb(struct uc_struct *uc, pio_addr_t addr)
|
||||
struct hook *hook;
|
||||
HOOK_FOREACH_VAR_DECLARE;
|
||||
HOOK_FOREACH(uc, hook, UC_HOOK_INSN) {
|
||||
if (hook->to_delete)
|
||||
continue;
|
||||
if (hook->insn == UC_X86_INS_IN)
|
||||
return ((uc_cb_insn_in_t)hook->callback)(uc, addr, 1, hook->user_data);
|
||||
}
|
||||
@ -120,6 +128,8 @@ uint16_t cpu_inw(struct uc_struct *uc, pio_addr_t addr)
|
||||
struct hook *hook;
|
||||
HOOK_FOREACH_VAR_DECLARE;
|
||||
HOOK_FOREACH(uc, hook, UC_HOOK_INSN) {
|
||||
if (hook->to_delete)
|
||||
continue;
|
||||
if (hook->insn == UC_X86_INS_IN)
|
||||
return ((uc_cb_insn_in_t)hook->callback)(uc, addr, 2, hook->user_data);
|
||||
}
|
||||
@ -134,6 +144,8 @@ uint32_t cpu_inl(struct uc_struct *uc, pio_addr_t addr)
|
||||
struct hook *hook;
|
||||
HOOK_FOREACH_VAR_DECLARE;
|
||||
HOOK_FOREACH(uc, hook, UC_HOOK_INSN) {
|
||||
if (hook->to_delete)
|
||||
continue;
|
||||
if (hook->insn == UC_X86_INS_IN)
|
||||
return ((uc_cb_insn_in_t)hook->callback)(uc, addr, 4, hook->user_data);
|
||||
}
|
||||
|
@ -202,6 +202,8 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
|
||||
#if defined(SOFTMMU_CODE_ACCESS)
|
||||
error_code = UC_ERR_FETCH_UNMAPPED;
|
||||
HOOK_FOREACH(uc, hook, UC_HOOK_MEM_FETCH_UNMAPPED) {
|
||||
if (hook->to_delete)
|
||||
continue;
|
||||
if (!HOOK_BOUND_CHECK(hook, addr))
|
||||
continue;
|
||||
if ((handled = ((uc_cb_eventmem_t)hook->callback)(uc, UC_MEM_FETCH_UNMAPPED, addr, DATA_SIZE, 0, hook->user_data)))
|
||||
@ -210,6 +212,8 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
|
||||
#else
|
||||
error_code = UC_ERR_READ_UNMAPPED;
|
||||
HOOK_FOREACH(uc, hook, UC_HOOK_MEM_READ_UNMAPPED) {
|
||||
if (hook->to_delete)
|
||||
continue;
|
||||
if (!HOOK_BOUND_CHECK(hook, addr))
|
||||
continue;
|
||||
if ((handled = ((uc_cb_eventmem_t)hook->callback)(uc, UC_MEM_READ_UNMAPPED, addr, DATA_SIZE, 0, hook->user_data)))
|
||||
@ -233,6 +237,8 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
|
||||
if (mr != NULL && !(mr->perms & UC_PROT_EXEC)) { // non-executable
|
||||
handled = false;
|
||||
HOOK_FOREACH(uc, hook, UC_HOOK_MEM_FETCH_PROT) {
|
||||
if (hook->to_delete)
|
||||
continue;
|
||||
if (!HOOK_BOUND_CHECK(hook, addr))
|
||||
continue;
|
||||
if ((handled = ((uc_cb_eventmem_t)hook->callback)(uc, UC_MEM_FETCH_PROT, addr, DATA_SIZE, 0, hook->user_data)))
|
||||
@ -258,6 +264,8 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
|
||||
// about successful read
|
||||
if (READ_ACCESS_TYPE == MMU_DATA_LOAD) {
|
||||
HOOK_FOREACH(uc, hook, UC_HOOK_MEM_READ) {
|
||||
if (hook->to_delete)
|
||||
continue;
|
||||
if (!HOOK_BOUND_CHECK(hook, addr))
|
||||
continue;
|
||||
((uc_cb_hookmem_t)hook->callback)(env->uc, UC_MEM_READ, addr, DATA_SIZE, 0, hook->user_data);
|
||||
@ -268,6 +276,8 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
|
||||
if (READ_ACCESS_TYPE == MMU_DATA_LOAD && mr != NULL && !(mr->perms & UC_PROT_READ)) { //non-readable
|
||||
handled = false;
|
||||
HOOK_FOREACH(uc, hook, UC_HOOK_MEM_READ_PROT) {
|
||||
if (hook->to_delete)
|
||||
continue;
|
||||
if (!HOOK_BOUND_CHECK(hook, addr))
|
||||
continue;
|
||||
if ((handled = ((uc_cb_eventmem_t)hook->callback)(uc, UC_MEM_READ_PROT, addr, DATA_SIZE, 0, hook->user_data)))
|
||||
@ -399,6 +409,8 @@ _out:
|
||||
// Unicorn: callback on successful read
|
||||
if (READ_ACCESS_TYPE == MMU_DATA_LOAD) {
|
||||
HOOK_FOREACH(uc, hook, UC_HOOK_MEM_READ_AFTER) {
|
||||
if (hook->to_delete)
|
||||
continue;
|
||||
if (!HOOK_BOUND_CHECK(hook, addr))
|
||||
continue;
|
||||
((uc_cb_hookmem_t)hook->callback)(env->uc, UC_MEM_READ_AFTER, addr, DATA_SIZE, res, hook->user_data);
|
||||
@ -433,6 +445,8 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
|
||||
#if defined(SOFTMMU_CODE_ACCESS)
|
||||
error_code = UC_ERR_FETCH_UNMAPPED;
|
||||
HOOK_FOREACH(uc, hook, UC_HOOK_MEM_FETCH_UNMAPPED) {
|
||||
if (hook->to_delete)
|
||||
continue;
|
||||
if (!HOOK_BOUND_CHECK(hook, addr))
|
||||
continue;
|
||||
if ((handled = ((uc_cb_eventmem_t)hook->callback)(uc, UC_MEM_FETCH_UNMAPPED, addr, DATA_SIZE, 0, hook->user_data)))
|
||||
@ -441,6 +455,8 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
|
||||
#else
|
||||
error_code = UC_ERR_READ_UNMAPPED;
|
||||
HOOK_FOREACH(uc, hook, UC_HOOK_MEM_READ_UNMAPPED) {
|
||||
if (hook->to_delete)
|
||||
continue;
|
||||
if (!HOOK_BOUND_CHECK(hook, addr))
|
||||
continue;
|
||||
if ((handled = ((uc_cb_eventmem_t)hook->callback)(uc, UC_MEM_READ_UNMAPPED, addr, DATA_SIZE, 0, hook->user_data)))
|
||||
@ -464,6 +480,8 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
|
||||
if (mr != NULL && !(mr->perms & UC_PROT_EXEC)) { // non-executable
|
||||
handled = false;
|
||||
HOOK_FOREACH(uc, hook, UC_HOOK_MEM_FETCH_PROT) {
|
||||
if (hook->to_delete)
|
||||
continue;
|
||||
if (!HOOK_BOUND_CHECK(hook, addr))
|
||||
continue;
|
||||
if ((handled = ((uc_cb_eventmem_t)hook->callback)(uc, UC_MEM_FETCH_PROT, addr, DATA_SIZE, 0, hook->user_data)))
|
||||
@ -489,6 +507,8 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
|
||||
// about successful read
|
||||
if (READ_ACCESS_TYPE == MMU_DATA_LOAD) {
|
||||
HOOK_FOREACH(uc, hook, UC_HOOK_MEM_READ) {
|
||||
if (hook->to_delete)
|
||||
continue;
|
||||
if (!HOOK_BOUND_CHECK(hook, addr))
|
||||
continue;
|
||||
((uc_cb_hookmem_t)hook->callback)(env->uc, UC_MEM_READ, addr, DATA_SIZE, 0, hook->user_data);
|
||||
@ -499,6 +519,8 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
|
||||
if (READ_ACCESS_TYPE == MMU_DATA_LOAD && mr != NULL && !(mr->perms & UC_PROT_READ)) { //non-readable
|
||||
handled = false;
|
||||
HOOK_FOREACH(uc, hook, UC_HOOK_MEM_READ_PROT) {
|
||||
if (hook->to_delete)
|
||||
continue;
|
||||
if (!HOOK_BOUND_CHECK(hook, addr))
|
||||
continue;
|
||||
if ((handled = ((uc_cb_eventmem_t)hook->callback)(uc, UC_MEM_READ_PROT, addr, DATA_SIZE, 0, hook->user_data)))
|
||||
@ -625,6 +647,8 @@ _out:
|
||||
// Unicorn: callback on successful read
|
||||
if (READ_ACCESS_TYPE == MMU_DATA_LOAD) {
|
||||
HOOK_FOREACH(uc, hook, UC_HOOK_MEM_READ_AFTER) {
|
||||
if (hook->to_delete)
|
||||
continue;
|
||||
if (!HOOK_BOUND_CHECK(hook, addr))
|
||||
continue;
|
||||
((uc_cb_hookmem_t)hook->callback)(env->uc, UC_MEM_READ_AFTER, addr, DATA_SIZE, res, hook->user_data);
|
||||
@ -697,8 +721,10 @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
|
||||
|
||||
// Unicorn: callback on memory write
|
||||
HOOK_FOREACH(uc, hook, UC_HOOK_MEM_WRITE) {
|
||||
if (!HOOK_BOUND_CHECK(hook, addr))
|
||||
continue;
|
||||
if (hook->to_delete)
|
||||
continue;
|
||||
if (!HOOK_BOUND_CHECK(hook, addr))
|
||||
continue;
|
||||
((uc_cb_hookmem_t)hook->callback)(uc, UC_MEM_WRITE, addr, DATA_SIZE, val, hook->user_data);
|
||||
}
|
||||
|
||||
@ -706,6 +732,8 @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
|
||||
if (mr == NULL) {
|
||||
handled = false;
|
||||
HOOK_FOREACH(uc, hook, UC_HOOK_MEM_WRITE_UNMAPPED) {
|
||||
if (hook->to_delete)
|
||||
continue;
|
||||
if (!HOOK_BOUND_CHECK(hook, addr))
|
||||
continue;
|
||||
if ((handled = ((uc_cb_eventmem_t)hook->callback)(uc, UC_MEM_WRITE_UNMAPPED, addr, DATA_SIZE, val, hook->user_data)))
|
||||
@ -729,6 +757,8 @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
|
||||
if (mr != NULL && !(mr->perms & UC_PROT_WRITE)) { //non-writable
|
||||
handled = false;
|
||||
HOOK_FOREACH(uc, hook, UC_HOOK_MEM_WRITE_PROT) {
|
||||
if (hook->to_delete)
|
||||
continue;
|
||||
if (!HOOK_BOUND_CHECK(hook, addr))
|
||||
continue;
|
||||
if ((handled = ((uc_cb_eventmem_t)hook->callback)(uc, UC_MEM_WRITE_PROT, addr, DATA_SIZE, val, hook->user_data)))
|
||||
@ -856,6 +886,8 @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
|
||||
|
||||
// Unicorn: callback on memory write
|
||||
HOOK_FOREACH(uc, hook, UC_HOOK_MEM_WRITE) {
|
||||
if (hook->to_delete)
|
||||
continue;
|
||||
if (!HOOK_BOUND_CHECK(hook, addr))
|
||||
continue;
|
||||
((uc_cb_hookmem_t)hook->callback)(uc, UC_MEM_WRITE, addr, DATA_SIZE, val, hook->user_data);
|
||||
@ -865,6 +897,8 @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
|
||||
if (mr == NULL) {
|
||||
handled = false;
|
||||
HOOK_FOREACH(uc, hook, UC_HOOK_MEM_WRITE_UNMAPPED) {
|
||||
if (hook->to_delete)
|
||||
continue;
|
||||
if (!HOOK_BOUND_CHECK(hook, addr))
|
||||
continue;
|
||||
if ((handled = ((uc_cb_eventmem_t)hook->callback)(uc, UC_MEM_WRITE_UNMAPPED, addr, DATA_SIZE, val, hook->user_data)))
|
||||
@ -888,6 +922,8 @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
|
||||
if (mr != NULL && !(mr->perms & UC_PROT_WRITE)) { //non-writable
|
||||
handled = false;
|
||||
HOOK_FOREACH(uc, hook, UC_HOOK_MEM_WRITE_PROT) {
|
||||
if (hook->to_delete)
|
||||
continue;
|
||||
if (!HOOK_BOUND_CHECK(hook, addr))
|
||||
continue;
|
||||
if ((handled = ((uc_cb_eventmem_t)hook->callback)(uc, UC_MEM_WRITE_PROT, addr, DATA_SIZE, val, hook->user_data)))
|
||||
|
@ -949,6 +949,8 @@ void helper_syscall(CPUX86State *env, int next_eip_addend)
|
||||
struct hook *hook;
|
||||
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_SYSCALL)
|
||||
@ -2389,6 +2391,8 @@ void helper_sysenter(CPUX86State *env, int next_eip_addend)
|
||||
struct hook *hook;
|
||||
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_SYSENTER)
|
||||
|
Reference in New Issue
Block a user