mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2024-10-19 08:38:27 +02:00
Merge branch 'hook'
This commit is contained in:
commit
871cdb692f
@ -6,9 +6,9 @@ open System
|
|||||||
|
|
||||||
[<AutoOpen>]
|
[<AutoOpen>]
|
||||||
module Common =
|
module Common =
|
||||||
|
let UC_API_MAJOR = 1
|
||||||
|
|
||||||
let UC_API_MAJOR = 0
|
let UC_API_MINOR = 0
|
||||||
let UC_API_MINOR = 9
|
|
||||||
let UC_SECOND_SCALE = 1000000
|
let UC_SECOND_SCALE = 1000000
|
||||||
let UC_MILISECOND_SCALE = 1000
|
let UC_MILISECOND_SCALE = 1000
|
||||||
let UC_ARCH_ARM = 1
|
let UC_ARCH_ARM = 1
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package unicorn
|
package unicorn
|
||||||
// For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT [unicorn_const.go]
|
// For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT [unicorn_const.go]
|
||||||
const (
|
const (
|
||||||
|
API_MAJOR = 1
|
||||||
|
|
||||||
API_MAJOR = 0
|
API_MINOR = 0
|
||||||
API_MINOR = 9
|
|
||||||
SECOND_SCALE = 1000000
|
SECOND_SCALE = 1000000
|
||||||
MILISECOND_SCALE = 1000
|
MILISECOND_SCALE = 1000
|
||||||
ARCH_ARM = 1
|
ARCH_ARM = 1
|
||||||
|
@ -3,9 +3,9 @@
|
|||||||
package unicorn;
|
package unicorn;
|
||||||
|
|
||||||
public interface UnicornConst {
|
public interface UnicornConst {
|
||||||
|
public static final int UC_API_MAJOR = 1;
|
||||||
|
|
||||||
public static final int UC_API_MAJOR = 0;
|
public static final int UC_API_MINOR = 0;
|
||||||
public static final int UC_API_MINOR = 9;
|
|
||||||
public static final int UC_SECOND_SCALE = 1000000;
|
public static final int UC_SECOND_SCALE = 1000000;
|
||||||
public static final int UC_MILISECOND_SCALE = 1000;
|
public static final int UC_MILISECOND_SCALE = 1000;
|
||||||
public static final int UC_ARCH_ARM = 1;
|
public static final int UC_ARCH_ARM = 1;
|
||||||
|
@ -291,8 +291,8 @@ def test_i386_inout():
|
|||||||
mu.hook_add(UC_HOOK_CODE, hook_code)
|
mu.hook_add(UC_HOOK_CODE, hook_code)
|
||||||
|
|
||||||
# handle IN & OUT instruction
|
# handle IN & OUT instruction
|
||||||
mu.hook_add(UC_HOOK_INSN, hook_in, None, UC_X86_INS_IN)
|
mu.hook_add(UC_HOOK_INSN, hook_in, None, 1, 0, UC_X86_INS_IN)
|
||||||
mu.hook_add(UC_HOOK_INSN, hook_out, None, UC_X86_INS_OUT)
|
mu.hook_add(UC_HOOK_INSN, hook_out, None, 1, 0, UC_X86_INS_OUT)
|
||||||
|
|
||||||
# emulate machine code in infinite time
|
# emulate machine code in infinite time
|
||||||
mu.emu_start(ADDRESS, ADDRESS + len(X86_CODE32_INOUT))
|
mu.emu_start(ADDRESS, ADDRESS + len(X86_CODE32_INOUT))
|
||||||
@ -417,7 +417,7 @@ def test_x86_64_syscall():
|
|||||||
print('ERROR: was not expecting rax=%d in syscall' % rax)
|
print('ERROR: was not expecting rax=%d in syscall' % rax)
|
||||||
|
|
||||||
# hook interrupts for syscall
|
# hook interrupts for syscall
|
||||||
mu.hook_add(UC_HOOK_INSN, hook_syscall, None, UC_X86_INS_SYSCALL)
|
mu.hook_add(UC_HOOK_INSN, hook_syscall, None, 1, 0, UC_X86_INS_SYSCALL)
|
||||||
|
|
||||||
# syscall handler is expecting rax=0x100
|
# syscall handler is expecting rax=0x100
|
||||||
mu.reg_write(UC_X86_REG_RAX, 0x100)
|
mu.reg_write(UC_X86_REG_RAX, 0x100)
|
||||||
|
@ -97,7 +97,7 @@ def test_i386(mode, code):
|
|||||||
mu.hook_add(UC_HOOK_INTR, hook_intr)
|
mu.hook_add(UC_HOOK_INTR, hook_intr)
|
||||||
|
|
||||||
# handle SYSCALL
|
# handle SYSCALL
|
||||||
mu.hook_add(UC_HOOK_INSN, hook_syscall, None, UC_X86_INS_SYSCALL)
|
mu.hook_add(UC_HOOK_INSN, hook_syscall, None, 1, 0, UC_X86_INS_SYSCALL)
|
||||||
|
|
||||||
# emulate machine code in infinite time
|
# emulate machine code in infinite time
|
||||||
mu.emu_start(ADDRESS, ADDRESS + len(code))
|
mu.emu_start(ADDRESS, ADDRESS + len(code))
|
||||||
|
@ -315,7 +315,7 @@ class Uc(object):
|
|||||||
|
|
||||||
|
|
||||||
# add a hook
|
# add a hook
|
||||||
def hook_add(self, htype, callback, user_data=None, arg1=1, arg2=0):
|
def hook_add(self, htype, callback, user_data=None, begin=1, end=0, arg1=0):
|
||||||
_h2 = uc_hook_h()
|
_h2 = uc_hook_h()
|
||||||
|
|
||||||
# save callback & user_data
|
# save callback & user_data
|
||||||
@ -332,30 +332,28 @@ class Uc(object):
|
|||||||
if arg1 in (x86_const.UC_X86_INS_SYSCALL, x86_const.UC_X86_INS_SYSENTER): # SYSCALL/SYSENTER instruction
|
if arg1 in (x86_const.UC_X86_INS_SYSCALL, x86_const.UC_X86_INS_SYSENTER): # SYSCALL/SYSENTER instruction
|
||||||
cb = ctypes.cast(UC_HOOK_INSN_SYSCALL_CB(self._hook_insn_syscall_cb), UC_HOOK_INSN_SYSCALL_CB)
|
cb = ctypes.cast(UC_HOOK_INSN_SYSCALL_CB(self._hook_insn_syscall_cb), UC_HOOK_INSN_SYSCALL_CB)
|
||||||
status = _uc.uc_hook_add(self._uch, ctypes.byref(_h2), htype, \
|
status = _uc.uc_hook_add(self._uch, ctypes.byref(_h2), htype, \
|
||||||
cb, ctypes.cast(self._callback_count, ctypes.c_void_p), insn)
|
cb, ctypes.cast(self._callback_count, ctypes.c_void_p), ctypes.c_uint64(begin), ctypes.c_uint64(end), insn)
|
||||||
elif htype == UC_HOOK_INTR:
|
elif htype == UC_HOOK_INTR:
|
||||||
cb = ctypes.cast(UC_HOOK_INTR_CB(self._hook_intr_cb), UC_HOOK_INTR_CB)
|
cb = ctypes.cast(UC_HOOK_INTR_CB(self._hook_intr_cb), UC_HOOK_INTR_CB)
|
||||||
status = _uc.uc_hook_add(self._uch, ctypes.byref(_h2), htype, \
|
status = _uc.uc_hook_add(self._uch, ctypes.byref(_h2), htype, \
|
||||||
cb, ctypes.cast(self._callback_count, ctypes.c_void_p))
|
cb, ctypes.cast(self._callback_count, ctypes.c_void_p), ctypes.c_uint64(begin), ctypes.c_uint64(end))
|
||||||
else:
|
else:
|
||||||
begin = ctypes.c_uint64(arg1)
|
|
||||||
end = ctypes.c_uint64(arg2)
|
|
||||||
if htype in (UC_HOOK_BLOCK, UC_HOOK_CODE):
|
if htype in (UC_HOOK_BLOCK, UC_HOOK_CODE):
|
||||||
# set callback with wrapper, so it can be called
|
# set callback with wrapper, so it can be called
|
||||||
# with this object as param
|
# with this object as param
|
||||||
cb = ctypes.cast(UC_HOOK_CODE_CB(self._hookcode_cb), UC_HOOK_CODE_CB)
|
cb = ctypes.cast(UC_HOOK_CODE_CB(self._hookcode_cb), UC_HOOK_CODE_CB)
|
||||||
status = _uc.uc_hook_add(self._uch, ctypes.byref(_h2), htype, cb, \
|
status = _uc.uc_hook_add(self._uch, ctypes.byref(_h2), htype, cb, \
|
||||||
ctypes.cast(self._callback_count, ctypes.c_void_p), begin, end)
|
ctypes.cast(self._callback_count, ctypes.c_void_p), ctypes.c_uint64(begin), ctypes.c_uint64(end))
|
||||||
elif htype & UC_HOOK_MEM_READ_UNMAPPED or htype & UC_HOOK_MEM_WRITE_UNMAPPED or \
|
elif htype & UC_HOOK_MEM_READ_UNMAPPED or htype & UC_HOOK_MEM_WRITE_UNMAPPED or \
|
||||||
htype & UC_HOOK_MEM_FETCH_UNMAPPED or htype & UC_HOOK_MEM_READ_PROT or \
|
htype & UC_HOOK_MEM_FETCH_UNMAPPED or htype & UC_HOOK_MEM_READ_PROT or \
|
||||||
htype & UC_HOOK_MEM_WRITE_PROT or htype & UC_HOOK_MEM_FETCH_PROT:
|
htype & UC_HOOK_MEM_WRITE_PROT or htype & UC_HOOK_MEM_FETCH_PROT:
|
||||||
cb = ctypes.cast(UC_HOOK_MEM_INVALID_CB(self._hook_mem_invalid_cb), UC_HOOK_MEM_INVALID_CB)
|
cb = ctypes.cast(UC_HOOK_MEM_INVALID_CB(self._hook_mem_invalid_cb), UC_HOOK_MEM_INVALID_CB)
|
||||||
status = _uc.uc_hook_add(self._uch, ctypes.byref(_h2), htype, \
|
status = _uc.uc_hook_add(self._uch, ctypes.byref(_h2), htype, \
|
||||||
cb, ctypes.cast(self._callback_count, ctypes.c_void_p))
|
cb, ctypes.cast(self._callback_count, ctypes.c_void_p), ctypes.c_uint64(begin), ctypes.c_uint64(end))
|
||||||
else:
|
else:
|
||||||
cb = ctypes.cast(UC_HOOK_MEM_ACCESS_CB(self._hook_mem_access_cb), UC_HOOK_MEM_ACCESS_CB)
|
cb = ctypes.cast(UC_HOOK_MEM_ACCESS_CB(self._hook_mem_access_cb), UC_HOOK_MEM_ACCESS_CB)
|
||||||
status = _uc.uc_hook_add(self._uch, ctypes.byref(_h2), htype, \
|
status = _uc.uc_hook_add(self._uch, ctypes.byref(_h2), htype, \
|
||||||
cb, ctypes.cast(self._callback_count, ctypes.c_void_p))
|
cb, ctypes.cast(self._callback_count, ctypes.c_void_p), ctypes.c_uint64(begin), ctypes.c_uint64(end))
|
||||||
|
|
||||||
# save the ctype function so gc will leave it alone.
|
# save the ctype function so gc will leave it alone.
|
||||||
self._ctype_cbs[self._callback_count] = cb
|
self._ctype_cbs[self._callback_count] = cb
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT [unicorn_const.py]
|
# For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT [unicorn_const.py]
|
||||||
|
UC_API_MAJOR = 1
|
||||||
|
|
||||||
UC_API_MAJOR = 0
|
UC_API_MINOR = 0
|
||||||
UC_API_MINOR = 9
|
|
||||||
UC_SECOND_SCALE = 1000000
|
UC_SECOND_SCALE = 1000000
|
||||||
UC_MILISECOND_SCALE = 1000
|
UC_MILISECOND_SCALE = 1000
|
||||||
UC_ARCH_ARM = 1
|
UC_ARCH_ARM = 1
|
||||||
|
@ -57,8 +57,8 @@ typedef size_t uc_hook;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Unicorn API version
|
// Unicorn API version
|
||||||
#define UC_API_MAJOR 0
|
#define UC_API_MAJOR 1
|
||||||
#define UC_API_MINOR 9
|
#define UC_API_MINOR 0
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Macro to create combined version which can be compared to
|
Macro to create combined version which can be compared to
|
||||||
@ -457,13 +457,19 @@ uc_err uc_emu_stop(uc_engine *uc);
|
|||||||
@callback: callback to be run when instruction is hit
|
@callback: callback to be run when instruction is hit
|
||||||
@user_data: user-defined data. This will be passed to callback function in its
|
@user_data: user-defined data. This will be passed to callback function in its
|
||||||
last argument @user_data
|
last argument @user_data
|
||||||
|
@begin: start address of the area where the callback is effect (inclusive)
|
||||||
|
@begin: end address of the area where the callback is effect (inclusive)
|
||||||
|
NOTE 1: the callback is called only if related address is in range [@begin, @end]
|
||||||
|
NOTE 2: if @begin > @end, callback is called whenever this hook type is triggered
|
||||||
@...: variable arguments (depending on @type)
|
@...: variable arguments (depending on @type)
|
||||||
|
NOTE: if @type = UC_HOOK_INSN, this is the instruction ID (ex: UC_X86_INS_OUT)
|
||||||
|
|
||||||
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
|
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
|
||||||
for detailed error).
|
for detailed error).
|
||||||
*/
|
*/
|
||||||
UNICORN_EXPORT
|
UNICORN_EXPORT
|
||||||
uc_err uc_hook_add(uc_engine *uc, uc_hook *hh, int type, void *callback, void *user_data, ...);
|
uc_err uc_hook_add(uc_engine *uc, uc_hook *hh, int type, void *callback,
|
||||||
|
void *user_data, uint64_t begin, uint64_t end, ...);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Unregister (remove) a hook callback.
|
Unregister (remove) a hook callback.
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
# To be used to generate unicorn.pc for pkg-config
|
# To be used to generate unicorn.pc for pkg-config
|
||||||
|
|
||||||
# version major & minor
|
# version major & minor
|
||||||
PKG_MAJOR = 0
|
PKG_MAJOR = 1
|
||||||
PKG_MINOR = 9
|
PKG_MINOR = 0
|
||||||
|
|
||||||
# version bugfix level. Example: PKG_EXTRA = 1
|
# version bugfix level. Example: PKG_EXTRA = 1
|
||||||
PKG_EXTRA =
|
PKG_EXTRA =
|
||||||
|
@ -168,9 +168,9 @@ static void do_nx_demo(bool cause_fault)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// intercept code and invalid memory events
|
// intercept code and invalid memory events
|
||||||
if (uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)1, (uint64_t)0) != UC_ERR_OK ||
|
if (uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, 1, 0) != UC_ERR_OK ||
|
||||||
uc_hook_add(uc, &trace1, UC_HOOK_MEM_INVALID,
|
uc_hook_add(uc, &trace1, UC_HOOK_MEM_INVALID,
|
||||||
hook_mem_invalid, NULL, (uint64_t)1, (uint64_t)0) != UC_ERR_OK) {
|
hook_mem_invalid, NULL, 1, 0) != UC_ERR_OK) {
|
||||||
printf("not ok - Failed to install hooks\n");
|
printf("not ok - Failed to install hooks\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -248,10 +248,10 @@ static void do_perms_demo(bool change_perms)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// intercept code and invalid memory events
|
// intercept code and invalid memory events
|
||||||
if (uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)1, (uint64_t)0) != UC_ERR_OK ||
|
if (uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, 1, 0) != UC_ERR_OK ||
|
||||||
uc_hook_add(uc, &trace1,
|
uc_hook_add(uc, &trace1,
|
||||||
UC_HOOK_MEM_INVALID,
|
UC_HOOK_MEM_INVALID,
|
||||||
hook_mem_invalid, NULL, (uint64_t)1, (uint64_t)0) != UC_ERR_OK) {
|
hook_mem_invalid, NULL, 1, 0) != UC_ERR_OK) {
|
||||||
printf("not ok - Failed to install hooks\n");
|
printf("not ok - Failed to install hooks\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -326,10 +326,10 @@ static void do_unmap_demo(bool do_unmap)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// intercept code and invalid memory events
|
// intercept code and invalid memory events
|
||||||
if (uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)1, (uint64_t)0) != UC_ERR_OK ||
|
if (uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, 1, 0) != UC_ERR_OK ||
|
||||||
uc_hook_add(uc, &trace1,
|
uc_hook_add(uc, &trace1,
|
||||||
UC_HOOK_MEM_INVALID,
|
UC_HOOK_MEM_INVALID,
|
||||||
hook_mem_invalid, NULL, (uint64_t)1, (uint64_t)0) != UC_ERR_OK) {
|
hook_mem_invalid, NULL, 1, 0) != UC_ERR_OK) {
|
||||||
printf("not ok - Failed to install hooks\n");
|
printf("not ok - Failed to install hooks\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -77,10 +77,10 @@ static void test_arm(void)
|
|||||||
uc_reg_write(uc, UC_ARM_REG_R3, &r3);
|
uc_reg_write(uc, UC_ARM_REG_R3, &r3);
|
||||||
|
|
||||||
// tracing all basic blocks with customized callback
|
// tracing all basic blocks with customized callback
|
||||||
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
|
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, 1, 0);
|
||||||
|
|
||||||
// tracing one instruction at ADDRESS with customized callback
|
// tracing one instruction at ADDRESS with customized callback
|
||||||
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)ADDRESS, (uint64_t)ADDRESS);
|
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, ADDRESS, ADDRESS);
|
||||||
|
|
||||||
// emulate machine code in infinite time (last param = 0), or when
|
// emulate machine code in infinite time (last param = 0), or when
|
||||||
// finishing all the code.
|
// finishing all the code.
|
||||||
@ -128,10 +128,10 @@ static void test_thumb(void)
|
|||||||
uc_reg_write(uc, UC_ARM_REG_SP, &sp);
|
uc_reg_write(uc, UC_ARM_REG_SP, &sp);
|
||||||
|
|
||||||
// tracing all basic blocks with customized callback
|
// tracing all basic blocks with customized callback
|
||||||
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
|
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, 1, 0);
|
||||||
|
|
||||||
// tracing one instruction at ADDRESS with customized callback
|
// tracing one instruction at ADDRESS with customized callback
|
||||||
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)ADDRESS, (uint64_t)ADDRESS);
|
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, ADDRESS, ADDRESS);
|
||||||
|
|
||||||
// emulate machine code in infinite time (last param = 0), or when
|
// emulate machine code in infinite time (last param = 0), or when
|
||||||
// finishing all the code.
|
// finishing all the code.
|
||||||
|
@ -75,10 +75,10 @@ static void test_arm64(void)
|
|||||||
uc_reg_write(uc, UC_ARM64_REG_X15, &x15);
|
uc_reg_write(uc, UC_ARM64_REG_X15, &x15);
|
||||||
|
|
||||||
// tracing all basic blocks with customized callback
|
// tracing all basic blocks with customized callback
|
||||||
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
|
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, 1, 0);
|
||||||
|
|
||||||
// tracing one instruction at ADDRESS with customized callback
|
// tracing one instruction at ADDRESS with customized callback
|
||||||
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)ADDRESS, (uint64_t)ADDRESS);
|
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, ADDRESS, ADDRESS);
|
||||||
|
|
||||||
// emulate machine code in infinite time (last param = 0), or when
|
// emulate machine code in infinite time (last param = 0), or when
|
||||||
// finishing all the code.
|
// finishing all the code.
|
||||||
|
@ -108,10 +108,10 @@ static void test_m68k(void)
|
|||||||
uc_reg_write(uc, UC_M68K_REG_SR, &sr);
|
uc_reg_write(uc, UC_M68K_REG_SR, &sr);
|
||||||
|
|
||||||
// tracing all basic blocks with customized callback
|
// tracing all basic blocks with customized callback
|
||||||
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
|
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, 1, 0);
|
||||||
|
|
||||||
// tracing all instruction
|
// tracing all instruction
|
||||||
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)1, (uint64_t)0);
|
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, 1, 0);
|
||||||
|
|
||||||
// emulate machine code in infinite time (last param = 0), or when
|
// emulate machine code in infinite time (last param = 0), or when
|
||||||
// finishing all the code.
|
// finishing all the code.
|
||||||
|
@ -72,10 +72,10 @@ static void test_mips_eb(void)
|
|||||||
uc_reg_write(uc, UC_MIPS_REG_1, &r1);
|
uc_reg_write(uc, UC_MIPS_REG_1, &r1);
|
||||||
|
|
||||||
// tracing all basic blocks with customized callback
|
// tracing all basic blocks with customized callback
|
||||||
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
|
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, 1, 0);
|
||||||
|
|
||||||
// tracing one instruction at ADDRESS with customized callback
|
// tracing one instruction at ADDRESS with customized callback
|
||||||
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)ADDRESS, (uint64_t)ADDRESS);
|
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, ADDRESS, ADDRESS);
|
||||||
|
|
||||||
// emulate machine code in infinite time (last param = 0), or when
|
// emulate machine code in infinite time (last param = 0), or when
|
||||||
// finishing all the code.
|
// finishing all the code.
|
||||||
@ -122,10 +122,10 @@ static void test_mips_el(void)
|
|||||||
uc_reg_write(uc, UC_MIPS_REG_1, &r1);
|
uc_reg_write(uc, UC_MIPS_REG_1, &r1);
|
||||||
|
|
||||||
// tracing all basic blocks with customized callback
|
// tracing all basic blocks with customized callback
|
||||||
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
|
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, 1, 0);
|
||||||
|
|
||||||
// tracing one instruction at ADDRESS with customized callback
|
// tracing one instruction at ADDRESS with customized callback
|
||||||
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)ADDRESS, (uint64_t)ADDRESS);
|
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, ADDRESS, ADDRESS);
|
||||||
|
|
||||||
// emulate machine code in infinite time (last param = 0), or when
|
// emulate machine code in infinite time (last param = 0), or when
|
||||||
// finishing all the code.
|
// finishing all the code.
|
||||||
|
@ -76,10 +76,10 @@ static void test_sparc(void)
|
|||||||
uc_reg_write(uc, UC_SPARC_REG_G3, &g3);
|
uc_reg_write(uc, UC_SPARC_REG_G3, &g3);
|
||||||
|
|
||||||
// tracing all basic blocks with customized callback
|
// tracing all basic blocks with customized callback
|
||||||
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
|
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, 1, 0);
|
||||||
|
|
||||||
// tracing all instructions with customized callback
|
// tracing all instructions with customized callback
|
||||||
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)1, (uint64_t)0);
|
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, 1, 0);
|
||||||
|
|
||||||
// emulate machine code in infinite time (last param = 0), or when
|
// emulate machine code in infinite time (last param = 0), or when
|
||||||
// finishing all the code.
|
// finishing all the code.
|
||||||
|
@ -219,10 +219,10 @@ static void test_i386(void)
|
|||||||
uc_reg_write(uc, UC_X86_REG_EDX, &r_edx);
|
uc_reg_write(uc, UC_X86_REG_EDX, &r_edx);
|
||||||
|
|
||||||
// tracing all basic blocks with customized callback
|
// tracing all basic blocks with customized callback
|
||||||
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
|
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, 1, 0);
|
||||||
|
|
||||||
// tracing all instruction by having @begin > @end
|
// tracing all instruction by having @begin > @end
|
||||||
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)1, (uint64_t)0);
|
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, 1, 0);
|
||||||
|
|
||||||
// emulate machine code in infinite time
|
// emulate machine code in infinite time
|
||||||
err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(X86_CODE32) - 1, 0, 0);
|
err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(X86_CODE32) - 1, 0, 0);
|
||||||
@ -289,10 +289,10 @@ static void test_i386_map_ptr(void)
|
|||||||
uc_reg_write(uc, UC_X86_REG_EDX, &r_edx);
|
uc_reg_write(uc, UC_X86_REG_EDX, &r_edx);
|
||||||
|
|
||||||
// tracing all basic blocks with customized callback
|
// tracing all basic blocks with customized callback
|
||||||
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
|
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, 1, 0);
|
||||||
|
|
||||||
// tracing all instruction by having @begin > @end
|
// tracing all instruction by having @begin > @end
|
||||||
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)1, (uint64_t)0);
|
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, 1, 0);
|
||||||
|
|
||||||
// emulate machine code in infinite time
|
// emulate machine code in infinite time
|
||||||
err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(X86_CODE32) - 1, 0, 0);
|
err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(X86_CODE32) - 1, 0, 0);
|
||||||
@ -345,10 +345,10 @@ static void test_i386_jump(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// tracing 1 basic block with customized callback
|
// tracing 1 basic block with customized callback
|
||||||
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)ADDRESS, (uint64_t)ADDRESS);
|
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, ADDRESS, ADDRESS);
|
||||||
|
|
||||||
// tracing 1 instruction at ADDRESS
|
// tracing 1 instruction at ADDRESS
|
||||||
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)ADDRESS, (uint64_t)ADDRESS);
|
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, ADDRESS, ADDRESS);
|
||||||
|
|
||||||
// emulate machine code in infinite time
|
// emulate machine code in infinite time
|
||||||
err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(X86_CODE32_JUMP) - 1, 0, 0);
|
err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(X86_CODE32_JUMP) - 1, 0, 0);
|
||||||
@ -447,10 +447,10 @@ static void test_i386_invalid_mem_read(void)
|
|||||||
uc_reg_write(uc, UC_X86_REG_EDX, &r_edx);
|
uc_reg_write(uc, UC_X86_REG_EDX, &r_edx);
|
||||||
|
|
||||||
// tracing all basic blocks with customized callback
|
// tracing all basic blocks with customized callback
|
||||||
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
|
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, 1, 0);
|
||||||
|
|
||||||
// tracing all instruction by having @begin > @end
|
// tracing all instruction by having @begin > @end
|
||||||
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)1, (uint64_t)0);
|
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, 1, 0);
|
||||||
|
|
||||||
// emulate machine code in infinite time
|
// emulate machine code in infinite time
|
||||||
err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(X86_CODE32_MEM_READ) - 1, 0, 0);
|
err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(X86_CODE32_MEM_READ) - 1, 0, 0);
|
||||||
@ -505,13 +505,13 @@ static void test_i386_invalid_mem_write(void)
|
|||||||
uc_reg_write(uc, UC_X86_REG_EDX, &r_edx);
|
uc_reg_write(uc, UC_X86_REG_EDX, &r_edx);
|
||||||
|
|
||||||
// tracing all basic blocks with customized callback
|
// tracing all basic blocks with customized callback
|
||||||
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
|
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, 1, 0);
|
||||||
|
|
||||||
// tracing all instruction by having @begin > @end
|
// tracing all instruction by having @begin > @end
|
||||||
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)1, (uint64_t)0);
|
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, 1, 0);
|
||||||
|
|
||||||
// intercept invalid memory events
|
// intercept invalid memory events
|
||||||
uc_hook_add(uc, &trace3, UC_HOOK_MEM_READ_UNMAPPED | UC_HOOK_MEM_WRITE_UNMAPPED, hook_mem_invalid, NULL);
|
uc_hook_add(uc, &trace3, UC_HOOK_MEM_READ_UNMAPPED | UC_HOOK_MEM_WRITE_UNMAPPED, hook_mem_invalid, NULL, 1, 0);
|
||||||
|
|
||||||
// emulate machine code in infinite time
|
// emulate machine code in infinite time
|
||||||
err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(X86_CODE32_MEM_WRITE) - 1, 0, 0);
|
err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(X86_CODE32_MEM_WRITE) - 1, 0, 0);
|
||||||
@ -576,10 +576,10 @@ static void test_i386_jump_invalid(void)
|
|||||||
uc_reg_write(uc, UC_X86_REG_EDX, &r_edx);
|
uc_reg_write(uc, UC_X86_REG_EDX, &r_edx);
|
||||||
|
|
||||||
// tracing all basic blocks with customized callback
|
// tracing all basic blocks with customized callback
|
||||||
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
|
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, 1, 0);
|
||||||
|
|
||||||
// tracing all instructions by having @begin > @end
|
// tracing all instructions by having @begin > @end
|
||||||
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)1, (uint64_t)0);
|
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, 1, 0);
|
||||||
|
|
||||||
// emulate machine code in infinite time
|
// emulate machine code in infinite time
|
||||||
err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(X86_CODE32_JMP_INVALID) - 1, 0, 0);
|
err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(X86_CODE32_JMP_INVALID) - 1, 0, 0);
|
||||||
@ -632,15 +632,15 @@ static void test_i386_inout(void)
|
|||||||
uc_reg_write(uc, UC_X86_REG_ECX, &r_ecx);
|
uc_reg_write(uc, UC_X86_REG_ECX, &r_ecx);
|
||||||
|
|
||||||
// tracing all basic blocks with customized callback
|
// tracing all basic blocks with customized callback
|
||||||
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
|
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, 1, 0);
|
||||||
|
|
||||||
// tracing all instructions
|
// tracing all instructions
|
||||||
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)1, (uint64_t)0);
|
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, 1, 0);
|
||||||
|
|
||||||
// uc IN instruction
|
// uc IN instruction
|
||||||
uc_hook_add(uc, &trace3, UC_HOOK_INSN, hook_in, NULL, UC_X86_INS_IN);
|
uc_hook_add(uc, &trace3, UC_HOOK_INSN, hook_in, NULL, 1, 0, UC_X86_INS_IN);
|
||||||
// uc OUT instruction
|
// uc OUT instruction
|
||||||
uc_hook_add(uc, &trace4, UC_HOOK_INSN, hook_out, NULL, UC_X86_INS_OUT);
|
uc_hook_add(uc, &trace4, UC_HOOK_INSN, hook_out, NULL, 1, 0, UC_X86_INS_OUT);
|
||||||
|
|
||||||
// emulate machine code in infinite time
|
// emulate machine code in infinite time
|
||||||
err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(X86_CODE32_INOUT) - 1, 0, 0);
|
err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(X86_CODE32_INOUT) - 1, 0, 0);
|
||||||
@ -721,16 +721,16 @@ static void test_x86_64(void)
|
|||||||
uc_reg_write(uc, UC_X86_REG_R15, &r15);
|
uc_reg_write(uc, UC_X86_REG_R15, &r15);
|
||||||
|
|
||||||
// tracing all basic blocks with customized callback
|
// tracing all basic blocks with customized callback
|
||||||
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
|
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, 1, 0);
|
||||||
|
|
||||||
// tracing all instructions in the range [ADDRESS, ADDRESS+20]
|
// tracing all instructions in the range [ADDRESS, ADDRESS+20]
|
||||||
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code64, NULL, (uint64_t)ADDRESS, (uint64_t)(ADDRESS+20));
|
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code64, NULL, ADDRESS, ADDRESS+20);
|
||||||
|
|
||||||
// tracing all memory WRITE access (with @begin > @end)
|
// tracing all memory WRITE access (with @begin > @end)
|
||||||
uc_hook_add(uc, &trace3, UC_HOOK_MEM_WRITE, hook_mem64, NULL, (uint64_t)1, (uint64_t)0);
|
uc_hook_add(uc, &trace3, UC_HOOK_MEM_WRITE, hook_mem64, NULL, 1, 0);
|
||||||
|
|
||||||
// tracing all memory READ access (with @begin > @end)
|
// tracing all memory READ access (with @begin > @end)
|
||||||
uc_hook_add(uc, &trace4, UC_HOOK_MEM_READ, hook_mem64, NULL, (uint64_t)1, (uint64_t)0);
|
uc_hook_add(uc, &trace4, UC_HOOK_MEM_READ, hook_mem64, NULL, 1, 0);
|
||||||
|
|
||||||
// emulate machine code in infinite time (last param = 0), or when
|
// emulate machine code in infinite time (last param = 0), or when
|
||||||
// finishing all the code.
|
// finishing all the code.
|
||||||
@ -804,7 +804,7 @@ static void test_x86_64_syscall(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// hook interrupts for syscall
|
// hook interrupts for syscall
|
||||||
uc_hook_add(uc, &trace1, UC_HOOK_INSN, hook_syscall, NULL, UC_X86_INS_SYSCALL);
|
uc_hook_add(uc, &trace1, UC_HOOK_INSN, hook_syscall, NULL, 1, 0, UC_X86_INS_SYSCALL);
|
||||||
|
|
||||||
// initialize machine registers
|
// initialize machine registers
|
||||||
uc_reg_write(uc, UC_X86_REG_RAX, &rax);
|
uc_reg_write(uc, UC_X86_REG_RAX, &rax);
|
||||||
|
@ -138,7 +138,7 @@ static void test_i386(void)
|
|||||||
uc_hook_add(uc, &trace1, UC_HOOK_CODE, hook_code, NULL, 1, 0);
|
uc_hook_add(uc, &trace1, UC_HOOK_CODE, hook_code, NULL, 1, 0);
|
||||||
|
|
||||||
// handle interrupt ourself
|
// handle interrupt ourself
|
||||||
uc_hook_add(uc, &trace2, UC_HOOK_INTR, hook_intr, NULL);
|
uc_hook_add(uc, &trace2, UC_HOOK_INTR, hook_intr, NULL, 1, 0);
|
||||||
|
|
||||||
printf("\n>>> Start tracing this Linux code\n");
|
printf("\n>>> Start tracing this Linux code\n");
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ static void test_high_address_reads(void **state)
|
|||||||
uint8_t code[] = {0x48,0x8b,0x00,0x90,0x90,0x90,0x90}; // mov rax, [rax], nops
|
uint8_t code[] = {0x48,0x8b,0x00,0x90,0x90,0x90,0x90}; // mov rax, [rax], nops
|
||||||
uc_assert_success(uc_mem_map(uc, base_addr, 4096, UC_PROT_ALL));
|
uc_assert_success(uc_mem_map(uc, base_addr, 4096, UC_PROT_ALL));
|
||||||
uc_assert_success(uc_mem_write(uc, base_addr, code, 7));
|
uc_assert_success(uc_mem_write(uc, base_addr, code, 7));
|
||||||
uc_assert_success(uc_hook_add(uc, &trace2, UC_HOOK_MEM_READ, hook_mem64, NULL, (uint64_t)1, (uint64_t)0));
|
uc_assert_success(uc_hook_add(uc, &trace2, UC_HOOK_MEM_READ, hook_mem64, NULL, 1, 0));
|
||||||
uc_assert_success(uc_emu_start(uc, base_addr, base_addr + 3, 0, 0));
|
uc_assert_success(uc_emu_start(uc, base_addr, base_addr + 3, 0, 0));
|
||||||
if(number_of_memory_reads != 1) {
|
if(number_of_memory_reads != 1) {
|
||||||
fail_msg("wrong number of memory reads for instruction %i", number_of_memory_reads);
|
fail_msg("wrong number of memory reads for instruction %i", number_of_memory_reads);
|
||||||
|
@ -96,8 +96,8 @@ static void test_basic_blocks(void **state)
|
|||||||
OK(uc_mem_write(uc, address, code, sizeof(code)));
|
OK(uc_mem_write(uc, address, code, sizeof(code)));
|
||||||
|
|
||||||
// trace all basic blocks
|
// trace all basic blocks
|
||||||
OK(uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, test_basic_blocks_hook, &bbtest, (uint64_t)1, (uint64_t)0));
|
OK(uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, test_basic_blocks_hook, &bbtest, 1, 0));
|
||||||
OK(uc_hook_add(uc, &trace2, UC_HOOK_BLOCK, test_basic_blocks_hook2, &bbtest, (uint64_t)1, (uint64_t)0));
|
OK(uc_hook_add(uc, &trace2, UC_HOOK_BLOCK, test_basic_blocks_hook2, &bbtest, 1, 0));
|
||||||
|
|
||||||
OK(uc_emu_start(uc, address, address+sizeof(code), 0, 0));
|
OK(uc_emu_start(uc, address, address+sizeof(code), 0, 0));
|
||||||
}
|
}
|
||||||
|
@ -83,7 +83,7 @@ static void test_pc_change(void **state)
|
|||||||
printf("ECX = %u, EDX = %u\n", r_ecx, r_edx);
|
printf("ECX = %u, EDX = %u\n", r_ecx, r_edx);
|
||||||
|
|
||||||
// trace all instructions
|
// trace all instructions
|
||||||
OK(uc_hook_add(uc, &trace1, UC_HOOK_CODE, test_code_hook, NULL, (uint64_t)1, (uint64_t)0));
|
OK(uc_hook_add(uc, &trace1, UC_HOOK_CODE, test_code_hook, NULL, 1, 0));
|
||||||
|
|
||||||
OK(uc_emu_start(uc, address, address+sizeof(code), 0, 0));
|
OK(uc_emu_start(uc, address, address+sizeof(code), 0, 0));
|
||||||
|
|
||||||
|
@ -273,16 +273,16 @@ static void test_tb_x86_64_32_imul_Gv_Ev_Ib(void **state)
|
|||||||
UC_HOOK_CODE,
|
UC_HOOK_CODE,
|
||||||
hook_code32,
|
hook_code32,
|
||||||
NULL,
|
NULL,
|
||||||
(uint64_t)1,
|
1,
|
||||||
(uint64_t)0));
|
0));
|
||||||
|
|
||||||
uc_assert_success(uc_hook_add(uc,
|
uc_assert_success(uc_hook_add(uc,
|
||||||
&trace2,
|
&trace2,
|
||||||
UC_HOOK_MEM_VALID,
|
UC_HOOK_MEM_VALID,
|
||||||
hook_mem32,
|
hook_mem32,
|
||||||
NULL,
|
NULL,
|
||||||
(uint64_t)1,
|
1,
|
||||||
(uint64_t)0));
|
0));
|
||||||
|
|
||||||
uc_assert_success(uc_emu_start(uc,
|
uc_assert_success(uc_emu_start(uc,
|
||||||
#ifdef RIP_NEXT_TO_THE_SELFMODIFY_OPCODE
|
#ifdef RIP_NEXT_TO_THE_SELFMODIFY_OPCODE
|
||||||
|
@ -85,7 +85,7 @@ static void test_basic_blocks(void **state)
|
|||||||
OK(uc_mem_write(uc, address, code, sizeof(code)));
|
OK(uc_mem_write(uc, address, code, sizeof(code)));
|
||||||
|
|
||||||
// trace all basic blocks
|
// trace all basic blocks
|
||||||
OK(uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, test_basic_blocks_hook, &bbtest, (uint64_t)1, (uint64_t)0));
|
OK(uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, test_basic_blocks_hook, &bbtest, 1, 0));
|
||||||
|
|
||||||
OK(uc_emu_start(uc, address, address+sizeof(code), 0, 0));
|
OK(uc_emu_start(uc, address, address+sizeof(code), 0, 0));
|
||||||
}
|
}
|
||||||
@ -144,11 +144,11 @@ static void test_i386(void **state)
|
|||||||
uc_assert_success(err);
|
uc_assert_success(err);
|
||||||
|
|
||||||
// tracing all basic blocks with customized callback
|
// tracing all basic blocks with customized callback
|
||||||
err = uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
|
err = uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, 1, 0);
|
||||||
uc_assert_success(err);
|
uc_assert_success(err);
|
||||||
|
|
||||||
// tracing all instruction by having @begin > @end
|
// tracing all instruction by having @begin > @end
|
||||||
err = uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)1, (uint64_t)0);
|
err = uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, 1, 0);
|
||||||
uc_assert_success(err);
|
uc_assert_success(err);
|
||||||
|
|
||||||
// emulate machine code in infinite time
|
// emulate machine code in infinite time
|
||||||
@ -194,11 +194,11 @@ static void test_i386_jump(void **state)
|
|||||||
uc_assert_success(err);
|
uc_assert_success(err);
|
||||||
|
|
||||||
// tracing 1 basic block with customized callback
|
// tracing 1 basic block with customized callback
|
||||||
err = uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)address, (uint64_t)address);
|
err = uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, address, address);
|
||||||
uc_assert_success(err);
|
uc_assert_success(err);
|
||||||
|
|
||||||
// tracing 1 instruction at address
|
// tracing 1 instruction at address
|
||||||
err = uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)address, (uint64_t)address);
|
err = uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, address, address);
|
||||||
uc_assert_success(err);
|
uc_assert_success(err);
|
||||||
|
|
||||||
// emulate machine code in infinite time
|
// emulate machine code in infinite time
|
||||||
@ -302,19 +302,19 @@ static void test_i386_inout(void **state)
|
|||||||
uc_assert_success(err);
|
uc_assert_success(err);
|
||||||
|
|
||||||
// tracing all basic blocks with customized callback
|
// tracing all basic blocks with customized callback
|
||||||
err = uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
|
err = uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, 1, 0);
|
||||||
uc_assert_success(err);
|
uc_assert_success(err);
|
||||||
|
|
||||||
// tracing all instructions
|
// tracing all instructions
|
||||||
err = uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)1, (uint64_t)0);
|
err = uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, 1, 0);
|
||||||
uc_assert_success(err);
|
uc_assert_success(err);
|
||||||
|
|
||||||
// uc IN instruction
|
// uc IN instruction
|
||||||
err = uc_hook_add(uc, &trace3, UC_HOOK_INSN, hook_in, NULL, UC_X86_INS_IN);
|
err = uc_hook_add(uc, &trace3, UC_HOOK_INSN, hook_in, NULL, 1, 0, UC_X86_INS_IN);
|
||||||
uc_assert_success(err);
|
uc_assert_success(err);
|
||||||
|
|
||||||
// uc OUT instruction
|
// uc OUT instruction
|
||||||
err = uc_hook_add(uc, &trace4, UC_HOOK_INSN, hook_out, NULL, UC_X86_INS_OUT);
|
err = uc_hook_add(uc, &trace4, UC_HOOK_INSN, hook_out, NULL, 1, 0, UC_X86_INS_OUT);
|
||||||
uc_assert_success(err);
|
uc_assert_success(err);
|
||||||
|
|
||||||
// emulate machine code in infinite time
|
// emulate machine code in infinite time
|
||||||
@ -566,19 +566,19 @@ static void test_x86_64(void **state)
|
|||||||
uc_assert_success(uc_reg_write(uc, UC_X86_REG_R15, &r15));
|
uc_assert_success(uc_reg_write(uc, UC_X86_REG_R15, &r15));
|
||||||
|
|
||||||
// tracing all basic blocks with customized callback
|
// tracing all basic blocks with customized callback
|
||||||
err = uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
|
err = uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, 1, 0);
|
||||||
uc_assert_success(err);
|
uc_assert_success(err);
|
||||||
|
|
||||||
// tracing all instructions in the range [address, address+20]
|
// tracing all instructions in the range [address, address+20]
|
||||||
err = uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code64, NULL, (uint64_t)address, (uint64_t)(address+20));
|
err = uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code64, NULL, address, address+20);
|
||||||
uc_assert_success(err);
|
uc_assert_success(err);
|
||||||
|
|
||||||
// tracing all memory WRITE access (with @begin > @end)
|
// tracing all memory WRITE access (with @begin > @end)
|
||||||
err = uc_hook_add(uc, &trace3, UC_HOOK_MEM_WRITE, hook_mem64, NULL, (uint64_t)1, (uint64_t)0);
|
err = uc_hook_add(uc, &trace3, UC_HOOK_MEM_WRITE, hook_mem64, NULL, 1, 0);
|
||||||
uc_assert_success(err);
|
uc_assert_success(err);
|
||||||
|
|
||||||
// tracing all memory READ access (with @begin > @end)
|
// tracing all memory READ access (with @begin > @end)
|
||||||
err = uc_hook_add(uc, &trace4, UC_HOOK_MEM_READ, hook_mem64, NULL, (uint64_t)1, (uint64_t)0);
|
err = uc_hook_add(uc, &trace4, UC_HOOK_MEM_READ, hook_mem64, NULL, 1, 0);
|
||||||
uc_assert_success(err);
|
uc_assert_success(err);
|
||||||
|
|
||||||
// emulate machine code in infinite time (last param = 0), or when
|
// emulate machine code in infinite time (last param = 0), or when
|
||||||
@ -662,7 +662,7 @@ static void test_x86_64_syscall(void **state)
|
|||||||
uc_assert_success(err);
|
uc_assert_success(err);
|
||||||
|
|
||||||
// hook interrupts for syscall
|
// hook interrupts for syscall
|
||||||
err = uc_hook_add(uc, &trace1, UC_HOOK_INSN, hook_syscall, NULL, UC_X86_INS_SYSCALL);
|
err = uc_hook_add(uc, &trace1, UC_HOOK_INSN, hook_syscall, NULL, 1, 0, UC_X86_INS_SYSCALL);
|
||||||
uc_assert_success(err);
|
uc_assert_success(err);
|
||||||
|
|
||||||
// initialize machine registers
|
// initialize machine registers
|
||||||
|
28
uc.c
28
uc.c
@ -551,7 +551,7 @@ uc_err uc_emu_start(uc_engine* uc, uint64_t begin, uint64_t until, uint64_t time
|
|||||||
}
|
}
|
||||||
// set up count hook to count instructions.
|
// set up count hook to count instructions.
|
||||||
if (count > 0 && uc->count_hook == 0) {
|
if (count > 0 && uc->count_hook == 0) {
|
||||||
uc_err err = uc_hook_add(uc, &uc->count_hook, UC_HOOK_CODE, hook_count_cb, NULL);
|
uc_err err = uc_hook_add(uc, &uc->count_hook, UC_HOOK_CODE, hook_count_cb, NULL, 1, 0);
|
||||||
if (err != UC_ERR_OK) {
|
if (err != UC_ERR_OK) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@ -565,6 +565,7 @@ uc_err uc_emu_start(uc_engine* uc, uint64_t begin, uint64_t until, uint64_t time
|
|||||||
|
|
||||||
if (timeout)
|
if (timeout)
|
||||||
enable_emu_timer(uc, timeout * 1000); // microseconds -> nanoseconds
|
enable_emu_timer(uc, timeout * 1000); // microseconds -> nanoseconds
|
||||||
|
|
||||||
uc->pause_all_vcpus(uc);
|
uc->pause_all_vcpus(uc);
|
||||||
// emulation is done
|
// emulation is done
|
||||||
uc->emulation_done = true;
|
uc->emulation_done = true;
|
||||||
@ -964,41 +965,42 @@ MemoryRegion *memory_mapping(struct uc_struct* uc, uint64_t address)
|
|||||||
}
|
}
|
||||||
|
|
||||||
UNICORN_EXPORT
|
UNICORN_EXPORT
|
||||||
uc_err uc_hook_add(uc_engine *uc, uc_hook *hh, int type, void *callback, void *user_data, ...)
|
uc_err uc_hook_add(uc_engine *uc, uc_hook *hh, int type, void *callback,
|
||||||
|
void *user_data, uint64_t begin, uint64_t end, ...)
|
||||||
{
|
{
|
||||||
va_list valist;
|
|
||||||
int ret = UC_ERR_OK;
|
int ret = UC_ERR_OK;
|
||||||
|
int i = 0;
|
||||||
va_start(valist, user_data);
|
|
||||||
|
|
||||||
struct hook *hook = calloc(1, sizeof(struct hook));
|
struct hook *hook = calloc(1, sizeof(struct hook));
|
||||||
if (hook == NULL) {
|
if (hook == NULL) {
|
||||||
return UC_ERR_NOMEM;
|
return UC_ERR_NOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hook->begin = begin;
|
||||||
|
hook->end = end;
|
||||||
hook->type = type;
|
hook->type = type;
|
||||||
hook->callback = callback;
|
hook->callback = callback;
|
||||||
hook->user_data = user_data;
|
hook->user_data = user_data;
|
||||||
hook->refs = 0;
|
hook->refs = 0;
|
||||||
*hh = (uc_hook)hook;
|
*hh = (uc_hook)hook;
|
||||||
|
|
||||||
// everybody but HOOK_INSN gets begin/end, so exit early here.
|
// UC_HOOK_INSN has an extra argument for instruction ID
|
||||||
if (type & UC_HOOK_INSN) {
|
if (type & UC_HOOK_INSN) {
|
||||||
|
va_list valist;
|
||||||
|
|
||||||
|
va_start(valist, end);
|
||||||
hook->insn = va_arg(valist, int);
|
hook->insn = va_arg(valist, int);
|
||||||
hook->begin = 1;
|
va_end(valist);
|
||||||
hook->end = 0;
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
hook->refs++;
|
hook->refs++;
|
||||||
return UC_ERR_OK;
|
return UC_ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
hook->begin = va_arg(valist, uint64_t);
|
|
||||||
hook->end = va_arg(valist, uint64_t);
|
|
||||||
va_end(valist);
|
|
||||||
|
|
||||||
int i = 0;
|
|
||||||
while ((type >> i) > 0) {
|
while ((type >> i) > 0) {
|
||||||
if ((type >> i) & 1) {
|
if ((type >> i) & 1) {
|
||||||
// TODO: invalid hook error?
|
// TODO: invalid hook error?
|
||||||
|
Loading…
Reference in New Issue
Block a user