mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-02-03 15:01:11 +00:00
add new API uc_option() and option UC_OPT_WINDOWS_TIB. see issue #422
This commit is contained in:
parent
d2ffea0e88
commit
66526d775b
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue