Merge branch 'master' into mem_map_ex_cse

This commit is contained in:
Chris Eagle 2015-08-30 19:52:18 -07:00
commit de7ac7fc48
6 changed files with 124 additions and 55 deletions

View file

@ -66,11 +66,11 @@ Unicorn requires few dependent packages as followings
- To compile for current platform, run: - To compile for current platform, run:
$ ./make.sh $ ./make.sh
- On 64-bit OS, run the command below to cross-compile Unicorn for 32-bit binary: - On 64-bit OS, run the command below to cross-compile Unicorn for 32-bit binary:
$ ./make.sh nix32 $ ./make.sh nix32
@ -78,11 +78,11 @@ Unicorn requires few dependent packages as followings
To install Unicorn, run: To install Unicorn, run:
$ sudo ./make.sh install $ sudo ./make.sh install
For FreeBSD/OpenBSD, where sudo is unavailable, run: For FreeBSD/OpenBSD, where sudo is unavailable, run:
$ su; ./make.sh install $ su; ./make.sh install
Users are then required to enter root password to copy Unicorn into machine Users are then required to enter root password to copy Unicorn into machine
system directories. system directories.
@ -93,17 +93,17 @@ Unicorn requires few dependent packages as followings
NOTE: The core framework installed by "./make.sh install" consist of NOTE: The core framework installed by "./make.sh install" consist of
following files: following files:
/usr/include/unicorn/unicorn.h /usr/include/unicorn/unicorn.h
/usr/include/unicorn/x86.h /usr/include/unicorn/x86.h
/usr/include/unicorn/arm.h /usr/include/unicorn/arm.h
/usr/include/unicorn/arm64.h /usr/include/unicorn/arm64.h
/usr/include/unicorn/mips.h /usr/include/unicorn/mips.h
/usr/include/unicorn/ppc.h /usr/include/unicorn/ppc.h
/usr/include/unicorn/sparc.h /usr/include/unicorn/sparc.h
/usr/include/unicorn/m68k.h /usr/include/unicorn/m68k.h
/usr/include/unicorn/platform.h /usr/include/unicorn/platform.h
/usr/lib/libunicorn.so (for Linux/*nix), or /usr/lib/libunicorn.dylib (OSX) /usr/lib/libunicorn.so (for Linux/*nix), or /usr/lib/libunicorn.dylib (OSX)
/usr/lib/libunicorn.a /usr/lib/libunicorn.a
@ -112,19 +112,18 @@ Unicorn requires few dependent packages as followings
To cross-compile for Windows, Linux & gcc-mingw-w64-i686 (and also gcc-mingw-w64-x86-64 To cross-compile for Windows, Linux & gcc-mingw-w64-i686 (and also gcc-mingw-w64-x86-64
for 64-bit binaries) are required. for 64-bit binaries) are required.
- To cross-compile Windows 32-bit binary, simply run: - To cross-compile Windows 32-bit binary, simply run:
$ ./make.sh cross-win32 $ ./make.sh cross-win32
- To cross-compile Windows 64-bit binary, run: - To cross-compile Windows 64-bit binary, run:
$ ./make.sh cross-win64 $ ./make.sh cross-win64
Resulted files libunicorn.dll, libunicorn.dll.a & tests/test*.exe can then Resulted files unicorn.dll, unicorn.lib & samples/sample*.exe can then
be used on Windows machine. be used on Windows machine.
To run sample_x86.exe on Windows 32-bit, you need the following files: To run sample_x86.exe on Windows 32-bit, you need the following files:
- unicorn.dll - unicorn.dll
- /usr/i686-w64-mingw32/sys-root/mingw/bin/libglib-2.0-0.dll - /usr/i686-w64-mingw32/sys-root/mingw/bin/libglib-2.0-0.dll
- /usr/lib/gcc/i686-w64-mingw32/4.8/libgcc_s_sjlj-1.dll - /usr/lib/gcc/i686-w64-mingw32/4.8/libgcc_s_sjlj-1.dll
@ -145,17 +144,17 @@ Unicorn requires few dependent packages as followings
To cross-compile for iOS (iPhone/iPad/iPod), Mac OSX with XCode installed is required. To cross-compile for iOS (iPhone/iPad/iPod), Mac OSX with XCode installed is required.
- To cross-compile for ArmV7 (iPod 4, iPad 1/2/3, iPhone4, iPhone4S), run: - To cross-compile for ArmV7 (iPod 4, iPad 1/2/3, iPhone4, iPhone4S), run:
$ ./make.sh ios_armv7 $ ./make.sh ios_armv7
- To cross-compile for ArmV7s (iPad 4, iPhone 5C, iPad mini), run: - To cross-compile for ArmV7s (iPad 4, iPhone 5C, iPad mini), run:
$ ./make.sh ios_armv7s $ ./make.sh ios_armv7s
- To cross-compile for Arm64 (iPhone 5S, iPad mini Retina, iPad Air), run: - To cross-compile for Arm64 (iPhone 5S, iPad mini Retina, iPad Air), run:
$ ./make.sh ios_arm64 $ ./make.sh ios_arm64
- To cross-compile for all iDevices (armv7 + armv7s + arm64), run: - To cross-compile for all iDevices (armv7 + armv7s + arm64), run:
$ ./make.sh ios $ ./make.sh ios
Resulted files libunicorn.dylib, libunicorn.a & tests/test* can then Resulted files libunicorn.dylib, libunicorn.a & tests/test* can then
be used on iOS devices. be used on iOS devices.
@ -167,47 +166,69 @@ Unicorn requires few dependent packages as followings
To cross-compile for Android (smartphone/tablet), Android NDK is required. To cross-compile for Android (smartphone/tablet), Android NDK is required.
NOTE: Only ARM and ARM64 are currently supported. NOTE: Only ARM and ARM64 are currently supported.
$ NDK=/android/android-ndk-r10e ./make.sh cross-android arm $ NDK=/android/android-ndk-r10e ./make.sh cross-android arm
or or
$ NDK=/android/android-ndk-r10e ./make.sh cross-android arm64 $ NDK=/android/android-ndk-r10e ./make.sh cross-android arm64
Resulted files libunicorn.so, libunicorn.a & tests/test* can then Resulted files libunicorn.so, libunicorn.a & tests/test* can then
be used on Android devices. be used on Android devices.
[7] Compile on Windows with Cygwin [7] Compile on Windows with MinGW (MSYS2)
To compile under Cygwin gcc-mingw-w64-i686 or x86_64-w64-mingw32 run: To compile with MinGW you need to install MSYS2: https://msys2.github.io/
Follow the install instructions and don't forget to update the system packages as written in 5 & 6 paragraphs
- To compile Windows 32-bit binary with MinGW, run:
$ pacman -S make
$ pacman -S pkg-config
$ pacman -S mingw-w64-i686-glib2
$ pacman -S mingw-w64-i686-toolchain
$ ./make.sh cross-win32
- To compile Windows 32-bit binary under Cygwin, run: - To compile Windows 64-bit binary with MinGW, run:
$ pacman -S make
$ pacman -S pkg-config
$ pacman -S mingw-w64-x86_64-glib2
$ pacman -S mingw-w64-x86_64-toolchain
$ ./make.sh cross-win64
$ ./make.sh cygwin-mingw32 Resulted files unicorn.dll, unicorn.lib & samples/sample*.exe can then
- To compile Windows 64-bit binary under Cygwin, run:
$ ./make.sh cygwin-mingw64
Resulted files libunicorn.dll, libunicorn.dll.a & tests/test*.exe can then
be used on Windows machine. be used on Windows machine.
To run sample_x86.exe on Windows 32-bit, you need the following files:
- unicorn.dll
- %MSYS2%\mingw32\bin\libiconv-2.dll
- %MSYS2%\mingw32\bin\libintl-8.dll
- %MSYS2%\mingw32\bin\libglib-2.0-0.dll
- %MSYS2%\mingw32\bin\libgcc_s_dw2-1.dll
- %MSYS2%\mingw32\bin\libwinpthread-1.dll
To run sample_x86.exe on Windows 64-bit, you need the following files:
- unicorn.dll
- %MSYS2%\mingw64\bin\libiconv-2.dll
- %MSYS2%\mingw64\bin\libintl-8.dll
- %MSYS2%\mingw64\bin\libglib-2.0-0.dll
- %MSYS2%\mingw64\bin\libgcc_s_seh-1.dll
- %MSYS2%\mingw64\bin\libwinpthread-1.dll
[8] By default, "cc" (default C compiler on the system) is used as compiler. [8] By default, "cc" (default C compiler on the system) is used as compiler.
- To use "clang" compiler instead, run the command below: - To use "clang" compiler instead, run the command below:
$ ./make.sh clang $ ./make.sh clang
- To use "gcc" compiler instead, run: - To use "gcc" compiler instead, run:
$ ./make.sh gcc $ ./make.sh gcc
[9] To uninstall Unicorn, run the command below: [9] To uninstall Unicorn, run the command below:
$ sudo ./make.sh uninstall $ sudo ./make.sh uninstall

View file

@ -37,6 +37,8 @@ Luke Burnett
Parker Thompson Parker Thompson
Daniel Godas-Lopez Daniel Godas-Lopez
Antonio "s4tan" Parata Antonio "s4tan" Parata
Corey Kallenberg
Shift
Contributors (in no particular order) Contributors (in no particular order)
===================================== =====================================

View file

@ -17,6 +17,10 @@ void hookMemAccess_cgo(uch handle, uc_mem_type type, uint64_t addr, int size, in
hookMemAccess(handle, type, addr, size, value, user); hookMemAccess(handle, type, addr, size, value, user);
} }
void hookInterrupt_cgo(uch handle, uint32_t intno, void *user) {
hookInterrupt(handle, intno, user);
}
uint32_t hookX86In_cgo(uch handle, uint32_t port, uint32_t size, void *user) { uint32_t hookX86In_cgo(uch handle, uint32_t port, uint32_t size, void *user) {
return hookX86In(handle, port, size, user); return hookX86In(handle, port, size, user);
} }

View file

@ -17,33 +17,39 @@ type HookData struct {
} }
//export hookCode //export hookCode
func hookCode(handle C.uch, addr C.uint64_t, size C.uint32_t, user unsafe.Pointer) { func hookCode(handle C.uch, addr uint64, size uint32, user unsafe.Pointer) {
hook := (*HookData)(user) hook := (*HookData)(user)
hook.Callback.(func(*Uc, uint64, uint32))(hook.Uc, uint64(addr), uint32(size)) hook.Callback.(func(*Uc, uint64, uint32))(hook.Uc, uint64(addr), uint32(size))
} }
//export hookMemInvalid //export hookMemInvalid
func hookMemInvalid(handle C.uch, typ C.uc_mem_type, addr C.uint64_t, size int, value C.int64_t, user unsafe.Pointer) C.bool { func hookMemInvalid(handle C.uch, typ C.uc_mem_type, addr uint64, size int, value int64, user unsafe.Pointer) bool {
hook := (*HookData)(user) hook := (*HookData)(user)
return C.bool(hook.Callback.(func(*Uc, int, uint64, int, int64) bool)(hook.Uc, int(typ), uint64(addr), size, int64(value))) return hook.Callback.(func(*Uc, int, uint64, int, int64) bool)(hook.Uc, int(typ), addr, size, value)
} }
//export hookMemAccess //export hookMemAccess
func hookMemAccess(handle C.uch, typ C.uc_mem_type, addr C.uint64_t, size int, value C.int64_t, user unsafe.Pointer) { func hookMemAccess(handle C.uch, typ C.uc_mem_type, addr uint64, size int, value int64, user unsafe.Pointer) {
hook := (*HookData)(user) hook := (*HookData)(user)
hook.Callback.(func(*Uc, int, uint64, int, int64))(hook.Uc, int(typ), uint64(addr), size, int64(value)) hook.Callback.(func(*Uc, int, uint64, int, int64))(hook.Uc, int(typ), addr, size, value)
}
//export hookInterrupt
func hookInterrupt(handle C.uch, intno uint32, user unsafe.Pointer) {
hook := (*HookData)(user)
hook.Callback.(func(*Uc, uint32))(hook.Uc, intno)
} }
//export hookX86In //export hookX86In
func hookX86In(handle C.uch, port, size uint32, user unsafe.Pointer) C.uint32_t { func hookX86In(handle C.uch, port, size uint32, user unsafe.Pointer) uint32 {
hook := (*HookData)(user) hook := (*HookData)(user)
return C.uint32_t(hook.Callback.(func(*Uc, uint32, uint32) uint32)(hook.Uc, port, size)) return hook.Callback.(func(*Uc, uint32, uint32) uint32)(hook.Uc, port, size)
} }
//export hookX86Out //export hookX86Out
func hookX86Out(handle C.uch, port, size, value uint32, user unsafe.Pointer) { func hookX86Out(handle C.uch, port, size, value uint32, user unsafe.Pointer) {
hook := (*HookData)(user) hook := (*HookData)(user)
hook.Callback.(func(*Uc, uint32, uint32, uint32))(hook.Uc, uint32(port), uint32(size), uint32(value)) hook.Callback.(func(*Uc, uint32, uint32, uint32))(hook.Uc, port, size, value)
} }
//export hookX86Syscall //export hookX86Syscall
@ -64,6 +70,8 @@ func (u *Uc) HookAdd(htype int, cb interface{}, insn ...int) (C.uch, error) {
callback = C.hookMemInvalid_cgo callback = C.hookMemInvalid_cgo
case UC_HOOK_MEM_READ, UC_HOOK_MEM_WRITE, UC_HOOK_MEM_READ_WRITE: case UC_HOOK_MEM_READ, UC_HOOK_MEM_WRITE, UC_HOOK_MEM_READ_WRITE:
callback = C.hookMemAccess_cgo callback = C.hookMemAccess_cgo
case UC_HOOK_INTR:
callback = C.hookInterrupt_cgo
case UC_HOOK_INSN: case UC_HOOK_INSN:
extra = C.int(insn[0]) extra = C.int(insn[0])
switch extra { switch extra {

View file

@ -2,6 +2,7 @@ uc_err uc_hook_add2(uch handle, uch *h2, uc_hook_t type, void *callback, void *u
void hookCode_cgo(uch handle, uint64_t addr, uint32_t size, void *user); void hookCode_cgo(uch handle, uint64_t addr, uint32_t size, void *user);
bool hookMemInvalid_cgo(uch handle, uc_mem_type type, uint64_t addr, int size, int64_t value, void *user); bool hookMemInvalid_cgo(uch handle, uc_mem_type type, uint64_t addr, int size, int64_t value, void *user);
void hookMemAccess_cgo(uch handle, uc_mem_type type, uint64_t addr, int size, int64_t value, void *user); void hookMemAccess_cgo(uch handle, uc_mem_type type, uint64_t addr, int size, int64_t value, void *user);
void hookInterrupt_cgo(uch handle, uint32_t intno, void *user);
uint32_t hookX86In_cgo(uch handle, uint32_t port, uint32_t size, void *user); uint32_t hookX86In_cgo(uch handle, uint32_t port, uint32_t size, void *user);
void hookX86Out_cgo(uch handle, uint32_t port, uint32_t size, uint32_t value, void *user); void hookX86Out_cgo(uch handle, uint32_t port, uint32_t size, uint32_t value, void *user);
void hookX86Syscall_cgo(uch handle, void *user); void hookX86Syscall_cgo(uch handle, void *user);

33
regress/jmp_ebx_hang.py Executable file
View file

@ -0,0 +1,33 @@
#!/usr/bin/env python
"""See https://github.com/unicorn-engine/unicorn/issues/82"""
import unicorn
CODE_ADDR = 0x10101000
CODE = b'\xff\xe3'
mu = unicorn.Uc(unicorn.UC_ARCH_X86, unicorn.UC_MODE_32)
mu.mem_map(CODE_ADDR, 1024 * 4)
mu.mem_write(CODE_ADDR, CODE)
# If EBX is zero then an exception is raised, as expected
mu.reg_write(unicorn.x86_const.UC_X86_REG_EBX, 0x0)
try:
mu.emu_start(CODE_ADDR, CODE_ADDR + 2, count=1)
except unicorn.UcError as e:
assert(e.errno == unicorn.UC_ERR_CODE_INVALID)
else:
assert(False)
mu = unicorn.Uc(unicorn.UC_ARCH_X86, unicorn.UC_MODE_32)
mu.mem_map(CODE_ADDR, 1024 * 4)
# If we write this address to EBX then the emulator hangs on emu_start
mu.reg_write(unicorn.x86_const.UC_X86_REG_EBX, 0xaa96a47f)
mu.mem_write(CODE_ADDR, CODE)
try:
mu.emu_start(CODE_ADDR, CODE_ADDR + 2, count=1)
except unicorn.UcError as e:
assert(e.errno == unicorn.UC_ERR_CODE_INVALID)
else:
assert(False)
print "Success"