add new API uc_option() and option UC_OPT_WINDOWS_TIB. see issue #422

This commit is contained in:
Nguyen Anh Quynh 2016-03-22 13:42:32 +08:00
parent d2ffea0e88
commit 66526d775b
9 changed files with 71 additions and 0 deletions

View file

@ -63,6 +63,8 @@ module Common =
let UC_ERR_FETCH_UNALIGNED = 18
let UC_ERR_HOOK_EXIST = 19
let UC_ERR_RESOURCE = 20
let UC_ERR_OPT_INVALID = 21
let UC_OPT_WINDOWS_TIB = 1
let UC_MEM_READ = 16
let UC_MEM_WRITE = 17
let UC_MEM_FETCH = 18

View file

@ -58,6 +58,8 @@ const (
ERR_FETCH_UNALIGNED = 18
ERR_HOOK_EXIST = 19
ERR_RESOURCE = 20
ERR_OPT_INVALID = 21
OPT_WINDOWS_TIB = 1
MEM_READ = 16
MEM_WRITE = 17
MEM_FETCH = 18

View file

@ -60,6 +60,8 @@ public interface UnicornConst {
public static final int UC_ERR_FETCH_UNALIGNED = 18;
public static final int UC_ERR_HOOK_EXIST = 19;
public static final int UC_ERR_RESOURCE = 20;
public static final int UC_ERR_OPT_INVALID = 21;
public static final int UC_OPT_WINDOWS_TIB = 1;
public static final int UC_MEM_READ = 16;
public static final int UC_MEM_WRITE = 17;
public static final int UC_MEM_FETCH = 18;

View file

@ -110,6 +110,7 @@ _setup_prototype(_uc, "uc_mem_map_ptr", ucerr, uc_engine, ctypes.c_uint64, ctype
_setup_prototype(_uc, "uc_mem_unmap", ucerr, uc_engine, ctypes.c_uint64, ctypes.c_size_t)
_setup_prototype(_uc, "uc_mem_protect", ucerr, uc_engine, ctypes.c_uint64, ctypes.c_size_t, ctypes.c_uint32)
_setup_prototype(_uc, "uc_query", ucerr, uc_engine, ctypes.c_uint32, ctypes.POINTER(ctypes.c_size_t))
_setup_prototype(_ks, "uc_option", ucerr, uc_engine, c_int, c_void_p)
# uc_hook_add is special due to variable number of arguments
_uc.uc_hook_add = getattr(_uc, "uc_hook_add")
@ -322,6 +323,19 @@ class Uc(object):
raise UcError(status)
return result.value
# return Windows TIB
@property
def windows_tib(self):
return self._windows_tib
# Windows TIB setter
@windows_tib.setter
def windows_tib(self, base_addr):
status = _uc.uc_option(self._uch, UC_OPT_WINDOWS_TIB, base_addr)
if status != UC_ERR_OK:
raise UcError(status)
# save this address
self._windows_tib = base_addr
def _hookcode_cb(self, handle, address, size, user_data):
# call user's callback with self object

View file

@ -56,6 +56,8 @@ UC_ERR_WRITE_UNALIGNED = 17
UC_ERR_FETCH_UNALIGNED = 18
UC_ERR_HOOK_EXIST = 19
UC_ERR_RESOURCE = 20
UC_ERR_OPT_INVALID = 21
UC_OPT_WINDOWS_TIB = 1
UC_MEM_READ = 16
UC_MEM_WRITE = 17
UC_MEM_FETCH = 18

View file

@ -68,6 +68,8 @@ typedef void (*uc_args_uc_long_t)(struct uc_struct*, unsigned long);
typedef void (*uc_args_uc_u64_t)(struct uc_struct *, uint64_t addr);
typedef uc_err (*uc_args_uc_int_size_t)(struct uc_struct*, uc_opt_type, size_t);
typedef MemoryRegion* (*uc_args_uc_ram_size_t)(struct uc_struct*, ram_addr_t begin, size_t size, uint32_t perms);
typedef MemoryRegion* (*uc_args_uc_ram_size_ptr_t)(struct uc_struct*, ram_addr_t begin, size_t size, uint32_t perms, void *ptr);
@ -172,6 +174,8 @@ struct uc_struct {
uc_mem_unmap_t memory_unmap;
uc_readonly_mem_t readonly_mem;
uc_mem_redirect_t mem_redirect;
uc_args_uc_int_size_t option;
// list of cpu
void* cpu;

View file

@ -138,8 +138,14 @@ typedef enum uc_err {
UC_ERR_FETCH_UNALIGNED, // Unaligned fetch
UC_ERR_HOOK_EXIST, // hook for this event already existed
UC_ERR_RESOURCE, // Insufficient resource: uc_emu_start()
UC_ERR_OPT_INVALID, // Invalid option type: uc_option()
} uc_err;
// Runtime option for the Unicorn engine
typedef enum uc_opt_type {
UC_OPT_WINDOWS_TIB = 1, // Setup Windows Thread Information Block
} uc_opt_type;
/*
Callback function for tracing code (UC_HOOK_CODE & UC_HOOK_BLOCK)
@ -588,6 +594,20 @@ uc_err uc_mem_protect(uc_engine *uc, uint64_t address, size_t size, uint32_t per
UNICORN_EXPORT
uc_err uc_mem_regions(uc_engine *uc, uc_mem_region **regions, uint32_t *count);
/*
Set option for Unicorn engine at runtime
@uc: handle returned by uc_open()
@type: type of option to be set
@value: option value corresponding with @type
@return: UC_ERR_OK on success, or other value on failure.
Refer to uc_err enum for detailed error.
*/
UNICORN_EXPORT
uc_err uc_option(uc_engine *uc, uc_opt_type type, size_t value);
#ifdef __cplusplus
}
#endif

View file

@ -1121,6 +1121,19 @@ static bool x86_stop_interrupt(int intno)
}
}
static uc_err x86_option(struct uc_struct *uc, uc_opt_type type, size_t value)
{
CPUState *mycpu = first_cpu;
if (type != UC_OPT_WINDOWS_TIB)
return UC_ERR_OPT_INVALID;
// TODO: setup limit?
X86_CPU(uc, mycpu)->env.segs[R_FS].base = value;
return UC_ERR_OK;
}
void pc_machine_init(struct uc_struct *uc);
__attribute__ ((visibility ("default")))
@ -1138,5 +1151,8 @@ void x86_uc_init(struct uc_struct* uc)
uc->release = x86_release;
uc->set_pc = x86_set_pc;
uc->stop_interrupt = x86_stop_interrupt;
uc->option = x86_option;
uc_common_init(uc);
}

9
uc.c
View file

@ -1108,3 +1108,12 @@ uc_err uc_query(uc_engine *uc, uc_query_type type, size_t *result)
return UC_ERR_OK;
}
UNICORN_EXPORT
uc_err uc_option(uc_engine *uc, uc_opt_type type, size_t value)
{
if (uc->option)
return uc->option(uc, type, value);
else
return UC_ERR_OPT_INVALID;
}