diff --git a/bindings/dotnet/UnicornEngine/Binding/NativeBinding.fs b/bindings/dotnet/UnicornEngine/Binding/NativeBinding.fs index efaccc48aa..6e0e2f0d74 100644 --- a/bindings/dotnet/UnicornEngine/Binding/NativeBinding.fs +++ b/bindings/dotnet/UnicornEngine/Binding/NativeBinding.fs @@ -1,4 +1,4 @@ -namespace UnicornEngine.Binding +namespace UnicornEngine.Binding open System open System.Runtime.InteropServices @@ -6,34 +6,35 @@ open System.Runtime.InteropServices module NativeBinding = [] - module private Imported = + module private Imported = [] extern Int32 uc_version(UIntPtr major, UIntPtr minor) [] - extern Int32 uc_open(UInt32 arch, UInt32 mode, UIntPtr[] engine) + + extern Int32 uc_open(UInt32 arch, UInt32 mode, UIntPtr[] engine) [] - extern Int32 uc_close(UIntPtr eng) + extern Int32 uc_close(UIntPtr eng) [] - extern Int32 uc_mem_map(UIntPtr eng, UInt64 address, UIntPtr size, UInt32 perm) + extern Int32 uc_mem_map(UIntPtr eng, UInt64 address, UInt64 size, UInt32 perm) [] - extern Int32 uc_mem_map_ptr(UIntPtr eng, UInt64 address, UIntPtr size, UInt32 perm, UIntPtr ptr) + extern Int32 uc_mem_map_ptr(UIntPtr eng, UInt64 address, UInt64 size, UInt32 perm, UIntPtr ptr) [] - extern Int32 uc_mem_unmap(UIntPtr eng, UInt64 address, UIntPtr size) + extern Int32 uc_mem_unmap(UIntPtr eng, UInt64 address, UInt64 size) [] - extern Int32 uc_mem_protect(UIntPtr eng, UInt64 address, UIntPtr size, UInt32 perms) - + extern Int32 uc_mem_protect(UIntPtr eng, UInt64 address, UInt64 size, UInt32 perms) + [] - extern Int32 uc_mem_write(UIntPtr eng, UInt64 address, Byte[] value, UIntPtr size) + extern Int32 uc_mem_write(UIntPtr eng, UInt64 address, Byte[] value, UInt64 size) [] - extern Int32 uc_mem_read(UIntPtr eng, UInt64 address, Byte[] value, UIntPtr size) + extern Int32 uc_mem_read(UIntPtr eng, UInt64 address, Byte[] value, UInt64 size) [] extern Int32 uc_reg_write(UIntPtr eng, Int32 regId, Byte[] value) @@ -67,7 +68,7 @@ module NativeBinding = [] extern Int32 uc_hook_add_arg0_arg1(UIntPtr eng, UIntPtr hh, Int32 callbackType, UIntPtr callback, IntPtr userData, UInt64 hookbegin, UInt64 hookend, UInt64 arg0, UInt64 arg1) - + let instance = {new IBinding with member thi.Version(major, minor) = uc_version(major, minor) @@ -90,4 +91,4 @@ module NativeBinding = member thi.HookAddNoarg(eng, hh, callbackType, callback, userData, hookBegin, hookEnd) = uc_hook_add_noarg(eng, hh, callbackType, callback, userData, hookBegin, hookEnd) member thi.HookAddArg0(eng, hh, callbackType, callback, userData, hookBegin, hookEnd, arg0) = uc_hook_add_arg0(eng, hh, callbackType, callback, userData, hookBegin, hookEnd, arg0) member thi.HookAddArg0Arg1(eng, hh, callbackType, callback, userData, hookBegin, hookEnd, arg0, arg1) = uc_hook_add_arg0_arg1(eng, hh, callbackType, callback, userData, hookBegin, hookEnd, arg0, arg1) - } \ No newline at end of file + } diff --git a/bindings/go/unicorn/unicorn.go b/bindings/go/unicorn/unicorn.go index 50b221adaa..2e3aad1155 100644 --- a/bindings/go/unicorn/unicorn.go +++ b/bindings/go/unicorn/unicorn.go @@ -190,14 +190,14 @@ func (u *uc) MemWrite(addr uint64, data []byte) error { if len(data) == 0 { return nil } - return errReturn(C.uc_mem_write(u.handle, C.uint64_t(addr), unsafe.Pointer(&data[0]), C.size_t(len(data)))) + return errReturn(C.uc_mem_write(u.handle, C.uint64_t(addr), unsafe.Pointer(&data[0]), C.uint64_t(len(data)))) } func (u *uc) MemReadInto(dst []byte, addr uint64) error { if len(dst) == 0 { return nil } - return errReturn(C.uc_mem_read(u.handle, C.uint64_t(addr), unsafe.Pointer(&dst[0]), C.size_t(len(dst)))) + return errReturn(C.uc_mem_read(u.handle, C.uint64_t(addr), unsafe.Pointer(&dst[0]), C.uint64_t(len(dst)))) } func (u *uc) MemRead(addr, size uint64) ([]byte, error) { @@ -206,7 +206,7 @@ func (u *uc) MemRead(addr, size uint64) ([]byte, error) { } func (u *uc) MemMapProt(addr, size uint64, prot int) error { - return errReturn(C.uc_mem_map(u.handle, C.uint64_t(addr), C.size_t(size), C.uint32_t(prot))) + return errReturn(C.uc_mem_map(u.handle, C.uint64_t(addr), C.uint64_t(size), C.uint32_t(prot))) } func (u *uc) MemMap(addr, size uint64) error { @@ -214,15 +214,15 @@ func (u *uc) MemMap(addr, size uint64) error { } func (u *uc) MemMapPtr(addr, size uint64, prot int, ptr unsafe.Pointer) error { - return errReturn(C.uc_mem_map_ptr(u.handle, C.uint64_t(addr), C.size_t(size), C.uint32_t(prot), ptr)) + return errReturn(C.uc_mem_map_ptr(u.handle, C.uint64_t(addr), C.uint64_t(size), C.uint32_t(prot), ptr)) } func (u *uc) MemProtect(addr, size uint64, prot int) error { - return errReturn(C.uc_mem_protect(u.handle, C.uint64_t(addr), C.size_t(size), C.uint32_t(prot))) + return errReturn(C.uc_mem_protect(u.handle, C.uint64_t(addr), C.uint64_t(size), C.uint32_t(prot))) } func (u *uc) MemUnmap(addr, size uint64) error { - return errReturn(C.uc_mem_unmap(u.handle, C.uint64_t(addr), C.size_t(size))) + return errReturn(C.uc_mem_unmap(u.handle, C.uint64_t(addr), C.uint64_t(size))) } func (u *uc) Query(queryType int) (uint64, error) { diff --git a/bindings/java/unicorn_Unicorn.c b/bindings/java/unicorn_Unicorn.c index fb7f220f27..10a02826a7 100644 --- a/bindings/java/unicorn_Unicorn.c +++ b/bindings/java/unicorn_Unicorn.c @@ -447,7 +447,7 @@ JNIEXPORT void JNICALL Java_unicorn_Unicorn_mem_1write uc_engine *eng = getEngine(env, self); jbyte *array = (*env)->GetByteArrayElements(env, bytes, NULL); jsize size = (*env)->GetArrayLength(env, bytes); - uc_err err = uc_mem_write(eng, (uint64_t)address, array, (size_t)size); + uc_err err = uc_mem_write(eng, (uint64_t)address, array, (uint64_t)size); if (err != UC_ERR_OK) { throwException(env, err); @@ -467,7 +467,7 @@ JNIEXPORT jbyteArray JNICALL Java_unicorn_Unicorn_mem_1read jbyteArray bytes = (*env)->NewByteArray(env, (jsize)size); jbyte *array = (*env)->GetByteArrayElements(env, bytes, NULL); - uc_err err = uc_mem_read(eng, (uint64_t)address, array, (size_t)size); + uc_err err = uc_mem_read(eng, (uint64_t)address, array, (uint64_t)size); if (err != UC_ERR_OK) { throwException(env, err); } @@ -634,7 +634,7 @@ JNIEXPORT void JNICALL Java_unicorn_Unicorn_mem_1map (JNIEnv *env, jobject self, jlong address, jlong size, jint perms) { uc_engine *eng = getEngine(env, self); - uc_err err = uc_mem_map(eng, (uint64_t)address, (size_t)size, (uint32_t)perms); + uc_err err = uc_mem_map(eng, (uint64_t)address, (uint64_t)size, (uint32_t)perms); if (err != UC_ERR_OK) { throwException(env, err); } @@ -649,7 +649,7 @@ JNIEXPORT void JNICALL Java_unicorn_Unicorn_mem_1map_1ptr (JNIEnv *env, jobject self, jlong address, jlong size, jint perms, jbyteArray block) { uc_engine *eng = getEngine(env, self); jbyte *array = (*env)->GetByteArrayElements(env, block, NULL); - uc_err err = uc_mem_map_ptr(eng, (uint64_t)address, (size_t)size, (uint32_t)perms, (void*)array); + uc_err err = uc_mem_map_ptr(eng, (uint64_t)address, (uint64_t)size, (uint32_t)perms, (void*)array); if (err != UC_ERR_OK) { throwException(env, err); } @@ -667,7 +667,7 @@ JNIEXPORT void JNICALL Java_unicorn_Unicorn_mem_1unmap (JNIEnv *env, jobject self, jlong address, jlong size) { uc_engine *eng = getEngine(env, self); - uc_err err = uc_mem_unmap(eng, (uint64_t)address, (size_t)size); + uc_err err = uc_mem_unmap(eng, (uint64_t)address, (uint64_t)size); if (err != UC_ERR_OK) { throwException(env, err); } @@ -685,7 +685,7 @@ JNIEXPORT void JNICALL Java_unicorn_Unicorn_mem_1protect (JNIEnv *env, jobject self, jlong address, jlong size, jint perms) { uc_engine *eng = getEngine(env, self); - uc_err err = uc_mem_protect(eng, (uint64_t)address, (size_t)size, (uint32_t)perms); + uc_err err = uc_mem_protect(eng, (uint64_t)address, (uint64_t)size, (uint32_t)perms); if (err != UC_ERR_OK) { throwException(env, err); } diff --git a/bindings/pascal/unicorn/Unicorn_dyn.pas b/bindings/pascal/unicorn/Unicorn_dyn.pas index 427813cf75..96f296587c 100755 --- a/bindings/pascal/unicorn/Unicorn_dyn.pas +++ b/bindings/pascal/unicorn/Unicorn_dyn.pas @@ -291,7 +291,7 @@ uc_mem_region = record for detailed error). *) uc_mem_write_ : function (uc : uc_engine; address : UInt64; const bytes : Pointer; - size : Cardinal) : uc_err; cdecl; + size : UInt64) : uc_err; cdecl; (* Read a range of bytes in memory. @@ -307,7 +307,7 @@ uc_mem_region = record for detailed error). *) uc_mem_read_ : function (uc : uc_engine; address : UInt64; bytes : Pointer; - size : Cardinal) : uc_err; cdecl; + size : UInt64) : uc_err; cdecl; (* Emulate machine code in a specific duration of time. @@ -400,7 +400,7 @@ function (uc : uc_engine; var hh : uc_hook; _type : integer; @return UC_ERR_OK on success, or other value on failure (refer to uc_err enum for detailed error). *) - uc_mem_map : function (uc : uc_engine; address : UInt64; size : Cardinal; perms : UInt32) : uc_err; cdecl; + uc_mem_map : function (uc : uc_engine; address : UInt64; size : UInt64; perms : UInt32) : uc_err; cdecl; (* @@ -422,7 +422,7 @@ function (uc : uc_engine; var hh : uc_hook; _type : integer; @return UC_ERR_OK on success, or other value on failure (refer to uc_err enum for detailed error). *) - uc_mem_map_ptr : function(uc : uc_engine; address : UInt64; size : Cardinal; perms : UInt32; ptr : Pointer) : uc_err; cdecl; + uc_mem_map_ptr : function(uc : uc_engine; address : UInt64; size : UInt64; perms : UInt32; ptr : Pointer) : uc_err; cdecl; (* @@ -438,7 +438,7 @@ function (uc : uc_engine; var hh : uc_hook; _type : integer; @return UC_ERR_OK on success, or other value on failure (refer to uc_err enum \ for detailed error). *) - uc_mem_unmap : function (uc : uc_engine; address : UInt64; size : Cardinal) : uc_err; cdecl ; + uc_mem_unmap : function (uc : uc_engine; address : UInt64; size : UInt64) : uc_err; cdecl ; (* Set memory permissions for emulation memory. @@ -456,7 +456,7 @@ function (uc : uc_engine; var hh : uc_hook; _type : integer; @return UC_ERR_OK on success, or other value on failure (refer to uc_err enum \ for detailed error). *) - uc_mem_protect : function (uc : uc_engine; address : UInt64; size : Cardinal; perms : UInt32) : uc_err; cdecl ; + uc_mem_protect : function (uc : uc_engine; address : UInt64; size : UInt64; perms : UInt32) : uc_err; cdecl ; (* Retrieve all memory regions mapped by uc_mem_map() and uc_mem_map_ptr() diff --git a/bindings/python/unicorn/unicorn.py b/bindings/python/unicorn/unicorn.py index 0aacfb135d..eb30eb0521 100644 --- a/bindings/python/unicorn/unicorn.py +++ b/bindings/python/unicorn/unicorn.py @@ -103,7 +103,7 @@ def _load_lib(path, lib_name): for _path in _path_list: if _path is None: continue - + _uc = _load_lib(_path, "libunicorn.so") if _uc is not None: # In this case, show a warning for users @@ -153,16 +153,16 @@ class uc_tb(ctypes.Structure): _setup_prototype(_uc, "uc_errno", ucerr, uc_engine) _setup_prototype(_uc, "uc_reg_read", ucerr, uc_engine, ctypes.c_int, ctypes.c_void_p) _setup_prototype(_uc, "uc_reg_write", ucerr, uc_engine, ctypes.c_int, ctypes.c_void_p) -_setup_prototype(_uc, "uc_mem_read", ucerr, uc_engine, ctypes.c_uint64, ctypes.POINTER(ctypes.c_char), ctypes.c_size_t) -_setup_prototype(_uc, "uc_mem_write", ucerr, uc_engine, ctypes.c_uint64, ctypes.POINTER(ctypes.c_char), ctypes.c_size_t) +_setup_prototype(_uc, "uc_mem_read", ucerr, uc_engine, ctypes.c_uint64, ctypes.POINTER(ctypes.c_char), ctypes.c_uint64) +_setup_prototype(_uc, "uc_mem_write", ucerr, uc_engine, ctypes.c_uint64, ctypes.POINTER(ctypes.c_char), ctypes.c_uint64) _setup_prototype(_uc, "uc_emu_start", ucerr, uc_engine, ctypes.c_uint64, ctypes.c_uint64, ctypes.c_uint64, ctypes.c_size_t) _setup_prototype(_uc, "uc_emu_stop", ucerr, uc_engine) _setup_prototype(_uc, "uc_hook_del", ucerr, uc_engine, uc_hook_h) -_setup_prototype(_uc, "uc_mmio_map", ucerr, uc_engine, ctypes.c_uint64, ctypes.c_size_t, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p) -_setup_prototype(_uc, "uc_mem_map", ucerr, uc_engine, ctypes.c_uint64, ctypes.c_size_t, ctypes.c_uint32) -_setup_prototype(_uc, "uc_mem_map_ptr", ucerr, uc_engine, ctypes.c_uint64, ctypes.c_size_t, ctypes.c_uint32, ctypes.c_void_p) -_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_mmio_map", ucerr, uc_engine, ctypes.c_uint64, ctypes.c_uint64, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p) +_setup_prototype(_uc, "uc_mem_map", ucerr, uc_engine, ctypes.c_uint64, ctypes.c_uint64, ctypes.c_uint32) +_setup_prototype(_uc, "uc_mem_map_ptr", ucerr, uc_engine, ctypes.c_uint64, ctypes.c_uint64, ctypes.c_uint32, ctypes.c_void_p) +_setup_prototype(_uc, "uc_mem_unmap", ucerr, uc_engine, ctypes.c_uint64, ctypes.c_uint64) +_setup_prototype(_uc, "uc_mem_protect", ucerr, uc_engine, ctypes.c_uint64, ctypes.c_uint64, ctypes.c_uint32) _setup_prototype(_uc, "uc_query", ucerr, uc_engine, ctypes.c_uint32, ctypes.POINTER(ctypes.c_size_t)) _setup_prototype(_uc, "uc_context_alloc", ucerr, uc_engine, ctypes.POINTER(uc_context)) _setup_prototype(_uc, "uc_free", ucerr, ctypes.c_void_p) @@ -593,7 +593,7 @@ def _mmio_map_write_cb(self, handle, offset, size, value, user_data): (cb, data) = self._callbacks[user_data] cb(self, offset, size, value, data) - def mmio_map(self, address: int, size: int, + def mmio_map(self, address: int, size: int, read_cb: UC_MMIO_READ_TYPE, user_data_read: Any, write_cb: UC_MMIO_WRITE_TYPE, user_data_write: Any): internal_read_cb = ctypes.cast(UC_MMIO_READ_CB(self._mmio_map_read_cb), UC_MMIO_READ_CB) @@ -609,7 +609,7 @@ def mmio_map(self, address: int, size: int, status = _uc.uc_mmio_map(self._uch, address, size, internal_read_cb, read_count, internal_write_cb, write_count) if status != uc.UC_ERR_OK: raise UcError(status) - + # https://docs.python.org/3/library/ctypes.html#callback-functions self._ctype_cbs.append(internal_read_cb) self._ctype_cbs.append(internal_write_cb) @@ -731,12 +731,12 @@ def __ctl(self, ctl, nr, rw): def __ctl_r(self, ctl, nr): return self.__ctl(ctl, nr, uc.UC_CTL_IO_READ) - + def __ctl_w(self, ctl, nr): return self.__ctl(ctl, nr, uc.UC_CTL_IO_WRITE) - + def __ctl_rw(self, ctl, nr): - return self.__ctl(ctl, nr, uc.UC_CTL_IO_READ_WRITE) + return self.__ctl(ctl, nr, uc.UC_CTL_IO_READ_WRITE) def __ctl_r_1_arg(self, ctl, ctp): arg = ctp() @@ -746,7 +746,7 @@ def __ctl_r_1_arg(self, ctl, ctp): def __ctl_w_1_arg(self, ctl, val, ctp): arg = ctp(val) self.ctl(self.__ctl_w(ctl, 1), arg) - + def __ctl_w_2_arg(self, ctl, val1, val2, ctp1, ctp2): arg1 = ctp1(val1) arg2 = ctp2(val2) @@ -763,7 +763,7 @@ def ctl_get_mode(self): def ctl_get_page_size(self): return self.__ctl_r_1_arg(uc.UC_CTL_UC_PAGE_SIZE, ctypes.c_uint32) - + def ctl_set_page_size(self, val: int): self.__ctl_w_1_arg(uc.UC_CTL_UC_PAGE_SIZE, val, ctypes.c_uint32) @@ -772,10 +772,10 @@ def ctl_get_arch(self): def ctl_get_timeout(self): return self.__ctl_r_1_arg(uc.UC_CTL_UC_TIMEOUT, ctypes.c_uint64) - + def ctl_exits_enabled(self, val: bool): self.__ctl_w_1_arg(uc.UC_CTL_UC_USE_EXITS, val, ctypes.c_int) - + def ctl_get_exits_cnt(self): return self.__ctl_r_1_arg(uc.UC_CTL_UC_EXITS_CNT, ctypes.c_size_t) @@ -793,7 +793,7 @@ def ctl_set_exits(self, exits: List[int]): def ctl_get_cpu_model(self): return self.__ctl_r_1_arg(uc.UC_CTL_CPU_MODEL, ctypes.c_int) - + def ctl_set_cpu_model(self, val: int): self.__ctl_w_1_arg(uc.UC_CTL_CPU_MODEL, val, ctypes.c_int) @@ -802,7 +802,7 @@ def ctl_remove_cache(self, addr: int, end: int): def ctl_request_cache(self, addr: int): return self.__ctl_rw_1_1_arg(uc.UC_CTL_TB_REQUEST_CACHE, addr, ctypes.c_uint64, uc_tb) - + def ctl_flush_tb(self): self.ctl(self.__ctl_w(uc.UC_CTL_TB_FLUSH, 0)) @@ -963,7 +963,7 @@ def size(self): @property def arch(self): return self._arch - + @property def mode(self): return self._mode @@ -1012,11 +1012,11 @@ def __del__(self): UC_HOOK_TCG_OPCODE_TYPE = Callable[[Uc, int, int, int, Any], None] UC_HOOK_CALLBACK_TYPE = Union[ - UC_HOOK_CODE_TYPE, - UC_HOOK_INSN_INVALID_TYPE, - UC_HOOK_MEM_INVALID_TYPE, - UC_HOOK_MEM_ACCESS_TYPE, - UC_HOOK_INSN_IN_TYPE, + UC_HOOK_CODE_TYPE, + UC_HOOK_INSN_INVALID_TYPE, + UC_HOOK_MEM_INVALID_TYPE, + UC_HOOK_MEM_ACCESS_TYPE, + UC_HOOK_INSN_IN_TYPE, UC_HOOK_INSN_OUT_TYPE, UC_HOOK_INSN_SYSCALL_TYPE, UC_HOOK_INSN_SYS_TYPE, diff --git a/bindings/ruby/unicorn_gem/ext/unicorn.c b/bindings/ruby/unicorn_gem/ext/unicorn.c index bb7363f8d1..20472e6833 100644 --- a/bindings/ruby/unicorn_gem/ext/unicorn.c +++ b/bindings/ruby/unicorn_gem/ext/unicorn.c @@ -37,7 +37,7 @@ void Init_unicorn_engine() { UcError = rb_define_class_under(UnicornModule, "UcError", rb_eStandardError); SavedContext = rb_define_class_under(UnicornModule, "SavedContext", rb_cObject); Hook = rb_define_class_under(UnicornModule, "Hook", rb_cObject); - + UcClass = rb_define_class_under(UnicornModule, "Uc", rb_cObject); rb_define_method(UcClass, "initialize", m_uc_initialize, 2); rb_define_method(UcClass, "emu_start", m_uc_emu_start, -1); @@ -68,7 +68,7 @@ VALUE m_uc_initialize(VALUE self, VALUE arch, VALUE mode) { VALUE uc = Data_Wrap_Struct(UcClass, 0, uc_close, _uc); rb_iv_set(self, "@uch", uc); rb_iv_set(self, "@hooks", rb_ary_new()); - + return self; } @@ -201,7 +201,7 @@ VALUE m_uc_reg_write(VALUE self, VALUE reg_id, VALUE reg_value){ int64_t tmp; uc_engine *_uc; Data_Get_Struct(rb_iv_get(self,"@uch"), uc_engine, _uc); - + uc_arch arch; uc_query(_uc, UC_QUERY_ARCH, &arch); @@ -263,7 +263,7 @@ VALUE m_uc_reg_write(VALUE self, VALUE reg_id, VALUE reg_value){ return Qnil; } } - + tmp = NUM2ULL(reg_value); err = uc_reg_write(_uc, NUM2INT(reg_id), &tmp); if (err != UC_ERR_OK) { @@ -273,17 +273,17 @@ VALUE m_uc_reg_write(VALUE self, VALUE reg_id, VALUE reg_value){ } VALUE m_uc_mem_read(VALUE self, VALUE address, VALUE size){ - size_t isize = NUM2UINT(size); - uint8_t bytes[isize]; + size_t _size = NUM2ULL(size); + uint8_t bytes[_size]; uc_err err; uc_engine *_uc; Data_Get_Struct(rb_iv_get(self,"@uch"), uc_engine, _uc); - err = uc_mem_read(_uc, NUM2ULL(address), &bytes, isize); + err = uc_mem_read(_uc, NUM2ULL(address), &bytes, _size); if (err != UC_ERR_OK) { rb_raise(UcError, "%s", uc_strerror(err)); } - return rb_str_new(bytes, isize); + return rb_str_new(bytes, _size); } VALUE m_uc_mem_write(VALUE self, VALUE address, VALUE bytes){ @@ -308,7 +308,7 @@ VALUE m_uc_mem_map(int argc, VALUE* argv, VALUE self){ if (NIL_P(perms)) perms = INT2NUM(UC_PROT_ALL); - err = uc_mem_map(_uc, NUM2ULL(address), NUM2UINT(size), NUM2UINT(perms)); + err = uc_mem_map(_uc, NUM2ULL(address), NUM2ULL(size), NUM2UINT(perms)); if (err != UC_ERR_OK) { rb_raise(UcError, "%s", uc_strerror(err)); } @@ -319,7 +319,7 @@ VALUE m_uc_mem_unmap(VALUE self, VALUE address, VALUE size){ uc_err err; uc_engine *_uc; Data_Get_Struct(rb_iv_get(self, "@uch"), uc_engine, _uc); - err = uc_mem_unmap(_uc, NUM2ULL(address), NUM2UINT(size)); + err = uc_mem_unmap(_uc, NUM2ULL(address), NUM2ULL(size)); if (err != UC_ERR_OK) { rb_raise(UcError, "%s", uc_strerror(err)); } @@ -330,7 +330,7 @@ VALUE m_uc_mem_protect(VALUE self, VALUE address, VALUE size, VALUE perms){ uc_err err; uc_engine *_uc; Data_Get_Struct(rb_iv_get(self,"@uch"), uc_engine, _uc); - err = uc_mem_protect(_uc, NUM2ULL(address), NUM2UINT(size), NUM2UINT(perms)); + err = uc_mem_protect(_uc, NUM2ULL(address), NUM2ULL(size), NUM2UINT(perms)); if (err != UC_ERR_OK) { rb_raise(UcError, "%s", uc_strerror(err)); } @@ -370,7 +370,7 @@ static bool cb_hook_mem_invalid(uc_engine *uc, uint32_t access, uint64_t address cb = hook->cb; ud = hook->ud; rUc = hook->rUc; - + return RTEST(rb_funcall(cb, rb_intern("call"), 6, rUc, UINT2NUM(access), ULL2NUM(address), UINT2NUM(size), LL2NUM(value), ud)); } @@ -438,7 +438,7 @@ VALUE m_uc_hook_add(int argc, VALUE* argv, VALUE self){ VALUE arg1; uc_engine *_uc; Data_Get_Struct(rb_iv_get(self, "@uch"), uc_engine, _uc); - + rb_scan_args(argc, argv, "24",&hook_type, &callback, &user_data, &begin, &end, &arg1); if (NIL_P(begin)) begin = ULL2NUM(1); @@ -463,7 +463,7 @@ VALUE m_uc_hook_add(int argc, VALUE* argv, VALUE self){ r_hook = Data_Wrap_Struct(Hook, mark_hook, free, hook); hooks_list = rb_iv_get(self, "@hooks"); rb_ary_push(hooks_list, r_hook); - + uint32_t htype = NUM2UINT(hook_type); if(htype == UC_HOOK_INSN){ switch(NUM2INT(arg1)){ @@ -516,7 +516,7 @@ VALUE m_uc_hook_del(VALUE self, VALUE hook){ struct hook *h; Data_Get_Struct(hook, struct hook, h); err = uc_hook_del(_uc, h->trace); - + rb_ary_delete(rb_iv_get(self, "@hooks"), hook); if (err != UC_ERR_OK) { diff --git a/bindings/rust/src/ffi.rs b/bindings/rust/src/ffi.rs index b1c04f57c0..84044b1de5 100644 --- a/bindings/rust/src/ffi.rs +++ b/bindings/rust/src/ffi.rs @@ -26,36 +26,36 @@ extern "C" { engine: uc_handle, address: u64, bytes: *const u8, - size: libc::size_t, + size: u64, ) -> uc_error; pub fn uc_mem_read( engine: uc_handle, address: u64, bytes: *mut u8, - size: libc::size_t, + size: u64, ) -> uc_error; - pub fn uc_mem_map(engine: uc_handle, address: u64, size: libc::size_t, perms: u32) -> uc_error; + pub fn uc_mem_map(engine: uc_handle, address: u64, size: u64, perms: u32) -> uc_error; pub fn uc_mem_map_ptr( engine: uc_handle, address: u64, - size: libc::size_t, + size: u64, perms: u32, ptr: *mut c_void, ) -> uc_error; pub fn uc_mmio_map( engine: uc_handle, address: u64, - size: libc::size_t, + size: u64, read_cb: *mut c_void, user_data_read: *mut c_void, write_cb: *mut c_void, user_data_write: *mut c_void, ) -> uc_error; - pub fn uc_mem_unmap(engine: uc_handle, address: u64, size: libc::size_t) -> uc_error; + pub fn uc_mem_unmap(engine: uc_handle, address: u64, size: u64) -> uc_error; pub fn uc_mem_protect( engine: uc_handle, address: u64, - size: libc::size_t, + size: u64, perms: u32, ) -> uc_error; pub fn uc_mem_regions( diff --git a/bindings/rust/src/lib.rs b/bindings/rust/src/lib.rs index cb8497c7dd..1c6acc343b 100644 --- a/bindings/rust/src/lib.rs +++ b/bindings/rust/src/lib.rs @@ -90,7 +90,7 @@ impl<'a> MmioCallbackScope<'a> { !self.regions.is_empty() } - fn unmap(&mut self, begin: u64, size: usize) { + fn unmap(&mut self, begin: u64, size: u64) { let end: u64 = begin + size as u64; self.regions = self .regions @@ -276,7 +276,7 @@ impl<'a, D> Unicorn<'a, D> { /// Read a range of bytes from memory at the specified address. pub fn mem_read(&self, address: u64, buf: &mut [u8]) -> Result<(), uc_error> { let err = - unsafe { ffi::uc_mem_read(self.get_handle(), address, buf.as_mut_ptr(), buf.len()) }; + unsafe { ffi::uc_mem_read(self.get_handle(), address, buf.as_mut_ptr(), buf.len().try_into().unwrap()) }; if err == uc_error::OK { Ok(()) } else { @@ -285,8 +285,8 @@ impl<'a, D> Unicorn<'a, D> { } /// Return a range of bytes from memory at the specified address as vector. - pub fn mem_read_as_vec(&self, address: u64, size: usize) -> Result, uc_error> { - let mut buf = vec![0; size]; + pub fn mem_read_as_vec(&self, address: u64, size: u64) -> Result, uc_error> { + let mut buf = vec![0; size.try_into().unwrap()]; let err = unsafe { ffi::uc_mem_read(self.get_handle(), address, buf.as_mut_ptr(), size) }; if err == uc_error::OK { Ok(buf) @@ -297,7 +297,7 @@ impl<'a, D> Unicorn<'a, D> { pub fn mem_write(&mut self, address: u64, bytes: &[u8]) -> Result<(), uc_error> { let err = - unsafe { ffi::uc_mem_write(self.get_handle(), address, bytes.as_ptr(), bytes.len()) }; + unsafe { ffi::uc_mem_write(self.get_handle(), address, bytes.as_ptr(), bytes.len().try_into().unwrap()) }; if err == uc_error::OK { Ok(()) } else { @@ -321,7 +321,7 @@ impl<'a, D> Unicorn<'a, D> { pub unsafe fn mem_map_ptr( &mut self, address: u64, - size: usize, + size: u64, perms: Permission, ptr: *mut c_void, ) -> Result<(), uc_error> { @@ -340,7 +340,7 @@ impl<'a, D> Unicorn<'a, D> { pub fn mem_map( &mut self, address: u64, - size: libc::size_t, + size: u64, perms: Permission, ) -> Result<(), uc_error> { let err = unsafe { ffi::uc_mem_map(self.get_handle(), address, size, perms.bits()) }; @@ -358,7 +358,7 @@ impl<'a, D> Unicorn<'a, D> { pub fn mmio_map( &mut self, address: u64, - size: libc::size_t, + size: u64, read_callback: Option, write_callback: Option, ) -> Result<(), uc_error> @@ -407,7 +407,7 @@ impl<'a, D> Unicorn<'a, D> { let rd = read_data.map(|c| c as Box); let wd = write_data.map(|c| c as Box); self.inner_mut().mmio_callbacks.push(MmioCallbackScope { - regions: vec![(address, size)], + regions: vec![(address, size.try_into().unwrap())], read_callback: rd, write_callback: wd, }); @@ -425,7 +425,7 @@ impl<'a, D> Unicorn<'a, D> { pub fn mmio_map_ro( &mut self, address: u64, - size: libc::size_t, + size: u64, callback: F, ) -> Result<(), uc_error> where @@ -446,7 +446,7 @@ impl<'a, D> Unicorn<'a, D> { pub fn mmio_map_wo( &mut self, address: u64, - size: libc::size_t, + size: u64, callback: F, ) -> Result<(), uc_error> where @@ -464,7 +464,7 @@ impl<'a, D> Unicorn<'a, D> { /// /// `address` must be aligned to 4kb or this will return `Error::ARG`. /// `size` must be a multiple of 4kb or this will return `Error::ARG`. - pub fn mem_unmap(&mut self, address: u64, size: libc::size_t) -> Result<(), uc_error> { + pub fn mem_unmap(&mut self, address: u64, size: u64) -> Result<(), uc_error> { let err = unsafe { ffi::uc_mem_unmap(self.get_handle(), address, size) }; self.mmio_unmap(address, size); @@ -476,7 +476,7 @@ impl<'a, D> Unicorn<'a, D> { } } - fn mmio_unmap(&mut self, address: u64, size: libc::size_t) { + fn mmio_unmap(&mut self, address: u64, size: u64) { for scope in self.inner_mut().mmio_callbacks.iter_mut() { scope.unmap(address, size); } @@ -492,7 +492,7 @@ impl<'a, D> Unicorn<'a, D> { pub fn mem_protect( &mut self, address: u64, - size: libc::size_t, + size: u64, perms: Permission, ) -> Result<(), uc_error> { let err = unsafe { ffi::uc_mem_protect(self.get_handle(), address, size, perms.bits()) }; diff --git a/bindings/vb6/main.cpp b/bindings/vb6/main.cpp index 140d44981a..4a73c9f3f4 100644 --- a/bindings/vb6/main.cpp +++ b/bindings/vb6/main.cpp @@ -1,8 +1,8 @@ -/* +/* stdcall unicorn engine shim layer for use with VB6 or C# - code ripped from unicorn_dynload.c - + code ripped from unicorn_dynload.c + Contributed by: FireEye FLARE team Author: David Zimmer , License: Apache 2.0 @@ -31,9 +31,9 @@ //you can find examples here: https://github.com/dzzie/VS_LIBEMU/tree/master/libemu/include //if you want to include disassembler support: -// 1) install libdasm in your compilers include directory +// 1) install libdasm in your compilers include directory // 2) add libdasm.h/.c to the project (drag and drop into VS project explorer), -// 3) remove the comment from the define below. +// 3) remove the comment from the define below. //The vb code detects the changes at runtime. //#define INCLUDE_DISASM @@ -49,21 +49,21 @@ enum hookCatagory{hc_code = 0, hc_block = 1, hc_inst = 2, hc_int = 3, hc_mem = 4, hc_memInvalid = 5}; -//tracing UC_HOOK_CODE & UC_HOOK_BLOCK -typedef void (__stdcall *vb_cb_hookcode_t) (uc_engine *uc, uint64_t address, uint32_t size, void *user_data); +//tracing UC_HOOK_CODE & UC_HOOK_BLOCK +typedef void (__stdcall *vb_cb_hookcode_t) (uc_engine *uc, uint64_t address, uint32_t size, void *user_data); vb_cb_hookcode_t vbHookcode = 0; vb_cb_hookcode_t vbHookBlock = 0; -//hooking memory UC_MEM_READ/WRITE/FETCH +//hooking memory UC_MEM_READ/WRITE/FETCH typedef void (__stdcall *vb_cb_hookmem_t) (uc_engine *uc, uc_mem_type type, uint64_t address, int size,int64_t value, void *user_data); vb_cb_hookmem_t vbHookMem = 0; -//invalid memory access UC_MEM_*_UNMAPPED and UC_MEM_*PROT events -typedef bool (__stdcall *vb_cb_eventmem_t) (uc_engine *uc, uc_mem_type type, uint64_t address, int size, int64_t value, void *user_data); +//invalid memory access UC_MEM_*_UNMAPPED and UC_MEM_*PROT events +typedef bool (__stdcall *vb_cb_eventmem_t) (uc_engine *uc, uc_mem_type type, uint64_t address, int size, int64_t value, void *user_data); vb_cb_eventmem_t vbInvalidMem = 0; -//tracing interrupts for uc_hook_intr() -typedef void (__stdcall *vb_cb_hookintr_t) (uc_engine *uc, uint32_t intno, void *user_data); +//tracing interrupts for uc_hook_intr() +typedef void (__stdcall *vb_cb_hookintr_t) (uc_engine *uc, uint32_t intno, void *user_data); vb_cb_hookintr_t vbHookInt = 0; /* @@ -172,7 +172,7 @@ unsigned int __stdcall ucs_dynload(char *path){ return uc_dyn_load(path, 0); #else*/ return 1; - //#endif + //#endif } unsigned int __stdcall ucs_version(unsigned int *major, unsigned int *minor){ @@ -230,12 +230,12 @@ uc_err __stdcall ucs_reg_read_batch(uc_engine *uc, int *regs, void **vals, int c return uc_reg_read_batch(uc, regs, vals, count); } -uc_err __stdcall ucs_mem_write(uc_engine *uc, uint64_t address, const void *bytes, size_t size){ +uc_err __stdcall ucs_mem_write(uc_engine *uc, uint64_t address, const void *bytes, uint64_t size){ #pragma EXPORT return uc_mem_write(uc, address, bytes, size); } -uc_err __stdcall ucs_mem_read(uc_engine *uc, uint64_t address, void *bytes, size_t size){ +uc_err __stdcall ucs_mem_read(uc_engine *uc, uint64_t address, void *bytes, uint64_t size){ #pragma EXPORT return uc_mem_read(uc, address, bytes, size); } @@ -255,24 +255,24 @@ uc_err __stdcall ucs_hook_del(uc_engine *uc, uc_hook hh){ return uc_hook_del(uc, hh); } -uc_err __stdcall ucs_mem_map(uc_engine *uc, uint64_t address, size_t size, uint32_t perms){ +uc_err __stdcall ucs_mem_map(uc_engine *uc, uint64_t address, uint64_t size, uint32_t perms){ #pragma EXPORT return uc_mem_map(uc, address, size, perms); } //requires link against v1.0 -uc_err __stdcall ucs_mem_map_ptr(uc_engine *uc, uint64_t address, size_t size, uint32_t perms, void *ptr){ +uc_err __stdcall ucs_mem_map_ptr(uc_engine *uc, uint64_t address, uint64_t size, uint32_t perms, void *ptr){ #pragma EXPORT return uc_mem_map_ptr(uc, address, size, perms, ptr); } -uc_err __stdcall ucs_mem_unmap(uc_engine *uc, uint64_t address, size_t size){ +uc_err __stdcall ucs_mem_unmap(uc_engine *uc, uint64_t address, uint64_t size){ #pragma EXPORT return uc_mem_unmap(uc, address, size); } -uc_err __stdcall ucs_mem_protect(uc_engine *uc, uint64_t address, size_t size, uint32_t perms){ +uc_err __stdcall ucs_mem_protect(uc_engine *uc, uint64_t address, uint64_t size, uint32_t perms){ #pragma EXPORT return uc_mem_protect(uc, address, size, perms); } @@ -304,15 +304,15 @@ uc_err __stdcall ucs_context_restore(uc_engine *uc, uc_context *context){ /* char* asprintf(char* format, ...){ - + char *ret = 0; - + if(!format) return 0; - va_list args; - va_start(args,format); - int size = _vscprintf(format, args); - + va_list args; + va_start(args,format); + int size = _vscprintf(format, args); + if(size > 0){ size++; //for null ret = (char*)malloc(size+2); @@ -338,18 +338,18 @@ int __stdcall disasm_addr(uc_engine *uc, uint32_t va, char *str, int bufLen){ readLen--; if(readLen == 0) return -2; } - + instr_len = get_instruction(&inst, data, MODE_32); if( instr_len == 0 ) return -3; get_instruction_string(&inst, FORMAT_INTEL, va, str, bufLen); - /* + /* if(inst.type == INSTRUCTION_TYPE_JMP || inst.type == INSTRUCTION_TYPE_JMPC){ if(inst.op1.type == OPERAND_TYPE_IMMEDIATE){ if(strlen(str) + 6 < bufLen){ if(getJmpTarget(str) < va){ - strcat(str," ^^"); + strcat(str," ^^"); }else{ strcat(str," vv"); } @@ -363,18 +363,18 @@ int __stdcall disasm_addr(uc_engine *uc, uint32_t va, char *str, int bufLen){ //maps and write in one shot, auto handles alignment.. -uc_err __stdcall mem_write_block(uc_engine *uc, uint64_t address, void* data, uint32_t size, uint32_t perm){ +uc_err __stdcall mem_write_block(uc_engine *uc, uint64_t address, void* data, uint64_t size, uint32_t perm){ #pragma EXPORT uc_err x; uint64_t base = address; - uint32_t sz = size; + uint64_t sz = size; while(base % 0x1000 !=0){ base--; if(base==0) break; } - + sz += address-base; //if data starts mid block, we need to alloc more than just size.. while(sz % 0x1000 !=0){ sz++; @@ -402,7 +402,7 @@ uc_err __stdcall get_memMap(uc_engine *uc, _CollectionPtr *pColl){ char tmp[200]; //max 46 chars used uc_err err = uc_mem_regions(uc, ®ions, &count); - + if (err != UC_ERR_OK) return err; for (uint32_t i = 0; i < count; i++) { @@ -411,7 +411,7 @@ uc_err __stdcall get_memMap(uc_engine *uc, _CollectionPtr *pColl){ } //free(regions); //https://github.com/unicorn-engine/unicorn/pull/373#issuecomment-271187118 - + uc_free((void*)regions); return err; @@ -456,4 +456,4 @@ unsigned int __stdcall ULong(unsigned int v1, unsigned int v2, int operation){ return -1; -} \ No newline at end of file +} diff --git a/bindings/vb6/uc_def.bas b/bindings/vb6/uc_def.bas index 43193a8a15..497fc4b25e 100644 --- a/bindings/vb6/uc_def.bas +++ b/bindings/vb6/uc_def.bas @@ -2077,8 +2077,8 @@ Public Declare Function ucs_reg_read Lib "ucvbshim.dll" (ByVal hEngine As Long, ' for detailed error). '*/ 'UNICORN_EXPORT -'uc_err uc_mem_write(uc_engine *uc, uint64_t address, const void *bytes, size_t size); -Public Declare Function ucs_mem_write Lib "ucvbshim.dll" (ByVal hEngine As Long, ByVal addr As Currency, ByRef b As Byte, ByVal size As Long) As uc_err +'uc_err uc_mem_write(uc_engine *uc, uint64_t address, const void *bytes, uint64_t size); +Public Declare Function ucs_mem_write Lib "ucvbshim.dll" (ByVal hEngine As Long, ByVal addr As Currency, ByRef b As Byte, ByVal size As Currency) As uc_err @@ -2096,8 +2096,8 @@ Public Declare Function ucs_mem_write Lib "ucvbshim.dll" (ByVal hEngine As Long, ' for detailed error). '*/ 'UNICORN_EXPORT -'uc_err uc_mem_read(uc_engine *uc, uint64_t address, void *bytes, size_t size); -Public Declare Function ucs_mem_read Lib "ucvbshim.dll" (ByVal hEngine As Long, ByVal addr As Currency, ByRef b As Byte, ByVal size As Long) As uc_err +'uc_err uc_mem_read(uc_engine *uc, uint64_t address, void *bytes, uint64_t size); +Public Declare Function ucs_mem_read Lib "ucvbshim.dll" (ByVal hEngine As Long, ByVal addr As Currency, ByRef b As Byte, ByVal size As Currency) As uc_err @@ -2202,8 +2202,8 @@ Public Declare Function ucs_hook_del Lib "ucvbshim.dll" (ByVal hEngine As Long, ' for detailed error). '*/ 'UNICORN_EXPORT -'uc_err uc_mem_map(uc_engine *uc, uint64_t address, size_t size, uint32_t perms); -Public Declare Function ucs_mem_map Lib "ucvbshim.dll" (ByVal hEngine As Long, ByVal addr As Currency, ByVal size As Long, ByVal perms As uc_prot) As uc_err +'uc_err uc_mem_map(uc_engine *uc, uint64_t address, uint64_t size, uint32_t perms); +Public Declare Function ucs_mem_map Lib "ucvbshim.dll" (ByVal hEngine As Long, ByVal addr As Currency, ByVal size As Currency, ByVal perms As uc_prot) As uc_err @@ -2227,8 +2227,8 @@ Public Declare Function ucs_mem_map Lib "ucvbshim.dll" (ByVal hEngine As Long, B ' for detailed error). '*/ 'UNICORN_EXPORT -'uc_err uc_mem_map_ptr(uc_engine *uc, uint64_t address, size_t size, uint32_t perms, void *ptr); -Public Declare Function ucs_mem_map_ptr Lib "ucvbshim.dll" (ByVal hEngine As Long, ByVal addr As Currency, ByVal size As Long, ByVal perms As uc_prot, ByVal ptr As Long) As uc_err +'uc_err uc_mem_map_ptr(uc_engine *uc, uint64_t address, uint64_t size, uint32_t perms, void *ptr); +Public Declare Function ucs_mem_map_ptr Lib "ucvbshim.dll" (ByVal hEngine As Long, ByVal addr As Currency, ByVal size As Currency, ByVal perms As uc_prot, ByVal ptr As Long) As uc_err @@ -2246,8 +2246,8 @@ Public Declare Function ucs_mem_map_ptr Lib "ucvbshim.dll" (ByVal hEngine As Lon ' for detailed error). '*/ 'UNICORN_EXPORT -'uc_err uc_mem_unmap(uc_engine *uc, uint64_t address, size_t size); -Public Declare Function ucs_mem_unmap Lib "ucvbshim.dll" (ByVal hEngine As Long, ByVal addr As Currency, ByVal size As Long) As uc_err +'uc_err uc_mem_unmap(uc_engine *uc, uint64_t address, uint64_t size); +Public Declare Function ucs_mem_unmap Lib "ucvbshim.dll" (ByVal hEngine As Long, ByVal addr As Currency, ByVal size As Currency) As uc_err '/* @@ -2267,8 +2267,8 @@ Public Declare Function ucs_mem_unmap Lib "ucvbshim.dll" (ByVal hEngine As Long, ' for detailed error). '*/ 'UNICORN_EXPORT -'uc_err uc_mem_protect(uc_engine *uc, uint64_t address, size_t size, uint32_t perms); -Public Declare Function ucs_mem_protect Lib "ucvbshim.dll" (ByVal hEngine As Long, ByVal addr As Currency, ByVal size As Long, ByVal perm As uc_prot) As uc_err +'uc_err uc_mem_protect(uc_engine *uc, uint64_t address, uint64_t size, uint32_t perms); +Public Declare Function ucs_mem_protect Lib "ucvbshim.dll" (ByVal hEngine As Long, ByVal addr As Currency, ByVal size As Currency, ByVal perm As uc_prot) As uc_err @@ -2367,8 +2367,8 @@ Public Declare Function disasm_addr Lib "ucvbshim.dll" (ByVal hEngine As Long, B 'simplified access to map and write data to emu memory -'uc_err __stdcall mem_write_block(uc_engine *uc, uint64_t address, void* data, uint32_t size, uint32_t perm){ -Public Declare Function mem_write_block Lib "ucvbshim.dll" (ByVal hEngine As Long, ByVal addr As Currency, ByRef data As Byte, ByVal size As Long, ByVal perm As Long) As uc_err +'uc_err __stdcall mem_write_block(uc_engine *uc, uint64_t address, void* data, uint64_t size, uint32_t perm){ +Public Declare Function mem_write_block Lib "ucvbshim.dll" (ByVal hEngine As Long, ByVal addr As Currency, ByRef data As Byte, ByVal size As Currency, ByVal perm As Long) As uc_err Private Declare Function lstrcpy Lib "kernel32" Alias "lstrcpyA" (ByVal lpString1 As String, ByVal lpString2 As String) As Long Private Declare Function lstrlen Lib "kernel32" Alias "lstrlenA" (ByVal lpString As Long) As Long @@ -2393,9 +2393,9 @@ Private Declare Function lstrlen Lib "kernel32" Alias "lstrlenA" (ByVal lpString 'End Function Function err2str(e As uc_err) As String - + err2str = "Unknown error code: " & e - + If e = uc_err_ok Then err2str = "No error: everything was fine" If e = UC_ERR_NOMEM Then err2str = "Out-Of-Memory error: uc_open(), uc_emulate()" If e = UC_ERR_ARCH Then err2str = "Unsupported architecture: uc_open()" @@ -2418,13 +2418,13 @@ Function err2str(e As uc_err) As String If e = UC_ERR_HOOK_EXIST Then err2str = "hook for this event already existed" If e = UC_ERR_RESOURCE Then err2str = "Insufficient resource: uc_emu_start()" If e = UC_ERR_EXCEPTION Then err2str = "Unhandled CPU exception" - + End Function Function memType2str(t As uc_mem_type) - + memType2str = "Unknown memType: " & t - + If t = UC_MEM_READ Then memType2str = "Memory is read from" If t = uc_mem_write Then memType2str = "Memory is written to" If t = UC_MEM_FETCH Then memType2str = "Memory is fetched" @@ -2435,10 +2435,10 @@ Function memType2str(t As uc_mem_type) If t = UC_MEM_READ_PROT Then memType2str = "Read from read protected, but mapped, memory" If t = UC_MEM_FETCH_PROT Then memType2str = "Fetch from non-executable, but mapped, memory" If t = UC_MEM_READ_AFTER Then memType2str = "Memory is read from (successful access)" - + End Function - + diff --git a/include/uc_priv.h b/include/uc_priv.h index 60a9b486cb..7a4345a589 100644 --- a/include/uc_priv.h +++ b/include/uc_priv.h @@ -80,10 +80,10 @@ typedef struct { typedef void (*reg_reset_t)(struct uc_struct *uc); typedef bool (*uc_write_mem_t)(AddressSpace *as, hwaddr addr, - const uint8_t *buf, int len); + const uint8_t *buf, hwaddr len); typedef bool (*uc_read_mem_t)(AddressSpace *as, hwaddr addr, uint8_t *buf, - int len); + hwaddr len); typedef void (*uc_args_void_t)(void *); diff --git a/include/unicorn/unicorn.h b/include/unicorn/unicorn.h index 54ffd25107..d23d288e79 100644 --- a/include/unicorn/unicorn.h +++ b/include/unicorn/unicorn.h @@ -794,7 +794,7 @@ uc_err uc_reg_read_batch(uc_engine *uc, int *regs, void **vals, int count); */ UNICORN_EXPORT uc_err uc_mem_write(uc_engine *uc, uint64_t address, const void *bytes, - size_t size); + uint64_t size); /* Read a range of bytes in memory. @@ -810,7 +810,7 @@ uc_err uc_mem_write(uc_engine *uc, uint64_t address, const void *bytes, for detailed error). */ UNICORN_EXPORT -uc_err uc_mem_read(uc_engine *uc, uint64_t address, void *bytes, size_t size); +uc_err uc_mem_read(uc_engine *uc, uint64_t address, void *bytes, uint64_t size); /* Emulate machine code in a specific duration of time. @@ -917,7 +917,7 @@ typedef enum uc_prot { for detailed error). */ UNICORN_EXPORT -uc_err uc_mem_map(uc_engine *uc, uint64_t address, size_t size, uint32_t perms); +uc_err uc_mem_map(uc_engine *uc, uint64_t address, uint64_t size, uint32_t perms); /* Map existing host memory in for emulation. @@ -942,7 +942,7 @@ uc_err uc_mem_map(uc_engine *uc, uint64_t address, size_t size, uint32_t perms); for detailed error). */ UNICORN_EXPORT -uc_err uc_mem_map_ptr(uc_engine *uc, uint64_t address, size_t size, +uc_err uc_mem_map_ptr(uc_engine *uc, uint64_t address, uint64_t size, uint32_t perms, void *ptr); /* @@ -965,7 +965,7 @@ uc_err uc_mem_map_ptr(uc_engine *uc, uint64_t address, size_t size, for detailed error). */ UNICORN_EXPORT -uc_err uc_mmio_map(uc_engine *uc, uint64_t address, size_t size, +uc_err uc_mmio_map(uc_engine *uc, uint64_t address, uint64_t size, uc_cb_mmio_read_t read_cb, void *user_data_read, uc_cb_mmio_write_t write_cb, void *user_data_write); @@ -985,7 +985,7 @@ uc_err uc_mmio_map(uc_engine *uc, uint64_t address, size_t size, for detailed error). */ UNICORN_EXPORT -uc_err uc_mem_unmap(uc_engine *uc, uint64_t address, size_t size); +uc_err uc_mem_unmap(uc_engine *uc, uint64_t address, uint64_t size); /* Set memory permissions for emulation memory. @@ -1006,7 +1006,7 @@ uc_err uc_mem_unmap(uc_engine *uc, uint64_t address, size_t size); for detailed error). */ UNICORN_EXPORT -uc_err uc_mem_protect(uc_engine *uc, uint64_t address, size_t size, +uc_err uc_mem_protect(uc_engine *uc, uint64_t address, uint64_t size, uint32_t perms); /* diff --git a/qemu/unicorn_common.h b/qemu/unicorn_common.h index 3e06ccac61..a85c6d45c2 100644 --- a/qemu/unicorn_common.h +++ b/qemu/unicorn_common.h @@ -14,13 +14,13 @@ void tcg_exec_init(struct uc_struct *uc, unsigned long tb_size); // return true on success, false on failure static inline bool cpu_physical_mem_read(AddressSpace *as, hwaddr addr, - uint8_t *buf, int len) + uint8_t *buf, hwaddr len) { return cpu_physical_memory_rw(as, addr, (void *)buf, len, 0); } static inline bool cpu_physical_mem_write(AddressSpace *as, hwaddr addr, - const uint8_t *buf, int len) + const uint8_t *buf, hwaddr len) { return cpu_physical_memory_rw(as, addr, (void *)buf, len, 1); } diff --git a/tests/rust-tests/main.rs b/tests/rust-tests/main.rs index b64b6aa617..970bd922b1 100644 --- a/tests/rust-tests/main.rs +++ b/tests/rust-tests/main.rs @@ -153,7 +153,7 @@ fn emulate_x86() { assert_eq!(emu.mem_map(0x1000, 0x4000, Permission::ALL), Ok(())); assert_eq!(emu.mem_write(0x1000, &x86_code32), Ok(())); assert_eq!( - emu.mem_read_as_vec(0x1000, x86_code32.len()), + emu.mem_read_as_vec(0x1000, x86_code32.len().try_into().unwrap()), Ok(x86_code32.clone()) ); @@ -550,7 +550,7 @@ fn emulate_arm() { assert_eq!(emu.mem_map(0x1000, 0x4000, Permission::ALL), Ok(())); assert_eq!(emu.mem_write(0x1000, &arm_code32), Ok(())); assert_eq!( - emu.mem_read_as_vec(0x1000, arm_code32.len()), + emu.mem_read_as_vec(0x1000, arm_code32.len().try_into().unwrap()), Ok(arm_code32.clone()) ); @@ -581,7 +581,7 @@ fn emulate_mips() { assert_eq!(emu.mem_map(0x1000, 0x4000, Permission::ALL), Ok(())); assert_eq!(emu.mem_write(0x1000, &mips_code32), Ok(())); assert_eq!( - emu.mem_read_as_vec(0x1000, mips_code32.len()), + emu.mem_read_as_vec(0x1000, mips_code32.len().try_into().unwrap()), Ok(mips_code32.clone()) ); assert_eq!(emu.reg_write(RegisterMIPS::AT, 0), Ok(())); @@ -606,7 +606,7 @@ fn emulate_ppc() { assert_eq!(emu.mem_map(0x1000, 0x4000, Permission::ALL), Ok(())); assert_eq!(emu.mem_write(0x1000, &ppc_code32), Ok(())); assert_eq!( - emu.mem_read_as_vec(0x1000, ppc_code32.len()), + emu.mem_read_as_vec(0x1000, ppc_code32.len().try_into().unwrap()), Ok(ppc_code32.clone()) ); assert_eq!(emu.reg_write(RegisterPPC::R3, 42), Ok(())); @@ -652,7 +652,7 @@ fn mem_map_ptr() { ); assert_eq!(emu.mem_write(0x1000, &x86_code32), Ok(())); assert_eq!( - emu.mem_read_as_vec(0x1000, x86_code32.len()), + emu.mem_read_as_vec(0x1000, x86_code32.len().try_into().unwrap()), Ok(x86_code32.clone()) ); @@ -688,7 +688,7 @@ fn mem_map_ptr() { ); assert_eq!(emu.mem_write(0x1000, &x86_code32), Ok(())); assert_eq!( - emu.mem_read_as_vec(0x1000, x86_code32.len()), + emu.mem_read_as_vec(0x1000, x86_code32.len().try_into().unwrap()), Ok(x86_code32.clone()) ); diff --git a/tests/unit/test_mem.c b/tests/unit/test_mem.c index 4e2f176a39..2e963829f9 100644 --- a/tests/unit/test_mem.c +++ b/tests/unit/test_mem.c @@ -275,6 +275,79 @@ static void test_mem_protect_mmio(void) OK(uc_close(uc)); } +static void parts_increment(size_t idx, char parts[3]) +{ + if (idx && idx % 3 == 0) { + if (++parts[2] > '9') { + parts[2] = '0'; + if (++parts[1] > 'z') { + parts[1] = 'a'; + if (++parts[0] > 'Z') + parts[0] = 'A'; + } + } + } +} + +// Create a pattern string. It works the same as +// https://github.com/rapid7/metasploit-framework/blob/master/tools/exploit/pattern_create.rb +static void pattern_create(char *buf, size_t len) +{ + char parts[] = {'A', 'a', '0'}; + size_t i; + + for (i = 0; i < len; i++) { + buf[i] = parts[i % 3]; + parts_increment(i, parts); + } +} + +static bool pattern_verify(const char *buf, size_t len) +{ + char parts[] = {'A', 'a', '0'}; + size_t i; + + for (i = 0; i < len; i++) { + if (buf[i] != parts[i % 3]) + return false; + parts_increment(i, parts); + } + + return true; +} + +// Test for reading and writing memory block that are bigger than INT_MAX. +static void test_mem_read_and_write_large_memory_block(void) +{ + uc_engine *uc; + uint64_t mem_addr = 0x1000000; + uint64_t mem_size = 0x9f000000; + char *pmem = NULL; + + if (sizeof(void *) < 8) { + // Don't perform the test on a 32-bit platforms since we may not have + // enough memory space. + return; + } + + OK(uc_open(UC_ARCH_ARM64, UC_MODE_ARM, &uc)); + OK(uc_mem_map(uc, mem_addr, mem_size, UC_PROT_ALL)); + + pmem = malloc(mem_size); + if (TEST_CHECK(pmem != NULL)) { + pattern_create(pmem, mem_size); + + OK(uc_mem_write(uc, mem_addr, pmem, mem_size)); + memset(pmem, 'a', mem_size); + OK(uc_mem_read(uc, mem_addr, pmem, mem_size)); + TEST_CHECK(pattern_verify(pmem, mem_size)); + free(pmem); + } + + OK(uc_mem_unmap(uc, mem_addr, mem_size)); + OK(uc_close(uc)); +} + TEST_LIST = {{"test_map_correct", test_map_correct}, {"test_map_wrapping", test_map_wrapping}, {"test_mem_protect", test_mem_protect}, @@ -286,4 +359,6 @@ TEST_LIST = {{"test_map_correct", test_map_correct}, {"test_map_big_memory", test_map_big_memory}, {"test_mem_protect_remove_exec", test_mem_protect_remove_exec}, {"test_mem_protect_mmio", test_mem_protect_mmio}, + {"test_mem_read_and_write_large_memory_block", + test_mem_read_and_write_large_memory_block}, {NULL, NULL}}; diff --git a/uc.c b/uc.c index 76c4eb2881..8b12fbfb10 100644 --- a/uc.c +++ b/uc.c @@ -547,14 +547,14 @@ uc_err uc_reg_write(uc_engine *uc, int regid, const void *value) // check if a memory area is mapped // this is complicated because an area can overlap adjacent blocks -static bool check_mem_area(uc_engine *uc, uint64_t address, size_t size) +static bool check_mem_area(uc_engine *uc, uint64_t address, uint64_t size) { - size_t count = 0, len; + uint64_t count = 0, len; while (count < size) { MemoryRegion *mr = find_memory_region(uc, address); if (mr) { - len = (size_t)MIN(size - count, mr->end - address); + len = (uint64_t)MIN(size - count, mr->end - address); count += len; address += len; } else { // this address is not mapped in yet @@ -566,17 +566,13 @@ static bool check_mem_area(uc_engine *uc, uint64_t address, size_t size) } UNICORN_EXPORT -uc_err uc_mem_read(uc_engine *uc, uint64_t address, void *_bytes, size_t size) +uc_err uc_mem_read(uc_engine *uc, uint64_t address, void *_bytes, uint64_t size) { - size_t count = 0, len; + uint64_t count = 0, len; uint8_t *bytes = _bytes; UC_INIT(uc); - // qemu cpu_physical_memory_rw() size is an int - if (size > INT_MAX) - return UC_ERR_ARG; - if (uc->mem_redirect) { address = uc->mem_redirect(address); } @@ -589,7 +585,7 @@ uc_err uc_mem_read(uc_engine *uc, uint64_t address, void *_bytes, size_t size) while (count < size) { MemoryRegion *mr = find_memory_region(uc, address); if (mr) { - len = (size_t)MIN(size - count, mr->end - address); + len = (uint64_t)MIN(size - count, mr->end - address); if (uc->read_mem(&uc->address_space_memory, address, bytes, len) == false) { break; @@ -611,17 +607,13 @@ uc_err uc_mem_read(uc_engine *uc, uint64_t address, void *_bytes, size_t size) UNICORN_EXPORT uc_err uc_mem_write(uc_engine *uc, uint64_t address, const void *_bytes, - size_t size) + uint64_t size) { - size_t count = 0, len; + uint64_t count = 0, len; const uint8_t *bytes = _bytes; UC_INIT(uc); - // qemu cpu_physical_memory_rw() size is an int - if (size > INT_MAX) - return UC_ERR_ARG; - if (uc->mem_redirect) { address = uc->mem_redirect(address); } @@ -641,7 +633,7 @@ uc_err uc_mem_write(uc_engine *uc, uint64_t address, const void *_bytes, uc->readonly_mem(mr, false); } - len = (size_t)MIN(size - count, mr->end - address); + len = (uint64_t)MIN(size - count, mr->end - address); if (uc->write_mem(&uc->address_space_memory, address, bytes, len) == false) { break; @@ -945,7 +937,7 @@ static int bsearch_mapped_blocks(const uc_engine *uc, uint64_t address) } // find if a memory range overlaps with existing mapped regions -static bool memory_overlap(struct uc_struct *uc, uint64_t begin, size_t size) +static bool memory_overlap(struct uc_struct *uc, uint64_t begin, uint64_t size) { unsigned int i; uint64_t end = begin + size - 1; @@ -996,7 +988,7 @@ static uc_err mem_map(uc_engine *uc, MemoryRegion *block) return UC_ERR_OK; } -static uc_err mem_map_check(uc_engine *uc, uint64_t address, size_t size, +static uc_err mem_map_check(uc_engine *uc, uint64_t address, uint64_t size, uint32_t perms) { if (size == 0) { @@ -1033,7 +1025,7 @@ static uc_err mem_map_check(uc_engine *uc, uint64_t address, size_t size, } UNICORN_EXPORT -uc_err uc_mem_map(uc_engine *uc, uint64_t address, size_t size, uint32_t perms) +uc_err uc_mem_map(uc_engine *uc, uint64_t address, uint64_t size, uint32_t perms) { uc_err res; @@ -1052,7 +1044,7 @@ uc_err uc_mem_map(uc_engine *uc, uint64_t address, size_t size, uint32_t perms) } UNICORN_EXPORT -uc_err uc_mem_map_ptr(uc_engine *uc, uint64_t address, size_t size, +uc_err uc_mem_map_ptr(uc_engine *uc, uint64_t address, uint64_t size, uint32_t perms, void *ptr) { uc_err res; @@ -1076,7 +1068,7 @@ uc_err uc_mem_map_ptr(uc_engine *uc, uint64_t address, size_t size, } UNICORN_EXPORT -uc_err uc_mmio_map(uc_engine *uc, uint64_t address, size_t size, +uc_err uc_mmio_map(uc_engine *uc, uint64_t address, uint64_t size, uc_cb_mmio_read_t read_cb, void *user_data_read, uc_cb_mmio_write_t write_cb, void *user_data_write) { @@ -1102,10 +1094,10 @@ uc_err uc_mmio_map(uc_engine *uc, uint64_t address, size_t size, // Generally used in prepartion for splitting a MemoryRegion. static uint8_t *copy_region(struct uc_struct *uc, MemoryRegion *mr) { - uint8_t *block = (uint8_t *)g_malloc0((size_t)int128_get64(mr->size)); + uint8_t *block = (uint8_t *)g_malloc0((uint64_t)int128_get64(mr->size)); if (block != NULL) { uc_err err = - uc_mem_read(uc, mr->addr, block, (size_t)int128_get64(mr->size)); + uc_mem_read(uc, mr->addr, block, (uint64_t)int128_get64(mr->size)); if (err != UC_ERR_OK) { free(block); block = NULL; @@ -1121,10 +1113,10 @@ static uint8_t *copy_region(struct uc_struct *uc, MemoryRegion *mr) Note this function may be called recursively. */ static bool split_mmio_region(struct uc_struct *uc, MemoryRegion *mr, - uint64_t address, size_t size, bool do_delete) + uint64_t address, uint64_t size, bool do_delete) { uint64_t begin, end, chunk_end; - size_t l_size, r_size, m_size; + uint64_t l_size, r_size, m_size; mmio_cbs backup; chunk_end = address + size; @@ -1151,7 +1143,7 @@ static bool split_mmio_region(struct uc_struct *uc, MemoryRegion *mr, */ // unmap this region first, then do split it later - if (uc_mem_unmap(uc, mr->addr, (size_t)int128_get64(mr->size)) != + if (uc_mem_unmap(uc, mr->addr, (uint64_t)int128_get64(mr->size)) != UC_ERR_OK) { return false; } @@ -1165,9 +1157,9 @@ static bool split_mmio_region(struct uc_struct *uc, MemoryRegion *mr, } // compute sub region sizes - l_size = (size_t)(address - begin); - r_size = (size_t)(end - chunk_end); - m_size = (size_t)(chunk_end - address); + l_size = (uint64_t)(address - begin); + r_size = (uint64_t)(end - chunk_end); + m_size = (uint64_t)(chunk_end - address); if (l_size > 0) { if (uc_mmio_map(uc, begin, l_size, backup.read, backup.user_data_read, @@ -1210,12 +1202,12 @@ static bool split_mmio_region(struct uc_struct *uc, MemoryRegion *mr, // TODO: investigate whether qemu region manipulation functions already offered // this capability static bool split_region(struct uc_struct *uc, MemoryRegion *mr, - uint64_t address, size_t size, bool do_delete) + uint64_t address, uint64_t size, bool do_delete) { uint8_t *backup; uint32_t perms; uint64_t begin, end, chunk_end; - size_t l_size, m_size, r_size; + uint64_t l_size, m_size, r_size; RAMBlock *block = NULL; bool prealloc = false; @@ -1265,7 +1257,7 @@ static bool split_region(struct uc_struct *uc, MemoryRegion *mr, end = mr->end; // unmap this region first, then do split it later - if (uc_mem_unmap(uc, mr->addr, (size_t)int128_get64(mr->size)) != + if (uc_mem_unmap(uc, mr->addr, (uint64_t)int128_get64(mr->size)) != UC_ERR_OK) { goto error; } @@ -1286,9 +1278,9 @@ static bool split_region(struct uc_struct *uc, MemoryRegion *mr, } // compute sub region sizes - l_size = (size_t)(address - begin); - r_size = (size_t)(end - chunk_end); - m_size = (size_t)(chunk_end - address); + l_size = (uint64_t)(address - begin); + r_size = (uint64_t)(end - chunk_end); + m_size = (uint64_t)(chunk_end - address); // If there are error in any of the below operations, things are too far // gone at that point to recover. Could try to remap orignal region, but @@ -1356,13 +1348,13 @@ static bool split_region(struct uc_struct *uc, MemoryRegion *mr, } UNICORN_EXPORT -uc_err uc_mem_protect(struct uc_struct *uc, uint64_t address, size_t size, +uc_err uc_mem_protect(struct uc_struct *uc, uint64_t address, uint64_t size, uint32_t perms) { MemoryRegion *mr; uint64_t addr = address; uint64_t pc; - size_t count, len; + uint64_t count, len; bool remove_exec = false; UC_INIT(uc); @@ -1402,7 +1394,7 @@ uc_err uc_mem_protect(struct uc_struct *uc, uint64_t address, size_t size, count = 0; while (count < size) { mr = find_memory_region(uc, addr); - len = (size_t)MIN(size - count, mr->end - addr); + len = (uint64_t)MIN(size - count, mr->end - addr); if (mr->ram) { if (!split_region(uc, mr, addr, len, false)) { return UC_ERR_NOMEM; @@ -1444,11 +1436,11 @@ uc_err uc_mem_protect(struct uc_struct *uc, uint64_t address, size_t size, } UNICORN_EXPORT -uc_err uc_mem_unmap(struct uc_struct *uc, uint64_t address, size_t size) +uc_err uc_mem_unmap(struct uc_struct *uc, uint64_t address, uint64_t size) { MemoryRegion *mr; uint64_t addr; - size_t count, len; + uint64_t count, len; UC_INIT(uc); @@ -1482,7 +1474,7 @@ uc_err uc_mem_unmap(struct uc_struct *uc, uint64_t address, size_t size) count = 0; while (count < size) { mr = find_memory_region(uc, addr); - len = (size_t)MIN(size - count, mr->end - addr); + len = (uint64_t)MIN(size - count, mr->end - addr); if (!mr->ram) { if (!split_mmio_region(uc, mr, addr, len, true)) { return UC_ERR_NOMEM;