From 34c7b70bcb9c3afa3277dacd24928801058a7e49 Mon Sep 17 00:00:00 2001 From: Willi Ballenthin Date: Mon, 19 Oct 2015 16:52:56 -0400 Subject: [PATCH 01/11] uc.c: fix minor typo s/argumet/argument/g --- uc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uc.c b/uc.c index bb45fa5e..94ac155a 100644 --- a/uc.c +++ b/uc.c @@ -88,7 +88,7 @@ const char *uc_strerror(uc_err code) case UC_ERR_FETCH_PROT: return "Fetch from non-executable memory (UC_ERR_FETCH_PROT)"; case UC_ERR_ARG: - return "Invalid argumet (UC_ERR_ARG)"; + return "Invalid argument (UC_ERR_ARG)"; case UC_ERR_READ_UNALIGNED: return "Read from unaligned memory (UC_ERR_READ_UNALIGNED)"; case UC_ERR_WRITE_UNALIGNED: From b86ed781d78d286856344c674ca7d2a61176bcca Mon Sep 17 00:00:00 2001 From: Willi Ballenthin Date: Wed, 21 Oct 2015 11:42:43 -0400 Subject: [PATCH 02/11] COMPILE.TXT: add note to configure Python for build Addresses #206 --- COMPILE.TXT | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/COMPILE.TXT b/COMPILE.TXT index c14facd8..7804efd2 100644 --- a/COMPILE.TXT +++ b/COMPILE.TXT @@ -102,6 +102,10 @@ Unicorn requires few dependent packages as follows. $ ./make.sh nix32 + - If Python 2.x is not the default Python interpreter, ensure that the + appropriate option is set: + + $ UNICORN_QEMU_FLAGS="--python=/path/to/python2" ./make.sh After compiling, install Unicorn with: From dd56621bbb2f7137b065b5af1c13c227652416ad Mon Sep 17 00:00:00 2001 From: coco Date: Wed, 21 Oct 2015 22:25:49 +0200 Subject: [PATCH 03/11] fix for use after free in case of double unmap --- tests/regress/Makefile | 1 + tests/regress/mem_double_unmap.c | 51 ++++++++++++++++++++++++++++++++ uc.c | 2 +- 3 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 tests/regress/mem_double_unmap.c diff --git a/tests/regress/Makefile b/tests/regress/Makefile index e03c27e9..49010ebc 100644 --- a/tests/regress/Makefile +++ b/tests/regress/Makefile @@ -8,6 +8,7 @@ TESTS += ro_mem_test nr_mem_test TESTS += timeout_segfault TESTS += rep_movsb TESTS += mem_unmap +TESTS += mem_double_unmap TESTS += mem_protect TESTS += mem_exec diff --git a/tests/regress/mem_double_unmap.c b/tests/regress/mem_double_unmap.c new file mode 100644 index 00000000..95086714 --- /dev/null +++ b/tests/regress/mem_double_unmap.c @@ -0,0 +1,51 @@ +#define __STDC_FORMAT_MACROS +#include +#include +#include +#include +#include +#include + +#include + +int main(int argc, char **argv, char **envp) +{ + uc_engine *uc; + uc_hook trace1, trace2; + uc_err err; + + // Initialize emulator in X86-32bit mode + err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc); + if (err) { + printf("not ok - Failed on uc_open() with error returned: %u\n", err); + return; + } + + uc_mem_map(uc, 0x1000, 0x1000, UC_PROT_ALL); + if (err) { + printf("not ok - Failed on uc_mem_map() with error returned: %u\n", err); + return; + } + + uc_mem_map(uc, 0x4000, 0x1000, UC_PROT_ALL); + if (err) { + printf("not ok - Failed on uc_mem_map() with error returned: %u\n", err); + return; + } + + err = uc_mem_unmap(uc, 0x4000, 0x1000); + if (err) { + printf("not ok - Failed on uc_mem_unmap() with error returned: %u\n", err); + return; + } + + err = uc_mem_unmap(uc, 0x4000, 0x1000); + if (!err) { + printf("not ok - second unmap succeeded\n"); + return 1; + } + + printf("Tests OK\n"); + uc_close(uc); + return 0; +} diff --git a/uc.c b/uc.c index 94ac155a..02c157bc 100644 --- a/uc.c +++ b/uc.c @@ -814,7 +814,7 @@ MemoryRegion *memory_mapping(struct uc_struct* uc, uint64_t address) // try with the cache index first i = uc->mapped_block_cache_index; - if (address >= uc->mapped_blocks[i]->addr && address < uc->mapped_blocks[i]->end) + if (i < uc->mapped_block_count && address >= uc->mapped_blocks[i]->addr && address < uc->mapped_blocks[i]->end) return uc->mapped_blocks[i]; for(i = 0; i < uc->mapped_block_count; i++) { From c7de7e44a6e85d8a9d0f63ee12f388049c382e5e Mon Sep 17 00:00:00 2001 From: Jonathon Reinhart Date: Wed, 21 Oct 2015 22:43:14 -0400 Subject: [PATCH 04/11] create versioned library name and symlink unversioned name on *nix This allows executables (e.g. unit tests) to link against the libunicorn.so in the build directory, after the SONAME was added in 4860fdb3. Becuase libunicorn.so has an SONAME of libunicorn.so.0, the linker uses the SONAME for the DT_NEEDED entry of the tests. But because a library with that name did not exist, they would fail to run. --- .gitignore | 2 ++ Makefile | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 3fdb76f7..6831c5b6 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,8 @@ *.o *.a *.dSYM +*.so +*.so.* qemu/config-all-devices.mak diff --git a/Makefile b/Makefile index 4ce64736..51f8b469 100644 --- a/Makefile +++ b/Makefile @@ -131,7 +131,8 @@ LIBRARY = $(BLDIR)/$(LIBNAME).$(EXT) else ifeq ($(IS_CYGWIN),1) LIBRARY = $(BLDIR)/$(LIBNAME).$(EXT) else # *nix -LIBRARY = $(BLDIR)/lib$(LIBNAME).$(EXT) +LIBRARY = $(BLDIR)/lib$(LIBNAME).$(VERSION_EXT) +LIBRARY_SYMLINK = $(BLDIR)/lib$(LIBNAME).$(EXT) endif endif @@ -229,6 +230,9 @@ ifeq ($(V),0) else $(CC) $(CFLAGS) $($(LIBNAME)_LDFLAGS) -shared $^ -o $(LIBRARY) $(GLIB) -lm endif +ifneq (,$(LIBRARY_SYMLINK)) + @ln -sf $(LIBRARY) $(LIBRARY_SYMLINK) +endif endif $(ARCHIVE): $(UC_TARGET_OBJ) uc.o hook.o From 942edb99e2d5decf0bc517317ca52d478d9245fd Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Fri, 23 Oct 2015 11:02:04 +0800 Subject: [PATCH 05/11] update COMPILE.TXT for Python2 requirement --- COMPILE.TXT | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/COMPILE.TXT b/COMPILE.TXT index 7804efd2..69edf581 100644 --- a/COMPILE.TXT +++ b/COMPILE.TXT @@ -98,15 +98,15 @@ Unicorn requires few dependent packages as follows. $ ./make.sh + - Unicorn requires Python 2.x to compile. If Python 2.x is not the default + Python interpreter, ensure that the appropriate option is set: + + $ UNICORN_QEMU_FLAGS="--python=/path/to/python2" ./make.sh + - To cross-compile Unicorn on 64-bit OS to target 32-bit binary, run: $ ./make.sh nix32 - - If Python 2.x is not the default Python interpreter, ensure that the - appropriate option is set: - - $ UNICORN_QEMU_FLAGS="--python=/path/to/python2" ./make.sh - After compiling, install Unicorn with: $ sudo ./make.sh install From dfc86580836ba0006bf9ae7ac3a4206e32faa4a0 Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Fri, 23 Oct 2015 11:36:09 +0800 Subject: [PATCH 06/11] regress: fix compilation warning of mem_double_unmap.c --- tests/regress/mem_double_unmap.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/regress/mem_double_unmap.c b/tests/regress/mem_double_unmap.c index 95086714..3373a5cc 100644 --- a/tests/regress/mem_double_unmap.c +++ b/tests/regress/mem_double_unmap.c @@ -18,31 +18,31 @@ int main(int argc, char **argv, char **envp) err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc); if (err) { printf("not ok - Failed on uc_open() with error returned: %u\n", err); - return; + return -1; } uc_mem_map(uc, 0x1000, 0x1000, UC_PROT_ALL); if (err) { printf("not ok - Failed on uc_mem_map() with error returned: %u\n", err); - return; + return -1; } uc_mem_map(uc, 0x4000, 0x1000, UC_PROT_ALL); if (err) { printf("not ok - Failed on uc_mem_map() with error returned: %u\n", err); - return; + return -1; } err = uc_mem_unmap(uc, 0x4000, 0x1000); if (err) { printf("not ok - Failed on uc_mem_unmap() with error returned: %u\n", err); - return; + return -1; } err = uc_mem_unmap(uc, 0x4000, 0x1000); if (!err) { printf("not ok - second unmap succeeded\n"); - return 1; + return -1; } printf("Tests OK\n"); From 8c60d0dca511af1fbf7f7725c0a177e3c3c57a51 Mon Sep 17 00:00:00 2001 From: Ryan Hileman Date: Fri, 23 Oct 2015 00:10:38 -0700 Subject: [PATCH 07/11] allow setting x86 segment base to host-sized value --- qemu/target-i386/unicorn.c | 48 +++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/qemu/target-i386/unicorn.c b/qemu/target-i386/unicorn.c index 37e744b3..acac9638 100644 --- a/qemu/target-i386/unicorn.c +++ b/qemu/target-i386/unicorn.c @@ -260,22 +260,22 @@ int x86_reg_read(struct uc_struct *uc, unsigned int regid, void *value) *(int16_t *)value = READ_WORD(X86_CPU(uc, mycpu)->env.eip); break; case UC_X86_REG_CS: - *(int16_t *)value = X86_CPU(uc, mycpu)->env.segs[R_CS].base; + *(int32_t *)value = X86_CPU(uc, mycpu)->env.segs[R_CS].base; break; case UC_X86_REG_DS: - *(int16_t *)value = X86_CPU(uc, mycpu)->env.segs[R_DS].base; + *(int32_t *)value = X86_CPU(uc, mycpu)->env.segs[R_DS].base; break; case UC_X86_REG_SS: - *(int16_t *)value = X86_CPU(uc, mycpu)->env.segs[R_SS].base; + *(int32_t *)value = X86_CPU(uc, mycpu)->env.segs[R_SS].base; break; case UC_X86_REG_ES: - *(int16_t *)value = X86_CPU(uc, mycpu)->env.segs[R_ES].base; + *(int32_t *)value = X86_CPU(uc, mycpu)->env.segs[R_ES].base; break; case UC_X86_REG_FS: - *(int16_t *)value = X86_CPU(uc, mycpu)->env.segs[R_FS].base; + *(int32_t *)value = X86_CPU(uc, mycpu)->env.segs[R_FS].base; break; case UC_X86_REG_GS: - *(int16_t *)value = X86_CPU(uc, mycpu)->env.segs[R_GS].base; + *(int32_t *)value = X86_CPU(uc, mycpu)->env.segs[R_GS].base; break; } break; @@ -412,22 +412,22 @@ int x86_reg_read(struct uc_struct *uc, unsigned int regid, void *value) *(int16_t *)value = READ_WORD(X86_CPU(uc, mycpu)->env.eip); break; case UC_X86_REG_CS: - *(int16_t *)value = X86_CPU(uc, mycpu)->env.segs[R_CS].base; + *(int64_t *)value = X86_CPU(uc, mycpu)->env.segs[R_CS].base; break; case UC_X86_REG_DS: - *(int16_t *)value = X86_CPU(uc, mycpu)->env.segs[R_DS].base; + *(int64_t *)value = X86_CPU(uc, mycpu)->env.segs[R_DS].base; break; case UC_X86_REG_SS: - *(int16_t *)value = X86_CPU(uc, mycpu)->env.segs[R_SS].base; + *(int64_t *)value = X86_CPU(uc, mycpu)->env.segs[R_SS].base; break; case UC_X86_REG_ES: - *(int16_t *)value = X86_CPU(uc, mycpu)->env.segs[R_ES].base; + *(int64_t *)value = X86_CPU(uc, mycpu)->env.segs[R_ES].base; break; case UC_X86_REG_FS: - *(int16_t *)value = X86_CPU(uc, mycpu)->env.segs[R_FS].base; + *(int64_t *)value = X86_CPU(uc, mycpu)->env.segs[R_FS].base; break; case UC_X86_REG_GS: - *(int16_t *)value = X86_CPU(uc, mycpu)->env.segs[R_GS].base; + *(int64_t *)value = X86_CPU(uc, mycpu)->env.segs[R_GS].base; break; case UC_X86_REG_R8: *(int64_t *)value = READ_QWORD(X86_CPU(uc, mycpu)->env.regs[8]); @@ -660,22 +660,22 @@ int x86_reg_write(struct uc_struct *uc, unsigned int regid, const void *value) WRITE_WORD(X86_CPU(uc, mycpu)->env.eip, *(uint16_t *)value); break; case UC_X86_REG_CS: - X86_CPU(uc, mycpu)->env.segs[R_CS].base = *(uint16_t *)value; + X86_CPU(uc, mycpu)->env.segs[R_CS].base = *(uint32_t *)value; break; case UC_X86_REG_DS: - X86_CPU(uc, mycpu)->env.segs[R_DS].base = *(uint16_t *)value; + X86_CPU(uc, mycpu)->env.segs[R_DS].base = *(uint32_t *)value; break; case UC_X86_REG_SS: - X86_CPU(uc, mycpu)->env.segs[R_SS].base = *(uint16_t *)value; + X86_CPU(uc, mycpu)->env.segs[R_SS].base = *(uint32_t *)value; break; case UC_X86_REG_ES: - X86_CPU(uc, mycpu)->env.segs[R_ES].base = *(uint16_t *)value; + X86_CPU(uc, mycpu)->env.segs[R_ES].base = *(uint32_t *)value; break; case UC_X86_REG_FS: - X86_CPU(uc, mycpu)->env.segs[R_FS].base = *(uint16_t *)value; + X86_CPU(uc, mycpu)->env.segs[R_FS].base = *(uint32_t *)value; break; case UC_X86_REG_GS: - X86_CPU(uc, mycpu)->env.segs[R_GS].base = *(uint16_t *)value; + X86_CPU(uc, mycpu)->env.segs[R_GS].base = *(uint32_t *)value; break; } break; @@ -812,22 +812,22 @@ int x86_reg_write(struct uc_struct *uc, unsigned int regid, const void *value) WRITE_WORD(X86_CPU(uc, mycpu)->env.eip, *(uint16_t *)value); break; case UC_X86_REG_CS: - X86_CPU(uc, mycpu)->env.segs[R_CS].base = *(uint16_t *)value; + X86_CPU(uc, mycpu)->env.segs[R_CS].base = *(uint64_t *)value; break; case UC_X86_REG_DS: - X86_CPU(uc, mycpu)->env.segs[R_DS].base = *(uint16_t *)value; + X86_CPU(uc, mycpu)->env.segs[R_DS].base = *(uint64_t *)value; break; case UC_X86_REG_SS: - X86_CPU(uc, mycpu)->env.segs[R_SS].base = *(uint16_t *)value; + X86_CPU(uc, mycpu)->env.segs[R_SS].base = *(uint64_t *)value; break; case UC_X86_REG_ES: - X86_CPU(uc, mycpu)->env.segs[R_ES].base = *(uint16_t *)value; + X86_CPU(uc, mycpu)->env.segs[R_ES].base = *(uint64_t *)value; break; case UC_X86_REG_FS: - X86_CPU(uc, mycpu)->env.segs[R_FS].base = *(uint16_t *)value; + X86_CPU(uc, mycpu)->env.segs[R_FS].base = *(uint64_t *)value; break; case UC_X86_REG_GS: - X86_CPU(uc, mycpu)->env.segs[R_GS].base = *(uint16_t *)value; + X86_CPU(uc, mycpu)->env.segs[R_GS].base = *(uint64_t *)value; break; case UC_X86_REG_R8: X86_CPU(uc, mycpu)->env.regs[8] = *(uint64_t *)value; From 21ce78924c035d0898e7353f5e84d52be98793da Mon Sep 17 00:00:00 2001 From: gaffe Date: Fri, 23 Oct 2015 11:28:10 -0700 Subject: [PATCH 08/11] assert that PC was changed in callback-pc test --- tests/regress/callback-pc.py | 48 +++++++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/tests/regress/callback-pc.py b/tests/regress/callback-pc.py index 3edc67e6..77f4e5ab 100755 --- a/tests/regress/callback-pc.py +++ b/tests/regress/callback-pc.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # reg_write() can't modify PC from within trace callbacks -# Pull Request #4 +# issue #210 from __future__ import print_function from unicorn import * @@ -30,11 +30,7 @@ def hook_block(uc, address, size, user_data): class CallBackPCTest(regress.RegressTest): - def runTest(self): - self.instruction_trace_test() - - # set up emulation - def instruction_trace_test(self): + def test_instruction_trace(self): try: # initialize emulator in ARM's Thumb mode mu = Uc(UC_ARCH_ARM, UC_MODE_THUMB) @@ -51,14 +47,44 @@ class CallBackPCTest(regress.RegressTest): # tracing all instructions with customized callback mu.hook_add(UC_HOOK_CODE, hook_code, user_data=mu) - # tracing all basic blocks with customized callback - mu.hook_add(UC_HOOK_BLOCK, hook_block, user_data=mu) + # emulate one instruction + mu.emu_start(BASE_ADDRESS, BASE_ADDRESS + len(THUMB_CODE), count=1) - # emulate machine code in infinite time - mu.emu_start(BASE_ADDRESS, BASE_ADDRESS + len(THUMB_CODE)) + # the instruction trace callback set PC to 0xffffffff, so at this + # point, the PC value should be 0xffffffff. + pc = mu.reg_read(UC_ARM_REG_PC) + self.assertEqual(pc, 0xffffffff, "PC not set to 0xffffffff by instruction trace callback") except UcError as e: - assertFalse(0, "ERROR: %s" % e) + self.assertFalse(0, "ERROR: %s" % e) + + def test_block_trace(self): + try: + # initialize emulator in ARM's Thumb mode + mu = Uc(UC_ARCH_ARM, UC_MODE_THUMB) + + # map some memory + mu.mem_map(BASE_ADDRESS, 2 * 1024 * 1024) + + # write machine code to be emulated to memory + mu.mem_write(BASE_ADDRESS, THUMB_CODE) + + # setup stack + mu.reg_write(UC_ARM_REG_SP, BASE_ADDRESS + 2 * 1024 * 1024) + + # trace blocks with customized callback + mu.hook_add(UC_HOOK_BLOCK, hook_block, user_data=mu) + + # emulate one instruction + mu.emu_start(BASE_ADDRESS, BASE_ADDRESS + len(THUMB_CODE), count=1) + + # the block callback set PC to 0xffffffff, so at this point, the PC + # value should be 0xffffffff. + pc = mu.reg_read(UC_ARM_REG_PC) + self.assertEqual(pc, 0xffffffff, "PC not set to 0xffffffff by block callback") + + except UcError as e: + self.assertFalse(0, "ERROR: %s" % e) if __name__ == '__main__': regress.main() From efb0c87e392e4e719e7b22a4d171381a51998ff4 Mon Sep 17 00:00:00 2001 From: Jonathon Reinhart Date: Sat, 24 Oct 2015 16:43:34 -0400 Subject: [PATCH 09/11] fix install logic after changing LIBRARY Now that LIBRARY is the versioned name (e.g. "libunicorn.so.0"), we don't need this rename step; just create the symlink for libunicorn.so. If VERSION_EXT isn't set, then the library we installed already has the correct name, and no symlink is necessary. We should probably be running 'ldconfig' to handle this, or better yet, using libtool. --- Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/Makefile b/Makefile index 51f8b469..bed04589 100644 --- a/Makefile +++ b/Makefile @@ -266,7 +266,6 @@ ifeq ($(UNICORN_SHARED),yes) $(INSTALL_LIB) $(LIBRARY) $(LIBDIR) ifneq ($(VERSION_EXT),) cd $(LIBDIR) && \ - mv lib$(LIBNAME).$(EXT) lib$(LIBNAME).$(VERSION_EXT) && \ ln -s lib$(LIBNAME).$(VERSION_EXT) lib$(LIBNAME).$(EXT) endif endif From a1f8c8ae873b41d539571caa945624947c81e5f6 Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Sun, 25 Oct 2015 09:44:01 +0800 Subject: [PATCH 10/11] Makefile: overwrite existent library for install target with 'ln -sf' --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index bed04589..3a97a6a1 100644 --- a/Makefile +++ b/Makefile @@ -266,7 +266,7 @@ ifeq ($(UNICORN_SHARED),yes) $(INSTALL_LIB) $(LIBRARY) $(LIBDIR) ifneq ($(VERSION_EXT),) cd $(LIBDIR) && \ - ln -s lib$(LIBNAME).$(VERSION_EXT) lib$(LIBNAME).$(EXT) + ln -sf lib$(LIBNAME).$(VERSION_EXT) lib$(LIBNAME).$(EXT) endif endif ifeq ($(UNICORN_STATIC),yes) From 715d5c3557199d2b9b245f47d082798e8f33ccff Mon Sep 17 00:00:00 2001 From: Ryan Hileman Date: Sun, 25 Oct 2015 04:32:56 -0700 Subject: [PATCH 11/11] Go 1.2 binding compatibility --- bindings/go/unicorn/hook.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/bindings/go/unicorn/hook.go b/bindings/go/unicorn/hook.go index 3176df9f..13aba755 100644 --- a/bindings/go/unicorn/hook.go +++ b/bindings/go/unicorn/hook.go @@ -19,43 +19,43 @@ type HookData struct { type Hook uint64 //export hookCode -func hookCode(handle *C.uc_engine, addr uint64, size uint32, user unsafe.Pointer) { +func hookCode(handle unsafe.Pointer, addr uint64, size uint32, user unsafe.Pointer) { hook := (*HookData)(user) hook.Callback.(func(Unicorn, uint64, uint32))(hook.Uc, uint64(addr), uint32(size)) } //export hookMemInvalid -func hookMemInvalid(handle *C.uc_engine, typ C.uc_mem_type, addr uint64, size int, value int64, user unsafe.Pointer) bool { +func hookMemInvalid(handle unsafe.Pointer, typ C.uc_mem_type, addr uint64, size int, value int64, user unsafe.Pointer) bool { hook := (*HookData)(user) return hook.Callback.(func(Unicorn, int, uint64, int, int64) bool)(hook.Uc, int(typ), addr, size, value) } //export hookMemAccess -func hookMemAccess(handle *C.uc_engine, typ C.uc_mem_type, addr uint64, size int, value int64, user unsafe.Pointer) { +func hookMemAccess(handle unsafe.Pointer, typ C.uc_mem_type, addr uint64, size int, value int64, user unsafe.Pointer) { hook := (*HookData)(user) hook.Callback.(func(Unicorn, int, uint64, int, int64))(hook.Uc, int(typ), addr, size, value) } //export hookInterrupt -func hookInterrupt(handle *C.uc_engine, intno uint32, user unsafe.Pointer) { +func hookInterrupt(handle unsafe.Pointer, intno uint32, user unsafe.Pointer) { hook := (*HookData)(user) hook.Callback.(func(Unicorn, uint32))(hook.Uc, intno) } //export hookX86In -func hookX86In(handle *C.uc_engine, port, size uint32, user unsafe.Pointer) uint32 { +func hookX86In(handle unsafe.Pointer, port, size uint32, user unsafe.Pointer) uint32 { hook := (*HookData)(user) return hook.Callback.(func(Unicorn, uint32, uint32) uint32)(hook.Uc, port, size) } //export hookX86Out -func hookX86Out(handle *C.uc_engine, port, size, value uint32, user unsafe.Pointer) { +func hookX86Out(handle unsafe.Pointer, port, size, value uint32, user unsafe.Pointer) { hook := (*HookData)(user) hook.Callback.(func(Unicorn, uint32, uint32, uint32))(hook.Uc, port, size, value) } //export hookX86Syscall -func hookX86Syscall(handle *C.uc_engine, user unsafe.Pointer) { +func hookX86Syscall(handle unsafe.Pointer, user unsafe.Pointer) { hook := (*HookData)(user) hook.Callback.(func(Unicorn))(hook.Uc) }