Merge pull request #41 from cseagle/master

First crack at java bindings for unicorn
This commit is contained in:
Nguyen Anh Quynh 2015-08-26 08:59:19 +08:00
commit 8154c11480
33 changed files with 5594 additions and 0 deletions

65
bindings/java/Makefile Executable file
View File

@ -0,0 +1,65 @@
JAVA_HOME := $(shell jrunscript -e 'java.lang.System.out.println(java.lang.System.getProperty("java.home"));')
JAVA_INC := $(shell realpath $(JAVA_HOME)/../include)
JAVA_PLATFORM_INC := $(shell dirname `find $(JAVA_INC) -name jni_md.h`)
UNICORN_INC=../../include
SAMPLES := $(shell ls samples/*.java)
SRC := $(shell ls unicorn/*.java)
OS := $(shell uname)
ifeq ($(OS),Darwin)
LIB_EXT=.dylib
endif
ifeq ($(OS),Linux)
LIB_EXT=.so
else
LIB_EXT=.dll
endif
CC=gcc
CFLAGS=-fPIC
LDFLAGS=-shared -fPIC
LIBS=-lunicorn
LIBDIR=-L../../
INCS=-I$(JAVA_INC) -I$(JAVA_PLATFORM_INC) -I$(UNICORN_INC)
JC=javac
CLASSPATH=./
.SUFFIXES: .java .class
%.class: %.java
$(JC) $(JFLAGS) $<
OBJS=unicorn_Unicorn.o
JARFILE=unicorn.jar
all: lib jar samples
%.o: %.c
$(CC) -c $(CFLAGS) $(INCS) $< -o $@
unicorn_Unicorn.h: unicorn/Unicorn.java
javah unicorn.Unicorn
unicorn_Unicorn.o: unicorn_Unicorn.c unicorn_Unicorn.h
$(CC) -c $(CFLAGS) $(INCS) $< -o $@
libunicorn_java$(LIB_EXT): unicorn_Unicorn.o
lib: libunicorn_java$(LIB_EXT) unicorn_Unicorn.h
$(CC) -o $< $(LDFLAGS) $(OBJS) $(LIBDIR) $(LIBS)
samples: $(SAMPLES:.java=.class)
jarfiles: $(SRC:.java=.class)
jar: jarfiles
jar cf $(JARFILE) unicorn/*.class
install: lib jar
cp libunicorn_java$(LIB_EXT) $(JAVA_HOME)/lib/ext
cp $(JARFILE) $(JAVA_HOME)/lib/ext

View File

@ -0,0 +1,130 @@
/* Unicorn Emulator Engine */
/* By Nguyen Anh Quynh, 2015 */
/* Sample code to demonstrate how to emulate ARM code */
import unicorn.*;
public class Sample_arm {
// code to be emulated
public static final byte[] ARM_CODE = {55,0,(byte)0xa0,(byte)0xe3,3,16,66,(byte)0xe0}; // mov r0, #0x37; sub r1, r2, r3
public static final byte[] THUMB_CODE = {(byte)0x83, (byte)0xb0}; // sub sp, #0xc
// memory address where emulation starts
public static final int ADDRESS = 0x10000;
public static final long toInt(byte val[]) {
long res = 0;
for (int i = 0; i < val.length; i++) {
long v = val[i] & 0xff;
res = res + (v << (i * 8));
}
return res;
}
private static class MyBlockHook implements BlockHook {
public void hook(Unicorn u, long address, int size, Object user_data)
{
System.out.print(String.format(">>> Tracing basic block at 0x%x, block size = 0x%x\n", address, size));
}
}
// callback for tracing instruction
private static class MyCodeHook implements CodeHook {
public void hook(Unicorn u, long address, int size, Object user_data) {
System.out.print(String.format(">>> Tracing instruction at 0x%x, instruction size = 0x%x\n", address, size));
}
}
static void test_arm()
{
byte[] r0 = {0x34, 0x12, 0, 0}; // R0 register
byte[] r2 = {(byte)0x89, 0x67, 0, 0}; // R1 register
byte[] r3 = {0x33, 0x33, 0, 0}; // R2 register
byte[] r1; // R1 register
System.out.print("Emulate ARM code\n");
// Initialize emulator in ARM mode
Unicorn u = new Unicorn(Unicorn.UC_ARCH_ARM, Unicorn.UC_MODE_ARM);
// map 2MB memory for this emulation
u.mem_map(ADDRESS, 2 * 1024 * 1024);
// write machine code to be emulated to memory
u.mem_write(ADDRESS, ARM_CODE);
// initialize machine registers
u.reg_write(Unicorn.UC_ARM_REG_R0, r0);
u.reg_write(Unicorn.UC_ARM_REG_R2, r2);
u.reg_write(Unicorn.UC_ARM_REG_R3, r3);
// tracing all basic blocks with customized callback
u.hook_add(new MyBlockHook(), 1, 0, null);
// tracing one instruction at ADDRESS with customized callback
u.hook_add(new MyCodeHook(), ADDRESS, ADDRESS, null);
// emulate machine code in infinite time (last param = 0), or when
// finishing all the code.
u.emu_start(ADDRESS, ADDRESS + ARM_CODE.length, 0, 0);
// now print out some registers
System.out.print(">>> Emulation done. Below is the CPU context\n");
r0 = u.reg_read(Unicorn.UC_ARM_REG_R0, 4);
r1 = u.reg_read(Unicorn.UC_ARM_REG_R1, 4);
System.out.print(String.format(">>> R0 = 0x%x\n", toInt(r0)));
System.out.print(String.format(">>> R1 = 0x%x\n", toInt(r1)));
u.close();
}
static void test_thumb()
{
byte[] sp = {0x34, 0x12, 0, 0}; // R0 register
System.out.print("Emulate THUMB code\n");
// Initialize emulator in ARM mode
Unicorn u = new Unicorn(Unicorn.UC_ARCH_ARM, Unicorn.UC_MODE_THUMB);
// map 2MB memory for this emulation
u.mem_map(ADDRESS, 2 * 1024 * 1024);
// write machine code to be emulated to memory
u.mem_write(ADDRESS, THUMB_CODE);
// initialize machine registers
u.reg_write(Unicorn.UC_ARM_REG_SP, sp);
// tracing all basic blocks with customized callback
u.hook_add(new MyBlockHook(), 1, 0, null);
// tracing one instruction at ADDRESS with customized callback
u.hook_add(new MyCodeHook(), ADDRESS, ADDRESS, null);
// emulate machine code in infinite time (last param = 0), or when
// finishing all the code.
u.emu_start(ADDRESS, ADDRESS + THUMB_CODE.length, 0, 0);
// now print out some registers
System.out.print(">>> Emulation done. Below is the CPU context\n");
sp = u.reg_read(Unicorn.UC_ARM_REG_SP, 4);
System.out.print(String.format(">>> SP = 0x%x\n", toInt(sp)));
u.close();
}
public static void main(String args[])
{
test_arm();
System.out.print("==========================\n");
test_thumb();
}
}

View File

@ -0,0 +1,115 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2015 Chris Eagle
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/* Unicorn Emulator Engine */
/* By Nguyen Anh Quynh, 2015 */
/* Sample code to demonstrate how to emulate ARM64 code */
import unicorn.*;
public class Sample_arm64 {
// code to be emulated
public static final byte[] ARM_CODE = {-85,1,15,-117}; // add x11, x13, x15
// memory address where emulation starts
public static final int ADDRESS = 0x10000;
public static final long toInt(byte val[]) {
long res = 0;
for (int i = 0; i < val.length; i++) {
long v = val[i] & 0xff;
res = res + (v << (i * 8));
}
return res;
}
public static final byte[] toBytes(long val) {
byte[] res = new byte[8];
for (int i = 0; i < 8; i++) {
res[i] = (byte)(val & 0xff);
val >>>= 8;
}
return res;
}
// callback for tracing basic blocks
private static class MyBlockHook implements BlockHook {
public void hook(Unicorn u, long address, int size, Object user_data) {
System.out.print(String.format(">>> Tracing basic block at 0x%x, block size = 0x%x\n", address, size));
}
}
// callback for tracing instruction
private static class MyCodeHook implements CodeHook {
public void hook(Unicorn u, long address, int size, Object user_data) {
System.out.print(String.format(">>> Tracing instruction at 0x%x, instruction size = 0x%x\n", address, size));
}
}
static void test_arm64()
{
byte[] x11 = toBytes(0x1234); // X11 register
byte[] x13 = toBytes(0x6789); // X13 register
byte[] x15 = toBytes(0x3333); // X15 register
System.out.print("Emulate ARM64 code\n");
// Initialize emulator in ARM mode
Unicorn u = new Unicorn(Unicorn.UC_ARCH_ARM64, Unicorn.UC_MODE_ARM);
// map 2MB memory for this emulation
u.mem_map(ADDRESS, 2 * 1024 * 1024);
// write machine code to be emulated to memory
u.mem_write(ADDRESS, ARM_CODE);
// initialize machine registers
u.reg_write(Unicorn.UC_ARM64_REG_X11, x11);
u.reg_write(Unicorn.UC_ARM64_REG_X13, x13);
u.reg_write(Unicorn.UC_ARM64_REG_X15, x15);
// tracing all basic blocks with customized callback
u.hook_add(new MyBlockHook(), 1, 0, null);
// tracing one instruction at ADDRESS with customized callback
u.hook_add(new MyCodeHook(), ADDRESS, ADDRESS, null);
// emulate machine code in infinite time (last param = 0), or when
// finishing all the code.
u.emu_start(ADDRESS, ADDRESS + ARM_CODE.length, 0, 0);
// now print out some registers
System.out.print(">>> Emulation done. Below is the CPU context\n");
x11 = u.reg_read(Unicorn.UC_ARM64_REG_X11, 8);
System.out.print(String.format(">>> X11 = 0x%x\n", toInt(x11)));
u.close();
}
public static void main(String args[])
{
test_arm64();
}
}

View File

@ -0,0 +1,177 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2015 Chris Eagle
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/* Unicorn Emulator Engine */
/* By Loi Anh Tuan, 2015 */
/* Sample code to demonstrate how to emulate m68k code */
import unicorn.*;
public class Sample_m68k {
// code to be emulated
public static final byte[] M68K_CODE = {118,-19}; // movq #-19, %d3
// memory address where emulation starts
public static final int ADDRESS = 0x10000;
public static final long toInt(byte val[]) {
long res = 0;
for (int i = 0; i < val.length; i++) {
long v = val[i] & 0xff;
res = res + (v << (i * 8));
}
return res;
}
public static final byte[] toBytes(long val) {
byte[] res = new byte[8];
for (int i = 0; i < 8; i++) {
res[i] = (byte)(val & 0xff);
val >>>= 8;
}
return res;
}
// callback for tracing basic blocks
private static class MyBlockHook implements BlockHook {
public void hook(Unicorn u, long address, int size, Object user_data) {
System.out.print(String.format(">>> Tracing basic block at 0x%x, block size = 0x%x\n", address, size));
}
}
// callback for tracing instruction
private static class MyCodeHook implements CodeHook {
public void hook(Unicorn u, long address, int size, Object user_data) {
System.out.print(String.format(">>> Tracing instruction at 0x%x, instruction size = 0x%x\n", address, size));
}
}
static void test_m68k()
{
byte[] d0 = toBytes(0x0000); // d0 data register
byte[] d1 = toBytes(0x0000); // d1 data register
byte[] d2 = toBytes(0x0000); // d2 data register
byte[] d3 = toBytes(0x0000); // d3 data register
byte[] d4 = toBytes(0x0000); // d4 data register
byte[] d5 = toBytes(0x0000); // d5 data register
byte[] d6 = toBytes(0x0000); // d6 data register
byte[] d7 = toBytes(0x0000); // d7 data register
byte[] a0 = toBytes(0x0000); // a0 address register
byte[] a1 = toBytes(0x0000); // a1 address register
byte[] a2 = toBytes(0x0000); // a2 address register
byte[] a3 = toBytes(0x0000); // a3 address register
byte[] a4 = toBytes(0x0000); // a4 address register
byte[] a5 = toBytes(0x0000); // a5 address register
byte[] a6 = toBytes(0x0000); // a6 address register
byte[] a7 = toBytes(0x0000); // a6 address register
byte[] pc = toBytes(0x0000); // program counter
byte[] sr = toBytes(0x0000); // status register
System.out.print("Emulate M68K code\n");
// Initialize emulator in M68K mode
Unicorn u = new Unicorn(Unicorn.UC_ARCH_M68K, Unicorn.UC_MODE_BIG_ENDIAN);
// map 2MB memory for this emulation
u.mem_map(ADDRESS, 2 * 1024 * 1024);
// write machine code to be emulated to memory
u.mem_write(ADDRESS, M68K_CODE);
// initialize machine registers
u.reg_write(Unicorn.UC_M68K_REG_D0, d0);
u.reg_write(Unicorn.UC_M68K_REG_D1, d1);
u.reg_write(Unicorn.UC_M68K_REG_D2, d2);
u.reg_write(Unicorn.UC_M68K_REG_D3, d3);
u.reg_write(Unicorn.UC_M68K_REG_D4, d4);
u.reg_write(Unicorn.UC_M68K_REG_D5, d5);
u.reg_write(Unicorn.UC_M68K_REG_D6, d6);
u.reg_write(Unicorn.UC_M68K_REG_D7, d7);
u.reg_write(Unicorn.UC_M68K_REG_A0, a0);
u.reg_write(Unicorn.UC_M68K_REG_A1, a1);
u.reg_write(Unicorn.UC_M68K_REG_A2, a2);
u.reg_write(Unicorn.UC_M68K_REG_A3, a3);
u.reg_write(Unicorn.UC_M68K_REG_A4, a4);
u.reg_write(Unicorn.UC_M68K_REG_A5, a5);
u.reg_write(Unicorn.UC_M68K_REG_A6, a6);
u.reg_write(Unicorn.UC_M68K_REG_A7, a7);
u.reg_write(Unicorn.UC_M68K_REG_PC, pc);
u.reg_write(Unicorn.UC_M68K_REG_SR, sr);
// tracing all basic blocks with customized callback
u.hook_add(new MyBlockHook(), 1, 0, null);
// tracing all instruction
u.hook_add(new MyCodeHook(), 1, 0, null);
// emulate machine code in infinite time (last param = 0), or when
// finishing all the code.
u.emu_start(ADDRESS, ADDRESS + M68K_CODE.length, 0, 0);
// now print out some registers
System.out.print(">>> Emulation done. Below is the CPU context\n");
d0 = u.reg_read(Unicorn.UC_M68K_REG_D0, 4);
d1 = u.reg_read(Unicorn.UC_M68K_REG_D1, 4);
d2 = u.reg_read(Unicorn.UC_M68K_REG_D2, 4);
d3 = u.reg_read(Unicorn.UC_M68K_REG_D3, 4);
d4 = u.reg_read(Unicorn.UC_M68K_REG_D4, 4);
d5 = u.reg_read(Unicorn.UC_M68K_REG_D5, 4);
d6 = u.reg_read(Unicorn.UC_M68K_REG_D6, 4);
d7 = u.reg_read(Unicorn.UC_M68K_REG_D7, 4);
a0 = u.reg_read(Unicorn.UC_M68K_REG_A0, 4);
a1 = u.reg_read(Unicorn.UC_M68K_REG_A1, 4);
a2 = u.reg_read(Unicorn.UC_M68K_REG_A2, 4);
a3 = u.reg_read(Unicorn.UC_M68K_REG_A3, 4);
a4 = u.reg_read(Unicorn.UC_M68K_REG_A4, 4);
a5 = u.reg_read(Unicorn.UC_M68K_REG_A5, 4);
a6 = u.reg_read(Unicorn.UC_M68K_REG_A6, 4);
a7 = u.reg_read(Unicorn.UC_M68K_REG_A7, 4);
pc = u.reg_read(Unicorn.UC_M68K_REG_PC, 4);
sr = u.reg_read(Unicorn.UC_M68K_REG_SR, 4);
System.out.print(String.format(">>> A0 = 0x%x\t\t>>> D0 = 0x%x\n", toInt(a0), toInt(d0)));
System.out.print(String.format(">>> A1 = 0x%x\t\t>>> D1 = 0x%x\n", toInt(a1), toInt(d1)));
System.out.print(String.format(">>> A2 = 0x%x\t\t>>> D2 = 0x%x\n", toInt(a2), toInt(d2)));
System.out.print(String.format(">>> A3 = 0x%x\t\t>>> D3 = 0x%x\n", toInt(a3), toInt(d3)));
System.out.print(String.format(">>> A4 = 0x%x\t\t>>> D4 = 0x%x\n", toInt(a4), toInt(d4)));
System.out.print(String.format(">>> A5 = 0x%x\t\t>>> D5 = 0x%x\n", toInt(a5), toInt(d5)));
System.out.print(String.format(">>> A6 = 0x%x\t\t>>> D6 = 0x%x\n", toInt(a6), toInt(d6)));
System.out.print(String.format(">>> A7 = 0x%x\t\t>>> D7 = 0x%x\n", toInt(a7), toInt(d7)));
System.out.print(String.format(">>> PC = 0x%x\n", toInt(pc)));
System.out.print(String.format(">>> SR = 0x%x\n", toInt(sr)));
u.close();
}
public static void main(String args[])
{
test_m68k();
}
}

View File

@ -0,0 +1,151 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2015 Chris Eagle
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/* Unicorn Emulator Engine */
/* By Nguyen Anh Quynh, 2015 */
/* Sample code to demonstrate how to emulate Mips code (big endian) */
import unicorn.*;
public class Sample_mips {
// code to be emulated
public static final byte[] MIPS_CODE_EB = {52,33,52,86};
public static final byte[] MIPS_CODE_EL = {86,52,33,52};
// memory address where emulation starts
public static final int ADDRESS = 0x10000;
public static final long toInt(byte val[]) {
long res = 0;
for (int i = 0; i < val.length; i++) {
long v = val[i] & 0xff;
res = res + (v << (i * 8));
}
return res;
}
public static final byte[] toBytes(long val) {
byte[] res = new byte[8];
for (int i = 0; i < 8; i++) {
res[i] = (byte)(val & 0xff);
val >>>= 8;
}
return res;
}
// callback for tracing basic blocks
private static class MyBlockHook implements BlockHook {
public void hook(Unicorn u, long address, int size, Object user_data) {
System.out.print(String.format(">>> Tracing basic block at 0x%x, block size = 0x%x\n", address, size));
}
}
// callback for tracing instruction
private static class MyCodeHook implements CodeHook {
public void hook(Unicorn u, long address, int size, Object user_data) {
System.out.print(String.format(">>> Tracing instruction at 0x%x, instruction size = 0x%x\n", address, size));
}
}
static void test_mips_eb()
{
byte[] r1 = toBytes(0x6789); // R1 register
System.out.print("Emulate MIPS code (big-endian)\n");
// Initialize emulator in MIPS mode
Unicorn u = new Unicorn(Unicorn.UC_ARCH_MIPS, Unicorn.UC_MODE_MIPS32 + Unicorn.UC_MODE_BIG_ENDIAN);
// map 2MB memory for this emulation
u.mem_map(ADDRESS, 2 * 1024 * 1024);
// write machine code to be emulated to memory
u.mem_write(ADDRESS, MIPS_CODE_EB);
// initialize machine registers
u.reg_write(Unicorn.UC_MIPS_REG_1, r1);
// tracing all basic blocks with customized callback
u.hook_add(new MyBlockHook(), 1, 0, null);
// tracing one instruction at ADDRESS with customized callback
u.hook_add(new MyCodeHook(), ADDRESS, ADDRESS, null);
// emulate machine code in infinite time (last param = 0), or when
// finishing all the code.
u.emu_start(ADDRESS, ADDRESS + MIPS_CODE_EB.length, 0, 0);
// now print out some registers
System.out.print(">>> Emulation done. Below is the CPU context\n");
r1 = u.reg_read(Unicorn.UC_MIPS_REG_1, 4);
System.out.print(String.format(">>> R1 = 0x%x\n", toInt(r1)));
u.close();
}
static void test_mips_el()
{
byte[] r1 = toBytes(0x6789); // R1 register
System.out.print("===========================\n");
System.out.print("Emulate MIPS code (little-endian)\n");
// Initialize emulator in MIPS mode
Unicorn u = new Unicorn(Unicorn.UC_ARCH_MIPS, Unicorn.UC_MODE_MIPS32);
// map 2MB memory for this emulation
u.mem_map(ADDRESS, 2 * 1024 * 1024);
// write machine code to be emulated to memory
u.mem_write(ADDRESS, MIPS_CODE_EL);
// initialize machine registers
u.reg_write(Unicorn.UC_MIPS_REG_1, r1);
// tracing all basic blocks with customized callback
u.hook_add(new MyBlockHook(), 1, 0, null);
// tracing one instruction at ADDRESS with customized callback
u.hook_add(new MyCodeHook(), ADDRESS, ADDRESS, null);
// emulate machine code in infinite time (last param = 0), or when
// finishing all the code.
u.emu_start(ADDRESS, ADDRESS + MIPS_CODE_EL.length, 0, 0);
// now print out some registers
System.out.print(">>> Emulation done. Below is the CPU context\n");
r1 = u.reg_read(Unicorn.UC_MIPS_REG_1, 4);
System.out.print(String.format(">>> R1 = 0x%x\n", toInt(r1)));
u.close();
}
public static void main(String args[])
{
test_mips_eb();
test_mips_el();
}
}

View File

@ -0,0 +1,115 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2015 Chris Eagle
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/* Unicorn Emulator Engine */
/* By Nguyen Anh Quynh, 2015 */
/* Sample code to demonstrate how to emulate Sparc code */
import unicorn.*;
public class Sample_sparc {
// code to be emulated
public static final byte[] SPARC_CODE = {-122,0,64,2};
//public static final byte[] SPARC_CODE = {-69,112,0,0}; //illegal code
// memory address where emulation starts
public static final int ADDRESS = 0x10000;
public static final long toInt(byte val[]) {
long res = 0;
for (int i = 0; i < val.length; i++) {
long v = val[i] & 0xff;
res = res + (v << (i * 8));
}
return res;
}
public static final byte[] toBytes(long val) {
byte[] res = new byte[8];
for (int i = 0; i < 8; i++) {
res[i] = (byte)(val & 0xff);
val >>>= 8;
}
return res;
}
// callback for tracing basic blocks
private static class MyBlockHook implements BlockHook {
public void hook(Unicorn u, long address, int size, Object user_data) {
System.out.print(String.format(">>> Tracing basic block at 0x%x, block size = 0x%x\n", address, size));
}
}
// callback for tracing instruction
private static class MyCodeHook implements CodeHook {
public void hook(Unicorn u, long address, int size, Object user_data) {
System.out.print(String.format(">>> Tracing instruction at 0x%x, instruction size = 0x%x\n", address, size));
}
}
static void test_sparc()
{
byte[] g1 = toBytes(0x1230); // G1 register
byte[] g2 = toBytes(0x6789); // G2 register
byte[] g3 = toBytes(0x5555); // G3 register
System.out.print("Emulate SPARC code\n");
// Initialize emulator in Sparc mode
Unicorn u = new Unicorn(Unicorn.UC_ARCH_SPARC, Unicorn.UC_MODE_BIG_ENDIAN);
// map 2MB memory for this emulation
u.mem_map(ADDRESS, 2 * 1024 * 1024);
// write machine code to be emulated to memory
u.mem_write(ADDRESS, SPARC_CODE);
// initialize machine registers
u.reg_write(Unicorn.UC_SPARC_REG_G1, g1);
u.reg_write(Unicorn.UC_SPARC_REG_G2, g2);
u.reg_write(Unicorn.UC_SPARC_REG_G3, g3);
// tracing all basic blocks with customized callback
u.hook_add(new MyBlockHook(), 1, 0, null);
// tracing one instruction at ADDRESS with customized callback
u.hook_add(new MyCodeHook(), ADDRESS, ADDRESS, null);
// emulate machine code in infinite time (last param = 0), or when
// finishing all the code.
u.emu_start(ADDRESS, ADDRESS + SPARC_CODE.length, 0, 0);
// now print out some registers
System.out.print(">>> Emulation done. Below is the CPU context\n");
g3 = u.reg_read(Unicorn.UC_SPARC_REG_G3, 4);
System.out.print(String.format(">>> G3 = 0x%x\n", toInt(g3)));
u.close();
}
public static void main(String args[])
{
test_sparc();
}
}

View File

@ -0,0 +1,618 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2015 Chris Eagle
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/* Unicorn Emulator Engine */
/* By Nguyen Anh Quynh & Dang Hoang Vu, 2015 */
/* Sample code to demonstrate how to emulate X86 code */
import unicorn.*;
public class Sample_x86 {
// code to be emulated
public static final byte[] X86_CODE32 = {65,74};
public static final byte[] X86_CODE32_JUMP = {-21,2,-112,-112,-112,-112,-112,-112};
public static final byte[] X86_CODE32_SELF = {-21,28,90,-119,-42,-117,2,102,61,-54,125,117,6,102,5,3,3,-119,2,-2,-62,61,65,65,65,65,117,-23,-1,-26,-24,-33,-1,-1,-1,49,-46,106,11,88,-103,82,104,47,47,115,104,104,47,98,105,110,-119,-29,82,83,-119,-31,-54,125,65,65,65,65};
public static final byte[] X86_CODE32_LOOP = {65,74,-21,-2};
public static final byte[] X86_CODE32_MEM_WRITE = {-119,13,-86,-86,-86,-86,65,74};
public static final byte[] X86_CODE32_MEM_READ = {-117,13,-86,-86,-86,-86,65,74};
public static final byte[] X86_CODE32_JMP_INVALID = {-23,-23,-18,-18,-18,65,74};
public static final byte[] X86_CODE32_INOUT = {65,-28,63,74,-26,70,67};
public static final byte[] X86_CODE64 = {65,-68,59,-80,40,42,73,15,-55,-112,77,15,-83,-49,73,-121,-3,-112,72,-127,-46,-118,-50,119,53,72,-9,-39,77,41,-12,73,-127,-55,-10,-118,-58,83,77,-121,-19,72,15,-83,-46,73,-9,-44,72,-9,-31,77,25,-59,77,-119,-59,72,-9,-42,65,-72,79,-115,107,89,77,-121,-48,104,106,30,9,60,89};
// memory address where emulation starts
public static final int ADDRESS = 0x1000000;
public static final long toInt(byte val[]) {
long res = 0;
for (int i = 0; i < val.length; i++) {
long v = val[i] & 0xff;
res = res + (v << (i * 8));
}
return res;
}
public static final byte[] toBytes(long val) {
byte[] res = new byte[8];
for (int i = 0; i < 8; i++) {
res[i] = (byte)(val & 0xff);
val >>>= 8;
}
return res;
}
// callback for tracing basic blocks
// callback for tracing instruction
private static class MyBlockHook implements BlockHook {
public void hook(Unicorn u, long address, int size, Object user_data)
{
System.out.print(String.format(">>> Tracing basic block at 0x%x, block size = 0x%x\n", address, size));
}
}
// callback for tracing instruction
private static class MyCodeHook implements CodeHook {
public void hook(Unicorn u, long address, int size, Object user_data) {
System.out.print(String.format(">>> Tracing instruction at 0x%x, instruction size = 0x%x\n", address, size));
byte eflags[] = u.reg_read(Unicorn.UC_X86_REG_EFLAGS, 4);
System.out.print(String.format(">>> --- EFLAGS is 0x%x\n", toInt(eflags)));
// Uncomment below code to stop the emulation using uc_emu_stop()
// if (address == 0x1000009)
// u.emu_stop();
}
}
private static class MyMemInvalidHook implements MemoryInvalidHook {
public boolean hook(Unicorn u, int type, long address, int size, long value, Object user) {
switch(type) {
case Unicorn.UC_MEM_WRITE:
System.out.print(String.format(">>> Missing memory is being WRITE at 0x%x, data size = %d, data value = 0x%x\n",
address, size, value));
// map this memory in with 2MB in size
u.mem_map(0xaaaa0000, 2 * 1024*1024);
// return true to indicate we want to continue
return true;
}
return false;
}
}
// callback for tracing instruction
private static class MyCode64Hook implements CodeHook {
public void hook(Unicorn u, long address, int size, Object user_data) {
byte[] r_rip = u.reg_read(Unicorn.UC_X86_REG_RIP, 8);
System.out.print(String.format(">>> Tracing instruction at 0x%x, instruction size = 0x%x\n", address, size));
System.out.print(String.format(">>> RIP is 0x%x\n", toInt(r_rip)));
// Uncomment below code to stop the emulation using uc_emu_stop()
// if (address == 0x1000009)
// uc_emu_stop(handle);
}
}
private static class MyRead64Hook implements ReadHook {
public void hook(Unicorn u, long address, int size, Object user) {
System.out.print(String.format(">>> Memory is being READ at 0x%x, data size = %d\n", address, size));
}
}
private static class MyWrite64Hook implements WriteHook {
public void hook(Unicorn u, long address, int size, long value, Object user) {
System.out.print(String.format(">>> Memory is being WRITE at 0x%x, data size = %d, data value = 0x%x\n",
address, size, value));
}
}
// callback for IN instruction (X86).
// this returns the data read from the port
private static class MyInHook implements InHook {
public int hook(Unicorn u, int port, int size, Object user_data)
{
byte[] r_eip = u.reg_read(Unicorn.UC_X86_REG_EIP, 4);
System.out.print(String.format("--- reading from port 0x%x, size: %d, address: 0x%x\n", port, size, toInt(r_eip)));
switch(size) {
case 1:
// read 1 byte to AL
return 0xf1;
case 2:
// read 2 byte to AX
return 0xf2;
case 4:
// read 4 byte to EAX
return 0xf4;
}
return 0;
}
}
// callback for OUT instruction (X86).
private static class MyOutHook implements OutHook {
public void hook(Unicorn u, int port, int size, int value, Object user) {
byte[] eip = u.reg_read(Unicorn.UC_X86_REG_EIP, 4);
byte[] tmp = null;
System.out.print(String.format("--- writing to port 0x%x, size: %d, value: 0x%x, address: 0x%x\n", port, size, value, toInt(eip)));
// confirm that value is indeed the value of AL/AX/EAX
switch(size) {
default:
return; // should never reach this
case 1:
tmp = u.reg_read(Unicorn.UC_X86_REG_AL, 1);
break;
case 2:
tmp = u.reg_read(Unicorn.UC_X86_REG_AX, 2);
break;
case 4:
tmp = u.reg_read(Unicorn.UC_X86_REG_EAX, 4);
break;
}
System.out.print(String.format("--- register value = 0x%x\n", toInt(tmp)));
}
}
static void test_i386()
{
byte r_ecx[] = {(byte)0x34, (byte)0x12, 0, 0}; //0x1234; // ECX register
byte r_edx[] = {(byte)0x90, (byte)0x78, 0, 0}; //0x7890; // EDX register
System.out.print("Emulate i386 code\n");
// Initialize emulator in X86-32bit mode
Unicorn uc;
try {
uc = new Unicorn(Unicorn.UC_ARCH_X86, Unicorn.UC_MODE_32);
} catch (UnicornException uex) {
System.out.println("Failed on uc_open() with error returned: " + uex);
return;
}
// map 2MB memory for this emulation
uc.mem_map(ADDRESS, 2 * 1024 * 1024);
// write machine code to be emulated to memory
try {
uc.mem_write(ADDRESS, X86_CODE32);
} catch (UnicornException uex) {
System.out.println("Failed to write emulation code to memory, quit!\n");
return;
}
// initialize machine registers
uc.reg_write(Unicorn.UC_X86_REG_ECX, r_ecx);
uc.reg_write(Unicorn.UC_X86_REG_EDX, r_edx);
// tracing all basic blocks with customized callback
uc.hook_add(new MyBlockHook(), 1, 0, null);
// tracing all instruction by having @begin > @end
uc.hook_add(new MyCodeHook(), 1, 0, null);
// emulate machine code in infinite time
try {
uc.emu_start(ADDRESS, ADDRESS + X86_CODE32.length, 0, 0);
} catch (UnicornException uex) {
System.out.print(String.format("Failed on uc_emu_start() with error : %s\n",
uex.getMessage()));
}
// now print out some registers
System.out.print(">>> Emulation done. Below is the CPU context\n");
r_ecx = uc.reg_read(Unicorn.UC_X86_REG_ECX, 4);
r_edx = uc.reg_read(Unicorn.UC_X86_REG_EDX, 4);
System.out.print(String.format(">>> ECX = 0x%x\n", toInt(r_ecx)));
System.out.print(String.format(">>> EDX = 0x%x\n", toInt(r_edx)));
// read from memory
try {
byte tmp[] = uc.mem_read(ADDRESS, 4);
System.out.print(String.format(">>> Read 4 bytes from [0x%x] = 0x%x\n", ADDRESS, toInt(tmp)));
} catch (UnicornException ex) {
System.out.print(String.format(">>> Failed to read 4 bytes from [0x%x]\n", ADDRESS));
}
uc.close();
}
static void test_i386_inout()
{
byte[] r_eax = {0x34, 0x12, 0, 0}; //0x1234; // EAX register
byte[] r_ecx = {(byte)0x89, 0x67, 0, 0}; //0x6789; // ECX register
System.out.print("===================================\n");
System.out.print("Emulate i386 code with IN/OUT instructions\n");
// Initialize emulator in X86-32bit mode
Unicorn u = new Unicorn(Unicorn.UC_ARCH_X86, Unicorn.UC_MODE_32);
// map 2MB memory for this emulation
u.mem_map(ADDRESS, 2 * 1024 * 1024);
// write machine code to be emulated to memory
u.mem_write(ADDRESS, X86_CODE32_INOUT);
// initialize machine registers
u.reg_write(Unicorn.UC_X86_REG_EAX, r_eax);
u.reg_write(Unicorn.UC_X86_REG_ECX, r_ecx);
// tracing all basic blocks with customized callback
u.hook_add(new MyBlockHook(), 1, 0, null);
// tracing all instructions
u.hook_add(new MyCodeHook(), 1, 0, null);
// handle IN instruction
u.hook_add(new MyInHook(), null);
// handle OUT instruction
u.hook_add(new MyOutHook(), null);
// emulate machine code in infinite time
u.emu_start(ADDRESS, ADDRESS + X86_CODE32_INOUT.length, 0, 0);
// now print out some registers
System.out.print(">>> Emulation done. Below is the CPU context\n");
r_eax = u.reg_read(Unicorn.UC_X86_REG_EAX, 4);
r_ecx = u.reg_read(Unicorn.UC_X86_REG_ECX, 4);
System.out.print(String.format(">>> EAX = 0x%x\n", toInt(r_eax)));
System.out.print(String.format(">>> ECX = 0x%x\n", toInt(r_ecx)));
u.close();
}
static void test_i386_jump()
{
System.out.print("===================================\n");
System.out.print("Emulate i386 code with jump\n");
// Initialize emulator in X86-32bit mode
Unicorn u = new Unicorn(Unicorn.UC_ARCH_X86, Unicorn.UC_MODE_32);
// map 2MB memory for this emulation
u.mem_map(ADDRESS, 2 * 1024 * 1024);
// write machine code to be emulated to memory
u.mem_write(ADDRESS, X86_CODE32_JUMP);
// tracing 1 basic block with customized callback
u.hook_add(new MyBlockHook(), ADDRESS, ADDRESS, null);
// tracing 1 instruction at ADDRESS
u.hook_add(new MyCodeHook(), ADDRESS, ADDRESS, null);
// emulate machine code in infinite time
u.emu_start(ADDRESS, ADDRESS + X86_CODE32_JUMP.length, 0, 0);
System.out.print(">>> Emulation done. Below is the CPU context\n");
u.close();
}
// emulate code that loop forever
static void test_i386_loop()
{
byte r_ecx[] = {(byte)0x34, (byte)0x12, 0, 0}; //0x1234; // ECX register
byte r_edx[] = {(byte)0x90, (byte)0x78, 0, 0}; //0x7890; // EDX register
System.out.print("===================================\n");
System.out.print("Emulate i386 code that loop forever\n");
// Initialize emulator in X86-32bit mode
Unicorn u = new Unicorn(Unicorn.UC_ARCH_X86, Unicorn.UC_MODE_32);
// map 2MB memory for this emulation
u.mem_map(ADDRESS, 2 * 1024 * 1024);
// write machine code to be emulated to memory
u.mem_write(ADDRESS, X86_CODE32_LOOP);
// initialize machine registers
u.reg_write(Unicorn.UC_X86_REG_ECX, r_ecx);
u.reg_write(Unicorn.UC_X86_REG_EDX, r_edx);
// emulate machine code in 2 seconds, so we can quit even
// if the code loops
u.emu_start(ADDRESS, ADDRESS + X86_CODE32_LOOP.length, 2 * Unicorn.UC_SECOND_SCALE, 0);
// now print out some registers
System.out.print(">>> Emulation done. Below is the CPU context\n");
r_ecx = u.reg_read(Unicorn.UC_X86_REG_ECX, 4);
r_edx = u.reg_read(Unicorn.UC_X86_REG_EDX, 4);
System.out.print(String.format(">>> ECX = 0x%x\n", toInt(r_ecx)));
System.out.print(String.format(">>> EDX = 0x%x\n", toInt(r_edx)));
u.close();
}
// emulate code that read invalid memory
static void test_i386_invalid_mem_read()
{
byte r_ecx[] = {(byte)0x34, (byte)0x12, 0, 0}; //0x1234; // ECX register
byte r_edx[] = {(byte)0x90, (byte)0x78, 0, 0}; //0x7890; // EDX register
System.out.print("===================================\n");
System.out.print("Emulate i386 code that read from invalid memory\n");
// Initialize emulator in X86-32bit mode
Unicorn u = new Unicorn(Unicorn.UC_ARCH_X86, Unicorn.UC_MODE_32);
// map 2MB memory for this emulation
u.mem_map(ADDRESS, 2 * 1024 * 1024);
// write machine code to be emulated to memory
u.mem_write(ADDRESS, X86_CODE32_MEM_READ);
// initialize machine registers
u.reg_write(Unicorn.UC_X86_REG_ECX, r_ecx);
u.reg_write(Unicorn.UC_X86_REG_EDX, r_edx);
// tracing all basic blocks with customized callback
u.hook_add(new MyBlockHook(), 1, 0, null);
// tracing all instruction by having @begin > @end
u.hook_add(new MyCodeHook(), 1, 0, null);
// emulate machine code in infinite time
u.emu_start(ADDRESS, ADDRESS + X86_CODE32_MEM_READ.length, 0, 0);
// now print out some registers
System.out.print(">>> Emulation done. Below is the CPU context\n");
r_ecx = u.reg_read(Unicorn.UC_X86_REG_ECX, 4);
r_edx = u.reg_read(Unicorn.UC_X86_REG_EDX, 4);
System.out.print(String.format(">>> ECX = 0x%x\n", toInt(r_ecx)));
System.out.print(String.format(">>> EDX = 0x%x\n", toInt(r_edx)));
u.close();
}
// emulate code that read invalid memory
static void test_i386_invalid_mem_write()
{
byte r_ecx[] = {(byte)0x34, (byte)0x12, 0, 0}; //0x1234; // ECX register
byte r_edx[] = {(byte)0x90, (byte)0x78, 0, 0}; //0x7890; // EDX register
System.out.print("===================================\n");
System.out.print("Emulate i386 code that write to invalid memory\n");
// Initialize emulator in X86-32bit mode
Unicorn u = new Unicorn(Unicorn.UC_ARCH_X86, Unicorn.UC_MODE_32);
// map 2MB memory for this emulation
u.mem_map(ADDRESS, 2 * 1024 * 1024);
// write machine code to be emulated to memory
u.mem_write(ADDRESS, X86_CODE32_MEM_WRITE);
// initialize machine registers
u.reg_write(Unicorn.UC_X86_REG_ECX, r_ecx);
u.reg_write(Unicorn.UC_X86_REG_EDX, r_edx);
// tracing all basic blocks with customized callback
u.hook_add(new MyBlockHook(), 1, 0, null);
// tracing all instruction by having @begin > @end
u.hook_add(new MyCodeHook(), 1, 0, null);
// intercept invalid memory events
u.hook_add(new MyMemInvalidHook(), null);
// emulate machine code in infinite time
u.emu_start(ADDRESS, ADDRESS + X86_CODE32_MEM_WRITE.length, 0, 0);
// now print out some registers
System.out.print(">>> Emulation done. Below is the CPU context\n");
r_ecx = u.reg_read(Unicorn.UC_X86_REG_ECX, 4);
r_edx = u.reg_read(Unicorn.UC_X86_REG_EDX, 4);
System.out.print(String.format(">>> ECX = 0x%x\n", toInt(r_ecx)));
System.out.print(String.format(">>> EDX = 0x%x\n", toInt(r_edx)));
// read from memory
byte tmp[] = u.mem_read(0xaaaaaaaa, 4);
System.out.print(String.format(">>> Read 4 bytes from [0x%x] = 0x%x\n", 0xaaaaaaaa, toInt(tmp)));
u.mem_read(0xffffffaa, 4);
System.out.print(String.format(">>> Read 4 bytes from [0x%x] = 0x%x\n", 0xffffffaa, toInt(tmp)));
u.close();
}
// emulate code that jump to invalid memory
static void test_i386_jump_invalid()
{
byte r_ecx[] = {(byte)0x34, (byte)0x12, 0, 0}; //0x1234; // ECX register
byte r_edx[] = {(byte)0x90, (byte)0x78, 0, 0}; //0x7890; // EDX register
System.out.print("===================================\n");
System.out.print("Emulate i386 code that jumps to invalid memory\n");
// Initialize emulator in X86-32bit mode
Unicorn u = new Unicorn(Unicorn.UC_ARCH_X86, Unicorn.UC_MODE_32);
// map 2MB memory for this emulation
u.mem_map(ADDRESS, 2 * 1024 * 1024);
// write machine code to be emulated to memory
u.mem_write(ADDRESS, X86_CODE32_JMP_INVALID);
// initialize machine registers
u.reg_write(Unicorn.UC_X86_REG_ECX, r_ecx);
u.reg_write(Unicorn.UC_X86_REG_EDX, r_edx);
// tracing all basic blocks with customized callback
u.hook_add(new MyBlockHook(), 1, 0, null);
// tracing all instructions by having @begin > @end
u.hook_add(new MyCodeHook(), 1, 0, null);
// emulate machine code in infinite time
u.emu_start(ADDRESS, ADDRESS + X86_CODE32_JMP_INVALID.length, 0, 0);
// now print out some registers
System.out.print(">>> Emulation done. Below is the CPU context\n");
r_ecx = u.reg_read(Unicorn.UC_X86_REG_ECX, 4);
r_edx = u.reg_read(Unicorn.UC_X86_REG_EDX, 4);
System.out.print(String.format(">>> ECX = 0x%x\n", toInt(r_ecx)));
System.out.print(String.format(">>> EDX = 0x%x\n", toInt(r_edx)));
u.close();
}
static void test_x86_64()
{
long rax = 0x71f3029efd49d41dL;
long rbx = 0xd87b45277f133ddbL;
long rcx = 0xab40d1ffd8afc461L;
long rdx = 0x919317b4a733f01L;
long rsi = 0x4c24e753a17ea358L;
long rdi = 0xe509a57d2571ce96L;
long r8 = 0xea5b108cc2b9ab1fL;
long r9 = 0x19ec097c8eb618c1L;
long r10 = 0xec45774f00c5f682L;
long r11 = 0xe17e9dbec8c074aaL;
long r12 = 0x80f86a8dc0f6d457L;
long r13 = 0x48288ca5671c5492L;
long r14 = 0x595f72f6e4017f6eL;
long r15 = 0x1efd97aea331ccccL;
long rsp = ADDRESS + 0x200000;
System.out.print("Emulate x86_64 code\n");
// Initialize emulator in X86-64bit mode
Unicorn u = new Unicorn(Unicorn.UC_ARCH_X86, Unicorn.UC_MODE_64);
// map 2MB memory for this emulation
u.mem_map(ADDRESS, 2 * 1024 * 1024);
// write machine code to be emulated to memory
u.mem_write(ADDRESS, X86_CODE64);
// initialize machine registers
u.reg_write(Unicorn.UC_X86_REG_RSP, toBytes(rsp));
u.reg_write(Unicorn.UC_X86_REG_RAX, toBytes(rax));
u.reg_write(Unicorn.UC_X86_REG_RBX, toBytes(rbx));
u.reg_write(Unicorn.UC_X86_REG_RCX, toBytes(rcx));
u.reg_write(Unicorn.UC_X86_REG_RDX, toBytes(rdx));
u.reg_write(Unicorn.UC_X86_REG_RSI, toBytes(rsi));
u.reg_write(Unicorn.UC_X86_REG_RDI, toBytes(rdi));
u.reg_write(Unicorn.UC_X86_REG_R8, toBytes(r8));
u.reg_write(Unicorn.UC_X86_REG_R9, toBytes(r9));
u.reg_write(Unicorn.UC_X86_REG_R10, toBytes(r10));
u.reg_write(Unicorn.UC_X86_REG_R11, toBytes(r11));
u.reg_write(Unicorn.UC_X86_REG_R12, toBytes(r12));
u.reg_write(Unicorn.UC_X86_REG_R13, toBytes(r13));
u.reg_write(Unicorn.UC_X86_REG_R14, toBytes(r14));
u.reg_write(Unicorn.UC_X86_REG_R15, toBytes(r15));
// tracing all basic blocks with customized callback
u.hook_add(new MyBlockHook(), 1, 0, null);
// tracing all instructions in the range [ADDRESS, ADDRESS+20]
u.hook_add(new MyCode64Hook(), ADDRESS, ADDRESS+20, null);
// tracing all memory WRITE access (with @begin > @end)
u.hook_add(new MyWrite64Hook(), 1, 0, null);
// tracing all memory READ access (with @begin > @end)
u.hook_add(new MyRead64Hook(), 1, 0, null);
// emulate machine code in infinite time (last param = 0), or when
// finishing all the code.
u.emu_start(ADDRESS, ADDRESS + X86_CODE64.length, 0, 0);
// now print out some registers
System.out.print(">>> Emulation done. Below is the CPU context\n");
byte[] r_rax = u.reg_read(Unicorn.UC_X86_REG_RAX, 8);
byte[] r_rbx = u.reg_read(Unicorn.UC_X86_REG_RBX, 8);
byte[] r_rcx = u.reg_read(Unicorn.UC_X86_REG_RCX, 8);
byte[] r_rdx = u.reg_read(Unicorn.UC_X86_REG_RDX, 8);
byte[] r_rsi = u.reg_read(Unicorn.UC_X86_REG_RSI, 8);
byte[] r_rdi = u.reg_read(Unicorn.UC_X86_REG_RDI, 8);
byte[] r_r8 = u.reg_read(Unicorn.UC_X86_REG_R8, 8);
byte[] r_r9 = u.reg_read(Unicorn.UC_X86_REG_R9, 8);
byte[] r_r10 = u.reg_read(Unicorn.UC_X86_REG_R10, 8);
byte[] r_r11 = u.reg_read(Unicorn.UC_X86_REG_R11, 8);
byte[] r_r12 = u.reg_read(Unicorn.UC_X86_REG_R12, 8);
byte[] r_r13 = u.reg_read(Unicorn.UC_X86_REG_R13, 8);
byte[] r_r14 = u.reg_read(Unicorn.UC_X86_REG_R14, 8);
byte[] r_r15 = u.reg_read(Unicorn.UC_X86_REG_R15, 8);
System.out.print(String.format(">>> RAX = 0x%x\n", toInt(r_rax)));
System.out.print(String.format(">>> RBX = 0x%x\n", toInt(r_rbx)));
System.out.print(String.format(">>> RCX = 0x%x\n", toInt(r_rcx)));
System.out.print(String.format(">>> RDX = 0x%x\n", toInt(r_rdx)));
System.out.print(String.format(">>> RSI = 0x%x\n", toInt(r_rsi)));
System.out.print(String.format(">>> RDI = 0x%x\n", toInt(r_rdi)));
System.out.print(String.format(">>> R8 = 0x%x\n", toInt(r_r8)));
System.out.print(String.format(">>> R9 = 0x%x\n", toInt(r_r9)));
System.out.print(String.format(">>> R10 = 0x%x\n", toInt(r_r10)));
System.out.print(String.format(">>> R11 = 0x%x\n", toInt(r_r11)));
System.out.print(String.format(">>> R12 = 0x%x\n", toInt(r_r12)));
System.out.print(String.format(">>> R13 = 0x%x\n", toInt(r_r13)));
System.out.print(String.format(">>> R14 = 0x%x\n", toInt(r_r14)));
System.out.print(String.format(">>> R15 = 0x%x\n", toInt(r_r15)));
u.close();
}
public static void main(String args[])
{
if (args.length == 1) {
if (args[0].equals("-32")) {
test_i386();
test_i386_inout();
test_i386_jump();
test_i386_loop();
test_i386_invalid_mem_read();
test_i386_invalid_mem_write();
test_i386_jump_invalid();
}
if (args[0].equals("-64")) {
test_x86_64();
}
// test memleak
if (args[0].equals("-0")) {
while(true) {
test_i386();
// test_x86_64();
}
}
} else {
System.out.print("Syntax: java Sample_x86 <-32|-64>\n");
}
}
}

View File

@ -0,0 +1,161 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2015 Chris Eagle
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/* Unicorn Emulator Engine */
/* By Nguyen Anh Quynh & Dang Hoang Vu, 2015 */
/* Sample code to trace code with Linux code with syscall */
import unicorn.*;
import java.math.*;
public class Shellcode {
public static final byte[] X86_CODE32 = {-21,25,49,-64,49,-37,49,-46,49,-55,-80,4,-77,1,89,-78,5,-51,-128,49,-64,-80,1,49,-37,-51,-128,-24,-30,-1,-1,-1,104,101,108,108,111};
public static final byte[] X86_CODE32_SELF = {-21,28,90,-119,-42,-117,2,102,61,-54,125,117,6,102,5,3,3,-119,2,-2,-62,61,65,65,65,65,117,-23,-1,-26,-24,-33,-1,-1,-1,49,-46,106,11,88,-103,82,104,47,47,115,104,104,47,98,105,110,-119,-29,82,83,-119,-31,-54,125,65,65,65,65,65,65,65,65};
// memory address where emulation starts
public static final int ADDRESS = 0x1000000;
public static final long toInt(byte val[]) {
long res = 0;
for (int i = 0; i < val.length; i++) {
long v = val[i] & 0xff;
res = res + (v << (i * 8));
}
return res;
}
public static final byte[] toBytes(long val) {
byte[] res = new byte[8];
for (int i = 0; i < 8; i++) {
res[i] = (byte)(val & 0xff);
val >>>= 8;
}
return res;
}
public static class MyCodeHook implements CodeHook {
public void hook(Unicorn u, long address, int size, Object user) {
System.out.print(String.format("Tracing instruction at 0x%x, instruction size = 0x%x\n", address, size));
byte[] r_eip = u.reg_read(Unicorn.UC_X86_REG_EIP, 4);
System.out.print(String.format("*** EIP = %x ***: ", toInt(r_eip)));
size = Math.min(16, size);
byte[] tmp = u.mem_read(address, size);
for (int i = 0; i < tmp.length; i++) {
System.out.print(String.format("%x ", 0xff & tmp[i]));
}
System.out.print("\n");
}
};
public static class MyInterruptHook implements InterruptHook {
public void hook(Unicorn u, int intno, Object user) {
long r_ecx;
long r_edx;
int size;
// only handle Linux syscall
if (intno != 0x80) {
return;
}
long r_eax = toInt(u.reg_read(Unicorn.UC_X86_REG_EAX, 4));
long r_eip = toInt(u.reg_read(Unicorn.UC_X86_REG_EIP, 4));
switch ((int)r_eax) {
default:
System.out.print(String.format(">>> 0x%x: interrupt 0x%x, EAX = 0x%x\n", r_eip, intno, r_eax));
break;
case 1: // sys_exit
System.out.print(String.format(">>> 0x%x: interrupt 0x%x, SYS_EXIT. quit!\n\n", r_eip, intno));
u.emu_stop();
break;
case 4: // sys_write
// ECX = buffer address
r_ecx = toInt(u.reg_read(Unicorn.UC_X86_REG_ECX, 4));
// EDX = buffer size
r_edx = toInt(u.reg_read(Unicorn.UC_X86_REG_EDX, 4));
// read the buffer in
size = (int)Math.min(256, r_edx);
byte[] buffer = u.mem_read(r_ecx, size);
System.out.print(String.format(">>> 0x%x: interrupt 0x%x, SYS_WRITE. buffer = 0x%x, size = %u, content = '%s'\n",
r_eip, intno, r_ecx, r_edx, new String(buffer)));
break;
}
}
}
static void test_i386()
{
long r_esp = ADDRESS + 0x200000; // ESP register
System.out.print("Emulate i386 code\n");
// Initialize emulator in X86-32bit mode
Unicorn u = new Unicorn(Unicorn.UC_ARCH_X86, Unicorn.UC_MODE_32);
// map 2MB memory for this emulation
u.mem_map(ADDRESS, 2 * 1024 * 1024);
// write machine code to be emulated to memory
u.mem_write(ADDRESS, X86_CODE32_SELF);
// initialize machine registers
u.reg_write(Unicorn.UC_X86_REG_ESP, toBytes(r_esp));
// tracing all instructions by having @begin > @end
u.hook_add(new MyCodeHook(), 1, 0, null);
// handle interrupt ourself
u.hook_add(new MyInterruptHook(), null);
System.out.print("\n>>> Start tracing this Linux code\n");
// emulate machine code in infinite time
// u.emu_start(ADDRESS, ADDRESS + X86_CODE32_SELF.length, 0, 12); <--- emulate only 12 instructions
u.emu_start(ADDRESS, ADDRESS + X86_CODE32_SELF.length, 0, 0);
System.out.print("\n>>> Emulation done.\n");
u.close();
}
public static void main(String args[])
{
if (args.length == 1) {
if ("-32".equals(args[0])) {
test_i386();
}
} else {
System.out.print("Syntax: java Shellcode <-32|-64>\n");
}
}
}

View File

@ -0,0 +1,291 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2015 Chris Eagle
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package unicorn;
public interface Arm64Regs {
public static final int UC_ARM64_REG_INVALID = 0;
public static final int UC_ARM64_REG_X29 = 1;
public static final int UC_ARM64_REG_X30 = 2;
public static final int UC_ARM64_REG_NZCV = 3;
public static final int UC_ARM64_REG_SP = 4;
public static final int UC_ARM64_REG_WSP = 5;
public static final int UC_ARM64_REG_WZR = 6;
public static final int UC_ARM64_REG_XZR = 7;
public static final int UC_ARM64_REG_B0 = 8;
public static final int UC_ARM64_REG_B1 = 9;
public static final int UC_ARM64_REG_B2 = 10;
public static final int UC_ARM64_REG_B3 = 11;
public static final int UC_ARM64_REG_B4 = 12;
public static final int UC_ARM64_REG_B5 = 13;
public static final int UC_ARM64_REG_B6 = 14;
public static final int UC_ARM64_REG_B7 = 15;
public static final int UC_ARM64_REG_B8 = 16;
public static final int UC_ARM64_REG_B9 = 17;
public static final int UC_ARM64_REG_B10 = 18;
public static final int UC_ARM64_REG_B11 = 19;
public static final int UC_ARM64_REG_B12 = 20;
public static final int UC_ARM64_REG_B13 = 21;
public static final int UC_ARM64_REG_B14 = 22;
public static final int UC_ARM64_REG_B15 = 23;
public static final int UC_ARM64_REG_B16 = 24;
public static final int UC_ARM64_REG_B17 = 25;
public static final int UC_ARM64_REG_B18 = 26;
public static final int UC_ARM64_REG_B19 = 27;
public static final int UC_ARM64_REG_B20 = 28;
public static final int UC_ARM64_REG_B21 = 29;
public static final int UC_ARM64_REG_B22 = 30;
public static final int UC_ARM64_REG_B23 = 31;
public static final int UC_ARM64_REG_B24 = 32;
public static final int UC_ARM64_REG_B25 = 33;
public static final int UC_ARM64_REG_B26 = 34;
public static final int UC_ARM64_REG_B27 = 35;
public static final int UC_ARM64_REG_B28 = 36;
public static final int UC_ARM64_REG_B29 = 37;
public static final int UC_ARM64_REG_B30 = 38;
public static final int UC_ARM64_REG_B31 = 39;
public static final int UC_ARM64_REG_D0 = 40;
public static final int UC_ARM64_REG_D1 = 41;
public static final int UC_ARM64_REG_D2 = 42;
public static final int UC_ARM64_REG_D3 = 43;
public static final int UC_ARM64_REG_D4 = 44;
public static final int UC_ARM64_REG_D5 = 45;
public static final int UC_ARM64_REG_D6 = 46;
public static final int UC_ARM64_REG_D7 = 47;
public static final int UC_ARM64_REG_D8 = 48;
public static final int UC_ARM64_REG_D9 = 49;
public static final int UC_ARM64_REG_D10 = 50;
public static final int UC_ARM64_REG_D11 = 51;
public static final int UC_ARM64_REG_D12 = 52;
public static final int UC_ARM64_REG_D13 = 53;
public static final int UC_ARM64_REG_D14 = 54;
public static final int UC_ARM64_REG_D15 = 55;
public static final int UC_ARM64_REG_D16 = 56;
public static final int UC_ARM64_REG_D17 = 57;
public static final int UC_ARM64_REG_D18 = 58;
public static final int UC_ARM64_REG_D19 = 59;
public static final int UC_ARM64_REG_D20 = 60;
public static final int UC_ARM64_REG_D21 = 61;
public static final int UC_ARM64_REG_D22 = 62;
public static final int UC_ARM64_REG_D23 = 63;
public static final int UC_ARM64_REG_D24 = 64;
public static final int UC_ARM64_REG_D25 = 65;
public static final int UC_ARM64_REG_D26 = 66;
public static final int UC_ARM64_REG_D27 = 67;
public static final int UC_ARM64_REG_D28 = 68;
public static final int UC_ARM64_REG_D29 = 69;
public static final int UC_ARM64_REG_D30 = 70;
public static final int UC_ARM64_REG_D31 = 71;
public static final int UC_ARM64_REG_H0 = 72;
public static final int UC_ARM64_REG_H1 = 73;
public static final int UC_ARM64_REG_H2 = 74;
public static final int UC_ARM64_REG_H3 = 75;
public static final int UC_ARM64_REG_H4 = 76;
public static final int UC_ARM64_REG_H5 = 77;
public static final int UC_ARM64_REG_H6 = 78;
public static final int UC_ARM64_REG_H7 = 79;
public static final int UC_ARM64_REG_H8 = 80;
public static final int UC_ARM64_REG_H9 = 81;
public static final int UC_ARM64_REG_H10 = 82;
public static final int UC_ARM64_REG_H11 = 83;
public static final int UC_ARM64_REG_H12 = 84;
public static final int UC_ARM64_REG_H13 = 85;
public static final int UC_ARM64_REG_H14 = 86;
public static final int UC_ARM64_REG_H15 = 87;
public static final int UC_ARM64_REG_H16 = 88;
public static final int UC_ARM64_REG_H17 = 89;
public static final int UC_ARM64_REG_H18 = 90;
public static final int UC_ARM64_REG_H19 = 91;
public static final int UC_ARM64_REG_H20 = 92;
public static final int UC_ARM64_REG_H21 = 93;
public static final int UC_ARM64_REG_H22 = 94;
public static final int UC_ARM64_REG_H23 = 95;
public static final int UC_ARM64_REG_H24 = 96;
public static final int UC_ARM64_REG_H25 = 97;
public static final int UC_ARM64_REG_H26 = 98;
public static final int UC_ARM64_REG_H27 = 99;
public static final int UC_ARM64_REG_H28 = 100;
public static final int UC_ARM64_REG_H29 = 101;
public static final int UC_ARM64_REG_H30 = 102;
public static final int UC_ARM64_REG_H31 = 103;
public static final int UC_ARM64_REG_Q0 = 104;
public static final int UC_ARM64_REG_Q1 = 105;
public static final int UC_ARM64_REG_Q2 = 106;
public static final int UC_ARM64_REG_Q3 = 107;
public static final int UC_ARM64_REG_Q4 = 108;
public static final int UC_ARM64_REG_Q5 = 109;
public static final int UC_ARM64_REG_Q6 = 110;
public static final int UC_ARM64_REG_Q7 = 111;
public static final int UC_ARM64_REG_Q8 = 112;
public static final int UC_ARM64_REG_Q9 = 113;
public static final int UC_ARM64_REG_Q10 = 114;
public static final int UC_ARM64_REG_Q11 = 115;
public static final int UC_ARM64_REG_Q12 = 116;
public static final int UC_ARM64_REG_Q13 = 117;
public static final int UC_ARM64_REG_Q14 = 118;
public static final int UC_ARM64_REG_Q15 = 119;
public static final int UC_ARM64_REG_Q16 = 120;
public static final int UC_ARM64_REG_Q17 = 121;
public static final int UC_ARM64_REG_Q18 = 122;
public static final int UC_ARM64_REG_Q19 = 123;
public static final int UC_ARM64_REG_Q20 = 124;
public static final int UC_ARM64_REG_Q21 = 125;
public static final int UC_ARM64_REG_Q22 = 126;
public static final int UC_ARM64_REG_Q23 = 127;
public static final int UC_ARM64_REG_Q24 = 128;
public static final int UC_ARM64_REG_Q25 = 129;
public static final int UC_ARM64_REG_Q26 = 130;
public static final int UC_ARM64_REG_Q27 = 131;
public static final int UC_ARM64_REG_Q28 = 132;
public static final int UC_ARM64_REG_Q29 = 133;
public static final int UC_ARM64_REG_Q30 = 134;
public static final int UC_ARM64_REG_Q31 = 135;
public static final int UC_ARM64_REG_S0 = 136;
public static final int UC_ARM64_REG_S1 = 137;
public static final int UC_ARM64_REG_S2 = 138;
public static final int UC_ARM64_REG_S3 = 139;
public static final int UC_ARM64_REG_S4 = 140;
public static final int UC_ARM64_REG_S5 = 141;
public static final int UC_ARM64_REG_S6 = 142;
public static final int UC_ARM64_REG_S7 = 143;
public static final int UC_ARM64_REG_S8 = 144;
public static final int UC_ARM64_REG_S9 = 145;
public static final int UC_ARM64_REG_S10 = 146;
public static final int UC_ARM64_REG_S11 = 147;
public static final int UC_ARM64_REG_S12 = 148;
public static final int UC_ARM64_REG_S13 = 149;
public static final int UC_ARM64_REG_S14 = 150;
public static final int UC_ARM64_REG_S15 = 151;
public static final int UC_ARM64_REG_S16 = 152;
public static final int UC_ARM64_REG_S17 = 153;
public static final int UC_ARM64_REG_S18 = 154;
public static final int UC_ARM64_REG_S19 = 155;
public static final int UC_ARM64_REG_S20 = 156;
public static final int UC_ARM64_REG_S21 = 157;
public static final int UC_ARM64_REG_S22 = 158;
public static final int UC_ARM64_REG_S23 = 159;
public static final int UC_ARM64_REG_S24 = 160;
public static final int UC_ARM64_REG_S25 = 161;
public static final int UC_ARM64_REG_S26 = 162;
public static final int UC_ARM64_REG_S27 = 163;
public static final int UC_ARM64_REG_S28 = 164;
public static final int UC_ARM64_REG_S29 = 165;
public static final int UC_ARM64_REG_S30 = 166;
public static final int UC_ARM64_REG_S31 = 167;
public static final int UC_ARM64_REG_W0 = 168;
public static final int UC_ARM64_REG_W1 = 169;
public static final int UC_ARM64_REG_W2 = 170;
public static final int UC_ARM64_REG_W3 = 171;
public static final int UC_ARM64_REG_W4 = 172;
public static final int UC_ARM64_REG_W5 = 173;
public static final int UC_ARM64_REG_W6 = 174;
public static final int UC_ARM64_REG_W7 = 175;
public static final int UC_ARM64_REG_W8 = 176;
public static final int UC_ARM64_REG_W9 = 177;
public static final int UC_ARM64_REG_W10 = 178;
public static final int UC_ARM64_REG_W11 = 179;
public static final int UC_ARM64_REG_W12 = 180;
public static final int UC_ARM64_REG_W13 = 181;
public static final int UC_ARM64_REG_W14 = 182;
public static final int UC_ARM64_REG_W15 = 183;
public static final int UC_ARM64_REG_W16 = 184;
public static final int UC_ARM64_REG_W17 = 185;
public static final int UC_ARM64_REG_W18 = 186;
public static final int UC_ARM64_REG_W19 = 187;
public static final int UC_ARM64_REG_W20 = 188;
public static final int UC_ARM64_REG_W21 = 189;
public static final int UC_ARM64_REG_W22 = 190;
public static final int UC_ARM64_REG_W23 = 191;
public static final int UC_ARM64_REG_W24 = 192;
public static final int UC_ARM64_REG_W25 = 193;
public static final int UC_ARM64_REG_W26 = 194;
public static final int UC_ARM64_REG_W27 = 195;
public static final int UC_ARM64_REG_W28 = 196;
public static final int UC_ARM64_REG_W29 = 197;
public static final int UC_ARM64_REG_W30 = 198;
public static final int UC_ARM64_REG_X0 = 199;
public static final int UC_ARM64_REG_X1 = 200;
public static final int UC_ARM64_REG_X2 = 201;
public static final int UC_ARM64_REG_X3 = 202;
public static final int UC_ARM64_REG_X4 = 203;
public static final int UC_ARM64_REG_X5 = 204;
public static final int UC_ARM64_REG_X6 = 205;
public static final int UC_ARM64_REG_X7 = 206;
public static final int UC_ARM64_REG_X8 = 207;
public static final int UC_ARM64_REG_X9 = 208;
public static final int UC_ARM64_REG_X10 = 209;
public static final int UC_ARM64_REG_X11 = 210;
public static final int UC_ARM64_REG_X12 = 211;
public static final int UC_ARM64_REG_X13 = 212;
public static final int UC_ARM64_REG_X14 = 213;
public static final int UC_ARM64_REG_X15 = 214;
public static final int UC_ARM64_REG_X16 = 215;
public static final int UC_ARM64_REG_X17 = 216;
public static final int UC_ARM64_REG_X18 = 217;
public static final int UC_ARM64_REG_X19 = 218;
public static final int UC_ARM64_REG_X20 = 219;
public static final int UC_ARM64_REG_X21 = 220;
public static final int UC_ARM64_REG_X22 = 221;
public static final int UC_ARM64_REG_X23 = 222;
public static final int UC_ARM64_REG_X24 = 223;
public static final int UC_ARM64_REG_X25 = 224;
public static final int UC_ARM64_REG_X26 = 225;
public static final int UC_ARM64_REG_X27 = 226;
public static final int UC_ARM64_REG_X28 = 227;
public static final int UC_ARM64_REG_V0 = 228;
public static final int UC_ARM64_REG_V1 = 229;
public static final int UC_ARM64_REG_V2 = 230;
public static final int UC_ARM64_REG_V3 = 231;
public static final int UC_ARM64_REG_V4 = 232;
public static final int UC_ARM64_REG_V5 = 233;
public static final int UC_ARM64_REG_V6 = 234;
public static final int UC_ARM64_REG_V7 = 235;
public static final int UC_ARM64_REG_V8 = 236;
public static final int UC_ARM64_REG_V9 = 237;
public static final int UC_ARM64_REG_V10 = 238;
public static final int UC_ARM64_REG_V11 = 239;
public static final int UC_ARM64_REG_V12 = 240;
public static final int UC_ARM64_REG_V13 = 241;
public static final int UC_ARM64_REG_V14 = 242;
public static final int UC_ARM64_REG_V15 = 243;
public static final int UC_ARM64_REG_V16 = 244;
public static final int UC_ARM64_REG_V17 = 245;
public static final int UC_ARM64_REG_V18 = 246;
public static final int UC_ARM64_REG_V19 = 247;
public static final int UC_ARM64_REG_V20 = 248;
public static final int UC_ARM64_REG_V21 = 249;
public static final int UC_ARM64_REG_V22 = 250;
public static final int UC_ARM64_REG_V23 = 251;
public static final int UC_ARM64_REG_V24 = 252;
public static final int UC_ARM64_REG_V25 = 253;
public static final int UC_ARM64_REG_V26 = 254;
public static final int UC_ARM64_REG_V27 = 255;
public static final int UC_ARM64_REG_V28 = 256;
public static final int UC_ARM64_REG_V29 = 257;
public static final int UC_ARM64_REG_V30 = 258;
public static final int UC_ARM64_REG_V31 = 259;
public static final int UC_ARM64_REG_PC = 260;
public static final int UC_ARM64_REG_ENDING = 261;
public static final int UC_ARM64_REG_IP1 = UC_ARM64_REG_X16;
public static final int UC_ARM64_REG_IP0 = UC_ARM64_REG_X17;
public static final int UC_ARM64_REG_FP = UC_ARM64_REG_X29;
public static final int UC_ARM64_REG_LR = UC_ARM64_REG_X30;
}

View File

@ -0,0 +1,144 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2015 Chris Eagle
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package unicorn;
public interface ArmRegs {
public static final int UC_ARM_REG_INVALID = 0;
public static final int UC_ARM_REG_APSR = 1;
public static final int UC_ARM_REG_APSR_NZCV = 2;
public static final int UC_ARM_REG_CPSR = 3;
public static final int UC_ARM_REG_FPEXC = 4;
public static final int UC_ARM_REG_FPINST = 5;
public static final int UC_ARM_REG_FPSCR = 6;
public static final int UC_ARM_REG_FPSCR_NZCV = 7;
public static final int UC_ARM_REG_FPSID = 8;
public static final int UC_ARM_REG_ITSTATE = 9;
public static final int UC_ARM_REG_LR = 10;
public static final int UC_ARM_REG_PC = 11;
public static final int UC_ARM_REG_SP = 12;
public static final int UC_ARM_REG_SPSR = 13;
public static final int UC_ARM_REG_D0 = 14;
public static final int UC_ARM_REG_D1 = 15;
public static final int UC_ARM_REG_D2 = 16;
public static final int UC_ARM_REG_D3 = 17;
public static final int UC_ARM_REG_D4 = 18;
public static final int UC_ARM_REG_D5 = 19;
public static final int UC_ARM_REG_D6 = 20;
public static final int UC_ARM_REG_D7 = 21;
public static final int UC_ARM_REG_D8 = 22;
public static final int UC_ARM_REG_D9 = 23;
public static final int UC_ARM_REG_D10 = 24;
public static final int UC_ARM_REG_D11 = 25;
public static final int UC_ARM_REG_D12 = 26;
public static final int UC_ARM_REG_D13 = 27;
public static final int UC_ARM_REG_D14 = 28;
public static final int UC_ARM_REG_D15 = 29;
public static final int UC_ARM_REG_D16 = 30;
public static final int UC_ARM_REG_D17 = 31;
public static final int UC_ARM_REG_D18 = 32;
public static final int UC_ARM_REG_D19 = 33;
public static final int UC_ARM_REG_D20 = 34;
public static final int UC_ARM_REG_D21 = 35;
public static final int UC_ARM_REG_D22 = 36;
public static final int UC_ARM_REG_D23 = 37;
public static final int UC_ARM_REG_D24 = 38;
public static final int UC_ARM_REG_D25 = 39;
public static final int UC_ARM_REG_D26 = 40;
public static final int UC_ARM_REG_D27 = 41;
public static final int UC_ARM_REG_D28 = 42;
public static final int UC_ARM_REG_D29 = 43;
public static final int UC_ARM_REG_D30 = 44;
public static final int UC_ARM_REG_D31 = 45;
public static final int UC_ARM_REG_FPINST2 = 46;
public static final int UC_ARM_REG_MVFR0 = 47;
public static final int UC_ARM_REG_MVFR1 = 48;
public static final int UC_ARM_REG_MVFR2 = 49;
public static final int UC_ARM_REG_Q0 = 50;
public static final int UC_ARM_REG_Q1 = 51;
public static final int UC_ARM_REG_Q2 = 52;
public static final int UC_ARM_REG_Q3 = 53;
public static final int UC_ARM_REG_Q4 = 54;
public static final int UC_ARM_REG_Q5 = 55;
public static final int UC_ARM_REG_Q6 = 56;
public static final int UC_ARM_REG_Q7 = 57;
public static final int UC_ARM_REG_Q8 = 58;
public static final int UC_ARM_REG_Q9 = 59;
public static final int UC_ARM_REG_Q10 = 60;
public static final int UC_ARM_REG_Q11 = 61;
public static final int UC_ARM_REG_Q12 = 62;
public static final int UC_ARM_REG_Q13 = 63;
public static final int UC_ARM_REG_Q14 = 64;
public static final int UC_ARM_REG_Q15 = 65;
public static final int UC_ARM_REG_R0 = 66;
public static final int UC_ARM_REG_R1 = 67;
public static final int UC_ARM_REG_R2 = 68;
public static final int UC_ARM_REG_R3 = 69;
public static final int UC_ARM_REG_R4 = 70;
public static final int UC_ARM_REG_R5 = 71;
public static final int UC_ARM_REG_R6 = 72;
public static final int UC_ARM_REG_R7 = 73;
public static final int UC_ARM_REG_R8 = 74;
public static final int UC_ARM_REG_R9 = 75;
public static final int UC_ARM_REG_R10 = 76;
public static final int UC_ARM_REG_R11 = 77;
public static final int UC_ARM_REG_R12 = 78;
public static final int UC_ARM_REG_S0 = 79;
public static final int UC_ARM_REG_S1 = 80;
public static final int UC_ARM_REG_S2 = 81;
public static final int UC_ARM_REG_S3 = 82;
public static final int UC_ARM_REG_S4 = 83;
public static final int UC_ARM_REG_S5 = 84;
public static final int UC_ARM_REG_S6 = 85;
public static final int UC_ARM_REG_S7 = 86;
public static final int UC_ARM_REG_S8 = 87;
public static final int UC_ARM_REG_S9 = 88;
public static final int UC_ARM_REG_S10 = 89;
public static final int UC_ARM_REG_S11 = 90;
public static final int UC_ARM_REG_S12 = 91;
public static final int UC_ARM_REG_S13 = 92;
public static final int UC_ARM_REG_S14 = 93;
public static final int UC_ARM_REG_S15 = 94;
public static final int UC_ARM_REG_S16 = 95;
public static final int UC_ARM_REG_S17 = 96;
public static final int UC_ARM_REG_S18 = 97;
public static final int UC_ARM_REG_S19 = 98;
public static final int UC_ARM_REG_S20 = 99;
public static final int UC_ARM_REG_S21 = 100;
public static final int UC_ARM_REG_S22 = 101;
public static final int UC_ARM_REG_S23 = 102;
public static final int UC_ARM_REG_S24 = 103;
public static final int UC_ARM_REG_S25 = 104;
public static final int UC_ARM_REG_S26 = 105;
public static final int UC_ARM_REG_S27 = 106;
public static final int UC_ARM_REG_S28 = 107;
public static final int UC_ARM_REG_S29 = 108;
public static final int UC_ARM_REG_S30 = 109;
public static final int UC_ARM_REG_S31 = 110;
public static final int UC_ARM_REG_ENDING = 111;
public static final int UC_ARM_REG_R13 = UC_ARM_REG_SP;
public static final int UC_ARM_REG_R14 = UC_ARM_REG_LR;
public static final int UC_ARM_REG_R15 = UC_ARM_REG_PC;
public static final int UC_ARM_REG_SB = UC_ARM_REG_R9;
public static final int UC_ARM_REG_SL = UC_ARM_REG_R10;
public static final int UC_ARM_REG_FP = UC_ARM_REG_R11;
public static final int UC_ARM_REG_IP = UC_ARM_REG_R12;
}

View File

@ -0,0 +1,29 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2015 Chris Eagle
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package unicorn;
public interface BlockHook extends Hook {
public void hook(Unicorn u, long address, int size, Object user);
}

View File

@ -0,0 +1,29 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2015 Chris Eagle
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package unicorn;
public interface CodeHook extends Hook {
public void hook(Unicorn u, long address, int size, Object user);
}

29
bindings/java/unicorn/Hook.java Executable file
View File

@ -0,0 +1,29 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2015 Chris Eagle
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package unicorn;
/**
* Base class for all unicorn hooking interfaces
*/
public interface Hook {
}

View File

@ -0,0 +1,29 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2015 Chris Eagle
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package unicorn;
public interface InHook extends Hook {
public int hook(Unicorn u, int port, int size, Object user);
}

View File

@ -0,0 +1,29 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2015 Chris Eagle
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package unicorn;
public interface InterruptHook extends Hook {
public void hook(Unicorn u, int intno, Object user);
}

View File

@ -0,0 +1,45 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2015 Chris Eagle
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package unicorn;
public interface M68kRegs {
public static final int UC_M68K_REG_INVALID = 0;
public static final int UC_M68K_REG_A0 = 1;
public static final int UC_M68K_REG_A1 = 2;
public static final int UC_M68K_REG_A2 = 3;
public static final int UC_M68K_REG_A3 = 4;
public static final int UC_M68K_REG_A4 = 5;
public static final int UC_M68K_REG_A5 = 6;
public static final int UC_M68K_REG_A6 = 7;
public static final int UC_M68K_REG_A7 = 8;
public static final int UC_M68K_REG_D0 = 9;
public static final int UC_M68K_REG_D1 = 10;
public static final int UC_M68K_REG_D2 = 11;
public static final int UC_M68K_REG_D3 = 12;
public static final int UC_M68K_REG_D4 = 13;
public static final int UC_M68K_REG_D5 = 14;
public static final int UC_M68K_REG_D6 = 15;
public static final int UC_M68K_REG_D7 = 16;
public static final int UC_M68K_REG_SR = 17;
public static final int UC_M68K_REG_PC = 18;
public static final int UC_M68K_REG_ENDING = 19;
}

View File

@ -0,0 +1,29 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2015 Chris Eagle
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package unicorn;
public interface MemoryInvalidHook extends Hook {
public boolean hook(Unicorn u, int type, long address, int size, long value, Object user);
}

View File

@ -0,0 +1,204 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2015 Chris Eagle
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package unicorn;
public interface MipsRegs {
public static final int UC_MIPS_REG_INVALID = 0;
public static final int UC_MIPS_REG_PC = 1;
public static final int UC_MIPS_REG_0 = 2;
public static final int UC_MIPS_REG_1 = 3;
public static final int UC_MIPS_REG_2 = 4;
public static final int UC_MIPS_REG_3 = 5;
public static final int UC_MIPS_REG_4 = 6;
public static final int UC_MIPS_REG_5 = 7;
public static final int UC_MIPS_REG_6 = 8;
public static final int UC_MIPS_REG_7 = 9;
public static final int UC_MIPS_REG_8 = 10;
public static final int UC_MIPS_REG_9 = 11;
public static final int UC_MIPS_REG_10 = 12;
public static final int UC_MIPS_REG_11 = 13;
public static final int UC_MIPS_REG_12 = 14;
public static final int UC_MIPS_REG_13 = 15;
public static final int UC_MIPS_REG_14 = 16;
public static final int UC_MIPS_REG_15 = 17;
public static final int UC_MIPS_REG_16 = 18;
public static final int UC_MIPS_REG_17 = 19;
public static final int UC_MIPS_REG_18 = 20;
public static final int UC_MIPS_REG_19 = 21;
public static final int UC_MIPS_REG_20 = 22;
public static final int UC_MIPS_REG_21 = 23;
public static final int UC_MIPS_REG_22 = 24;
public static final int UC_MIPS_REG_23 = 25;
public static final int UC_MIPS_REG_24 = 26;
public static final int UC_MIPS_REG_25 = 27;
public static final int UC_MIPS_REG_26 = 28;
public static final int UC_MIPS_REG_27 = 29;
public static final int UC_MIPS_REG_28 = 30;
public static final int UC_MIPS_REG_29 = 31;
public static final int UC_MIPS_REG_30 = 32;
public static final int UC_MIPS_REG_31 = 33;
public static final int UC_MIPS_REG_DSPCCOND = 34;
public static final int UC_MIPS_REG_DSPCARRY = 35;
public static final int UC_MIPS_REG_DSPEFI = 36;
public static final int UC_MIPS_REG_DSPOUTFLAG = 37;
public static final int UC_MIPS_REG_DSPOUTFLAG16_19 = 38;
public static final int UC_MIPS_REG_DSPOUTFLAG20 = 39;
public static final int UC_MIPS_REG_DSPOUTFLAG21 = 40;
public static final int UC_MIPS_REG_DSPOUTFLAG22 = 41;
public static final int UC_MIPS_REG_DSPOUTFLAG23 = 42;
public static final int UC_MIPS_REG_DSPPOS = 43;
public static final int UC_MIPS_REG_DSPSCOUNT = 44;
public static final int UC_MIPS_REG_AC0 = 45;
public static final int UC_MIPS_REG_AC1 = 46;
public static final int UC_MIPS_REG_AC2 = 47;
public static final int UC_MIPS_REG_AC3 = 48;
public static final int UC_MIPS_REG_CC0 = 49;
public static final int UC_MIPS_REG_CC1 = 50;
public static final int UC_MIPS_REG_CC2 = 51;
public static final int UC_MIPS_REG_CC3 = 52;
public static final int UC_MIPS_REG_CC4 = 53;
public static final int UC_MIPS_REG_CC5 = 54;
public static final int UC_MIPS_REG_CC6 = 55;
public static final int UC_MIPS_REG_CC7 = 56;
public static final int UC_MIPS_REG_F0 = 57;
public static final int UC_MIPS_REG_F1 = 58;
public static final int UC_MIPS_REG_F2 = 59;
public static final int UC_MIPS_REG_F3 = 60;
public static final int UC_MIPS_REG_F4 = 61;
public static final int UC_MIPS_REG_F5 = 62;
public static final int UC_MIPS_REG_F6 = 63;
public static final int UC_MIPS_REG_F7 = 64;
public static final int UC_MIPS_REG_F8 = 65;
public static final int UC_MIPS_REG_F9 = 66;
public static final int UC_MIPS_REG_F10 = 67;
public static final int UC_MIPS_REG_F11 = 68;
public static final int UC_MIPS_REG_F12 = 69;
public static final int UC_MIPS_REG_F13 = 70;
public static final int UC_MIPS_REG_F14 = 71;
public static final int UC_MIPS_REG_F15 = 72;
public static final int UC_MIPS_REG_F16 = 73;
public static final int UC_MIPS_REG_F17 = 74;
public static final int UC_MIPS_REG_F18 = 75;
public static final int UC_MIPS_REG_F19 = 76;
public static final int UC_MIPS_REG_F20 = 77;
public static final int UC_MIPS_REG_F21 = 78;
public static final int UC_MIPS_REG_F22 = 79;
public static final int UC_MIPS_REG_F23 = 80;
public static final int UC_MIPS_REG_F24 = 81;
public static final int UC_MIPS_REG_F25 = 82;
public static final int UC_MIPS_REG_F26 = 83;
public static final int UC_MIPS_REG_F27 = 84;
public static final int UC_MIPS_REG_F28 = 85;
public static final int UC_MIPS_REG_F29 = 86;
public static final int UC_MIPS_REG_F30 = 87;
public static final int UC_MIPS_REG_F31 = 88;
public static final int UC_MIPS_REG_FCC0 = 89;
public static final int UC_MIPS_REG_FCC1 = 90;
public static final int UC_MIPS_REG_FCC2 = 91;
public static final int UC_MIPS_REG_FCC3 = 92;
public static final int UC_MIPS_REG_FCC4 = 93;
public static final int UC_MIPS_REG_FCC5 = 94;
public static final int UC_MIPS_REG_FCC6 = 95;
public static final int UC_MIPS_REG_FCC7 = 96;
public static final int UC_MIPS_REG_W0 = 97;
public static final int UC_MIPS_REG_W1 = 98;
public static final int UC_MIPS_REG_W2 = 99;
public static final int UC_MIPS_REG_W3 = 100;
public static final int UC_MIPS_REG_W4 = 101;
public static final int UC_MIPS_REG_W5 = 102;
public static final int UC_MIPS_REG_W6 = 103;
public static final int UC_MIPS_REG_W7 = 104;
public static final int UC_MIPS_REG_W8 = 105;
public static final int UC_MIPS_REG_W9 = 106;
public static final int UC_MIPS_REG_W10 = 107;
public static final int UC_MIPS_REG_W11 = 108;
public static final int UC_MIPS_REG_W12 = 109;
public static final int UC_MIPS_REG_W13 = 110;
public static final int UC_MIPS_REG_W14 = 111;
public static final int UC_MIPS_REG_W15 = 112;
public static final int UC_MIPS_REG_W16 = 113;
public static final int UC_MIPS_REG_W17 = 114;
public static final int UC_MIPS_REG_W18 = 115;
public static final int UC_MIPS_REG_W19 = 116;
public static final int UC_MIPS_REG_W20 = 117;
public static final int UC_MIPS_REG_W21 = 118;
public static final int UC_MIPS_REG_W22 = 119;
public static final int UC_MIPS_REG_W23 = 120;
public static final int UC_MIPS_REG_W24 = 121;
public static final int UC_MIPS_REG_W25 = 122;
public static final int UC_MIPS_REG_W26 = 123;
public static final int UC_MIPS_REG_W27 = 124;
public static final int UC_MIPS_REG_W28 = 125;
public static final int UC_MIPS_REG_W29 = 126;
public static final int UC_MIPS_REG_W30 = 127;
public static final int UC_MIPS_REG_W31 = 128;
public static final int UC_MIPS_REG_HI = 129;
public static final int UC_MIPS_REG_LO = 130;
public static final int UC_MIPS_REG_P0 = 131;
public static final int UC_MIPS_REG_P1 = 132;
public static final int UC_MIPS_REG_P2 = 133;
public static final int UC_MIPS_REG_MPL0 = 134;
public static final int UC_MIPS_REG_MPL1 = 135;
public static final int UC_MIPS_REG_MPL2 = 136;
public static final int UC_MIPS_REG_ENDING = 137;
public static final int UC_MIPS_REG_ZERO = UC_MIPS_REG_0;
public static final int UC_MIPS_REG_AT = UC_MIPS_REG_1;
public static final int UC_MIPS_REG_V0 = UC_MIPS_REG_2;
public static final int UC_MIPS_REG_V1 = UC_MIPS_REG_3;
public static final int UC_MIPS_REG_A0 = UC_MIPS_REG_4;
public static final int UC_MIPS_REG_A1 = UC_MIPS_REG_5;
public static final int UC_MIPS_REG_A2 = UC_MIPS_REG_6;
public static final int UC_MIPS_REG_A3 = UC_MIPS_REG_7;
public static final int UC_MIPS_REG_T0 = UC_MIPS_REG_8;
public static final int UC_MIPS_REG_T1 = UC_MIPS_REG_9;
public static final int UC_MIPS_REG_T2 = UC_MIPS_REG_10;
public static final int UC_MIPS_REG_T3 = UC_MIPS_REG_11;
public static final int UC_MIPS_REG_T4 = UC_MIPS_REG_12;
public static final int UC_MIPS_REG_T5 = UC_MIPS_REG_13;
public static final int UC_MIPS_REG_T6 = UC_MIPS_REG_14;
public static final int UC_MIPS_REG_T7 = UC_MIPS_REG_15;
public static final int UC_MIPS_REG_S0 = UC_MIPS_REG_16;
public static final int UC_MIPS_REG_S1 = UC_MIPS_REG_17;
public static final int UC_MIPS_REG_S2 = UC_MIPS_REG_18;
public static final int UC_MIPS_REG_S3 = UC_MIPS_REG_19;
public static final int UC_MIPS_REG_S4 = UC_MIPS_REG_20;
public static final int UC_MIPS_REG_S5 = UC_MIPS_REG_21;
public static final int UC_MIPS_REG_S6 = UC_MIPS_REG_22;
public static final int UC_MIPS_REG_S7 = UC_MIPS_REG_23;
public static final int UC_MIPS_REG_T8 = UC_MIPS_REG_24;
public static final int UC_MIPS_REG_T9 = UC_MIPS_REG_25;
public static final int UC_MIPS_REG_K0 = UC_MIPS_REG_26;
public static final int UC_MIPS_REG_K1 = UC_MIPS_REG_27;
public static final int UC_MIPS_REG_GP = UC_MIPS_REG_28;
public static final int UC_MIPS_REG_SP = UC_MIPS_REG_29;
public static final int UC_MIPS_REG_FP = UC_MIPS_REG_30;
public static final int UC_MIPS_REG_S8 = UC_MIPS_REG_30;
public static final int UC_MIPS_REG_RA = UC_MIPS_REG_31;
public static final int UC_MIPS_REG_HI0 = UC_MIPS_REG_AC0;
public static final int UC_MIPS_REG_HI1 = UC_MIPS_REG_AC1;
public static final int UC_MIPS_REG_HI2 = UC_MIPS_REG_AC2;
public static final int UC_MIPS_REG_HI3 = UC_MIPS_REG_AC3;
public static final int UC_MIPS_REG_LO0 = UC_MIPS_REG_HI0;
public static final int UC_MIPS_REG_LO1 = UC_MIPS_REG_HI1;
public static final int UC_MIPS_REG_LO2 = UC_MIPS_REG_HI2;
public static final int UC_MIPS_REG_LO3 = UC_MIPS_REG_HI3;
}

View File

@ -0,0 +1,29 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2015 Chris Eagle
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package unicorn;
public interface OutHook extends Hook {
public void hook(Unicorn u, int port, int size, int value, Object user);
}

View File

@ -0,0 +1,29 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2015 Chris Eagle
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package unicorn;
public interface ReadHook extends Hook {
public void hook(Unicorn u, long address, int size, Object user);
}

View File

@ -0,0 +1,29 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2015 Chris Eagle
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package unicorn;
public interface ReadWriteHook extends Hook {
public void hook(Unicorn u, int type, long address, int size, long value, Object user);
}

View File

@ -0,0 +1,117 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2015 Chris Eagle
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package unicorn;
public interface SparcRegs {
public static final int UC_SPARC_REG_INVALID = 0;
public static final int UC_SPARC_REG_F0 = 1;
public static final int UC_SPARC_REG_F1 = 2;
public static final int UC_SPARC_REG_F2 = 3;
public static final int UC_SPARC_REG_F3 = 4;
public static final int UC_SPARC_REG_F4 = 5;
public static final int UC_SPARC_REG_F5 = 6;
public static final int UC_SPARC_REG_F6 = 7;
public static final int UC_SPARC_REG_F7 = 8;
public static final int UC_SPARC_REG_F8 = 9;
public static final int UC_SPARC_REG_F9 = 10;
public static final int UC_SPARC_REG_F10 = 11;
public static final int UC_SPARC_REG_F11 = 12;
public static final int UC_SPARC_REG_F12 = 13;
public static final int UC_SPARC_REG_F13 = 14;
public static final int UC_SPARC_REG_F14 = 15;
public static final int UC_SPARC_REG_F15 = 16;
public static final int UC_SPARC_REG_F16 = 17;
public static final int UC_SPARC_REG_F17 = 18;
public static final int UC_SPARC_REG_F18 = 19;
public static final int UC_SPARC_REG_F19 = 20;
public static final int UC_SPARC_REG_F20 = 21;
public static final int UC_SPARC_REG_F21 = 22;
public static final int UC_SPARC_REG_F22 = 23;
public static final int UC_SPARC_REG_F23 = 24;
public static final int UC_SPARC_REG_F24 = 25;
public static final int UC_SPARC_REG_F25 = 26;
public static final int UC_SPARC_REG_F26 = 27;
public static final int UC_SPARC_REG_F27 = 28;
public static final int UC_SPARC_REG_F28 = 29;
public static final int UC_SPARC_REG_F29 = 30;
public static final int UC_SPARC_REG_F30 = 31;
public static final int UC_SPARC_REG_F31 = 32;
public static final int UC_SPARC_REG_F32 = 33;
public static final int UC_SPARC_REG_F34 = 34;
public static final int UC_SPARC_REG_F36 = 35;
public static final int UC_SPARC_REG_F38 = 36;
public static final int UC_SPARC_REG_F40 = 37;
public static final int UC_SPARC_REG_F42 = 38;
public static final int UC_SPARC_REG_F44 = 39;
public static final int UC_SPARC_REG_F46 = 40;
public static final int UC_SPARC_REG_F48 = 41;
public static final int UC_SPARC_REG_F50 = 42;
public static final int UC_SPARC_REG_F52 = 43;
public static final int UC_SPARC_REG_F54 = 44;
public static final int UC_SPARC_REG_F56 = 45;
public static final int UC_SPARC_REG_F58 = 46;
public static final int UC_SPARC_REG_F60 = 47;
public static final int UC_SPARC_REG_F62 = 48;
public static final int UC_SPARC_REG_FCC0 = 49;
public static final int UC_SPARC_REG_FCC1 = 50;
public static final int UC_SPARC_REG_FCC2 = 51;
public static final int UC_SPARC_REG_FCC3 = 52;
public static final int UC_SPARC_REG_FP = 53;
public static final int UC_SPARC_REG_G0 = 54;
public static final int UC_SPARC_REG_G1 = 55;
public static final int UC_SPARC_REG_G2 = 56;
public static final int UC_SPARC_REG_G3 = 57;
public static final int UC_SPARC_REG_G4 = 58;
public static final int UC_SPARC_REG_G5 = 59;
public static final int UC_SPARC_REG_G6 = 60;
public static final int UC_SPARC_REG_G7 = 61;
public static final int UC_SPARC_REG_I0 = 62;
public static final int UC_SPARC_REG_I1 = 63;
public static final int UC_SPARC_REG_I2 = 64;
public static final int UC_SPARC_REG_I3 = 65;
public static final int UC_SPARC_REG_I4 = 66;
public static final int UC_SPARC_REG_I5 = 67;
public static final int UC_SPARC_REG_I7 = 68;
public static final int UC_SPARC_REG_ICC = 69;
public static final int UC_SPARC_REG_L0 = 70;
public static final int UC_SPARC_REG_L1 = 71;
public static final int UC_SPARC_REG_L2 = 72;
public static final int UC_SPARC_REG_L3 = 73;
public static final int UC_SPARC_REG_L4 = 74;
public static final int UC_SPARC_REG_L5 = 75;
public static final int UC_SPARC_REG_L6 = 76;
public static final int UC_SPARC_REG_L7 = 77;
public static final int UC_SPARC_REG_O0 = 78;
public static final int UC_SPARC_REG_O1 = 79;
public static final int UC_SPARC_REG_O2 = 80;
public static final int UC_SPARC_REG_O3 = 81;
public static final int UC_SPARC_REG_O4 = 82;
public static final int UC_SPARC_REG_O5 = 83;
public static final int UC_SPARC_REG_O7 = 84;
public static final int UC_SPARC_REG_SP = 85;
public static final int UC_SPARC_REG_Y = 86;
public static final int UC_SPARC_REG_XCC = 87;
public static final int UC_SPARC_REG_PC = 88;
public static final int UC_SPARC_REG_ENDING = 89;
public static final int UC_SPARC_REG_O6 = UC_SPARC_REG_SP;
public static final int UC_SPARC_REG_I6 = UC_SPARC_REG_FP;
}

View File

@ -0,0 +1,29 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2015 Chris Eagle
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package unicorn;
public interface SyscallHook extends Hook {
public void hook(Unicorn u, Object user);
}

View File

@ -0,0 +1,630 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2015 Chris Eagle
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package unicorn;
import java.util.*;
public class Unicorn implements UnicornArchs, UnicornModes, UnicornHooks,
ArmRegs, Arm64Regs, M68kRegs, SparcRegs, MipsRegs, X86Regs, X86Instructions {
// Scales to calculate timeout on microsecond unit
// 1 second = 1000,000 microseconds
public static final int UC_SECOND_SCALE = 1000000;
// 1 milisecond = 1000 nanoseconds
public static final int UC_MILISECOND_SCALE = 1000;
private long blockHandle = 0;
private long interruptHandle = 0;
private long codeHandle = 0;
private long memInvalidHandle = 0;
private long readHandle = 0;
private long writeHandle = 0;
private long readWriteHandle = 0;
private long inHandle = 0;
private long outHandle = 0;
private long syscallHandle = 0;
private class Tuple {
public Hook function;
public Object data;
public Tuple(Hook f, Object d) {
function = f;
data = d;
}
}
private ArrayList<Tuple> blockList = new ArrayList<Tuple>();
private ArrayList<Tuple> intrList = new ArrayList<Tuple>();
private ArrayList<Tuple> codeList = new ArrayList<Tuple>();
private ArrayList<Tuple> memInvalidList = new ArrayList<Tuple>();
private ArrayList<Tuple> readList = new ArrayList<Tuple>();
private ArrayList<Tuple> writeList = new ArrayList<Tuple>();
private ArrayList<Tuple> readWriteList = new ArrayList<Tuple>();
private ArrayList<Tuple> inList = new ArrayList<Tuple>();
private ArrayList<Tuple> outList = new ArrayList<Tuple>();
private ArrayList<Tuple> syscallList = new ArrayList<Tuple>();
private ArrayList<ArrayList<Tuple>> allLists = new ArrayList<ArrayList<Tuple>>();
private static Hashtable<Long,Unicorn> unicorns = new Hashtable<Long,Unicorn>();
//required to load native method implementations
static {
System.loadLibrary("unicorn_java"); //loads unicorn.dll or libunicorn.so
}
/**
* Invoke all UC_HOOK_BLOCK callbacks registered for a specific Unicorn.
* This function gets invoked from the native C callback registered for
* for UC_HOOK_BLOCK
*
* @param handle A Unicorn uch handle returned by uc_open
* @param address The address of the instruction being executed
* @param size The size of the basic block being executed
* @see hook_add, unicorn.BlockHook
*/
private static void invokeBlockCallbacks(long handle, long address, int size) {
Unicorn u = unicorns.get(handle);
if (u != null) {
for (Tuple p : u.blockList) {
BlockHook bh = (BlockHook)p.function;
bh.hook(u, address, size, p.data);
}
}
}
/**
* Invoke all UC_HOOK_INTR callbacks registered for a specific Unicorn.
* This function gets invoked from the native C callback registered for
* for UC_HOOK_INTR
*
* @param handle A Unicorn uch handle returned by uc_open
* @param intno The interrupt number
* @see hook_add, unicorn.InterruptHook
*/
private static void invokeInterruptCallbacks(long handle, int intno) {
Unicorn u = unicorns.get(handle);
if (u != null) {
for (Tuple p : u.intrList) {
InterruptHook ih = (InterruptHook)p.function;
ih.hook(u, intno, p.data);
}
}
}
/**
* Invoke all UC_HOOK_CODE callbacks registered for a specific Unicorn.
* This function gets invoked from the native C callback registered for
* for UC_HOOK_CODE
*
* @param handle A Unicorn uch handle returned by uc_open
* @param address The address of the instruction being executed
* @param size The size of the instruction being executed
* @see hook_add, unicorn.CodeHook
*/
private static void invokeCodeCallbacks(long handle, long address, int size) {
Unicorn u = unicorns.get(handle);
if (u != null) {
for (Tuple p : u.codeList) {
CodeHook ch = (CodeHook)p.function;
ch.hook(u, address, size, p.data);
}
}
}
/**
* Invoke all UC_HOOK_MEM_INVALID callbacks registered for a specific Unicorn.
* This function gets invoked from the native C callback registered for
* for UC_HOOK_MEM_INVALID
*
* @param handle A Unicorn uch handle returned by uc_open
* @param type This memory is being read (UC_MEM_READ), or written (UC_MEM_WRITE)
* @param address Address of instruction being executed
* @param size Size of data being read or written
* @param value Value of data being written to memory, or irrelevant if type = READ.
* @return true to continue, or false to stop program (due to invalid memory).
* @see hook_add, unicorn.MemoryInvalidHook
*/
private static boolean invokeMemInvalidCallbacks(long handle, int type, long address, int size, long value) {
Unicorn u = unicorns.get(handle);
boolean result = true;
if (u != null) {
for (Tuple p : u.memInvalidList) {
MemoryInvalidHook mh = (MemoryInvalidHook)p.function;
result &= mh.hook(u, type, address, size, value, p.data);
}
}
return result;
}
/**
* Invoke all UC_HOOK_MEM_READ callbacks registered for a specific Unicorn.
* This function gets invoked from the native C callback registered for
* for UC_HOOK_MEM_READ
*
* @param handle A Unicorn uch handle returned by uc_open
* @param address Address of instruction being executed
* @param size Size of data being read
* @see hook_add, unicorn.ReadHook
*/
private static void invokeReadCallbacks(long handle, long address, int size) {
Unicorn u = unicorns.get(handle);
if (u != null) {
for (Tuple p : u.readList) {
ReadHook rh = (ReadHook)p.function;
rh.hook(u, address, size, p.data);
}
}
}
/**
* Invoke all UC_HOOK_MEM_WRITE callbacks registered for a specific Unicorn.
* This function gets invoked from the native C callback registered for
* for UC_HOOK_MEM_WRITE
*
* @param handle A Unicorn uch handle returned by uc_open
* @param address Address of instruction being executed
* @param size Size of data being read
* @param value value being written
* @see hook_add, unicorn.WriteHook
*/
private static void invokeWriteCallbacks(long handle, long address, int size, long value) {
Unicorn u = unicorns.get(handle);
if (u != null) {
for (Tuple p : u.writeList) {
WriteHook wh = (WriteHook)p.function;
wh.hook(u, address, size, value, p.data);
}
}
}
/**
* Invoke all UC_HOOK_MEM_READ_WRITE callbacks registered for a specific Unicorn.
* This function gets invoked from the native C callback registered for
* for UC_HOOK_MEM_READ_WRITE
*
* @param handle A Unicorn uch handle returned by uc_open
* @param type Type of access being performed (UC_MEM_READ, UC_MEM_WRITE, UC_MEM_READ_WRITE)
* @param address Address of instruction being executed
* @param size Size of data being read
* @param value value being written (if applicable)
* @see hook_add, unicorn.ReadWriteHook
*/
private static void invokeReadWriteCallbacks(long handle, int type, long address, int size, long value) {
Unicorn u = unicorns.get(handle);
if (u != null) {
for (Tuple p : u.readWriteList) {
ReadWriteHook rwh = (ReadWriteHook)p.function;
rwh.hook(u, type, address, size, value, p.data);
}
}
}
/**
* Invoke all UC_HOOK_INSN callbacks registered for a specific Unicorn.
* This is specifically for the x86 IN instruction.
* This function gets invoked from the native C callback registered for
* for UC_HOOK_INSN
*
* @param handle A Unicorn uch handle returned by uc_open
* @param port I/O Port number
* @param size Data size (1/2/4) to be read from this port
* @return Data supplied from the input port
* @see hook_add, unicorn.InHook
*/
private static int invokeInCallbacks(long handle, int port, int size) {
Unicorn u = unicorns.get(handle);
int result = 0;
if (u != null) {
for (Tuple p : u.inList) {
InHook ih = (InHook)p.function;
result = ih.hook(u, port, size, p.data);
}
}
return result;
}
/**
* Invoke all UC_HOOK_INSN callbacks registered for a specific Unicorn.
* This is specifically for the x86 OUT instruction.
* This function gets invoked from the native C callback registered for
* for UC_HOOK_INSN
*
* @param handle A Unicorn uch handle returned by uc_open
* @param port I/O Port number
* @param size Data size (1/2/4) to be written to this port
* @see hook_add, unicorn.OutHook
*/
private static void invokeOutCallbacks(long handle, int port, int size, int value) {
Unicorn u = unicorns.get(handle);
int result = 0;
if (u != null) {
for (Tuple p : u.outList) {
OutHook oh = (OutHook)p.function;
oh.hook(u, port, size, value, p.data);
}
}
}
/**
* Invoke all UC_HOOK_INSN callbacks registered for a specific Unicorn.
* This is specifically for the x86 SYSCALL and SYSENTER instruction.
* This function gets invoked from the native C callback registered for
* for UC_HOOK_INSN
*
* @param handle A Unicorn uch handle returned by uc_open
* @see hook_add, unicorn.SyscallHook
*/
private static void invokeSyscallCallbacks(long handle) {
Unicorn u = unicorns.get(handle);
int result = 0;
if (u != null) {
for (Tuple p : u.syscallList) {
SyscallHook sh = (SyscallHook)p.function;
sh.hook(u, p.data);
}
}
}
/**
* Native access to uc_open
*
* @param arch Architecture type (UC_ARCH_*)
* @param mode Hardware mode. This is combined of UC_MODE_*
*/
private native long open(int arch, int mode) throws UnicornException;
private long handle;
/**
* Create a new Unicorn object
*
* @param arch Architecture type (UC_ARCH_*)
* @param mode Hardware mode. This is combined of UC_MODE_*
* @see unicorn.UnicornArchs, unicorn.UnicornModes
*
*/
public Unicorn(int arch, int mode) throws UnicornException {
handle = open(arch, mode);
unicorns.put(handle, this);
allLists.add(blockList);
allLists.add(intrList);
allLists.add(codeList);
allLists.add(memInvalidList);
allLists.add(readList);
allLists.add(writeList);
allLists.add(readWriteList);
allLists.add(inList);
allLists.add(outList);
allLists.add(syscallList);
}
/**
* Perform native cleanup tasks associated with a Unicorn object
*
*/
protected void finalize() {
unicorns.remove(handle);
close();
}
/**
* Return combined API version & major and minor version numbers.
*
* @return hexadecimal number as (major << 8 | minor), which encodes both major & minor versions.
*
* For example Unicorn version 1.2 whould yield 0x0102
*/
public native static int version();
/**
* Determine if the given architecture is supported by this library.
*
* @param arch Architecture type (UC_ARCH_*)
* @return true if this library supports the given arch.
* @see unicorn.UnicornArchs
*/
public native static boolean arch_supported(int arch);
/**
* Close the underlying uch handle associated with this Unicorn object
*
*/
public native void close() throws UnicornException;
/**
* Report the last error number when some API function fail.
* Like glibc's errno, uc_errno might not retain its old value once accessed.
*
* @return Error code of uc_err enum type (UC_ERR_*, see above)
* @see unicorn.UnicornErrors
*/
public native int errno();
/**
* Return a string describing given error code.
*
* @param code Error code (see UC_ERR_* above)
* @return Returns a String that describes the error code
* @see unicorn.UnicornErrors
*/
public native static String strerror(int code);
/**
* Write to register.
*
* @param regid Register ID that is to be modified.
* @param value Array containing value that will be written into register @regid
*/
public native void reg_write(int regid, byte[] value) throws UnicornException;
/**
* Read register value.
*
* @param regid Register ID that is to be retrieved.
* @param regsz Size of the register being retrieved.
* @return Byte array containing the requested register value.
*/
public native byte[] reg_read(int regid, int regsz) throws UnicornException;
/**
* Write to memory.
*
* @param address Start addres of the memory region to be written.
* @param bytes The values to be written into memory. bytes.length bytes will be written.
*/
public native void mem_write(long address, byte[] bytes) throws UnicornException;
/**
* Read memory contents.
*
* @param address Start addres of the memory region to be read.
* @param size Number of bytes to be retrieved.
* @return Byte array containing the contents of the requested memory range.
*/
public native byte[] mem_read(long address, long size) throws UnicornException;
/**
* Emulate machine code in a specific duration of time.
*
* @param begin Address where emulation starts
* @param until Address where emulation stops (i.e when this address is hit)
* @param timeout Duration to emulate the code (in microseconds). When this value is 0, we will emulate the code in infinite time, until the code is finished.
* @param count The number of instructions to be emulated. When this value is 0, we will emulate all the code available, until the code is finished.
*/
public native void emu_start(long begin, long until, long timeout, long count) throws UnicornException;
/**
* Stop emulation (which was started by emu_start() ).
* This is typically called from callback functions registered via tracing APIs.
* NOTE: for now, this will stop the execution only after the current block.
*/
public native void emu_stop() throws UnicornException;
/**
* Hook registration helper for hook types that require no additional arguments.
*
* @param handle Internal unicorn uch handle associated with hooking Unicorn object
* @param type UC_HOOK_* hook type
* @return Unicorn uch returned for registered hook function
*/
private native static long registerHook(long handle, int type);
/**
* Hook registration helper for hook types that require one additional argument.
*
* @param handle Internal unicorn uch handle associated with hooking Unicorn object
* @param type UC_HOOK_* hook type
* @param arg1 Additional varargs argument
* @return Unicorn uch returned for registered hook function
*/
private native static long registerHook(long handle, int type, int arg1);
/**
* Hook registration helper for hook types that require two additional arguments.
*
* @param handle Internal unicorn uch handle associated with hooking Unicorn object
* @param type UC_HOOK_* hook type
* @param arg1 First additional varargs argument
* @param arg2 Second additional varargs argument
* @return Unicorn uch returned for registered hook function
*/
private native static long registerHook(long handle, int type, long arg1, long arg2);
/**
* Hook registration for UC_HOOK_BLOCK hooks. The registered callback function will be
* invoked when a basic block is entered and the address of the basic block (BB) falls in the
* range begin <= BB <= end. For the special case in which begin > end, the callback will be
* invoked whenver any basic block is entered.
*
* @param callback Implementation of a BlockHook interface
* @param begin Start address of hooking range
* @param end End address of hooking range
* @param user_data User data to be passed to the callback function each time the event is triggered
*/
public void hook_add(BlockHook callback, long begin, long end, Object user_data) throws UnicornException {
if (blockHandle == 0) {
blockHandle = registerHook(handle, UC_HOOK_BLOCK, begin, end);
}
blockList.add(new Tuple(callback, user_data));
}
/**
* Hook registration for UC_HOOK_INTR hooks. The registered callback function will be
* invoked whenever an interrupt instruction is executed.
*
* @param callback Implementation of a InterruptHook interface
* @param user_data User data to be passed to the callback function each time the event is triggered
*/
public void hook_add(InterruptHook callback, Object user_data) throws UnicornException {
if (interruptHandle == 0) {
interruptHandle = registerHook(handle, UC_HOOK_INTR);
}
intrList.add(new Tuple(callback, user_data));
}
/**
* Hook registration for UC_HOOK_CODE hooks. The registered callback function will be
* invoked when an instruction is executed from the address range begin <= PC <= end. For
* the special case in which begin > end, the callback will be invoked for ALL instructions.
*
* @param callback Implementation of a CodeHook interface
* @param begin Start address of hooking range
* @param end End address of hooking range
* @param user_data User data to be passed to the callback function each time the event is triggered
*/
public void hook_add(CodeHook callback, long begin, long end, Object user_data) throws UnicornException {
if (codeHandle == 0) {
codeHandle = registerHook(handle, UC_HOOK_CODE, begin, end);
}
codeList.add(new Tuple(callback, user_data));
}
/**
* Hook registration for UC_HOOK_MEM_READ hooks. The registered callback function will be
* invoked whenever a memory read is performed within the address range begin <= read_addr <= end. For
* the special case in which begin > end, the callback will be invoked for ALL memory reads.
*
* @param callback Implementation of a ReadHook interface
* @param begin Start address of memory read range
* @param end End address of memory read range
* @param user_data User data to be passed to the callback function each time the event is triggered
*/
public void hook_add(ReadHook callback, long begin, long end, Object user_data) throws UnicornException {
if (readHandle == 0) {
readHandle = registerHook(handle, UC_HOOK_MEM_READ, begin, end);
}
readList.add(new Tuple(callback, user_data));
}
/**
* Hook registration for UC_HOOK_MEM_WRITE hooks. The registered callback function will be
* invoked whenever a memory write is performed within the address range begin <= write_addr <= end. For
* the special case in which begin > end, the callback will be invoked for ALL memory writes.
*
* @param callback Implementation of a WriteHook interface
* @param begin Start address of memory write range
* @param end End address of memory write range
* @param user_data User data to be passed to the callback function each time the event is triggered
*/
public void hook_add(WriteHook callback, long begin, long end, Object user_data) throws UnicornException {
if (writeHandle == 0) {
writeHandle = registerHook(handle, UC_HOOK_MEM_WRITE, begin, end);
}
writeList.add(new Tuple(callback, user_data));
}
/**
* Hook registration for UC_HOOK_MEM_READ_WRITE hooks. The registered callback function will be
* invoked whenever a memory read or write is performed within the address range begin <= mem_addr <= end. For
* the special case in which begin > end, the callback will be invoked for ALL memory reads and writes.
*
* @param callback Implementation of a ReadWriteHook interface
* @param begin Start address of memory read/write range
* @param end End address of memory read/write range
* @param user_data User data to be passed to the callback function each time the event is triggered
*/
public void hook_add(ReadWriteHook callback, long begin, long end, Object user_data) throws UnicornException {
if (readWriteHandle == 0) {
readWriteHandle = registerHook(handle, UC_HOOK_MEM_READ_WRITE, begin, end);
}
readWriteList.add(new Tuple(callback, user_data));
}
/**
* Hook registration for UC_HOOK_MEM_INVALID hooks. The registered callback function will be
* invoked whenever a read or write is attempted from an unmapped memory address.
*
* @param callback Implementation of a MemoryInvalidHook interface
* @param user_data User data to be passed to the callback function each time the event is triggered
*/
public void hook_add(MemoryInvalidHook callback, Object user_data) throws UnicornException {
if (memInvalidHandle == 0) {
memInvalidHandle = registerHook(handle, UC_HOOK_MEM_INVALID);
}
memInvalidList.add(new Tuple(callback, user_data));
}
/**
* Hook registration for UC_HOOK_INSN hooks (x86 IN instruction only). The registered callback
* function will be invoked whenever an x86 IN instruction is executed.
*
* @param callback Implementation of a InHook interface
* @param user_data User data to be passed to the callback function each time the event is triggered
*/
public void hook_add(InHook callback, Object user_data) throws UnicornException {
if (inHandle == 0) {
inHandle = registerHook(handle, UC_HOOK_INSN, Unicorn.UC_X86_INS_IN);
}
inList.add(new Tuple(callback, user_data));
}
/**
* Hook registration for UC_HOOK_INSN hooks (x86 OUT instruction only). The registered callback
* function will be invoked whenever an x86 OUT instruction is executed.
*
* @param callback Implementation of a OutHook interface
* @param user_data User data to be passed to the callback function each time the event is triggered
*/
public void hook_add(OutHook callback, Object user_data) throws UnicornException {
if (outHandle == 0) {
outHandle = registerHook(handle, UC_HOOK_INSN, Unicorn.UC_X86_INS_OUT);
}
outList.add(new Tuple(callback, user_data));
}
/**
* Hook registration for UC_HOOK_INSN hooks (x86 SYSCALL/SYSENTER instruction only). The registered callback
* function will be invoked whenever an x86 SYSCALL or SYSENTER instruction is executed.
*
* @param callback Implementation of a SyscallHook interface
* @param user_data User data to be passed to the callback function each time the event is triggered
*/
public void hook_add(SyscallHook callback, Object user_data) throws UnicornException {
if (syscallHandle == 0) {
syscallHandle = registerHook(handle, UC_HOOK_INSN, Unicorn.UC_X86_INS_SYSCALL);
}
syscallList.add(new Tuple(callback, user_data));
}
public void hook_del(Hook hook) throws UnicornException {
for (ArrayList<Tuple> l : allLists) {
for (Tuple t : l) {
if (t.function.equals(hook)) {
allLists.remove(t);
return;
}
}
}
}
/**
* Map a range of memory.
*
* @param address Base address of the memory range
* @param size Size of the memory block.
*/
public native void mem_map(long address, long size) throws UnicornException;
}

View File

@ -0,0 +1,34 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2015 Chris Eagle
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package unicorn;
public interface UnicornArchs {
public static final int UC_ARCH_ARM = 1; // ARM architecture (including Thumb, Thumb-2)
public static final int UC_ARCH_ARM64 = 2; // ARM-64, also called AArch64
public static final int UC_ARCH_MIPS = 3; // Mips architecture
public static final int UC_ARCH_X86 = 4; // X86 architecture (including x86 & x86-64)
public static final int UC_ARCH_PPC = 5; // PowerPC architecture
public static final int UC_ARCH_SPARC = 6; // Sparc architecture
public static final int UC_ARCH_M68K = 7; // M68K architecture
public static final int UC_ARCH_MAX = 8;
public static final int UC_ARCH_ALL = 0xFFFF; // All architectures - for uc_support()
}

View File

@ -0,0 +1,39 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2015 Chris Eagle
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package unicorn;
public interface UnicornErrors {
public static final int UC_ERR_OK = 0; // No error: everything was fine
public static final int UC_ERR_OOM = 1; // Out-Of-Memory error: uc_open(), uc_emulate()
public static final int UC_ERR_ARCH = 2; // Unsupported architecture: uc_open()
public static final int UC_ERR_HANDLE = 3; // Invalid handle
public static final int UC_ERR_UCH = 4; // Invalid handle (uch)
public static final int UC_ERR_MODE = 5; // Invalid/unsupported mode: uc_open()
public static final int UC_ERR_VERSION = 6; // Unsupported version (bindings)
public static final int UC_ERR_MEM_READ = 7; // Quit emulation due to invalid memory READ: uc_emu_start()
public static final int UC_ERR_MEM_WRITE = 8; // Quit emulation due to invalid memory WRITE: uc_emu_start()
public static final int UC_ERR_CODE_INVALID = 9; // Quit emulation due to invalid code address: uc_emu_start()
public static final int UC_ERR_HOOK = 10; // Invalid hook type: uc_hook_add()
public static final int UC_ERR_INSN_INVALID = 11; // Quit emulation due to invalid instruction: uc_emu_start()
public static final int UC_ERR_MAP = 12; // Invalid memory mapping: uc_mem_map()
}

View File

@ -0,0 +1,34 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2015 Chris Eagle
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package unicorn;
public class UnicornException extends RuntimeException {
public UnicornException() {
super();
}
public UnicornException(String msg) {
super(msg);
}
}

View File

@ -0,0 +1,38 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2015 Chris Eagle
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package unicorn;
public interface UnicornHooks {
public static final int UC_MEM_READ = 16; // Memory is read from
public static final int UC_MEM_WRITE = 17; // Memory is written to
public static final int UC_MEM_READ_WRITE = 18; // Memory is accessed (either READ or WRITE)
public static final int UC_HOOK_INTR = 32; // Hook all interrupt events
public static final int UC_HOOK_INSN = 33; // Hook a particular instruction
public static final int UC_HOOK_CODE = 34; // Hook a range of code
public static final int UC_HOOK_BLOCK = 35; // Hook basic blocks
public static final int UC_HOOK_MEM_INVALID = 36; // Hook for all invalid memory access events
public static final int UC_HOOK_MEM_READ = 37; // Hook all memory read events.
public static final int UC_HOOK_MEM_WRITE = 38; // Hook all memory write events.
public static final int UC_HOOK_MEM_READ_WRITE = 39; // Hook all memory accesses (either READ or WRITE).
}

View File

@ -0,0 +1,20 @@
package unicorn;
public interface UnicornModes {
public static final int UC_MODE_LITTLE_ENDIAN = 0; // little-endian mode (default mode)
public static final int UC_MODE_ARM = 0; // 32-bit ARM
public static final int UC_MODE_16 = 1 << 1; // 16-bit mode (X86)
public static final int UC_MODE_32 = 1 << 2; // 32-bit mode (X86)
public static final int UC_MODE_64 = 1 << 3; // 64-bit mode (X86; PPC)
public static final int UC_MODE_THUMB = 1 << 4; // ARM's Thumb mode; including Thumb-2
public static final int UC_MODE_MCLASS = 1 << 5; // ARM's Cortex-M series
public static final int UC_MODE_V8 = 1 << 6; // ARMv8 A32 encodings for ARM
public static final int UC_MODE_MICRO = 1 << 4; // MicroMips mode (MIPS)
public static final int UC_MODE_MIPS3 = 1 << 5; // Mips III ISA
public static final int UC_MODE_MIPS32R6 = 1 << 6; // Mips32r6 ISA
public static final int UC_MODE_V9 = 1 << 4; // SparcV9 mode (Sparc)
public static final int UC_MODE_QPX = 1 << 4; // Quad Processing eXtensions mode (PPC)
public static final int UC_MODE_BIG_ENDIAN = 1 << 31; // big-endian mode
public static final int UC_MODE_MIPS32 = UC_MODE_32; // Mips32 ISA (Mips)
public static final int UC_MODE_MIPS64 = UC_MODE_64; // Mips64 ISA (Mips)
}

View File

@ -0,0 +1,29 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2015 Chris Eagle
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package unicorn;
public interface WriteHook extends Hook {
public void hook(Unicorn u, long address, int size, long value, Object user);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,268 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2015 Chris Eagle
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package unicorn;
public interface X86Regs {
public static final int UC_X86_REG_INVALID = 0;
public static final int UC_X86_REG_AH = 1;
public static final int UC_X86_REG_AL = 2;
public static final int UC_X86_REG_AX = 3;
public static final int UC_X86_REG_BH = 4;
public static final int UC_X86_REG_BL = 5;
public static final int UC_X86_REG_BP = 6;
public static final int UC_X86_REG_BPL = 7;
public static final int UC_X86_REG_BX = 8;
public static final int UC_X86_REG_CH = 9;
public static final int UC_X86_REG_CL = 10;
public static final int UC_X86_REG_CS = 11;
public static final int UC_X86_REG_CX = 12;
public static final int UC_X86_REG_DH = 13;
public static final int UC_X86_REG_DI = 14;
public static final int UC_X86_REG_DIL = 15;
public static final int UC_X86_REG_DL = 16;
public static final int UC_X86_REG_DS = 17;
public static final int UC_X86_REG_DX = 18;
public static final int UC_X86_REG_EAX = 19;
public static final int UC_X86_REG_EBP = 20;
public static final int UC_X86_REG_EBX = 21;
public static final int UC_X86_REG_ECX = 22;
public static final int UC_X86_REG_EDI = 23;
public static final int UC_X86_REG_EDX = 24;
public static final int UC_X86_REG_EFLAGS = 25;
public static final int UC_X86_REG_EIP = 26;
public static final int UC_X86_REG_EIZ = 27;
public static final int UC_X86_REG_ES = 28;
public static final int UC_X86_REG_ESI = 29;
public static final int UC_X86_REG_ESP = 30;
public static final int UC_X86_REG_FPSW = 31;
public static final int UC_X86_REG_FS = 32;
public static final int UC_X86_REG_GS = 33;
public static final int UC_X86_REG_IP = 34;
public static final int UC_X86_REG_RAX = 35;
public static final int UC_X86_REG_RBP = 36;
public static final int UC_X86_REG_RBX = 37;
public static final int UC_X86_REG_RCX = 38;
public static final int UC_X86_REG_RDI = 39;
public static final int UC_X86_REG_RDX = 40;
public static final int UC_X86_REG_RIP = 41;
public static final int UC_X86_REG_RIZ = 42;
public static final int UC_X86_REG_RSI = 43;
public static final int UC_X86_REG_RSP = 44;
public static final int UC_X86_REG_SI = 45;
public static final int UC_X86_REG_SIL = 46;
public static final int UC_X86_REG_SP = 47;
public static final int UC_X86_REG_SPL = 48;
public static final int UC_X86_REG_SS = 49;
public static final int UC_X86_REG_CR0 = 50;
public static final int UC_X86_REG_CR1 = 51;
public static final int UC_X86_REG_CR2 = 52;
public static final int UC_X86_REG_CR3 = 53;
public static final int UC_X86_REG_CR4 = 54;
public static final int UC_X86_REG_CR5 = 55;
public static final int UC_X86_REG_CR6 = 56;
public static final int UC_X86_REG_CR7 = 57;
public static final int UC_X86_REG_CR8 = 58;
public static final int UC_X86_REG_CR9 = 59;
public static final int UC_X86_REG_CR10 = 60;
public static final int UC_X86_REG_CR11 = 61;
public static final int UC_X86_REG_CR12 = 62;
public static final int UC_X86_REG_CR13 = 63;
public static final int UC_X86_REG_CR14 = 64;
public static final int UC_X86_REG_CR15 = 65;
public static final int UC_X86_REG_DR0 = 66;
public static final int UC_X86_REG_DR1 = 67;
public static final int UC_X86_REG_DR2 = 68;
public static final int UC_X86_REG_DR3 = 69;
public static final int UC_X86_REG_DR4 = 70;
public static final int UC_X86_REG_DR5 = 71;
public static final int UC_X86_REG_DR6 = 72;
public static final int UC_X86_REG_DR7 = 73;
public static final int UC_X86_REG_DR8 = 74;
public static final int UC_X86_REG_DR9 = 75;
public static final int UC_X86_REG_DR10 = 76;
public static final int UC_X86_REG_DR11 = 77;
public static final int UC_X86_REG_DR12 = 78;
public static final int UC_X86_REG_DR13 = 79;
public static final int UC_X86_REG_DR14 = 80;
public static final int UC_X86_REG_DR15 = 81;
public static final int UC_X86_REG_FP0 = 82;
public static final int UC_X86_REG_FP1 = 83;
public static final int UC_X86_REG_FP2 = 84;
public static final int UC_X86_REG_FP3 = 85;
public static final int UC_X86_REG_FP4 = 86;
public static final int UC_X86_REG_FP5 = 87;
public static final int UC_X86_REG_FP6 = 88;
public static final int UC_X86_REG_FP7 = 89;
public static final int UC_X86_REG_K0 = 90;
public static final int UC_X86_REG_K1 = 91;
public static final int UC_X86_REG_K2 = 92;
public static final int UC_X86_REG_K3 = 93;
public static final int UC_X86_REG_K4 = 94;
public static final int UC_X86_REG_K5 = 95;
public static final int UC_X86_REG_K6 = 96;
public static final int UC_X86_REG_K7 = 97;
public static final int UC_X86_REG_MM0 = 98;
public static final int UC_X86_REG_MM1 = 99;
public static final int UC_X86_REG_MM2 = 100;
public static final int UC_X86_REG_MM3 = 101;
public static final int UC_X86_REG_MM4 = 102;
public static final int UC_X86_REG_MM5 = 103;
public static final int UC_X86_REG_MM6 = 104;
public static final int UC_X86_REG_MM7 = 105;
public static final int UC_X86_REG_R8 = 106;
public static final int UC_X86_REG_R9 = 107;
public static final int UC_X86_REG_R10 = 108;
public static final int UC_X86_REG_R11 = 109;
public static final int UC_X86_REG_R12 = 110;
public static final int UC_X86_REG_R13 = 111;
public static final int UC_X86_REG_R14 = 112;
public static final int UC_X86_REG_R15 = 113;
public static final int UC_X86_REG_ST0 = 114;
public static final int UC_X86_REG_ST1 = 115;
public static final int UC_X86_REG_ST2 = 116;
public static final int UC_X86_REG_ST3 = 117;
public static final int UC_X86_REG_ST4 = 118;
public static final int UC_X86_REG_ST5 = 119;
public static final int UC_X86_REG_ST6 = 120;
public static final int UC_X86_REG_ST7 = 121;
public static final int UC_X86_REG_XMM0 = 122;
public static final int UC_X86_REG_XMM1 = 123;
public static final int UC_X86_REG_XMM2 = 124;
public static final int UC_X86_REG_XMM3 = 125;
public static final int UC_X86_REG_XMM4 = 126;
public static final int UC_X86_REG_XMM5 = 127;
public static final int UC_X86_REG_XMM6 = 128;
public static final int UC_X86_REG_XMM7 = 129;
public static final int UC_X86_REG_XMM8 = 130;
public static final int UC_X86_REG_XMM9 = 131;
public static final int UC_X86_REG_XMM10 = 132;
public static final int UC_X86_REG_XMM11 = 133;
public static final int UC_X86_REG_XMM12 = 134;
public static final int UC_X86_REG_XMM13 = 135;
public static final int UC_X86_REG_XMM14 = 136;
public static final int UC_X86_REG_XMM15 = 137;
public static final int UC_X86_REG_XMM16 = 138;
public static final int UC_X86_REG_XMM17 = 139;
public static final int UC_X86_REG_XMM18 = 140;
public static final int UC_X86_REG_XMM19 = 141;
public static final int UC_X86_REG_XMM20 = 142;
public static final int UC_X86_REG_XMM21 = 143;
public static final int UC_X86_REG_XMM22 = 144;
public static final int UC_X86_REG_XMM23 = 145;
public static final int UC_X86_REG_XMM24 = 146;
public static final int UC_X86_REG_XMM25 = 147;
public static final int UC_X86_REG_XMM26 = 148;
public static final int UC_X86_REG_XMM27 = 149;
public static final int UC_X86_REG_XMM28 = 150;
public static final int UC_X86_REG_XMM29 = 151;
public static final int UC_X86_REG_XMM30 = 152;
public static final int UC_X86_REG_XMM31 = 153;
public static final int UC_X86_REG_YMM0 = 154;
public static final int UC_X86_REG_YMM1 = 155;
public static final int UC_X86_REG_YMM2 = 156;
public static final int UC_X86_REG_YMM3 = 157;
public static final int UC_X86_REG_YMM4 = 158;
public static final int UC_X86_REG_YMM5 = 159;
public static final int UC_X86_REG_YMM6 = 160;
public static final int UC_X86_REG_YMM7 = 161;
public static final int UC_X86_REG_YMM8 = 162;
public static final int UC_X86_REG_YMM9 = 163;
public static final int UC_X86_REG_YMM10 = 164;
public static final int UC_X86_REG_YMM11 = 165;
public static final int UC_X86_REG_YMM12 = 166;
public static final int UC_X86_REG_YMM13 = 167;
public static final int UC_X86_REG_YMM14 = 168;
public static final int UC_X86_REG_YMM15 = 169;
public static final int UC_X86_REG_YMM16 = 170;
public static final int UC_X86_REG_YMM17 = 171;
public static final int UC_X86_REG_YMM18 = 172;
public static final int UC_X86_REG_YMM19 = 173;
public static final int UC_X86_REG_YMM20 = 174;
public static final int UC_X86_REG_YMM21 = 175;
public static final int UC_X86_REG_YMM22 = 176;
public static final int UC_X86_REG_YMM23 = 177;
public static final int UC_X86_REG_YMM24 = 178;
public static final int UC_X86_REG_YMM25 = 179;
public static final int UC_X86_REG_YMM26 = 180;
public static final int UC_X86_REG_YMM27 = 181;
public static final int UC_X86_REG_YMM28 = 182;
public static final int UC_X86_REG_YMM29 = 183;
public static final int UC_X86_REG_YMM30 = 184;
public static final int UC_X86_REG_YMM31 = 185;
public static final int UC_X86_REG_ZMM0 = 186;
public static final int UC_X86_REG_ZMM1 = 187;
public static final int UC_X86_REG_ZMM2 = 188;
public static final int UC_X86_REG_ZMM3 = 189;
public static final int UC_X86_REG_ZMM4 = 190;
public static final int UC_X86_REG_ZMM5 = 191;
public static final int UC_X86_REG_ZMM6 = 192;
public static final int UC_X86_REG_ZMM7 = 193;
public static final int UC_X86_REG_ZMM8 = 194;
public static final int UC_X86_REG_ZMM9 = 195;
public static final int UC_X86_REG_ZMM10 = 196;
public static final int UC_X86_REG_ZMM11 = 197;
public static final int UC_X86_REG_ZMM12 = 198;
public static final int UC_X86_REG_ZMM13 = 199;
public static final int UC_X86_REG_ZMM14 = 200;
public static final int UC_X86_REG_ZMM15 = 201;
public static final int UC_X86_REG_ZMM16 = 202;
public static final int UC_X86_REG_ZMM17 = 203;
public static final int UC_X86_REG_ZMM18 = 204;
public static final int UC_X86_REG_ZMM19 = 205;
public static final int UC_X86_REG_ZMM20 = 206;
public static final int UC_X86_REG_ZMM21 = 207;
public static final int UC_X86_REG_ZMM22 = 208;
public static final int UC_X86_REG_ZMM23 = 209;
public static final int UC_X86_REG_ZMM24 = 210;
public static final int UC_X86_REG_ZMM25 = 211;
public static final int UC_X86_REG_ZMM26 = 212;
public static final int UC_X86_REG_ZMM27 = 213;
public static final int UC_X86_REG_ZMM28 = 214;
public static final int UC_X86_REG_ZMM29 = 215;
public static final int UC_X86_REG_ZMM30 = 216;
public static final int UC_X86_REG_ZMM31 = 217;
public static final int UC_X86_REG_R8B = 218;
public static final int UC_X86_REG_R9B = 219;
public static final int UC_X86_REG_R10B = 220;
public static final int UC_X86_REG_R11B = 221;
public static final int UC_X86_REG_R12B = 222;
public static final int UC_X86_REG_R13B = 223;
public static final int UC_X86_REG_R14B = 224;
public static final int UC_X86_REG_R15B = 225;
public static final int UC_X86_REG_R8D = 226;
public static final int UC_X86_REG_R9D = 227;
public static final int UC_X86_REG_R10D = 228;
public static final int UC_X86_REG_R11D = 229;
public static final int UC_X86_REG_R12D = 230;
public static final int UC_X86_REG_R13D = 231;
public static final int UC_X86_REG_R14D = 232;
public static final int UC_X86_REG_R15D = 233;
public static final int UC_X86_REG_R8W = 234;
public static final int UC_X86_REG_R9W = 235;
public static final int UC_X86_REG_R10W = 236;
public static final int UC_X86_REG_R11W = 237;
public static final int UC_X86_REG_R12W = 238;
public static final int UC_X86_REG_R13W = 239;
public static final int UC_X86_REG_R14W = 240;
public static final int UC_X86_REG_R15W = 241;
public static final int UC_X86_REG_ENDING = 242;
}

515
bindings/java/unicorn_Unicorn.c Executable file
View File

@ -0,0 +1,515 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2015 Chris Eagle
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <sys/types.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unicorn/unicorn.h>
#include "unicorn_Unicorn.h"
//cache jmethodID values as we look them up
static jmethodID invokeBlockCallbacks = 0;
static jmethodID invokeInterruptCallbacks = 0;
static jmethodID invokeCodeCallbacks = 0;
static jmethodID invokeMemInvalidCallbacks = 0;
static jmethodID invokeReadCallbacks = 0;
static jmethodID invokeWriteCallbacks = 0;
static jmethodID invokeReadWriteCallbacks = 0;
static jmethodID invokeInCallbacks = 0;
static jmethodID invokeOutCallbacks = 0;
static jmethodID invokeSyscallCallbacks = 0;
static JavaVM* cachedJVM;
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved) {
cachedJVM = jvm;
return JNI_VERSION_1_6;
}
// Callback function for tracing code (UC_HOOK_CODE & UC_HOOK_BLOCK)
// @address: address where the code is being executed
// @size: size of machine instruction being executed
// @user_data: user data passed to tracing APIs.
static void cb_hookcode(uch handle, uint64_t address, uint32_t size, void *user_data) {
JNIEnv *env;
(*cachedJVM)->AttachCurrentThread(cachedJVM, (void **)&env, NULL);
jclass clz = (*env)->FindClass(env, "unicorn/Unicorn");
if ((*env)->ExceptionCheck(env)) {
return;
}
(*env)->CallStaticVoidMethod(env, clz, invokeCodeCallbacks, (jlong)handle, (jlong)address, (int)size);
(*cachedJVM)->DetachCurrentThread(cachedJVM);
}
// Callback function for tracing code (UC_HOOK_CODE & UC_HOOK_BLOCK)
// @address: address where the code is being executed
// @size: size of machine instruction being executed
// @user_data: user data passed to tracing APIs.
static void cb_hookblock(uch handle, uint64_t address, uint32_t size, void *user_data) {
JNIEnv *env;
(*cachedJVM)->AttachCurrentThread(cachedJVM, (void **)&env, NULL);
jclass clz = (*env)->FindClass(env, "unicorn/Unicorn");
if ((*env)->ExceptionCheck(env)) {
return;
}
(*env)->CallStaticVoidMethod(env, clz, invokeBlockCallbacks, (jlong)handle, (jlong)address, (int)size);
(*cachedJVM)->DetachCurrentThread(cachedJVM);
}
// Callback function for tracing interrupts (for uc_hook_intr())
// @intno: interrupt number
// @user_data: user data passed to tracing APIs.
static void cb_hookintr(uch handle, uint32_t intno, void *user_data) {
JNIEnv *env;
(*cachedJVM)->AttachCurrentThread(cachedJVM, (void **)&env, NULL);
jclass clz = (*env)->FindClass(env, "unicorn/Unicorn");
if ((*env)->ExceptionCheck(env)) {
return;
}
(*env)->CallStaticVoidMethod(env, clz, invokeInterruptCallbacks, (jlong)handle, (int)intno);
(*cachedJVM)->DetachCurrentThread(cachedJVM);
}
// Callback function for tracing IN instruction of X86
// @port: port number
// @size: data size (1/2/4) to be read from this port
// @user_data: user data passed to tracing APIs.
static uint32_t cb_insn_in(uch handle, uint32_t port, int size, void *user_data) {
JNIEnv *env;
uint32_t res = 0;
(*cachedJVM)->AttachCurrentThread(cachedJVM, (void **)&env, NULL);
jclass clz = (*env)->FindClass(env, "unicorn/Unicorn");
if ((*env)->ExceptionCheck(env)) {
return 0;
}
res = (uint32_t)(*env)->CallStaticIntMethod(env, clz, invokeInCallbacks, (jlong)handle, (jint)port, (jint)size);
(*cachedJVM)->DetachCurrentThread(cachedJVM);
return res;
}
// x86's handler for OUT
// @port: port number
// @size: data size (1/2/4) to be written to this port
// @value: data value to be written to this port
static void cb_insn_out(uch handle, uint32_t port, int size, uint32_t value, void *user_data) {
JNIEnv *env;
(*cachedJVM)->AttachCurrentThread(cachedJVM, (void **)&env, NULL);
jclass clz = (*env)->FindClass(env, "unicorn/Unicorn");
if ((*env)->ExceptionCheck(env)) {
return;
}
(*env)->CallStaticVoidMethod(env, clz, invokeOutCallbacks, (jlong)handle, (jint)port, (jint)size, (jint)value);
(*cachedJVM)->DetachCurrentThread(cachedJVM);
}
// x86's handler for SYSCALL/SYSENTER
static void cb_insn_syscall(uch handle, void *user_data) {
JNIEnv *env;
(*cachedJVM)->AttachCurrentThread(cachedJVM, (void **)&env, NULL);
jclass clz = (*env)->FindClass(env, "unicorn/Unicorn");
if ((*env)->ExceptionCheck(env)) {
return;
}
(*env)->CallStaticVoidMethod(env, clz, invokeSyscallCallbacks, (jlong)handle);
(*cachedJVM)->DetachCurrentThread(cachedJVM);
}
// Callback function for hooking memory (UC_HOOK_MEM_*)
// @type: this memory is being READ, or WRITE
// @address: address where the code is being executed
// @size: size of data being read or written
// @value: value of data being written to memory, or irrelevant if type = READ.
// @user_data: user data passed to tracing APIs
static void cb_hookmem(uch handle, uc_mem_type type,
uint64_t address, int size, int64_t value, void *user_data) {
JNIEnv *env;
(*cachedJVM)->AttachCurrentThread(cachedJVM, (void **)&env, NULL);
jclass clz = (*env)->FindClass(env, "unicorn/Unicorn");
if ((*env)->ExceptionCheck(env)) {
return;
}
switch (type) {
case UC_MEM_READ:
(*env)->CallStaticVoidMethod(env, clz, invokeReadCallbacks, (jlong)handle, (jlong)address, (int)size);
break;
case UC_MEM_WRITE:
(*env)->CallStaticVoidMethod(env, clz, invokeWriteCallbacks, (jlong)handle, (jlong)address, (int)size, (jlong)value);
break;
case UC_MEM_READ_WRITE:
(*env)->CallStaticVoidMethod(env, clz, invokeReadWriteCallbacks, (jlong)handle, (int)type, (jlong)address, (int)size, (jlong)value);
break;
}
(*cachedJVM)->DetachCurrentThread(cachedJVM);
}
// Callback function for handling memory events (for UC_HOOK_MEM_INVALID)
// @type: this memory is being READ, or WRITE
// @address: address where the code is being executed
// @size: size of data being read or written
// @value: value of data being written to memory, or irrelevant if type = READ.
// @user_data: user data passed to tracing APIs
// @return: return true to continue, or false to stop program (due to invalid memory).
static bool cb_eventmem(uch handle, uc_mem_type type,
uint64_t address, int size, int64_t value, void *user_data) {
JNIEnv *env;
(*cachedJVM)->AttachCurrentThread(cachedJVM, (void **)&env, NULL);
jclass clz = (*env)->FindClass(env, "unicorn/Unicorn");
if ((*env)->ExceptionCheck(env)) {
return false;
}
jboolean res = (*env)->CallStaticBooleanMethod(env, clz, invokeMemInvalidCallbacks, (jlong)handle, (int)type, (jlong)address, (int)size, (jlong)value);
(*cachedJVM)->DetachCurrentThread(cachedJVM);
return res;
}
static void throwException(JNIEnv *env, uc_err err) {
//throw exception
jclass clazz = (*env)->FindClass(env, "unicorn/UnicornException");
if (err != UC_ERR_OK) {
const char *msg = uc_strerror(err);
(*env)->ThrowNew(env, clazz, msg);
}
}
static uch getHandle(JNIEnv *env, jobject self) {
static int haveFid = 0;
static jfieldID fid;
if (haveFid == 0) {
//cache the field id
jclass clazz = (*env)->GetObjectClass(env, self);
fid = (*env)->GetFieldID(env, clazz, "handle", "J");
haveFid = 1;
}
return (uch)(*env)->GetLongField(env, self, fid);
}
/*
* Class: unicorn_Unicorn
* Method: open
* Signature: (II)J
*/
JNIEXPORT jlong JNICALL Java_unicorn_Unicorn_open
(JNIEnv *env, jobject self, jint arch, jint mode) {
uch handle = -1;
uc_err err = uc_open((uc_arch)arch, (uc_mode)mode, &handle);
if (err != UC_ERR_OK) {
throwException(env, err);
}
return (jlong)handle;
}
/*
* Class: unicorn_Unicorn
* Method: version
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_unicorn_Unicorn_version
(JNIEnv *env, jclass clz) {
return (jint)uc_version(NULL, NULL);
}
/*
* Class: unicorn_Unicorn
* Method: arch_supported
* Signature: (I)Z
*/
JNIEXPORT jboolean JNICALL Java_unicorn_Unicorn_arch_1supported
(JNIEnv *env, jclass clz, jint arch) {
return (jboolean)(uc_arch_supported((uc_arch)arch) != 0);
}
/*
* Class: unicorn_Unicorn
* Method: close
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_unicorn_Unicorn_close
(JNIEnv *env, jobject self) {
uch handle = getHandle(env, self);
uc_close(&handle);
}
/*
* Class: unicorn_Unicorn
* Method: errno
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_unicorn_Unicorn_errno
(JNIEnv *env, jobject self) {
uch handle = getHandle(env, self);
return (jint)uc_errno(handle);
}
/*
* Class: unicorn_Unicorn
* Method: strerror
* Signature: (I)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_unicorn_Unicorn_strerror
(JNIEnv *env, jclass clz, jint code) {
const char *err = uc_strerror((int)code);
jstring s = (*env)->NewStringUTF(env, err);
return s;
}
/*
* Class: unicorn_Unicorn
* Method: reg_write
* Signature: (I[B)V
*/
JNIEXPORT void JNICALL Java_unicorn_Unicorn_reg_1write
(JNIEnv *env, jobject self, jint regid, jbyteArray value) {
uch handle = getHandle(env, self);
jbyte *array = (*env)->GetByteArrayElements(env, value, NULL);
uc_err err = uc_reg_write(handle, (int)regid, (void *)array);
if (err != UC_ERR_OK) {
throwException(env, err);
}
(*env)->ReleaseByteArrayElements(env, value, array, JNI_ABORT);
}
/*
* Class: unicorn_Unicorn
* Method: reg_read
* Signature: (II)[B
*/
JNIEXPORT jbyteArray JNICALL Java_unicorn_Unicorn_reg_1read
(JNIEnv *env, jobject self, jint regid, jint regsz) {
uch handle = getHandle(env, self);
jbyteArray regval = (*env)->NewByteArray(env, (jsize)regsz);
jbyte *array = (*env)->GetByteArrayElements(env, regval, NULL);
uc_err err = uc_reg_read(handle, (int)regid, (void *)array);
if (err != UC_ERR_OK) {
throwException(env, err);
}
(*env)->ReleaseByteArrayElements(env, regval, array, 0);
return regval;
}
/*
* Class: unicorn_Unicorn
* Method: mem_write
* Signature: (J[B)V
*/
JNIEXPORT void JNICALL Java_unicorn_Unicorn_mem_1write
(JNIEnv *env , jobject self, jlong address, jbyteArray bytes) {
uch handle = getHandle(env, self);
jbyte *array = (*env)->GetByteArrayElements(env, bytes, NULL);
jsize size = (*env)->GetArrayLength(env, bytes);
uc_err err = uc_mem_write(handle, (uint64_t)address, (uint8_t *)array, (size_t)size);
if (err != UC_ERR_OK) {
throwException(env, err);
}
(*env)->ReleaseByteArrayElements(env, bytes, array, JNI_ABORT);
}
/*
* Class: unicorn_Unicorn
* Method: mem_read
* Signature: (JJ)[B
*/
JNIEXPORT jbyteArray JNICALL Java_unicorn_Unicorn_mem_1read
(JNIEnv *env, jobject self, jlong address, jlong size) {
uch handle = getHandle(env, self);
jbyteArray bytes = (*env)->NewByteArray(env, (jsize)size);
jbyte *array = (*env)->GetByteArrayElements(env, bytes, NULL);
uc_err err = uc_mem_read(handle, (uint64_t)address, (uint8_t *)array, (size_t)size);
if (err != UC_ERR_OK) {
throwException(env, err);
}
(*env)->ReleaseByteArrayElements(env, bytes, array, 0);
return bytes;
}
/*
* Class: unicorn_Unicorn
* Method: emu_start
* Signature: (JJJJ)V
*/
JNIEXPORT void JNICALL Java_unicorn_Unicorn_emu_1start
(JNIEnv *env, jobject self, jlong begin, jlong until, jlong timeout, jlong count) {
uch handle = getHandle(env, self);
uc_err err = uc_emu_start(handle, (uint64_t)begin, (uint64_t)until, (uint64_t)timeout, (size_t)count);
if (err != UC_ERR_OK) {
throwException(env, err);
}
}
/*
* Class: unicorn_Unicorn
* Method: emu_stop
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_unicorn_Unicorn_emu_1stop
(JNIEnv *env, jobject self) {
uch handle = getHandle(env, self);
uc_err err = uc_emu_stop(handle);
if (err != UC_ERR_OK) {
throwException(env, err);
}
}
/*
* Class: unicorn_Unicorn
* Method: registerHook
* Signature: (JI)J
*/
JNIEXPORT jlong JNICALL Java_unicorn_Unicorn_registerHook__JI
(JNIEnv *env, jclass clz, jlong handle, jint type) {
uch h2 = 0;
uc_err err = 0;
switch (type) {
case UC_HOOK_INTR: // Hook all interrupt events
if (invokeInterruptCallbacks == 0) {
invokeInterruptCallbacks = (*env)->GetStaticMethodID(env, clz, "invokeInterruptCallbacks", "(JI)V");
}
err = uc_hook_add((uch)handle, &h2, (uc_hook_t)type, cb_hookintr, env);
break;
case UC_HOOK_MEM_INVALID: // Hook for all invalid memory access events
if (invokeMemInvalidCallbacks == 0) {
invokeMemInvalidCallbacks = (*env)->GetStaticMethodID(env, clz, "invokeMemInvalidCallbacks", "(JIJIJ)Z");
}
err = uc_hook_add((uch)handle, &h2, (uc_hook_t)type, cb_eventmem, env);
break;
}
return (jlong)h2;
}
/*
* Class: unicorn_Unicorn
* Method: registerHook
* Signature: (JII)J
*/
JNIEXPORT jlong JNICALL Java_unicorn_Unicorn_registerHook__JII
(JNIEnv *env, jclass clz, jlong handle, jint type, jint arg1) {
uch h2 = 0;
uc_err err = 0;
switch (type) {
case UC_HOOK_INSN: // Hook a particular instruction
switch (arg1) {
case UC_X86_INS_OUT:
if (invokeOutCallbacks == 0) {
invokeOutCallbacks = (*env)->GetStaticMethodID(env, clz, "invokeOutCallbacks", "(JIII)V");
}
err = uc_hook_add((uch)handle, &h2, (uc_hook_t)type, cb_insn_out, env, arg1);
case UC_X86_INS_IN:
if (invokeInCallbacks == 0) {
invokeInCallbacks = (*env)->GetStaticMethodID(env, clz, "invokeInCallbacks", "(JII)I");
}
err = uc_hook_add((uch)handle, &h2, (uc_hook_t)type, cb_insn_in, env, arg1);
case UC_X86_INS_SYSENTER:
case UC_X86_INS_SYSCALL:
if (invokeSyscallCallbacks == 0) {
invokeSyscallCallbacks = (*env)->GetStaticMethodID(env, clz, "invokeSyscallCallbacks", "(J)V");
}
err = uc_hook_add((uch)handle, &h2, (uc_hook_t)type, cb_insn_syscall, env, arg1);
}
break;
}
return (jlong)h2;
}
/*
* Class: unicorn_Unicorn
* Method: registerHook
* Signature: (JIJJ)J
*/
JNIEXPORT jlong JNICALL Java_unicorn_Unicorn_registerHook__JIJJ
(JNIEnv *env, jclass clz, jlong handle, jint type, jlong arg1, jlong arg2) {
uch h2 = 0;
uc_err err = 0;
switch (type) {
case UC_HOOK_CODE: // Hook a range of code
if (invokeCodeCallbacks == 0) {
invokeCodeCallbacks = (*env)->GetStaticMethodID(env, clz, "invokeCodeCallbacks", "(JJI)V");
}
err = uc_hook_add((uch)handle, &h2, (uc_hook_t)type, cb_hookcode, env, arg1, arg2);
break;
case UC_HOOK_BLOCK: // Hook basic blocks
if (invokeBlockCallbacks == 0) {
invokeBlockCallbacks = (*env)->GetStaticMethodID(env, clz, "invokeBlockCallbacks", "(JJI)V");
}
err = uc_hook_add((uch)handle, &h2, (uc_hook_t)type, cb_hookblock, env, arg1, arg2);
break;
case UC_HOOK_MEM_READ: // Hook all memory read events.
if (invokeReadCallbacks == 0) {
invokeReadCallbacks = (*env)->GetStaticMethodID(env, clz, "invokeReadCallbacks", "(JJI)V");
}
err = uc_hook_add((uch)handle, &h2, (uc_hook_t)type, cb_hookmem, env, arg1, arg2);
break;
case UC_HOOK_MEM_WRITE: // Hook all memory write events.
if (invokeWriteCallbacks == 0) {
invokeWriteCallbacks = (*env)->GetStaticMethodID(env, clz, "invokeWriteCallbacks", "(JJIJ)V");
}
err = uc_hook_add((uch)handle, &h2, (uc_hook_t)type, cb_hookmem, env, arg1, arg2);
break;
case UC_HOOK_MEM_READ_WRITE: // Hook all memory accesses (either READ or WRITE).
if (invokeReadWriteCallbacks == 0) {
invokeReadWriteCallbacks = (*env)->GetStaticMethodID(env, clz, "invokeReadWriteCallbacks", "(JIJIJ)V");
}
err = uc_hook_add((uch)handle, &h2, (uc_hook_t)type, cb_hookmem, env, arg1, arg2);
break;
}
return (jlong)h2;
}
/*
* Class: unicorn_Unicorn
* Method: hook_del
* Signature: (J)V
*/
JNIEXPORT void JNICALL Java_unicorn_Unicorn_hook_1del
(JNIEnv *env, jobject self, jlong hook) {
uch handle = getHandle(env, self);
uch h2 = (uch)hook;
//**** TODO remove hook from any internal hook tables as well
uc_err err = uc_hook_del(handle, &h2);
if (err != UC_ERR_OK) {
throwException(env, err);
}
}
/*
* Class: unicorn_Unicorn
* Method: mem_map
* Signature: (JJ)V
*/
JNIEXPORT void JNICALL Java_unicorn_Unicorn_mem_1map
(JNIEnv *env, jobject self, jlong address, jlong size) {
uch handle = getHandle(env, self);
uc_err err = uc_mem_map(handle, (uint64_t)address, (size_t)size);
if (err != UC_ERR_OK) {
throwException(env, err);
}
}