Merge branch 'master' into java_dev
This commit is contained in:
@@ -1,8 +1,12 @@
|
||||
#include <unicorn/unicorn.h>
|
||||
#include "_cgo_export.h"
|
||||
|
||||
uc_err uc_hook_add2(uch handle, uch *h2, uc_hook_t type, void *callback, void *user_data, int extra) {
|
||||
return uc_hook_add(handle, h2, type, callback, user_data, extra);
|
||||
uc_err uc_hook_add_i1(uch handle, uch *h2, uc_hook_t type, void *callback, void *user, int arg1) {
|
||||
return uc_hook_add(handle, h2, type, callback, user, arg1);
|
||||
}
|
||||
|
||||
uc_err uc_hook_add_u2(uch handle, uch *h2, uc_hook_t type, void *callback, void *user, uint64_t arg1, uint64_t arg2) {
|
||||
return uc_hook_add(handle, h2, type, callback, user, arg1, arg2);
|
||||
}
|
||||
|
||||
void hookCode_cgo(uch handle, uint64_t addr, uint32_t size, void *user) {
|
||||
|
||||
@@ -60,21 +60,26 @@ func hookX86Syscall(handle C.uch, user unsafe.Pointer) {
|
||||
|
||||
var hookRetain = make(map[C.uch]*HookData)
|
||||
|
||||
func (u *Uc) HookAdd(htype int, cb interface{}, insn ...int) (C.uch, error) {
|
||||
func (u *Uc) HookAdd(htype int, cb interface{}, extra ...uint64) (C.uch, error) {
|
||||
var callback unsafe.Pointer
|
||||
var extra C.int
|
||||
var iarg1 C.int
|
||||
var uarg1, uarg2 C.uint64_t
|
||||
rangeMode := false
|
||||
switch htype {
|
||||
case UC_HOOK_BLOCK, UC_HOOK_CODE:
|
||||
rangeMode = true
|
||||
callback = C.hookCode_cgo
|
||||
case UC_HOOK_MEM_INVALID:
|
||||
rangeMode = true
|
||||
callback = C.hookMemInvalid_cgo
|
||||
case UC_HOOK_MEM_READ, UC_HOOK_MEM_WRITE, UC_HOOK_MEM_READ_WRITE:
|
||||
rangeMode = true
|
||||
callback = C.hookMemAccess_cgo
|
||||
case UC_HOOK_INTR:
|
||||
callback = C.hookInterrupt_cgo
|
||||
case UC_HOOK_INSN:
|
||||
extra = C.int(insn[0])
|
||||
switch extra {
|
||||
iarg1 = C.int(extra[0])
|
||||
switch iarg1 {
|
||||
case UC_X86_INS_IN:
|
||||
callback = C.hookX86In_cgo
|
||||
case UC_X86_INS_OUT:
|
||||
@@ -89,7 +94,17 @@ func (u *Uc) HookAdd(htype int, cb interface{}, insn ...int) (C.uch, error) {
|
||||
}
|
||||
var h2 C.uch
|
||||
data := &HookData{u, cb}
|
||||
C.uc_hook_add2(u.Handle, &h2, C.uc_hook_t(htype), callback, unsafe.Pointer(data), extra)
|
||||
if rangeMode {
|
||||
if len(extra) == 2 {
|
||||
uarg1 = C.uint64_t(extra[0])
|
||||
uarg2 = C.uint64_t(extra[1])
|
||||
} else {
|
||||
uarg1, uarg2 = 1, 0
|
||||
}
|
||||
C.uc_hook_add_u2(u.Handle, &h2, C.uc_hook_t(htype), callback, unsafe.Pointer(data), uarg1, uarg2)
|
||||
} else {
|
||||
C.uc_hook_add_i1(u.Handle, &h2, C.uc_hook_t(htype), callback, unsafe.Pointer(data), iarg1)
|
||||
}
|
||||
hookRetain[h2] = data
|
||||
return h2, nil
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
uc_err uc_hook_add2(uch handle, uch *h2, uc_hook_t type, void *callback, void *user_data, int extra);
|
||||
uc_err uc_hook_add_i1(uch handle, uch *h2, uc_hook_t type, void *callback, void *user_data, int arg1);
|
||||
uc_err uc_hook_add_u2(uch handle, uch *h2, uc_hook_t type, void *callback, void *user_data, uint64_t arg1, uint64_t arg2);
|
||||
void hookCode_cgo(uch handle, uint64_t addr, uint32_t size, void *user);
|
||||
bool hookMemInvalid_cgo(uch handle, uc_mem_type type, uint64_t addr, int size, int64_t value, void *user);
|
||||
void hookMemAccess_cgo(uch handle, uc_mem_type type, uint64_t addr, int size, int64_t value, void *user);
|
||||
|
||||
@@ -34,25 +34,27 @@ const (
|
||||
UC_MODE_MIPS64 = 8
|
||||
|
||||
UC_ERR_OK = 0
|
||||
UC_ERR_OOM = 1
|
||||
UC_ERR_NOMEM = 1
|
||||
UC_ERR_ARCH = 2
|
||||
UC_ERR_HANDLE = 3
|
||||
UC_ERR_UCH = 4
|
||||
UC_ERR_MODE = 5
|
||||
UC_ERR_VERSION = 6
|
||||
UC_ERR_MEM_READ = 7
|
||||
UC_ERR_MEM_WRITE = 8
|
||||
UC_ERR_CODE_INVALID = 9
|
||||
UC_ERR_HOOK = 10
|
||||
UC_ERR_INSN_INVALID = 11
|
||||
UC_ERR_MAP = 12
|
||||
UC_ERR_MEM_WRITE_NW = 13
|
||||
UC_ERR_MEM_READ_NR = 14
|
||||
UC_ERR_MODE = 4
|
||||
UC_ERR_VERSION = 5
|
||||
UC_ERR_MEM_READ = 6
|
||||
UC_ERR_MEM_WRITE = 7
|
||||
UC_ERR_CODE_INVALID = 8
|
||||
UC_ERR_HOOK = 9
|
||||
UC_ERR_INSN_INVALID = 10
|
||||
UC_ERR_MAP = 11
|
||||
UC_ERR_WRITE_PROT = 12
|
||||
UC_ERR_READ_PROT = 13
|
||||
UC_ERR_EXEC_PROT = 14
|
||||
UC_ERR_INVAL = 15
|
||||
UC_MEM_READ = 16
|
||||
UC_MEM_WRITE = 17
|
||||
UC_MEM_READ_WRITE = 18
|
||||
UC_MEM_WRITE_NW = 19
|
||||
UC_MEM_READ_NR = 20
|
||||
UC_MEM_WRITE_PROT = 19
|
||||
UC_MEM_READ_PROT = 20
|
||||
UC_MEM_EXEC_PROT = 21
|
||||
UC_HOOK_INTR = 32
|
||||
UC_HOOK_INSN = 33
|
||||
UC_HOOK_CODE = 34
|
||||
@@ -65,5 +67,6 @@ const (
|
||||
UC_PROT_NONE = 0
|
||||
UC_PROT_READ = 1
|
||||
UC_PROT_WRITE = 2
|
||||
UC_PROT_ALL = 3
|
||||
UC_PROT_EXEC = 4
|
||||
UC_PROT_ALL = 7
|
||||
)
|
||||
@@ -60,37 +60,41 @@ def _setup_prototype(lib, fname, restype, *argtypes):
|
||||
getattr(lib, fname).restype = restype
|
||||
getattr(lib, fname).argtypes = argtypes
|
||||
|
||||
_setup_prototype(_uc, "uc_version", ctypes.c_int, ctypes.POINTER(ctypes.c_int), ctypes.POINTER(ctypes.c_int))
|
||||
ucerr = ctypes.c_int
|
||||
ucengine = ctypes.c_void_p
|
||||
uc_hook_h = ctypes.c_size_t
|
||||
|
||||
_setup_prototype(_uc, "uc_version", ctypes.c_uint, ctypes.POINTER(ctypes.c_int), ctypes.POINTER(ctypes.c_int))
|
||||
_setup_prototype(_uc, "uc_arch_supported", ctypes.c_bool, ctypes.c_int)
|
||||
_setup_prototype(_uc, "uc_open", ctypes.c_int, ctypes.c_uint, ctypes.c_uint, ctypes.POINTER(ctypes.c_size_t))
|
||||
_setup_prototype(_uc, "uc_close", ctypes.c_int, ctypes.POINTER(ctypes.c_size_t))
|
||||
_setup_prototype(_uc, "uc_strerror", ctypes.c_char_p, ctypes.c_int)
|
||||
_setup_prototype(_uc, "uc_errno", ctypes.c_int, ctypes.c_size_t)
|
||||
_setup_prototype(_uc, "uc_reg_read", ctypes.c_int, ctypes.c_size_t, ctypes.c_int, ctypes.c_void_p)
|
||||
_setup_prototype(_uc, "uc_reg_write", ctypes.c_int, ctypes.c_size_t, ctypes.c_int, ctypes.c_void_p)
|
||||
_setup_prototype(_uc, "uc_mem_read", ctypes.c_int, ctypes.c_size_t, ctypes.c_uint64, ctypes.POINTER(ctypes.c_char), ctypes.c_size_t)
|
||||
_setup_prototype(_uc, "uc_mem_write", ctypes.c_int, ctypes.c_size_t, ctypes.c_uint64, ctypes.POINTER(ctypes.c_char), ctypes.c_size_t)
|
||||
_setup_prototype(_uc, "uc_emu_start", ctypes.c_int, ctypes.c_size_t, ctypes.c_uint64, ctypes.c_uint64, ctypes.c_uint64, ctypes.c_size_t)
|
||||
_setup_prototype(_uc, "uc_emu_stop", ctypes.c_int, ctypes.c_size_t)
|
||||
_setup_prototype(_uc, "uc_hook_del", ctypes.c_int, ctypes.c_size_t, ctypes.POINTER(ctypes.c_size_t))
|
||||
_setup_prototype(_uc, "uc_mem_map", ctypes.c_int, ctypes.c_size_t, ctypes.c_uint64, ctypes.c_size_t, ctypes.c_uint32)
|
||||
_setup_prototype(_uc, "uc_open", ucerr, ctypes.c_uint, ctypes.c_uint, ctypes.POINTER(ucengine))
|
||||
_setup_prototype(_uc, "uc_close", ucerr, ucengine)
|
||||
_setup_prototype(_uc, "uc_strerror", ctypes.c_char_p, ucerr)
|
||||
_setup_prototype(_uc, "uc_errno", ucerr, ucengine)
|
||||
_setup_prototype(_uc, "uc_reg_read", ucerr, ucengine, ctypes.c_int, ctypes.c_void_p)
|
||||
_setup_prototype(_uc, "uc_reg_write", ucerr, ucengine, ctypes.c_int, ctypes.c_void_p)
|
||||
_setup_prototype(_uc, "uc_mem_read", ucerr, ucengine, ctypes.c_uint64, ctypes.POINTER(ctypes.c_char), ctypes.c_size_t)
|
||||
_setup_prototype(_uc, "uc_mem_write", ucerr, ucengine, ctypes.c_uint64, ctypes.POINTER(ctypes.c_char), ctypes.c_size_t)
|
||||
_setup_prototype(_uc, "uc_emu_start", ucerr, ucengine, ctypes.c_uint64, ctypes.c_uint64, ctypes.c_uint64, ctypes.c_size_t)
|
||||
_setup_prototype(_uc, "uc_emu_stop", ucerr, ucengine)
|
||||
_setup_prototype(_uc, "uc_hook_del", ucerr, ucengine, uc_hook_h)
|
||||
_setup_prototype(_uc, "uc_mem_map", ucerr, ucengine, ctypes.c_uint64, ctypes.c_size_t, ctypes.c_uint32)
|
||||
|
||||
# uc_hook_add is special due to variable number of arguments
|
||||
_uc.uc_hook_add = getattr(_uc, "uc_hook_add")
|
||||
_uc.uc_hook_add.restype = ctypes.c_int
|
||||
_uc.uc_hook_add.restype = ucerr
|
||||
|
||||
UC_HOOK_CODE_CB = ctypes.CFUNCTYPE(None, ctypes.c_size_t, ctypes.c_uint64, ctypes.c_size_t, ctypes.c_void_p)
|
||||
UC_HOOK_MEM_INVALID_CB = ctypes.CFUNCTYPE(ctypes.c_bool, ctypes.c_size_t, ctypes.c_int, \
|
||||
UC_HOOK_CODE_CB = ctypes.CFUNCTYPE(None, ucengine, ctypes.c_uint64, ctypes.c_size_t, ctypes.c_void_p)
|
||||
UC_HOOK_MEM_INVALID_CB = ctypes.CFUNCTYPE(ctypes.c_bool, ucengine, ctypes.c_int, \
|
||||
ctypes.c_uint64, ctypes.c_int, ctypes.c_int64, ctypes.c_void_p)
|
||||
UC_HOOK_MEM_ACCESS_CB = ctypes.CFUNCTYPE(None, ctypes.c_size_t, ctypes.c_int, \
|
||||
UC_HOOK_MEM_ACCESS_CB = ctypes.CFUNCTYPE(None, ucengine, ctypes.c_int, \
|
||||
ctypes.c_uint64, ctypes.c_int, ctypes.c_int64, ctypes.c_void_p)
|
||||
UC_HOOK_INTR_CB = ctypes.CFUNCTYPE(None, ctypes.c_size_t, ctypes.c_uint32, \
|
||||
UC_HOOK_INTR_CB = ctypes.CFUNCTYPE(None, ucengine, ctypes.c_uint32, \
|
||||
ctypes.c_void_p)
|
||||
UC_HOOK_INSN_IN_CB = ctypes.CFUNCTYPE(ctypes.c_uint32, ctypes.c_size_t, ctypes.c_uint32, \
|
||||
UC_HOOK_INSN_IN_CB = ctypes.CFUNCTYPE(ctypes.c_uint32, ucengine, ctypes.c_uint32, \
|
||||
ctypes.c_int, ctypes.c_void_p)
|
||||
UC_HOOK_INSN_OUT_CB = ctypes.CFUNCTYPE(None, ctypes.c_size_t, ctypes.c_uint32, \
|
||||
UC_HOOK_INSN_OUT_CB = ctypes.CFUNCTYPE(None, ucengine, ctypes.c_uint32, \
|
||||
ctypes.c_int, ctypes.c_uint32, ctypes.c_void_p)
|
||||
UC_HOOK_INSN_SYSCALL_CB = ctypes.CFUNCTYPE(None, ctypes.c_size_t, ctypes.c_void_p)
|
||||
UC_HOOK_INSN_SYSCALL_CB = ctypes.CFUNCTYPE(None, ucengine, ctypes.c_void_p)
|
||||
|
||||
|
||||
# access to error code via @errno of UcError
|
||||
@@ -130,7 +134,7 @@ class Uc(object):
|
||||
raise UcError(UC_ERR_VERSION)
|
||||
|
||||
self._arch, self._mode = arch, mode
|
||||
self._uch = ctypes.c_size_t()
|
||||
self._uch = ctypes.c_void_p()
|
||||
status = _uc.uc_open(arch, mode, ctypes.byref(self._uch))
|
||||
if status != UC_ERR_OK:
|
||||
self._uch = None
|
||||
@@ -144,7 +148,8 @@ class Uc(object):
|
||||
def __del__(self):
|
||||
if self._uch:
|
||||
try:
|
||||
status = _uc.uc_close(ctypes.byref(self._uch))
|
||||
status = _uc.uc_close(self._uch)
|
||||
self._uch = None
|
||||
if status != UC_ERR_OK:
|
||||
raise UcError(status)
|
||||
except: # _uc might be pulled from under our feet
|
||||
@@ -251,7 +256,7 @@ class Uc(object):
|
||||
|
||||
# add a hook
|
||||
def hook_add(self, htype, callback, user_data=None, arg1=1, arg2=0):
|
||||
_h2 = ctypes.c_size_t()
|
||||
_h2 = uc_hook_h()
|
||||
|
||||
# save callback & user_data
|
||||
self._callback_count += 1
|
||||
@@ -296,8 +301,8 @@ class Uc(object):
|
||||
|
||||
# delete a hook
|
||||
def hook_del(self, h):
|
||||
_h = ctypes.c_size_t(h)
|
||||
status = _uc.uc_hook_del(self._uch, ctypes.byref(_h))
|
||||
_h = uc_hook_h(h)
|
||||
status = _uc.uc_hook_del(self._uch, _h)
|
||||
if status != UC_ERR_OK:
|
||||
raise UcError(status)
|
||||
h = 0
|
||||
|
||||
@@ -32,25 +32,27 @@ UC_MODE_MIPS32 = 4
|
||||
UC_MODE_MIPS64 = 8
|
||||
|
||||
UC_ERR_OK = 0
|
||||
UC_ERR_OOM = 1
|
||||
UC_ERR_NOMEM = 1
|
||||
UC_ERR_ARCH = 2
|
||||
UC_ERR_HANDLE = 3
|
||||
UC_ERR_UCH = 4
|
||||
UC_ERR_MODE = 5
|
||||
UC_ERR_VERSION = 6
|
||||
UC_ERR_MEM_READ = 7
|
||||
UC_ERR_MEM_WRITE = 8
|
||||
UC_ERR_CODE_INVALID = 9
|
||||
UC_ERR_HOOK = 10
|
||||
UC_ERR_INSN_INVALID = 11
|
||||
UC_ERR_MAP = 12
|
||||
UC_ERR_MEM_WRITE_NW = 13
|
||||
UC_ERR_MEM_READ_NR = 14
|
||||
UC_ERR_MODE = 4
|
||||
UC_ERR_VERSION = 5
|
||||
UC_ERR_MEM_READ = 6
|
||||
UC_ERR_MEM_WRITE = 7
|
||||
UC_ERR_CODE_INVALID = 8
|
||||
UC_ERR_HOOK = 9
|
||||
UC_ERR_INSN_INVALID = 10
|
||||
UC_ERR_MAP = 11
|
||||
UC_ERR_WRITE_PROT = 12
|
||||
UC_ERR_READ_PROT = 13
|
||||
UC_ERR_EXEC_PROT = 14
|
||||
UC_ERR_INVAL = 15
|
||||
UC_MEM_READ = 16
|
||||
UC_MEM_WRITE = 17
|
||||
UC_MEM_READ_WRITE = 18
|
||||
UC_MEM_WRITE_NW = 19
|
||||
UC_MEM_READ_NR = 20
|
||||
UC_MEM_WRITE_PROT = 19
|
||||
UC_MEM_READ_PROT = 20
|
||||
UC_MEM_EXEC_PROT = 21
|
||||
UC_HOOK_INTR = 32
|
||||
UC_HOOK_INSN = 33
|
||||
UC_HOOK_CODE = 34
|
||||
@@ -63,4 +65,5 @@ UC_HOOK_MEM_READ_WRITE = 39
|
||||
UC_PROT_NONE = 0
|
||||
UC_PROT_READ = 1
|
||||
UC_PROT_WRITE = 2
|
||||
UC_PROT_ALL = 3
|
||||
UC_PROT_EXEC = 4
|
||||
UC_PROT_ALL = 7
|
||||
|
||||
Reference in New Issue
Block a user