mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-07-03 17:48:16 +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_FETCH_UNALIGNED = 18
|
||||||
let UC_ERR_HOOK_EXIST = 19
|
let UC_ERR_HOOK_EXIST = 19
|
||||||
let UC_ERR_RESOURCE = 20
|
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_READ = 16
|
||||||
let UC_MEM_WRITE = 17
|
let UC_MEM_WRITE = 17
|
||||||
let UC_MEM_FETCH = 18
|
let UC_MEM_FETCH = 18
|
||||||
|
|
|
@ -58,6 +58,8 @@ const (
|
||||||
ERR_FETCH_UNALIGNED = 18
|
ERR_FETCH_UNALIGNED = 18
|
||||||
ERR_HOOK_EXIST = 19
|
ERR_HOOK_EXIST = 19
|
||||||
ERR_RESOURCE = 20
|
ERR_RESOURCE = 20
|
||||||
|
ERR_OPT_INVALID = 21
|
||||||
|
OPT_WINDOWS_TIB = 1
|
||||||
MEM_READ = 16
|
MEM_READ = 16
|
||||||
MEM_WRITE = 17
|
MEM_WRITE = 17
|
||||||
MEM_FETCH = 18
|
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_FETCH_UNALIGNED = 18;
|
||||||
public static final int UC_ERR_HOOK_EXIST = 19;
|
public static final int UC_ERR_HOOK_EXIST = 19;
|
||||||
public static final int UC_ERR_RESOURCE = 20;
|
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_READ = 16;
|
||||||
public static final int UC_MEM_WRITE = 17;
|
public static final int UC_MEM_WRITE = 17;
|
||||||
public static final int UC_MEM_FETCH = 18;
|
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_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_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(_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_hook_add is special due to variable number of arguments
|
||||||
_uc.uc_hook_add = getattr(_uc, "uc_hook_add")
|
_uc.uc_hook_add = getattr(_uc, "uc_hook_add")
|
||||||
|
@ -322,6 +323,19 @@ class Uc(object):
|
||||||
raise UcError(status)
|
raise UcError(status)
|
||||||
return result.value
|
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):
|
def _hookcode_cb(self, handle, address, size, user_data):
|
||||||
# call user's callback with self object
|
# call user's callback with self object
|
||||||
|
|
|
@ -56,6 +56,8 @@ UC_ERR_WRITE_UNALIGNED = 17
|
||||||
UC_ERR_FETCH_UNALIGNED = 18
|
UC_ERR_FETCH_UNALIGNED = 18
|
||||||
UC_ERR_HOOK_EXIST = 19
|
UC_ERR_HOOK_EXIST = 19
|
||||||
UC_ERR_RESOURCE = 20
|
UC_ERR_RESOURCE = 20
|
||||||
|
UC_ERR_OPT_INVALID = 21
|
||||||
|
UC_OPT_WINDOWS_TIB = 1
|
||||||
UC_MEM_READ = 16
|
UC_MEM_READ = 16
|
||||||
UC_MEM_WRITE = 17
|
UC_MEM_WRITE = 17
|
||||||
UC_MEM_FETCH = 18
|
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 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_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);
|
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_mem_unmap_t memory_unmap;
|
||||||
uc_readonly_mem_t readonly_mem;
|
uc_readonly_mem_t readonly_mem;
|
||||||
uc_mem_redirect_t mem_redirect;
|
uc_mem_redirect_t mem_redirect;
|
||||||
|
uc_args_uc_int_size_t option;
|
||||||
|
|
||||||
// list of cpu
|
// list of cpu
|
||||||
void* cpu;
|
void* cpu;
|
||||||
|
|
||||||
|
|
|
@ -138,8 +138,14 @@ typedef enum uc_err {
|
||||||
UC_ERR_FETCH_UNALIGNED, // Unaligned fetch
|
UC_ERR_FETCH_UNALIGNED, // Unaligned fetch
|
||||||
UC_ERR_HOOK_EXIST, // hook for this event already existed
|
UC_ERR_HOOK_EXIST, // hook for this event already existed
|
||||||
UC_ERR_RESOURCE, // Insufficient resource: uc_emu_start()
|
UC_ERR_RESOURCE, // Insufficient resource: uc_emu_start()
|
||||||
|
UC_ERR_OPT_INVALID, // Invalid option type: uc_option()
|
||||||
} uc_err;
|
} 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)
|
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
|
UNICORN_EXPORT
|
||||||
uc_err uc_mem_regions(uc_engine *uc, uc_mem_region **regions, uint32_t *count);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#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);
|
void pc_machine_init(struct uc_struct *uc);
|
||||||
|
|
||||||
__attribute__ ((visibility ("default")))
|
__attribute__ ((visibility ("default")))
|
||||||
|
@ -1138,5 +1151,8 @@ void x86_uc_init(struct uc_struct* uc)
|
||||||
uc->release = x86_release;
|
uc->release = x86_release;
|
||||||
uc->set_pc = x86_set_pc;
|
uc->set_pc = x86_set_pc;
|
||||||
uc->stop_interrupt = x86_stop_interrupt;
|
uc->stop_interrupt = x86_stop_interrupt;
|
||||||
|
uc->option = x86_option;
|
||||||
uc_common_init(uc);
|
uc_common_init(uc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
9
uc.c
9
uc.c
|
@ -1108,3 +1108,12 @@ uc_err uc_query(uc_engine *uc, uc_query_type type, size_t *result)
|
||||||
|
|
||||||
return UC_ERR_OK;
|
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;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue