mirror of
				https://github.com/yuzu-emu/unicorn.git
				synced 2025-11-04 14:14:57 +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