mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-01-08 22:25:27 +00:00
Java bindings (#709)
* Remove glib from samples makefile * support new APIs * reimplement register batch mode interface * stop using deprecated java API
This commit is contained in:
parent
d00f773e8e
commit
21ffaf7d10
|
@ -67,11 +67,11 @@ public class SampleNetworkAuditing {
|
||||||
if (intno != 0x80) {
|
if (intno != 0x80) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
long eax = toInt(uc.reg_read(Unicorn.UC_X86_REG_EAX, 4));
|
Long eax = (Long)uc.reg_read(Unicorn.UC_X86_REG_EAX);
|
||||||
long ebx = toInt(uc.reg_read(Unicorn.UC_X86_REG_EBX, 4));
|
Long ebx = (Long)uc.reg_read(Unicorn.UC_X86_REG_EBX);
|
||||||
long ecx = toInt(uc.reg_read(Unicorn.UC_X86_REG_ECX, 4));
|
Long ecx = (Long)uc.reg_read(Unicorn.UC_X86_REG_ECX);
|
||||||
long edx = toInt(uc.reg_read(Unicorn.UC_X86_REG_EDX, 4));
|
Long edx = (Long)uc.reg_read(Unicorn.UC_X86_REG_EDX);
|
||||||
long eip = toInt(uc.reg_read(Unicorn.UC_X86_REG_EIP, 4));
|
Long eip = (Long)uc.reg_read(Unicorn.UC_X86_REG_EIP);
|
||||||
|
|
||||||
// System.out.printf(">>> INTERRUPT %d\n", toInt(eax));
|
// System.out.printf(">>> INTERRUPT %d\n", toInt(eax));
|
||||||
|
|
||||||
|
@ -112,8 +112,8 @@ public class SampleNetworkAuditing {
|
||||||
long mode = edx;
|
long mode = edx;
|
||||||
String filename = read_string(uc, filename_addr);
|
String filename = read_string(uc, filename_addr);
|
||||||
|
|
||||||
int dummy_fd = get_id();
|
Long dummy_fd = new Long(get_id());
|
||||||
uc.reg_write(Unicorn.UC_X86_REG_EAX, toBytes(dummy_fd));
|
uc.reg_write(Unicorn.UC_X86_REG_EAX, dummy_fd);
|
||||||
|
|
||||||
String msg = String.format("open file (filename=%s flags=%d mode=%d) with fd(%d)", filename, flags, mode, dummy_fd);
|
String msg = String.format("open file (filename=%s flags=%d mode=%d) with fd(%d)", filename, flags, mode, dummy_fd);
|
||||||
|
|
||||||
|
@ -133,8 +133,8 @@ public class SampleNetworkAuditing {
|
||||||
}
|
}
|
||||||
else if (eax == 102) { // sys_socketcall
|
else if (eax == 102) { // sys_socketcall
|
||||||
// ref: http://www.skyfree.org/linux/kernel_network/socket.html
|
// ref: http://www.skyfree.org/linux/kernel_network/socket.html
|
||||||
long call = toInt(uc.reg_read(Unicorn.UC_X86_REG_EBX, 4));
|
Long call = (Long)uc.reg_read(Unicorn.UC_X86_REG_EBX);
|
||||||
long args = toInt(uc.reg_read(Unicorn.UC_X86_REG_ECX, 4));
|
Long args = (Long)uc.reg_read(Unicorn.UC_X86_REG_ECX);
|
||||||
|
|
||||||
// int sys_socketcall(int call, unsigned long *args)
|
// int sys_socketcall(int call, unsigned long *args)
|
||||||
if (call == 1) { // sys_socket
|
if (call == 1) { // sys_socket
|
||||||
|
@ -144,8 +144,8 @@ public class SampleNetworkAuditing {
|
||||||
long sock_type = toInt(uc.mem_read(args + SIZE_REG, SIZE_REG));
|
long sock_type = toInt(uc.mem_read(args + SIZE_REG, SIZE_REG));
|
||||||
long protocol = toInt(uc.mem_read(args + SIZE_REG * 2, SIZE_REG));
|
long protocol = toInt(uc.mem_read(args + SIZE_REG * 2, SIZE_REG));
|
||||||
|
|
||||||
int dummy_fd = get_id();
|
Long dummy_fd = new Long(get_id());
|
||||||
uc.reg_write(Unicorn.UC_X86_REG_EAX, toBytes(dummy_fd));
|
uc.reg_write(Unicorn.UC_X86_REG_EAX, dummy_fd.intValue());
|
||||||
|
|
||||||
if (family == 2) { // AF_INET
|
if (family == 2) { // AF_INET
|
||||||
String msg = String.format("create socket (%s, %s) with fd(%d)", ADDR_FAMILY.get(family), SOCKET_TYPES.get(sock_type), dummy_fd);
|
String msg = String.format("create socket (%s, %s) with fd(%d)", ADDR_FAMILY.get(family), SOCKET_TYPES.get(sock_type), dummy_fd);
|
||||||
|
@ -401,7 +401,7 @@ public class SampleNetworkAuditing {
|
||||||
mu.mem_write(ADDRESS, code);
|
mu.mem_write(ADDRESS, code);
|
||||||
|
|
||||||
// initialize stack
|
// initialize stack
|
||||||
mu.reg_write(Unicorn.UC_X86_REG_ESP, toBytes(ADDRESS + 0x200000));
|
mu.reg_write(Unicorn.UC_X86_REG_ESP, new Long(ADDRESS + 0x200000));
|
||||||
|
|
||||||
// handle interrupt ourself
|
// handle interrupt ourself
|
||||||
mu.hook_add(new MyInterruptHook(), null);
|
mu.hook_add(new MyInterruptHook(), null);
|
||||||
|
|
|
@ -40,10 +40,10 @@ public class Sample_arm {
|
||||||
static void test_arm()
|
static void test_arm()
|
||||||
{
|
{
|
||||||
|
|
||||||
byte[] r0 = {0x34, 0x12, 0, 0}; // R0 register
|
Long r0 = new Long(0x1234); // R0 register
|
||||||
byte[] r2 = {(byte)0x89, 0x67, 0, 0}; // R1 register
|
Long r2 = new Long(0x6789); // R1 register
|
||||||
byte[] r3 = {0x33, 0x33, 0, 0}; // R2 register
|
Long r3 = new Long(0x3333); // R2 register
|
||||||
byte[] r1; // R1 register
|
Long r1; // R1 register
|
||||||
|
|
||||||
System.out.print("Emulate ARM code\n");
|
System.out.print("Emulate ARM code\n");
|
||||||
|
|
||||||
|
@ -74,10 +74,10 @@ public class Sample_arm {
|
||||||
// now print out some registers
|
// now print out some registers
|
||||||
System.out.print(">>> Emulation done. Below is the CPU context\n");
|
System.out.print(">>> Emulation done. Below is the CPU context\n");
|
||||||
|
|
||||||
r0 = u.reg_read(Unicorn.UC_ARM_REG_R0, 4);
|
r0 = (Long)u.reg_read(Unicorn.UC_ARM_REG_R0);
|
||||||
r1 = u.reg_read(Unicorn.UC_ARM_REG_R1, 4);
|
r1 = (Long)u.reg_read(Unicorn.UC_ARM_REG_R1);
|
||||||
System.out.print(String.format(">>> R0 = 0x%x\n", toInt(r0)));
|
System.out.print(String.format(">>> R0 = 0x%x\n", r0.intValue()));
|
||||||
System.out.print(String.format(">>> R1 = 0x%x\n", toInt(r1)));
|
System.out.print(String.format(">>> R1 = 0x%x\n", r1.intValue()));
|
||||||
|
|
||||||
u.close();
|
u.close();
|
||||||
}
|
}
|
||||||
|
@ -85,7 +85,7 @@ public class Sample_arm {
|
||||||
static void test_thumb()
|
static void test_thumb()
|
||||||
{
|
{
|
||||||
|
|
||||||
byte[] sp = {0x34, 0x12, 0, 0}; // R0 register
|
Long sp = new Long(0x1234); // R0 register
|
||||||
|
|
||||||
System.out.print("Emulate THUMB code\n");
|
System.out.print("Emulate THUMB code\n");
|
||||||
|
|
||||||
|
@ -114,8 +114,8 @@ public class Sample_arm {
|
||||||
// now print out some registers
|
// now print out some registers
|
||||||
System.out.print(">>> Emulation done. Below is the CPU context\n");
|
System.out.print(">>> Emulation done. Below is the CPU context\n");
|
||||||
|
|
||||||
sp = u.reg_read(Unicorn.UC_ARM_REG_SP, 4);
|
sp = (Long)u.reg_read(Unicorn.UC_ARM_REG_SP);
|
||||||
System.out.print(String.format(">>> SP = 0x%x\n", toInt(sp)));
|
System.out.print(String.format(">>> SP = 0x%x\n", sp.intValue()));
|
||||||
|
|
||||||
u.close();
|
u.close();
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,9 +69,9 @@ public class Sample_arm64 {
|
||||||
static void test_arm64()
|
static void test_arm64()
|
||||||
{
|
{
|
||||||
|
|
||||||
byte[] x11 = toBytes(0x1234); // X11 register
|
Long x11 = new Long(0x1234); // X11 register
|
||||||
byte[] x13 = toBytes(0x6789); // X13 register
|
Long x13 = new Long(0x6789); // X13 register
|
||||||
byte[] x15 = toBytes(0x3333); // X15 register
|
Long x15 = new Long(0x3333); // X15 register
|
||||||
|
|
||||||
System.out.print("Emulate ARM64 code\n");
|
System.out.print("Emulate ARM64 code\n");
|
||||||
|
|
||||||
|
@ -102,8 +102,8 @@ public class Sample_arm64 {
|
||||||
// now print out some registers
|
// now print out some registers
|
||||||
System.out.print(">>> Emulation done. Below is the CPU context\n");
|
System.out.print(">>> Emulation done. Below is the CPU context\n");
|
||||||
|
|
||||||
x11 = u.reg_read(Unicorn.UC_ARM64_REG_X11, 8);
|
x11 = (Long)u.reg_read(Unicorn.UC_ARM64_REG_X11);
|
||||||
System.out.print(String.format(">>> X11 = 0x%x\n", toInt(x11)));
|
System.out.print(String.format(">>> X11 = 0x%x\n", x11.longValue()));
|
||||||
|
|
||||||
u.close();
|
u.close();
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,26 +68,26 @@ public class Sample_m68k {
|
||||||
|
|
||||||
static void test_m68k()
|
static void test_m68k()
|
||||||
{
|
{
|
||||||
byte[] d0 = toBytes(0x0000); // d0 data register
|
Long d0 = new Long(0x0000); // d0 data register
|
||||||
byte[] d1 = toBytes(0x0000); // d1 data register
|
Long d1 = new Long(0x0000); // d1 data register
|
||||||
byte[] d2 = toBytes(0x0000); // d2 data register
|
Long d2 = new Long(0x0000); // d2 data register
|
||||||
byte[] d3 = toBytes(0x0000); // d3 data register
|
Long d3 = new Long(0x0000); // d3 data register
|
||||||
byte[] d4 = toBytes(0x0000); // d4 data register
|
Long d4 = new Long(0x0000); // d4 data register
|
||||||
byte[] d5 = toBytes(0x0000); // d5 data register
|
Long d5 = new Long(0x0000); // d5 data register
|
||||||
byte[] d6 = toBytes(0x0000); // d6 data register
|
Long d6 = new Long(0x0000); // d6 data register
|
||||||
byte[] d7 = toBytes(0x0000); // d7 data register
|
Long d7 = new Long(0x0000); // d7 data register
|
||||||
|
|
||||||
byte[] a0 = toBytes(0x0000); // a0 address register
|
Long a0 = new Long(0x0000); // a0 address register
|
||||||
byte[] a1 = toBytes(0x0000); // a1 address register
|
Long a1 = new Long(0x0000); // a1 address register
|
||||||
byte[] a2 = toBytes(0x0000); // a2 address register
|
Long a2 = new Long(0x0000); // a2 address register
|
||||||
byte[] a3 = toBytes(0x0000); // a3 address register
|
Long a3 = new Long(0x0000); // a3 address register
|
||||||
byte[] a4 = toBytes(0x0000); // a4 address register
|
Long a4 = new Long(0x0000); // a4 address register
|
||||||
byte[] a5 = toBytes(0x0000); // a5 address register
|
Long a5 = new Long(0x0000); // a5 address register
|
||||||
byte[] a6 = toBytes(0x0000); // a6 address register
|
Long a6 = new Long(0x0000); // a6 address register
|
||||||
byte[] a7 = toBytes(0x0000); // a6 address register
|
Long a7 = new Long(0x0000); // a6 address register
|
||||||
|
|
||||||
byte[] pc = toBytes(0x0000); // program counter
|
Long pc = new Long(0x0000); // program counter
|
||||||
byte[] sr = toBytes(0x0000); // status register
|
Long sr = new Long(0x0000); // status register
|
||||||
|
|
||||||
System.out.print("Emulate M68K code\n");
|
System.out.print("Emulate M68K code\n");
|
||||||
|
|
||||||
|
@ -135,37 +135,37 @@ public class Sample_m68k {
|
||||||
// now print out some registers
|
// now print out some registers
|
||||||
System.out.print(">>> Emulation done. Below is the CPU context\n");
|
System.out.print(">>> Emulation done. Below is the CPU context\n");
|
||||||
|
|
||||||
d0 = u.reg_read(Unicorn.UC_M68K_REG_D0, 4);
|
d0 = (Long)u.reg_read(Unicorn.UC_M68K_REG_D0);
|
||||||
d1 = u.reg_read(Unicorn.UC_M68K_REG_D1, 4);
|
d1 = (Long)u.reg_read(Unicorn.UC_M68K_REG_D1);
|
||||||
d2 = u.reg_read(Unicorn.UC_M68K_REG_D2, 4);
|
d2 = (Long)u.reg_read(Unicorn.UC_M68K_REG_D2);
|
||||||
d3 = u.reg_read(Unicorn.UC_M68K_REG_D3, 4);
|
d3 = (Long)u.reg_read(Unicorn.UC_M68K_REG_D3);
|
||||||
d4 = u.reg_read(Unicorn.UC_M68K_REG_D4, 4);
|
d4 = (Long)u.reg_read(Unicorn.UC_M68K_REG_D4);
|
||||||
d5 = u.reg_read(Unicorn.UC_M68K_REG_D5, 4);
|
d5 = (Long)u.reg_read(Unicorn.UC_M68K_REG_D5);
|
||||||
d6 = u.reg_read(Unicorn.UC_M68K_REG_D6, 4);
|
d6 = (Long)u.reg_read(Unicorn.UC_M68K_REG_D6);
|
||||||
d7 = u.reg_read(Unicorn.UC_M68K_REG_D7, 4);
|
d7 = (Long)u.reg_read(Unicorn.UC_M68K_REG_D7);
|
||||||
|
|
||||||
a0 = u.reg_read(Unicorn.UC_M68K_REG_A0, 4);
|
a0 = (Long)u.reg_read(Unicorn.UC_M68K_REG_A0);
|
||||||
a1 = u.reg_read(Unicorn.UC_M68K_REG_A1, 4);
|
a1 = (Long)u.reg_read(Unicorn.UC_M68K_REG_A1);
|
||||||
a2 = u.reg_read(Unicorn.UC_M68K_REG_A2, 4);
|
a2 = (Long)u.reg_read(Unicorn.UC_M68K_REG_A2);
|
||||||
a3 = u.reg_read(Unicorn.UC_M68K_REG_A3, 4);
|
a3 = (Long)u.reg_read(Unicorn.UC_M68K_REG_A3);
|
||||||
a4 = u.reg_read(Unicorn.UC_M68K_REG_A4, 4);
|
a4 = (Long)u.reg_read(Unicorn.UC_M68K_REG_A4);
|
||||||
a5 = u.reg_read(Unicorn.UC_M68K_REG_A5, 4);
|
a5 = (Long)u.reg_read(Unicorn.UC_M68K_REG_A5);
|
||||||
a6 = u.reg_read(Unicorn.UC_M68K_REG_A6, 4);
|
a6 = (Long)u.reg_read(Unicorn.UC_M68K_REG_A6);
|
||||||
a7 = u.reg_read(Unicorn.UC_M68K_REG_A7, 4);
|
a7 = (Long)u.reg_read(Unicorn.UC_M68K_REG_A7);
|
||||||
|
|
||||||
pc = u.reg_read(Unicorn.UC_M68K_REG_PC, 4);
|
pc = (Long)u.reg_read(Unicorn.UC_M68K_REG_PC);
|
||||||
sr = u.reg_read(Unicorn.UC_M68K_REG_SR, 4);
|
sr = (Long)u.reg_read(Unicorn.UC_M68K_REG_SR);
|
||||||
|
|
||||||
System.out.print(String.format(">>> A0 = 0x%x\t\t>>> D0 = 0x%x\n", toInt(a0), toInt(d0)));
|
System.out.print(String.format(">>> A0 = 0x%x\t\t>>> D0 = 0x%x\n", a0.intValue(), d0.intValue()));
|
||||||
System.out.print(String.format(">>> A1 = 0x%x\t\t>>> D1 = 0x%x\n", toInt(a1), toInt(d1)));
|
System.out.print(String.format(">>> A1 = 0x%x\t\t>>> D1 = 0x%x\n", a1.intValue(), d1.intValue()));
|
||||||
System.out.print(String.format(">>> A2 = 0x%x\t\t>>> D2 = 0x%x\n", toInt(a2), toInt(d2)));
|
System.out.print(String.format(">>> A2 = 0x%x\t\t>>> D2 = 0x%x\n", a2.intValue(), d2.intValue()));
|
||||||
System.out.print(String.format(">>> A3 = 0x%x\t\t>>> D3 = 0x%x\n", toInt(a3), toInt(d3)));
|
System.out.print(String.format(">>> A3 = 0x%x\t\t>>> D3 = 0x%x\n", a3.intValue(), d3.intValue()));
|
||||||
System.out.print(String.format(">>> A4 = 0x%x\t\t>>> D4 = 0x%x\n", toInt(a4), toInt(d4)));
|
System.out.print(String.format(">>> A4 = 0x%x\t\t>>> D4 = 0x%x\n", a4.intValue(), d4.intValue()));
|
||||||
System.out.print(String.format(">>> A5 = 0x%x\t\t>>> D5 = 0x%x\n", toInt(a5), toInt(d5)));
|
System.out.print(String.format(">>> A5 = 0x%x\t\t>>> D5 = 0x%x\n", a5.intValue(), d5.intValue()));
|
||||||
System.out.print(String.format(">>> A6 = 0x%x\t\t>>> D6 = 0x%x\n", toInt(a6), toInt(d6)));
|
System.out.print(String.format(">>> A6 = 0x%x\t\t>>> D6 = 0x%x\n", a6.intValue(), d6.intValue()));
|
||||||
System.out.print(String.format(">>> A7 = 0x%x\t\t>>> D7 = 0x%x\n", toInt(a7), toInt(d7)));
|
System.out.print(String.format(">>> A7 = 0x%x\t\t>>> D7 = 0x%x\n", a7.intValue(), d7.intValue()));
|
||||||
System.out.print(String.format(">>> PC = 0x%x\n", toInt(pc)));
|
System.out.print(String.format(">>> PC = 0x%x\n", pc.intValue()));
|
||||||
System.out.print(String.format(">>> SR = 0x%x\n", toInt(sr)));
|
System.out.print(String.format(">>> SR = 0x%x\n", sr.intValue()));
|
||||||
|
|
||||||
u.close();
|
u.close();
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,7 @@ public class Sample_mips {
|
||||||
static void test_mips_eb()
|
static void test_mips_eb()
|
||||||
{
|
{
|
||||||
|
|
||||||
byte[] r1 = toBytes(0x6789); // R1 register
|
Long r1 = new Long(0x6789); // R1 register
|
||||||
|
|
||||||
System.out.print("Emulate MIPS code (big-endian)\n");
|
System.out.print("Emulate MIPS code (big-endian)\n");
|
||||||
|
|
||||||
|
@ -99,15 +99,15 @@ public class Sample_mips {
|
||||||
// now print out some registers
|
// now print out some registers
|
||||||
System.out.print(">>> Emulation done. Below is the CPU context\n");
|
System.out.print(">>> Emulation done. Below is the CPU context\n");
|
||||||
|
|
||||||
r1 = u.reg_read(Unicorn.UC_MIPS_REG_1, 4);
|
r1 = (Long)u.reg_read(Unicorn.UC_MIPS_REG_1);
|
||||||
System.out.print(String.format(">>> R1 = 0x%x\n", toInt(r1)));
|
System.out.print(String.format(">>> R1 = 0x%x\n", r1.intValue()));
|
||||||
|
|
||||||
u.close();
|
u.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_mips_el()
|
static void test_mips_el()
|
||||||
{
|
{
|
||||||
byte[] r1 = toBytes(0x6789); // R1 register
|
Long r1 = new Long(0x6789); // R1 register
|
||||||
|
|
||||||
System.out.print("===========================\n");
|
System.out.print("===========================\n");
|
||||||
System.out.print("Emulate MIPS code (little-endian)\n");
|
System.out.print("Emulate MIPS code (little-endian)\n");
|
||||||
|
@ -137,8 +137,8 @@ public class Sample_mips {
|
||||||
// now print out some registers
|
// now print out some registers
|
||||||
System.out.print(">>> Emulation done. Below is the CPU context\n");
|
System.out.print(">>> Emulation done. Below is the CPU context\n");
|
||||||
|
|
||||||
r1 = u.reg_read(Unicorn.UC_MIPS_REG_1, 4);
|
r1 = (Long)u.reg_read(Unicorn.UC_MIPS_REG_1);
|
||||||
System.out.print(String.format(">>> R1 = 0x%x\n", toInt(r1)));
|
System.out.print(String.format(">>> R1 = 0x%x\n", r1.intValue()));
|
||||||
|
|
||||||
u.close();
|
u.close();
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,9 +69,9 @@ public class Sample_sparc {
|
||||||
|
|
||||||
static void test_sparc()
|
static void test_sparc()
|
||||||
{
|
{
|
||||||
byte[] g1 = toBytes(0x1230); // G1 register
|
Long g1 = new Long(0x1230); // G1 register
|
||||||
byte[] g2 = toBytes(0x6789); // G2 register
|
Long g2 = new Long(0x6789); // G2 register
|
||||||
byte[] g3 = toBytes(0x5555); // G3 register
|
Long g3 = new Long(0x5555); // G3 register
|
||||||
|
|
||||||
System.out.print("Emulate SPARC code\n");
|
System.out.print("Emulate SPARC code\n");
|
||||||
|
|
||||||
|
@ -102,8 +102,8 @@ public class Sample_sparc {
|
||||||
// now print out some registers
|
// now print out some registers
|
||||||
System.out.print(">>> Emulation done. Below is the CPU context\n");
|
System.out.print(">>> Emulation done. Below is the CPU context\n");
|
||||||
|
|
||||||
g3 = u.reg_read(Unicorn.UC_SPARC_REG_G3, 4);
|
g3 = (Long)u.reg_read(Unicorn.UC_SPARC_REG_G3);
|
||||||
System.out.print(String.format(">>> G3 = 0x%x\n", toInt(g3)));
|
System.out.print(String.format(">>> G3 = 0x%x\n", g3.intValue()));
|
||||||
|
|
||||||
u.close();
|
u.close();
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,8 +74,8 @@ public class Sample_x86 {
|
||||||
public void hook(Unicorn u, long address, int size, Object user_data) {
|
public void hook(Unicorn u, long address, int size, Object user_data) {
|
||||||
System.out.printf(">>> Tracing instruction at 0x%x, instruction size = 0x%x\n", address, size);
|
System.out.printf(">>> Tracing instruction at 0x%x, instruction size = 0x%x\n", address, size);
|
||||||
|
|
||||||
byte eflags[] = u.reg_read(Unicorn.UC_X86_REG_EFLAGS, 4);
|
Long eflags = (Long)u.reg_read(Unicorn.UC_X86_REG_EFLAGS);
|
||||||
System.out.printf(">>> --- EFLAGS is 0x%x\n", toInt(eflags));
|
System.out.printf(">>> --- EFLAGS is 0x%x\n", eflags.intValue());
|
||||||
|
|
||||||
// Uncomment below code to stop the emulation using uc_emu_stop()
|
// Uncomment below code to stop the emulation using uc_emu_stop()
|
||||||
// if (address == 0x1000009)
|
// if (address == 0x1000009)
|
||||||
|
@ -97,9 +97,9 @@ public class Sample_x86 {
|
||||||
// callback for tracing instruction
|
// callback for tracing instruction
|
||||||
private static class MyCode64Hook implements CodeHook {
|
private static class MyCode64Hook implements CodeHook {
|
||||||
public void hook(Unicorn u, long address, int size, Object user_data) {
|
public void hook(Unicorn u, long address, int size, Object user_data) {
|
||||||
byte[] r_rip = u.reg_read(Unicorn.UC_X86_REG_RIP, 8);
|
Long r_rip = (Long)u.reg_read(Unicorn.UC_X86_REG_RIP);
|
||||||
System.out.printf(">>> Tracing instruction at 0x%x, instruction size = 0x%x\n", address, size);
|
System.out.printf(">>> Tracing instruction at 0x%x, instruction size = 0x%x\n", address, size);
|
||||||
System.out.printf(">>> RIP is 0x%x\n", toInt(r_rip));
|
System.out.printf(">>> RIP is 0x%x\n", r_rip.longValue());
|
||||||
|
|
||||||
// Uncomment below code to stop the emulation using uc_emu_stop()
|
// Uncomment below code to stop the emulation using uc_emu_stop()
|
||||||
// if (address == 0x1000009)
|
// if (address == 0x1000009)
|
||||||
|
@ -125,9 +125,9 @@ public class Sample_x86 {
|
||||||
// this returns the data read from the port
|
// this returns the data read from the port
|
||||||
private static class MyInHook implements InHook {
|
private static class MyInHook implements InHook {
|
||||||
public int hook(Unicorn u, int port, int size, Object user_data) {
|
public int hook(Unicorn u, int port, int size, Object user_data) {
|
||||||
byte[] r_eip = u.reg_read(Unicorn.UC_X86_REG_EIP, 4);
|
Long r_eip = (Long)u.reg_read(Unicorn.UC_X86_REG_EIP);
|
||||||
|
|
||||||
System.out.printf("--- reading from port 0x%x, size: %d, address: 0x%x\n", port, size, toInt(r_eip));
|
System.out.printf("--- reading from port 0x%x, size: %d, address: 0x%x\n", port, size, r_eip.intValue());
|
||||||
|
|
||||||
switch(size) {
|
switch(size) {
|
||||||
case 1:
|
case 1:
|
||||||
|
@ -147,32 +147,32 @@ public class Sample_x86 {
|
||||||
// callback for OUT instruction (X86).
|
// callback for OUT instruction (X86).
|
||||||
private static class MyOutHook implements OutHook {
|
private static class MyOutHook implements OutHook {
|
||||||
public void hook(Unicorn u, int port, int size, int value, Object user) {
|
public void hook(Unicorn u, int port, int size, int value, Object user) {
|
||||||
byte[] eip = u.reg_read(Unicorn.UC_X86_REG_EIP, 4);
|
Long eip = (Long)u.reg_read(Unicorn.UC_X86_REG_EIP);
|
||||||
byte[] tmp = null;
|
Long tmp = null;
|
||||||
System.out.printf("--- writing to port 0x%x, size: %d, value: 0x%x, address: 0x%x\n", port, size, value, toInt(eip));
|
System.out.printf("--- writing to port 0x%x, size: %d, value: 0x%x, address: 0x%x\n", port, size, value, eip.intValue());
|
||||||
|
|
||||||
// confirm that value is indeed the value of AL/AX/EAX
|
// confirm that value is indeed the value of AL/AX/EAX
|
||||||
switch(size) {
|
switch(size) {
|
||||||
default:
|
default:
|
||||||
return; // should never reach this
|
return; // should never reach this
|
||||||
case 1:
|
case 1:
|
||||||
tmp = u.reg_read(Unicorn.UC_X86_REG_AL, 1);
|
tmp = (Long)u.reg_read(Unicorn.UC_X86_REG_AL);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
tmp = u.reg_read(Unicorn.UC_X86_REG_AX, 2);
|
tmp = (Long)u.reg_read(Unicorn.UC_X86_REG_AX);
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
tmp = u.reg_read(Unicorn.UC_X86_REG_EAX, 4);
|
tmp = (Long)u.reg_read(Unicorn.UC_X86_REG_EAX);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
System.out.printf("--- register value = 0x%x\n", toInt(tmp));
|
System.out.printf("--- register value = 0x%x\n", tmp.intValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_i386() {
|
static void test_i386() {
|
||||||
byte r_ecx[] = {(byte)0x34, (byte)0x12, 0, 0}; //0x1234; // ECX register
|
Long r_ecx = new Long(0x1234); // ECX register
|
||||||
byte r_edx[] = {(byte)0x90, (byte)0x78, 0, 0}; //0x7890; // EDX register
|
Long r_edx = new Long(0x7890); // EDX register
|
||||||
|
|
||||||
System.out.print("Emulate i386 code\n");
|
System.out.print("Emulate i386 code\n");
|
||||||
|
|
||||||
|
@ -217,14 +217,14 @@ public class Sample_x86 {
|
||||||
// now print out some registers
|
// now print out some registers
|
||||||
System.out.print(">>> Emulation done. Below is the CPU context\n");
|
System.out.print(">>> Emulation done. Below is the CPU context\n");
|
||||||
|
|
||||||
r_ecx = uc.reg_read(Unicorn.UC_X86_REG_ECX, 4);
|
r_ecx = (Long)uc.reg_read(Unicorn.UC_X86_REG_ECX);
|
||||||
r_edx = uc.reg_read(Unicorn.UC_X86_REG_EDX, 4);
|
r_edx = (Long)uc.reg_read(Unicorn.UC_X86_REG_EDX);
|
||||||
System.out.printf(">>> ECX = 0x%x\n", toInt(r_ecx));
|
System.out.printf(">>> ECX = 0x%x\n", r_ecx.intValue());
|
||||||
System.out.printf(">>> EDX = 0x%x\n", toInt(r_edx));
|
System.out.printf(">>> EDX = 0x%x\n", r_edx.intValue());
|
||||||
|
|
||||||
// read from memory
|
// read from memory
|
||||||
try {
|
try {
|
||||||
byte tmp[] = uc.mem_read(ADDRESS, 4);
|
byte[] tmp = uc.mem_read(ADDRESS, 4);
|
||||||
System.out.printf(">>> Read 4 bytes from [0x%x] = 0x%x\n", ADDRESS, toInt(tmp));
|
System.out.printf(">>> Read 4 bytes from [0x%x] = 0x%x\n", ADDRESS, toInt(tmp));
|
||||||
} catch (UnicornException ex) {
|
} catch (UnicornException ex) {
|
||||||
System.out.printf(">>> Failed to read 4 bytes from [0x%x]\n", ADDRESS);
|
System.out.printf(">>> Failed to read 4 bytes from [0x%x]\n", ADDRESS);
|
||||||
|
@ -234,8 +234,8 @@ public class Sample_x86 {
|
||||||
|
|
||||||
static void test_i386_inout()
|
static void test_i386_inout()
|
||||||
{
|
{
|
||||||
byte[] r_eax = {0x34, 0x12, 0, 0}; //0x1234; // EAX register
|
Long r_eax = new Long(0x1234); // ECX register
|
||||||
byte[] r_ecx = {(byte)0x89, 0x67, 0, 0}; //0x6789; // ECX register
|
Long r_ecx = new Long(0x6789); // EDX register
|
||||||
|
|
||||||
System.out.print("===================================\n");
|
System.out.print("===================================\n");
|
||||||
System.out.print("Emulate i386 code with IN/OUT instructions\n");
|
System.out.print("Emulate i386 code with IN/OUT instructions\n");
|
||||||
|
@ -270,10 +270,10 @@ public class Sample_x86 {
|
||||||
// now print out some registers
|
// now print out some registers
|
||||||
System.out.print(">>> Emulation done. Below is the CPU context\n");
|
System.out.print(">>> Emulation done. Below is the CPU context\n");
|
||||||
|
|
||||||
r_eax = u.reg_read(Unicorn.UC_X86_REG_EAX, 4);
|
r_eax = (Long)u.reg_read(Unicorn.UC_X86_REG_EAX);
|
||||||
r_ecx = u.reg_read(Unicorn.UC_X86_REG_ECX, 4);
|
r_ecx = (Long)u.reg_read(Unicorn.UC_X86_REG_ECX);
|
||||||
System.out.printf(">>> EAX = 0x%x\n", toInt(r_eax));
|
System.out.printf(">>> EAX = 0x%x\n", r_eax.intValue());
|
||||||
System.out.printf(">>> ECX = 0x%x\n", toInt(r_ecx));
|
System.out.printf(">>> ECX = 0x%x\n", r_ecx.intValue());
|
||||||
|
|
||||||
u.close();
|
u.close();
|
||||||
}
|
}
|
||||||
|
@ -309,8 +309,8 @@ public class Sample_x86 {
|
||||||
// emulate code that loop forever
|
// emulate code that loop forever
|
||||||
static void test_i386_loop()
|
static void test_i386_loop()
|
||||||
{
|
{
|
||||||
byte r_ecx[] = {(byte)0x34, (byte)0x12, 0, 0}; //0x1234; // ECX register
|
Long r_ecx = new Long(0x1234); // ECX register
|
||||||
byte r_edx[] = {(byte)0x90, (byte)0x78, 0, 0}; //0x7890; // EDX register
|
Long r_edx = new Long(0x7890); // EDX register
|
||||||
|
|
||||||
System.out.print("===================================\n");
|
System.out.print("===================================\n");
|
||||||
System.out.print("Emulate i386 code that loop forever\n");
|
System.out.print("Emulate i386 code that loop forever\n");
|
||||||
|
@ -335,10 +335,10 @@ public class Sample_x86 {
|
||||||
// now print out some registers
|
// now print out some registers
|
||||||
System.out.print(">>> Emulation done. Below is the CPU context\n");
|
System.out.print(">>> Emulation done. Below is the CPU context\n");
|
||||||
|
|
||||||
r_ecx = u.reg_read(Unicorn.UC_X86_REG_ECX, 4);
|
r_ecx = (Long)u.reg_read(Unicorn.UC_X86_REG_ECX);
|
||||||
r_edx = u.reg_read(Unicorn.UC_X86_REG_EDX, 4);
|
r_edx = (Long)u.reg_read(Unicorn.UC_X86_REG_EDX);
|
||||||
System.out.printf(">>> ECX = 0x%x\n", toInt(r_ecx));
|
System.out.printf(">>> ECX = 0x%x\n", r_ecx.intValue());
|
||||||
System.out.printf(">>> EDX = 0x%x\n", toInt(r_edx));
|
System.out.printf(">>> EDX = 0x%x\n", r_edx.intValue());
|
||||||
|
|
||||||
u.close();
|
u.close();
|
||||||
}
|
}
|
||||||
|
@ -346,8 +346,8 @@ public class Sample_x86 {
|
||||||
// emulate code that read invalid memory
|
// emulate code that read invalid memory
|
||||||
static void test_i386_invalid_mem_read()
|
static void test_i386_invalid_mem_read()
|
||||||
{
|
{
|
||||||
byte r_ecx[] = {(byte)0x34, (byte)0x12, 0, 0}; //0x1234; // ECX register
|
Long r_ecx = new Long(0x1234); // ECX register
|
||||||
byte r_edx[] = {(byte)0x90, (byte)0x78, 0, 0}; //0x7890; // EDX register
|
Long r_edx = new Long(0x7890); // EDX register
|
||||||
|
|
||||||
System.out.print("===================================\n");
|
System.out.print("===================================\n");
|
||||||
System.out.print("Emulate i386 code that read from invalid memory\n");
|
System.out.print("Emulate i386 code that read from invalid memory\n");
|
||||||
|
@ -382,10 +382,10 @@ public class Sample_x86 {
|
||||||
// now print out some registers
|
// now print out some registers
|
||||||
System.out.print(">>> Emulation done. Below is the CPU context\n");
|
System.out.print(">>> Emulation done. Below is the CPU context\n");
|
||||||
|
|
||||||
r_ecx = u.reg_read(Unicorn.UC_X86_REG_ECX, 4);
|
r_ecx = (Long)u.reg_read(Unicorn.UC_X86_REG_ECX);
|
||||||
r_edx = u.reg_read(Unicorn.UC_X86_REG_EDX, 4);
|
r_edx = (Long)u.reg_read(Unicorn.UC_X86_REG_EDX);
|
||||||
System.out.printf(">>> ECX = 0x%x\n", toInt(r_ecx));
|
System.out.printf(">>> ECX = 0x%x\n", r_ecx.intValue());
|
||||||
System.out.printf(">>> EDX = 0x%x\n", toInt(r_edx));
|
System.out.printf(">>> EDX = 0x%x\n", r_edx.intValue());
|
||||||
|
|
||||||
u.close();
|
u.close();
|
||||||
}
|
}
|
||||||
|
@ -393,8 +393,8 @@ public class Sample_x86 {
|
||||||
// emulate code that read invalid memory
|
// emulate code that read invalid memory
|
||||||
static void test_i386_invalid_mem_write()
|
static void test_i386_invalid_mem_write()
|
||||||
{
|
{
|
||||||
byte r_ecx[] = {(byte)0x34, (byte)0x12, 0, 0}; //0x1234; // ECX register
|
Long r_ecx = new Long(0x1234); // ECX register
|
||||||
byte r_edx[] = {(byte)0x90, (byte)0x78, 0, 0}; //0x7890; // EDX register
|
Long r_edx = new Long(0x7890); // EDX register
|
||||||
|
|
||||||
System.out.print("===================================\n");
|
System.out.print("===================================\n");
|
||||||
System.out.print("Emulate i386 code that write to invalid memory\n");
|
System.out.print("Emulate i386 code that write to invalid memory\n");
|
||||||
|
@ -431,10 +431,10 @@ public class Sample_x86 {
|
||||||
// now print out some registers
|
// now print out some registers
|
||||||
System.out.print(">>> Emulation done. Below is the CPU context\n");
|
System.out.print(">>> Emulation done. Below is the CPU context\n");
|
||||||
|
|
||||||
r_ecx = u.reg_read(Unicorn.UC_X86_REG_ECX, 4);
|
r_ecx = (Long)u.reg_read(Unicorn.UC_X86_REG_ECX);
|
||||||
r_edx = u.reg_read(Unicorn.UC_X86_REG_EDX, 4);
|
r_edx = (Long)u.reg_read(Unicorn.UC_X86_REG_EDX);
|
||||||
System.out.printf(">>> ECX = 0x%x\n", toInt(r_ecx));
|
System.out.printf(">>> ECX = 0x%x\n", r_ecx.intValue());
|
||||||
System.out.printf(">>> EDX = 0x%x\n", toInt(r_edx));
|
System.out.printf(">>> EDX = 0x%x\n", r_edx.intValue());
|
||||||
|
|
||||||
// read from memory
|
// read from memory
|
||||||
byte tmp[] = u.mem_read(0xaaaaaaaa, 4);
|
byte tmp[] = u.mem_read(0xaaaaaaaa, 4);
|
||||||
|
@ -453,8 +453,8 @@ public class Sample_x86 {
|
||||||
// emulate code that jump to invalid memory
|
// emulate code that jump to invalid memory
|
||||||
static void test_i386_jump_invalid()
|
static void test_i386_jump_invalid()
|
||||||
{
|
{
|
||||||
byte r_ecx[] = {(byte)0x34, (byte)0x12, 0, 0}; //0x1234; // ECX register
|
Long r_ecx = new Long(0x1234); // ECX register
|
||||||
byte r_edx[] = {(byte)0x90, (byte)0x78, 0, 0}; //0x7890; // EDX register
|
Long r_edx = new Long(0x7890); // EDX register
|
||||||
|
|
||||||
System.out.print("===================================\n");
|
System.out.print("===================================\n");
|
||||||
System.out.print("Emulate i386 code that jumps to invalid memory\n");
|
System.out.print("Emulate i386 code that jumps to invalid memory\n");
|
||||||
|
@ -488,10 +488,10 @@ public class Sample_x86 {
|
||||||
// now print out some registers
|
// now print out some registers
|
||||||
System.out.print(">>> Emulation done. Below is the CPU context\n");
|
System.out.print(">>> Emulation done. Below is the CPU context\n");
|
||||||
|
|
||||||
r_ecx = u.reg_read(Unicorn.UC_X86_REG_ECX, 4);
|
r_ecx = (Long)u.reg_read(Unicorn.UC_X86_REG_ECX);
|
||||||
r_edx = u.reg_read(Unicorn.UC_X86_REG_EDX, 4);
|
r_edx = (Long)u.reg_read(Unicorn.UC_X86_REG_EDX);
|
||||||
System.out.printf(">>> ECX = 0x%x\n", toInt(r_ecx));
|
System.out.printf(">>> ECX = 0x%x\n", r_ecx.intValue());
|
||||||
System.out.printf(">>> EDX = 0x%x\n", toInt(r_edx));
|
System.out.printf(">>> EDX = 0x%x\n", r_edx.intValue());
|
||||||
|
|
||||||
u.close();
|
u.close();
|
||||||
}
|
}
|
||||||
|
@ -527,22 +527,22 @@ public class Sample_x86 {
|
||||||
u.mem_write(ADDRESS, X86_CODE64);
|
u.mem_write(ADDRESS, X86_CODE64);
|
||||||
|
|
||||||
// initialize machine registers
|
// initialize machine registers
|
||||||
u.reg_write(Unicorn.UC_X86_REG_RSP, toBytes(rsp));
|
u.reg_write(Unicorn.UC_X86_REG_RSP, new Long(rsp));
|
||||||
|
|
||||||
u.reg_write(Unicorn.UC_X86_REG_RAX, toBytes(rax));
|
u.reg_write(Unicorn.UC_X86_REG_RAX, new Long(rax));
|
||||||
u.reg_write(Unicorn.UC_X86_REG_RBX, toBytes(rbx));
|
u.reg_write(Unicorn.UC_X86_REG_RBX, new Long(rbx));
|
||||||
u.reg_write(Unicorn.UC_X86_REG_RCX, toBytes(rcx));
|
u.reg_write(Unicorn.UC_X86_REG_RCX, new Long(rcx));
|
||||||
u.reg_write(Unicorn.UC_X86_REG_RDX, toBytes(rdx));
|
u.reg_write(Unicorn.UC_X86_REG_RDX, new Long(rdx));
|
||||||
u.reg_write(Unicorn.UC_X86_REG_RSI, toBytes(rsi));
|
u.reg_write(Unicorn.UC_X86_REG_RSI, new Long(rsi));
|
||||||
u.reg_write(Unicorn.UC_X86_REG_RDI, toBytes(rdi));
|
u.reg_write(Unicorn.UC_X86_REG_RDI, new Long(rdi));
|
||||||
u.reg_write(Unicorn.UC_X86_REG_R8, toBytes(r8));
|
u.reg_write(Unicorn.UC_X86_REG_R8, new Long(r8));
|
||||||
u.reg_write(Unicorn.UC_X86_REG_R9, toBytes(r9));
|
u.reg_write(Unicorn.UC_X86_REG_R9, new Long(r9));
|
||||||
u.reg_write(Unicorn.UC_X86_REG_R10, toBytes(r10));
|
u.reg_write(Unicorn.UC_X86_REG_R10, new Long(r10));
|
||||||
u.reg_write(Unicorn.UC_X86_REG_R11, toBytes(r11));
|
u.reg_write(Unicorn.UC_X86_REG_R11, new Long(r11));
|
||||||
u.reg_write(Unicorn.UC_X86_REG_R12, toBytes(r12));
|
u.reg_write(Unicorn.UC_X86_REG_R12, new Long(r12));
|
||||||
u.reg_write(Unicorn.UC_X86_REG_R13, toBytes(r13));
|
u.reg_write(Unicorn.UC_X86_REG_R13, new Long(r13));
|
||||||
u.reg_write(Unicorn.UC_X86_REG_R14, toBytes(r14));
|
u.reg_write(Unicorn.UC_X86_REG_R14, new Long(r14));
|
||||||
u.reg_write(Unicorn.UC_X86_REG_R15, toBytes(r15));
|
u.reg_write(Unicorn.UC_X86_REG_R15, new Long(r15));
|
||||||
|
|
||||||
// tracing all basic blocks with customized callback
|
// tracing all basic blocks with customized callback
|
||||||
u.hook_add(new MyBlockHook(), 1, 0, null);
|
u.hook_add(new MyBlockHook(), 1, 0, null);
|
||||||
|
@ -563,44 +563,44 @@ public class Sample_x86 {
|
||||||
// now print out some registers
|
// now print out some registers
|
||||||
System.out.print(">>> Emulation done. Below is the CPU context\n");
|
System.out.print(">>> Emulation done. Below is the CPU context\n");
|
||||||
|
|
||||||
byte[] r_rax = u.reg_read(Unicorn.UC_X86_REG_RAX, 8);
|
Long r_rax = (Long)u.reg_read(Unicorn.UC_X86_REG_RAX);
|
||||||
byte[] r_rbx = u.reg_read(Unicorn.UC_X86_REG_RBX, 8);
|
Long r_rbx = (Long)u.reg_read(Unicorn.UC_X86_REG_RBX);
|
||||||
byte[] r_rcx = u.reg_read(Unicorn.UC_X86_REG_RCX, 8);
|
Long r_rcx = (Long)u.reg_read(Unicorn.UC_X86_REG_RCX);
|
||||||
byte[] r_rdx = u.reg_read(Unicorn.UC_X86_REG_RDX, 8);
|
Long r_rdx = (Long)u.reg_read(Unicorn.UC_X86_REG_RDX);
|
||||||
byte[] r_rsi = u.reg_read(Unicorn.UC_X86_REG_RSI, 8);
|
Long r_rsi = (Long)u.reg_read(Unicorn.UC_X86_REG_RSI);
|
||||||
byte[] r_rdi = u.reg_read(Unicorn.UC_X86_REG_RDI, 8);
|
Long r_rdi = (Long)u.reg_read(Unicorn.UC_X86_REG_RDI);
|
||||||
byte[] r_r8 = u.reg_read(Unicorn.UC_X86_REG_R8, 8);
|
Long r_r8 = (Long)u.reg_read(Unicorn.UC_X86_REG_R8);
|
||||||
byte[] r_r9 = u.reg_read(Unicorn.UC_X86_REG_R9, 8);
|
Long r_r9 = (Long)u.reg_read(Unicorn.UC_X86_REG_R9);
|
||||||
byte[] r_r10 = u.reg_read(Unicorn.UC_X86_REG_R10, 8);
|
Long r_r10 = (Long)u.reg_read(Unicorn.UC_X86_REG_R10);
|
||||||
byte[] r_r11 = u.reg_read(Unicorn.UC_X86_REG_R11, 8);
|
Long r_r11 = (Long)u.reg_read(Unicorn.UC_X86_REG_R11);
|
||||||
byte[] r_r12 = u.reg_read(Unicorn.UC_X86_REG_R12, 8);
|
Long r_r12 = (Long)u.reg_read(Unicorn.UC_X86_REG_R12);
|
||||||
byte[] r_r13 = u.reg_read(Unicorn.UC_X86_REG_R13, 8);
|
Long r_r13 = (Long)u.reg_read(Unicorn.UC_X86_REG_R13);
|
||||||
byte[] r_r14 = u.reg_read(Unicorn.UC_X86_REG_R14, 8);
|
Long r_r14 = (Long)u.reg_read(Unicorn.UC_X86_REG_R14);
|
||||||
byte[] r_r15 = u.reg_read(Unicorn.UC_X86_REG_R15, 8);
|
Long r_r15 = (Long)u.reg_read(Unicorn.UC_X86_REG_R15);
|
||||||
|
|
||||||
System.out.printf(">>> RAX = 0x%x\n", toInt(r_rax));
|
System.out.printf(">>> RAX = 0x%x\n", r_rax.longValue());
|
||||||
System.out.printf(">>> RBX = 0x%x\n", toInt(r_rbx));
|
System.out.printf(">>> RBX = 0x%x\n", r_rbx.longValue());
|
||||||
System.out.printf(">>> RCX = 0x%x\n", toInt(r_rcx));
|
System.out.printf(">>> RCX = 0x%x\n", r_rcx.longValue());
|
||||||
System.out.printf(">>> RDX = 0x%x\n", toInt(r_rdx));
|
System.out.printf(">>> RDX = 0x%x\n", r_rdx.longValue());
|
||||||
System.out.printf(">>> RSI = 0x%x\n", toInt(r_rsi));
|
System.out.printf(">>> RSI = 0x%x\n", r_rsi.longValue());
|
||||||
System.out.printf(">>> RDI = 0x%x\n", toInt(r_rdi));
|
System.out.printf(">>> RDI = 0x%x\n", r_rdi.longValue());
|
||||||
System.out.printf(">>> R8 = 0x%x\n", toInt(r_r8));
|
System.out.printf(">>> R8 = 0x%x\n", r_r8.longValue());
|
||||||
System.out.printf(">>> R9 = 0x%x\n", toInt(r_r9));
|
System.out.printf(">>> R9 = 0x%x\n", r_r9.longValue());
|
||||||
System.out.printf(">>> R10 = 0x%x\n", toInt(r_r10));
|
System.out.printf(">>> R10 = 0x%x\n", r_r10.longValue());
|
||||||
System.out.printf(">>> R11 = 0x%x\n", toInt(r_r11));
|
System.out.printf(">>> R11 = 0x%x\n", r_r11.longValue());
|
||||||
System.out.printf(">>> R12 = 0x%x\n", toInt(r_r12));
|
System.out.printf(">>> R12 = 0x%x\n", r_r12.longValue());
|
||||||
System.out.printf(">>> R13 = 0x%x\n", toInt(r_r13));
|
System.out.printf(">>> R13 = 0x%x\n", r_r13.longValue());
|
||||||
System.out.printf(">>> R14 = 0x%x\n", toInt(r_r14));
|
System.out.printf(">>> R14 = 0x%x\n", r_r14.longValue());
|
||||||
System.out.printf(">>> R15 = 0x%x\n", toInt(r_r15));
|
System.out.printf(">>> R15 = 0x%x\n", r_r15.longValue());
|
||||||
|
|
||||||
u.close();
|
u.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_x86_16()
|
static void test_x86_16()
|
||||||
{
|
{
|
||||||
byte[] eax = toBytes(7);
|
Long eax = new Long(7);
|
||||||
byte[] ebx = toBytes(5);
|
Long ebx = new Long(5);
|
||||||
byte[] esi = toBytes(6);
|
Long esi = new Long(6);
|
||||||
|
|
||||||
System.out.print("Emulate x86 16-bit code\n");
|
System.out.print("Emulate x86 16-bit code\n");
|
||||||
|
|
||||||
|
|
|
@ -58,8 +58,8 @@ public class Shellcode {
|
||||||
|
|
||||||
System.out.print(String.format("Tracing instruction at 0x%x, instruction size = 0x%x\n", address, size));
|
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);
|
Long r_eip = (Long)u.reg_read(Unicorn.UC_X86_REG_EIP);
|
||||||
System.out.print(String.format("*** EIP = %x ***: ", toInt(r_eip)));
|
System.out.print(String.format("*** EIP = %x ***: ", r_eip.intValue()));
|
||||||
|
|
||||||
size = Math.min(16, size);
|
size = Math.min(16, size);
|
||||||
|
|
||||||
|
@ -73,8 +73,8 @@ public class Shellcode {
|
||||||
|
|
||||||
public static class MyInterruptHook implements InterruptHook {
|
public static class MyInterruptHook implements InterruptHook {
|
||||||
public void hook(Unicorn u, int intno, Object user) {
|
public void hook(Unicorn u, int intno, Object user) {
|
||||||
long r_ecx;
|
Long r_ecx;
|
||||||
long r_edx;
|
Long r_edx;
|
||||||
int size;
|
int size;
|
||||||
|
|
||||||
// only handle Linux syscall
|
// only handle Linux syscall
|
||||||
|
@ -82,30 +82,30 @@ public class Shellcode {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
long r_eax = toInt(u.reg_read(Unicorn.UC_X86_REG_EAX, 4));
|
Long r_eax = (Long)u.reg_read(Unicorn.UC_X86_REG_EAX);
|
||||||
long r_eip = toInt(u.reg_read(Unicorn.UC_X86_REG_EIP, 4));
|
Long r_eip = (Long)u.reg_read(Unicorn.UC_X86_REG_EIP);
|
||||||
|
|
||||||
switch ((int)r_eax) {
|
switch (r_eax.intValue()) {
|
||||||
default:
|
default:
|
||||||
System.out.print(String.format(">>> 0x%x: interrupt 0x%x, EAX = 0x%x\n", r_eip, intno, r_eax));
|
System.out.print(String.format(">>> 0x%x: interrupt 0x%x, EAX = 0x%x\n", r_eip.intValue(), intno, r_eax.intValue()));
|
||||||
break;
|
break;
|
||||||
case 1: // sys_exit
|
case 1: // sys_exit
|
||||||
System.out.print(String.format(">>> 0x%x: interrupt 0x%x, SYS_EXIT. quit!\n\n", r_eip, intno));
|
System.out.print(String.format(">>> 0x%x: interrupt 0x%x, SYS_EXIT. quit!\n\n", r_eip.intValue(), intno));
|
||||||
u.emu_stop();
|
u.emu_stop();
|
||||||
break;
|
break;
|
||||||
case 4: // sys_write
|
case 4: // sys_write
|
||||||
// ECX = buffer address
|
// ECX = buffer address
|
||||||
r_ecx = toInt(u.reg_read(Unicorn.UC_X86_REG_ECX, 4));
|
r_ecx = (Long)u.reg_read(Unicorn.UC_X86_REG_ECX);
|
||||||
|
|
||||||
// EDX = buffer size
|
// EDX = buffer size
|
||||||
r_edx = toInt(u.reg_read(Unicorn.UC_X86_REG_EDX, 4));
|
r_edx = (Long)u.reg_read(Unicorn.UC_X86_REG_EDX);
|
||||||
|
|
||||||
// read the buffer in
|
// read the buffer in
|
||||||
size = (int)Math.min(256, r_edx);
|
size = (int)Math.min(256, r_edx);
|
||||||
|
|
||||||
byte[] buffer = u.mem_read(r_ecx, size);
|
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",
|
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)));
|
r_eip.intValue(), intno, r_ecx.intValue(), r_edx.intValue(), new String(buffer)));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -113,7 +113,7 @@ public class Shellcode {
|
||||||
|
|
||||||
static void test_i386()
|
static void test_i386()
|
||||||
{
|
{
|
||||||
long r_esp = ADDRESS + 0x200000; // ESP register
|
Long r_esp = new Long(ADDRESS + 0x200000); // ESP register
|
||||||
|
|
||||||
System.out.print("Emulate i386 code\n");
|
System.out.print("Emulate i386 code\n");
|
||||||
|
|
||||||
|
@ -127,7 +127,7 @@ public class Shellcode {
|
||||||
u.mem_write(ADDRESS, X86_CODE32_SELF);
|
u.mem_write(ADDRESS, X86_CODE32_SELF);
|
||||||
|
|
||||||
// initialize machine registers
|
// initialize machine registers
|
||||||
u.reg_write(Unicorn.UC_X86_REG_ESP, toBytes(r_esp));
|
u.reg_write(Unicorn.UC_X86_REG_ESP, r_esp);
|
||||||
|
|
||||||
// tracing all instructions by having @begin > @end
|
// tracing all instructions by having @begin > @end
|
||||||
u.hook_add(new MyCodeHook(), 1, 0, null);
|
u.hook_add(new MyCodeHook(), 1, 0, null);
|
||||||
|
|
|
@ -19,11 +19,11 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package unicorn;
|
package unicorn;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class Unicorn implements UnicornConst, ArmConst, Arm64Const, M68kConst, SparcConst, MipsConst, X86Const {
|
public class Unicorn implements UnicornConst, ArmConst, Arm64Const, M68kConst, SparcConst, MipsConst, X86Const {
|
||||||
|
|
||||||
private long eng;
|
private long eng;
|
||||||
private int arch;
|
private int arch;
|
||||||
|
@ -55,24 +55,24 @@ public class Unicorn implements UnicornConst, ArmConst, Arm64Const, M68kConst, S
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ArrayList<Tuple> blockList = new ArrayList<Tuple>();
|
private ArrayList<Tuple> blockList = new ArrayList<Tuple>();
|
||||||
private ArrayList<Tuple> intrList = new ArrayList<Tuple>();
|
private ArrayList<Tuple> intrList = new ArrayList<Tuple>();
|
||||||
private ArrayList<Tuple> codeList = new ArrayList<Tuple>();
|
private ArrayList<Tuple> codeList = new ArrayList<Tuple>();
|
||||||
private ArrayList<Tuple> readList = new ArrayList<Tuple>();
|
private ArrayList<Tuple> readList = new ArrayList<Tuple>();
|
||||||
private ArrayList<Tuple> writeList = new ArrayList<Tuple>();
|
private ArrayList<Tuple> writeList = new ArrayList<Tuple>();
|
||||||
private ArrayList<Tuple> inList = new ArrayList<Tuple>();
|
private ArrayList<Tuple> inList = new ArrayList<Tuple>();
|
||||||
private ArrayList<Tuple> outList = new ArrayList<Tuple>();
|
private ArrayList<Tuple> outList = new ArrayList<Tuple>();
|
||||||
private ArrayList<Tuple> syscallList = new ArrayList<Tuple>();
|
private ArrayList<Tuple> syscallList = new ArrayList<Tuple>();
|
||||||
|
|
||||||
private Hashtable<Integer, ArrayList<Tuple> > eventMemLists = new Hashtable<Integer, ArrayList<Tuple> >();
|
private Hashtable<Integer, ArrayList<Tuple> > eventMemLists = new Hashtable<Integer, ArrayList<Tuple> >();
|
||||||
|
|
||||||
private ArrayList<ArrayList<Tuple>> allLists = new ArrayList<ArrayList<Tuple>>();
|
private ArrayList<ArrayList<Tuple>> allLists = new ArrayList<ArrayList<Tuple>>();
|
||||||
|
|
||||||
private static Hashtable<Integer,Integer> eventMemMap = new Hashtable<Integer,Integer>();
|
private static Hashtable<Integer,Integer> eventMemMap = new Hashtable<Integer,Integer>();
|
||||||
private static Hashtable<Long,Unicorn> unicorns = new Hashtable<Long,Unicorn>();
|
private static Hashtable<Long,Unicorn> unicorns = new Hashtable<Long,Unicorn>();
|
||||||
|
|
||||||
//required to load native method implementations
|
//required to load native method implementations
|
||||||
static {
|
static {
|
||||||
System.loadLibrary("unicorn_java"); //loads unicorn.dll or libunicorn.so
|
System.loadLibrary("unicorn_java"); //loads unicorn.dll or libunicorn.so
|
||||||
eventMemMap.put(UC_HOOK_MEM_READ_UNMAPPED, UC_MEM_READ_UNMAPPED);
|
eventMemMap.put(UC_HOOK_MEM_READ_UNMAPPED, UC_MEM_READ_UNMAPPED);
|
||||||
eventMemMap.put(UC_HOOK_MEM_WRITE_UNMAPPED, UC_MEM_WRITE_UNMAPPED);
|
eventMemMap.put(UC_HOOK_MEM_WRITE_UNMAPPED, UC_MEM_WRITE_UNMAPPED);
|
||||||
|
@ -80,12 +80,16 @@ public class Unicorn implements UnicornConst, ArmConst, Arm64Const, M68kConst, S
|
||||||
eventMemMap.put(UC_HOOK_MEM_READ_PROT, UC_MEM_READ_PROT);
|
eventMemMap.put(UC_HOOK_MEM_READ_PROT, UC_MEM_READ_PROT);
|
||||||
eventMemMap.put(UC_HOOK_MEM_WRITE_PROT, UC_MEM_WRITE_PROT);
|
eventMemMap.put(UC_HOOK_MEM_WRITE_PROT, UC_MEM_WRITE_PROT);
|
||||||
eventMemMap.put(UC_HOOK_MEM_FETCH_PROT, UC_MEM_FETCH_PROT);
|
eventMemMap.put(UC_HOOK_MEM_FETCH_PROT, UC_MEM_FETCH_PROT);
|
||||||
}
|
eventMemMap.put(UC_HOOK_MEM_READ, UC_MEM_READ);
|
||||||
|
eventMemMap.put(UC_HOOK_MEM_WRITE, UC_MEM_WRITE);
|
||||||
|
eventMemMap.put(UC_HOOK_MEM_FETCH, UC_MEM_FETCH);
|
||||||
|
eventMemMap.put(UC_HOOK_MEM_READ_AFTER, UC_MEM_READ_AFTER);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoke all UC_HOOK_BLOCK callbacks registered for a specific Unicorn.
|
* Invoke all UC_HOOK_BLOCK callbacks registered for a specific Unicorn.
|
||||||
* This function gets invoked from the native C callback registered for
|
* This function gets invoked from the native C callback registered for
|
||||||
* for UC_HOOK_BLOCK
|
* for UC_HOOK_BLOCK
|
||||||
*
|
*
|
||||||
* @param eng A Unicorn uc_engine* eng returned by uc_open
|
* @param eng A Unicorn uc_engine* eng returned by uc_open
|
||||||
* @param address The address of the instruction being executed
|
* @param address The address of the instruction being executed
|
||||||
|
@ -105,7 +109,7 @@ public class Unicorn implements UnicornConst, ArmConst, Arm64Const, M68kConst, S
|
||||||
/**
|
/**
|
||||||
* Invoke all UC_HOOK_INTR callbacks registered for a specific Unicorn.
|
* Invoke all UC_HOOK_INTR callbacks registered for a specific Unicorn.
|
||||||
* This function gets invoked from the native C callback registered for
|
* This function gets invoked from the native C callback registered for
|
||||||
* for UC_HOOK_INTR
|
* for UC_HOOK_INTR
|
||||||
*
|
*
|
||||||
* @param eng A Unicorn uc_engine* eng returned by uc_open
|
* @param eng A Unicorn uc_engine* eng returned by uc_open
|
||||||
* @param intno The interrupt number
|
* @param intno The interrupt number
|
||||||
|
@ -124,7 +128,7 @@ public class Unicorn implements UnicornConst, ArmConst, Arm64Const, M68kConst, S
|
||||||
/**
|
/**
|
||||||
* Invoke all UC_HOOK_CODE callbacks registered for a specific Unicorn.
|
* Invoke all UC_HOOK_CODE callbacks registered for a specific Unicorn.
|
||||||
* This function gets invoked from the native C callback registered for
|
* This function gets invoked from the native C callback registered for
|
||||||
* for UC_HOOK_CODE
|
* for UC_HOOK_CODE
|
||||||
*
|
*
|
||||||
* @param eng A Unicorn uc_engine* eng returned by uc_open
|
* @param eng A Unicorn uc_engine* eng returned by uc_open
|
||||||
* @param address The address of the instruction being executed
|
* @param address The address of the instruction being executed
|
||||||
|
@ -142,7 +146,7 @@ public class Unicorn implements UnicornConst, ArmConst, Arm64Const, M68kConst, S
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoke all UC_HOOK_MEM_XXX_UNMAPPED andor UC_HOOK_MEM_XXX_PROT callbacks registered
|
* Invoke all UC_HOOK_MEM_XXX_UNMAPPED and/or UC_HOOK_MEM_XXX_PROT callbacks registered
|
||||||
* for a specific Unicorn.
|
* for a specific Unicorn.
|
||||||
* This function gets invoked from the native C callback registered for
|
* This function gets invoked from the native C callback registered for
|
||||||
* for UC_HOOK_MEM_XXX_UNMAPPED or UC_HOOK_MEM_XXX_PROT
|
* for UC_HOOK_MEM_XXX_UNMAPPED or UC_HOOK_MEM_XXX_PROT
|
||||||
|
@ -173,7 +177,7 @@ public class Unicorn implements UnicornConst, ArmConst, Arm64Const, M68kConst, S
|
||||||
/**
|
/**
|
||||||
* Invoke all UC_HOOK_MEM_READ callbacks registered for a specific Unicorn.
|
* Invoke all UC_HOOK_MEM_READ callbacks registered for a specific Unicorn.
|
||||||
* This function gets invoked from the native C callback registered for
|
* This function gets invoked from the native C callback registered for
|
||||||
* for UC_HOOK_MEM_READ
|
* for UC_HOOK_MEM_READ
|
||||||
*
|
*
|
||||||
* @param eng A Unicorn uc_engine* eng returned by uc_open
|
* @param eng A Unicorn uc_engine* eng returned by uc_open
|
||||||
* @param address Address of instruction being executed
|
* @param address Address of instruction being executed
|
||||||
|
@ -193,7 +197,7 @@ public class Unicorn implements UnicornConst, ArmConst, Arm64Const, M68kConst, S
|
||||||
/**
|
/**
|
||||||
* Invoke all UC_HOOK_MEM_WRITE callbacks registered for a specific Unicorn.
|
* Invoke all UC_HOOK_MEM_WRITE callbacks registered for a specific Unicorn.
|
||||||
* This function gets invoked from the native C callback registered for
|
* This function gets invoked from the native C callback registered for
|
||||||
* for UC_HOOK_MEM_WRITE
|
* for UC_HOOK_MEM_WRITE
|
||||||
*
|
*
|
||||||
* @param eng A Unicorn uc_engine* eng returned by uc_open
|
* @param eng A Unicorn uc_engine* eng returned by uc_open
|
||||||
* @param address Address of instruction being executed
|
* @param address Address of instruction being executed
|
||||||
|
@ -215,7 +219,7 @@ public class Unicorn implements UnicornConst, ArmConst, Arm64Const, M68kConst, S
|
||||||
* Invoke all UC_HOOK_INSN callbacks registered for a specific Unicorn.
|
* Invoke all UC_HOOK_INSN callbacks registered for a specific Unicorn.
|
||||||
* This is specifically for the x86 IN instruction.
|
* This is specifically for the x86 IN instruction.
|
||||||
* This function gets invoked from the native C callback registered for
|
* This function gets invoked from the native C callback registered for
|
||||||
* for UC_HOOK_INSN
|
* for UC_HOOK_INSN
|
||||||
*
|
*
|
||||||
* @param eng A Unicorn uc_engine* eng returned by uc_open
|
* @param eng A Unicorn uc_engine* eng returned by uc_open
|
||||||
* @param port I/O Port number
|
* @param port I/O Port number
|
||||||
|
@ -239,7 +243,7 @@ public class Unicorn implements UnicornConst, ArmConst, Arm64Const, M68kConst, S
|
||||||
* Invoke all UC_HOOK_INSN callbacks registered for a specific Unicorn.
|
* Invoke all UC_HOOK_INSN callbacks registered for a specific Unicorn.
|
||||||
* This is specifically for the x86 OUT instruction.
|
* This is specifically for the x86 OUT instruction.
|
||||||
* This function gets invoked from the native C callback registered for
|
* This function gets invoked from the native C callback registered for
|
||||||
* for UC_HOOK_INSN
|
* for UC_HOOK_INSN
|
||||||
*
|
*
|
||||||
* @param eng A Unicorn uc_engine* eng returned by uc_open
|
* @param eng A Unicorn uc_engine* eng returned by uc_open
|
||||||
* @param port I/O Port number
|
* @param port I/O Port number
|
||||||
|
@ -261,7 +265,7 @@ public class Unicorn implements UnicornConst, ArmConst, Arm64Const, M68kConst, S
|
||||||
* Invoke all UC_HOOK_INSN callbacks registered for a specific Unicorn.
|
* Invoke all UC_HOOK_INSN callbacks registered for a specific Unicorn.
|
||||||
* This is specifically for the x86 SYSCALL and SYSENTER instruction.
|
* This is specifically for the x86 SYSCALL and SYSENTER instruction.
|
||||||
* This function gets invoked from the native C callback registered for
|
* This function gets invoked from the native C callback registered for
|
||||||
* for UC_HOOK_INSN
|
* for UC_HOOK_INSN
|
||||||
*
|
*
|
||||||
* @param eng A Unicorn uc_engine* eng returned by uc_open
|
* @param eng A Unicorn uc_engine* eng returned by uc_open
|
||||||
* @see hook_add, unicorn.SyscallHook
|
* @see hook_add, unicorn.SyscallHook
|
||||||
|
@ -277,7 +281,7 @@ public class Unicorn implements UnicornConst, ArmConst, Arm64Const, M68kConst, S
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write to register.
|
* Write to register.
|
||||||
*
|
*
|
||||||
* @param regid Register ID that is to be modified.
|
* @param regid Register ID that is to be modified.
|
||||||
|
@ -285,7 +289,7 @@ public class Unicorn implements UnicornConst, ArmConst, Arm64Const, M68kConst, S
|
||||||
*/
|
*/
|
||||||
private native void reg_write_num(int regid, Number value) throws UnicornException;
|
private native void reg_write_num(int regid, Number value) throws UnicornException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write to register.
|
* Write to register.
|
||||||
*
|
*
|
||||||
* @param regid Register ID that is to be modified.
|
* @param regid Register ID that is to be modified.
|
||||||
|
@ -310,15 +314,15 @@ public class Unicorn implements UnicornConst, ArmConst, Arm64Const, M68kConst, S
|
||||||
private native Number reg_read_mmr(int regid) throws UnicornException;
|
private native Number reg_read_mmr(int regid) throws UnicornException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Native access to uc_open
|
* Native access to uc_open
|
||||||
*
|
*
|
||||||
* @param arch Architecture type (UC_ARCH_*)
|
* @param arch Architecture type (UC_ARCH_*)
|
||||||
* @param mode Hardware mode. This is combined of UC_MODE_*
|
* @param mode Hardware mode. This is combined of UC_MODE_*
|
||||||
*/
|
*/
|
||||||
private native long open(int arch, int mode) throws UnicornException;
|
private native long open(int arch, int mode) throws UnicornException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new Unicorn object
|
* Create a new Unicorn object
|
||||||
*
|
*
|
||||||
* @param arch Architecture type (UC_ARCH_*)
|
* @param arch Architecture type (UC_ARCH_*)
|
||||||
* @param mode Hardware mode. This is combined of UC_MODE_*
|
* @param mode Hardware mode. This is combined of UC_MODE_*
|
||||||
|
@ -340,9 +344,9 @@ public class Unicorn implements UnicornConst, ArmConst, Arm64Const, M68kConst, S
|
||||||
allLists.add(outList);
|
allLists.add(outList);
|
||||||
allLists.add(syscallList);
|
allLists.add(syscallList);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform native cleanup tasks associated with a Unicorn object
|
* Perform native cleanup tasks associated with a Unicorn object
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
protected void finalize() {
|
protected void finalize() {
|
||||||
|
@ -369,17 +373,17 @@ public class Unicorn implements UnicornConst, ArmConst, Arm64Const, M68kConst, S
|
||||||
public native static boolean arch_supported(int arch);
|
public native static boolean arch_supported(int arch);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Close the underlying uc_engine* eng associated with this Unicorn object
|
* Close the underlying uc_engine* eng associated with this Unicorn object
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public native void close() throws UnicornException;
|
public native void close() throws UnicornException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Query internal status of engine.
|
* Query internal status of engine.
|
||||||
*
|
*
|
||||||
* @param type query type. See UC_QUERY_*
|
* @param type query type. See UC_QUERY_*
|
||||||
* @param result save the internal status queried
|
* @param result save the internal status queried
|
||||||
*
|
*
|
||||||
* @return: error code. see UC_ERR_*
|
* @return: error code. see UC_ERR_*
|
||||||
* @see unicorn.UnicornConst
|
* @see unicorn.UnicornConst
|
||||||
*/
|
*/
|
||||||
|
@ -403,7 +407,7 @@ public class Unicorn implements UnicornConst, ArmConst, Arm64Const, M68kConst, S
|
||||||
*/
|
*/
|
||||||
public native static String strerror(int code);
|
public native static String strerror(int code);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write to register.
|
* Write to register.
|
||||||
*
|
*
|
||||||
* @deprecated use reg_write(int regid, Object value) instead
|
* @deprecated use reg_write(int regid, Object value) instead
|
||||||
|
@ -413,7 +417,7 @@ public class Unicorn implements UnicornConst, ArmConst, Arm64Const, M68kConst, S
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public native void reg_write(int regid, byte[] value) throws UnicornException;
|
public native void reg_write(int regid, byte[] value) throws UnicornException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write to register.
|
* Write to register.
|
||||||
*
|
*
|
||||||
* @param regid Register ID that is to be modified.
|
* @param regid Register ID that is to be modified.
|
||||||
|
@ -437,7 +441,7 @@ public class Unicorn implements UnicornConst, ArmConst, Arm64Const, M68kConst, S
|
||||||
/**
|
/**
|
||||||
* Read register value.
|
* Read register value.
|
||||||
*
|
*
|
||||||
* @deprecated use Object reg_write(int regid) instead
|
* @deprecated use Object reg_read(int regid) instead
|
||||||
* @param regid Register ID that is to be retrieved.
|
* @param regid Register ID that is to be retrieved.
|
||||||
* @param regsz Size of the register being retrieved.
|
* @param regsz Size of the register being retrieved.
|
||||||
* @return Byte array containing the requested register value.
|
* @return Byte array containing the requested register value.
|
||||||
|
@ -461,7 +465,36 @@ public class Unicorn implements UnicornConst, ArmConst, Arm64Const, M68kConst, S
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Batch write register values. regids.length == vals.length or UC_ERR_ARG
|
||||||
|
*
|
||||||
|
* @param regids Array of register IDs to be written.
|
||||||
|
* @param vals Array of register values to be written.
|
||||||
|
*/
|
||||||
|
public void reg_write_batch(int regids[], Object vals[]) throws UnicornException {
|
||||||
|
if (regids.length != vals.length) {
|
||||||
|
throw new UnicornException(strerror(UC_ERR_ARG));
|
||||||
|
}
|
||||||
|
for (int i = 0; i < regids.length; i++) {
|
||||||
|
reg_write(regids[i], vals[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Batch read register values.
|
||||||
|
*
|
||||||
|
* @param regids Array of register IDs to be read.
|
||||||
|
* @return Array containing the requested register values.
|
||||||
|
*/
|
||||||
|
public Object[] reg_read_batch(int regids[]) throws UnicornException {
|
||||||
|
Object[] vals = new Object[regids.length];
|
||||||
|
for (int i = 0; i < regids.length; i++) {
|
||||||
|
vals[i] = reg_read(regids[i]);
|
||||||
|
}
|
||||||
|
return vals;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
* Write to memory.
|
* Write to memory.
|
||||||
*
|
*
|
||||||
* @param address Start addres of the memory region to be written.
|
* @param address Start addres of the memory region to be written.
|
||||||
|
@ -590,7 +623,7 @@ public class Unicorn implements UnicornConst, ArmConst, Arm64Const, M68kConst, S
|
||||||
}
|
}
|
||||||
readList.add(new Tuple(callback, user_data));
|
readList.add(new Tuple(callback, user_data));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hook registration for UC_HOOK_MEM_WRITE hooks. The registered callback function will be
|
* 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
|
* invoked whenever a memory write is performed within the address range begin <= write_addr <= end. For
|
||||||
|
@ -607,7 +640,7 @@ public class Unicorn implements UnicornConst, ArmConst, Arm64Const, M68kConst, S
|
||||||
}
|
}
|
||||||
writeList.add(new Tuple(callback, user_data));
|
writeList.add(new Tuple(callback, user_data));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hook registration for UC_HOOK_MEM_WRITE | UC_HOOK_MEM_WRITE hooks. The registered callback function will be
|
* Hook registration for UC_HOOK_MEM_WRITE | UC_HOOK_MEM_WRITE hooks. The registered callback function will be
|
||||||
* invoked whenever a memory write or read is performed within the address range begin <= addr <= end. For
|
* invoked whenever a memory write or read is performed within the address range begin <= addr <= end. For
|
||||||
|
@ -622,7 +655,7 @@ public class Unicorn implements UnicornConst, ArmConst, Arm64Const, M68kConst, S
|
||||||
hook_add((ReadHook)callback, begin, end, user_data);
|
hook_add((ReadHook)callback, begin, end, user_data);
|
||||||
hook_add((WriteHook)callback, begin, end, user_data);
|
hook_add((WriteHook)callback, begin, end, user_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hook registration for UC_HOOK_MEM_XXX_UNMAPPED and UC_HOOK_MEM_XXX_PROT hooks.
|
* Hook registration for UC_HOOK_MEM_XXX_UNMAPPED and UC_HOOK_MEM_XXX_PROT hooks.
|
||||||
* The registered callback function will be invoked whenever a read or write is
|
* The registered callback function will be invoked whenever a read or write is
|
||||||
|
@ -653,7 +686,7 @@ public class Unicorn implements UnicornConst, ArmConst, Arm64Const, M68kConst, S
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hook registration for UC_HOOK_INSN hooks (x86 IN instruction only). The registered callback
|
* 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.
|
* function will be invoked whenever an x86 IN instruction is executed.
|
||||||
*
|
*
|
||||||
* @param callback Implementation of a InHook interface
|
* @param callback Implementation of a InHook interface
|
||||||
|
@ -665,9 +698,9 @@ public class Unicorn implements UnicornConst, ArmConst, Arm64Const, M68kConst, S
|
||||||
}
|
}
|
||||||
inList.add(new Tuple(callback, user_data));
|
inList.add(new Tuple(callback, user_data));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hook registration for UC_HOOK_INSN hooks (x86 OUT instruction only). The registered callback
|
* 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.
|
* function will be invoked whenever an x86 OUT instruction is executed.
|
||||||
*
|
*
|
||||||
* @param callback Implementation of a OutHook interface
|
* @param callback Implementation of a OutHook interface
|
||||||
|
@ -681,7 +714,7 @@ public class Unicorn implements UnicornConst, ArmConst, Arm64Const, M68kConst, S
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hook registration for UC_HOOK_INSN hooks (x86 SYSCALL/SYSENTER instruction only). The registered callback
|
* 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.
|
* function will be invoked whenever an x86 SYSCALL or SYSENTER instruction is executed.
|
||||||
*
|
*
|
||||||
* @param callback Implementation of a SyscallHook interface
|
* @param callback Implementation of a SyscallHook interface
|
||||||
|
@ -747,10 +780,45 @@ public class Unicorn implements UnicornConst, ArmConst, Arm64Const, M68kConst, S
|
||||||
/**
|
/**
|
||||||
* Retrieve all memory regions mapped by mem_map() and mem_map_ptr()
|
* Retrieve all memory regions mapped by mem_map() and mem_map_ptr()
|
||||||
* NOTE: memory regions may be split by mem_unmap()
|
* NOTE: memory regions may be split by mem_unmap()
|
||||||
*
|
*
|
||||||
* @return list of mapped regions.
|
* @return list of mapped regions.
|
||||||
*/
|
*/
|
||||||
public native MemRegion[] mem_regions() throws UnicornException;
|
public native MemRegion[] mem_regions() throws UnicornException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allocate a region that can be used with uc_context_{save,restore} to perform
|
||||||
|
* quick save/rollback of the CPU context, which includes registers and some
|
||||||
|
* internal metadata. Contexts may not be shared across engine instances with
|
||||||
|
* differing arches or modes.
|
||||||
|
*
|
||||||
|
* @return context handle for use with save/restore.
|
||||||
|
*/
|
||||||
|
public native long context_alloc();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Free the resource allocated by context_alloc.
|
||||||
|
*
|
||||||
|
* @param context handle previously returned by context_alloc.
|
||||||
|
*/
|
||||||
|
public native void context_free(long context);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save a copy of the internal CPU context.
|
||||||
|
* This API should be used to efficiently make or update a saved copy of the
|
||||||
|
* internal CPU state.
|
||||||
|
*
|
||||||
|
* @param context handle previously returned by context_alloc.
|
||||||
|
*/
|
||||||
|
public native void context_save(long context);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restore the current CPU context from a saved copy.
|
||||||
|
* This API should be used to roll the CPU context back to a previous
|
||||||
|
* state saved by uc_context_save().
|
||||||
|
*
|
||||||
|
* @param context handle previously returned by context_alloc.
|
||||||
|
*/
|
||||||
|
public native void context_restore(long context);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -83,7 +83,7 @@ static void cb_hookblock(uc_engine *eng, uint64_t address, uint32_t size, void *
|
||||||
static void cb_hookintr(uc_engine *eng, uint32_t intno, void *user_data) {
|
static void cb_hookintr(uc_engine *eng, uint32_t intno, void *user_data) {
|
||||||
JNIEnv *env;
|
JNIEnv *env;
|
||||||
(*cachedJVM)->AttachCurrentThread(cachedJVM, (void **)&env, NULL);
|
(*cachedJVM)->AttachCurrentThread(cachedJVM, (void **)&env, NULL);
|
||||||
jclass clz = (*env)->FindClass(env, "unicorn/Unicorn");
|
jclass clz = (*env)->FindClass(env, "unicorn/Unicorn");
|
||||||
if ((*env)->ExceptionCheck(env)) {
|
if ((*env)->ExceptionCheck(env)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -99,7 +99,7 @@ static uint32_t cb_insn_in(uc_engine *eng, uint32_t port, int size, void *user_d
|
||||||
JNIEnv *env;
|
JNIEnv *env;
|
||||||
uint32_t res = 0;
|
uint32_t res = 0;
|
||||||
(*cachedJVM)->AttachCurrentThread(cachedJVM, (void **)&env, NULL);
|
(*cachedJVM)->AttachCurrentThread(cachedJVM, (void **)&env, NULL);
|
||||||
jclass clz = (*env)->FindClass(env, "unicorn/Unicorn");
|
jclass clz = (*env)->FindClass(env, "unicorn/Unicorn");
|
||||||
if ((*env)->ExceptionCheck(env)) {
|
if ((*env)->ExceptionCheck(env)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -115,7 +115,7 @@ static uint32_t cb_insn_in(uc_engine *eng, uint32_t port, int size, void *user_d
|
||||||
static void cb_insn_out(uc_engine *eng, uint32_t port, int size, uint32_t value, void *user_data) {
|
static void cb_insn_out(uc_engine *eng, uint32_t port, int size, uint32_t value, void *user_data) {
|
||||||
JNIEnv *env;
|
JNIEnv *env;
|
||||||
(*cachedJVM)->AttachCurrentThread(cachedJVM, (void **)&env, NULL);
|
(*cachedJVM)->AttachCurrentThread(cachedJVM, (void **)&env, NULL);
|
||||||
jclass clz = (*env)->FindClass(env, "unicorn/Unicorn");
|
jclass clz = (*env)->FindClass(env, "unicorn/Unicorn");
|
||||||
if ((*env)->ExceptionCheck(env)) {
|
if ((*env)->ExceptionCheck(env)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -127,7 +127,7 @@ static void cb_insn_out(uc_engine *eng, uint32_t port, int size, uint32_t value,
|
||||||
static void cb_insn_syscall(uc_engine *eng, void *user_data) {
|
static void cb_insn_syscall(uc_engine *eng, void *user_data) {
|
||||||
JNIEnv *env;
|
JNIEnv *env;
|
||||||
(*cachedJVM)->AttachCurrentThread(cachedJVM, (void **)&env, NULL);
|
(*cachedJVM)->AttachCurrentThread(cachedJVM, (void **)&env, NULL);
|
||||||
jclass clz = (*env)->FindClass(env, "unicorn/Unicorn");
|
jclass clz = (*env)->FindClass(env, "unicorn/Unicorn");
|
||||||
if ((*env)->ExceptionCheck(env)) {
|
if ((*env)->ExceptionCheck(env)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -145,7 +145,7 @@ static void cb_hookmem(uc_engine *eng, uc_mem_type type,
|
||||||
uint64_t address, int size, int64_t value, void *user_data) {
|
uint64_t address, int size, int64_t value, void *user_data) {
|
||||||
JNIEnv *env;
|
JNIEnv *env;
|
||||||
(*cachedJVM)->AttachCurrentThread(cachedJVM, (void **)&env, NULL);
|
(*cachedJVM)->AttachCurrentThread(cachedJVM, (void **)&env, NULL);
|
||||||
jclass clz = (*env)->FindClass(env, "unicorn/Unicorn");
|
jclass clz = (*env)->FindClass(env, "unicorn/Unicorn");
|
||||||
if ((*env)->ExceptionCheck(env)) {
|
if ((*env)->ExceptionCheck(env)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -171,7 +171,7 @@ static bool cb_eventmem(uc_engine *eng, uc_mem_type type,
|
||||||
uint64_t address, int size, int64_t value, void *user_data) {
|
uint64_t address, int size, int64_t value, void *user_data) {
|
||||||
JNIEnv *env;
|
JNIEnv *env;
|
||||||
(*cachedJVM)->AttachCurrentThread(cachedJVM, (void **)&env, NULL);
|
(*cachedJVM)->AttachCurrentThread(cachedJVM, (void **)&env, NULL);
|
||||||
jclass clz = (*env)->FindClass(env, "unicorn/Unicorn");
|
jclass clz = (*env)->FindClass(env, "unicorn/Unicorn");
|
||||||
if ((*env)->ExceptionCheck(env)) {
|
if ((*env)->ExceptionCheck(env)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -359,7 +359,7 @@ JNIEXPORT void JNICALL Java_unicorn_Unicorn_close
|
||||||
if (err != UC_ERR_OK) {
|
if (err != UC_ERR_OK) {
|
||||||
throwException(env, err);
|
throwException(env, err);
|
||||||
}
|
}
|
||||||
//We also need to ReleaseByteArrayElements for any regions that
|
//We also need to ReleaseByteArrayElements for any regions that
|
||||||
//were mapped with uc_mem_map_ptr
|
//were mapped with uc_mem_map_ptr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -398,7 +398,7 @@ JNIEXPORT jint JNICALL Java_unicorn_Unicorn_errno
|
||||||
JNIEXPORT jstring JNICALL Java_unicorn_Unicorn_strerror
|
JNIEXPORT jstring JNICALL Java_unicorn_Unicorn_strerror
|
||||||
(JNIEnv *env, jclass clz, jint code) {
|
(JNIEnv *env, jclass clz, jint code) {
|
||||||
const char *err = uc_strerror((int)code);
|
const char *err = uc_strerror((int)code);
|
||||||
jstring s = (*env)->NewStringUTF(env, err);
|
jstring s = (*env)->NewStringUTF(env, err);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -616,9 +616,9 @@ JNIEXPORT jlong JNICALL Java_unicorn_Unicorn_registerHook__JIJJ
|
||||||
JNIEXPORT void JNICALL Java_unicorn_Unicorn_hook_1del
|
JNIEXPORT void JNICALL Java_unicorn_Unicorn_hook_1del
|
||||||
(JNIEnv *env, jobject self, jlong hh) {
|
(JNIEnv *env, jobject self, jlong hh) {
|
||||||
uc_engine *eng = getEngine(env, self);
|
uc_engine *eng = getEngine(env, self);
|
||||||
|
|
||||||
//**** TODO remove hook from any internal hook tables as well
|
//**** TODO remove hook from any internal hook tables as well
|
||||||
|
|
||||||
uc_err err = uc_hook_del(eng, (uc_hook)hh);
|
uc_err err = uc_hook_del(eng, (uc_hook)hh);
|
||||||
if (err != UC_ERR_OK) {
|
if (err != UC_ERR_OK) {
|
||||||
throwException(env, err);
|
throwException(env, err);
|
||||||
|
@ -719,6 +719,63 @@ JNIEXPORT jobjectArray JNICALL Java_unicorn_Unicorn_mem_1regions
|
||||||
(*env)->SetObjectArrayElement(env, result, (jsize)i, mr);
|
(*env)->SetObjectArrayElement(env, result, (jsize)i, mr);
|
||||||
}
|
}
|
||||||
free(regions);
|
free(regions);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: unicorn_Unicorn
|
||||||
|
* Method: context_alloc
|
||||||
|
* Signature: ()J
|
||||||
|
*/
|
||||||
|
JNIEXPORT jlong JNICALL Java_unicorn_Unicorn_context_1alloc
|
||||||
|
(JNIEnv *env, jobject self) {
|
||||||
|
uc_engine *eng = getEngine(env, self);
|
||||||
|
uc_context *ctx;
|
||||||
|
uc_err err = uc_context_alloc(eng, &ctx);
|
||||||
|
if (err != UC_ERR_OK) {
|
||||||
|
throwException(env, err);
|
||||||
|
}
|
||||||
|
return (jlong)(uint64_t)ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: unicorn_Unicorn
|
||||||
|
* Method: context_free
|
||||||
|
* Signature: (J)V
|
||||||
|
*/
|
||||||
|
JNIEXPORT void JNICALL Java_unicorn_Unicorn_context_1free
|
||||||
|
(JNIEnv *env, jobject self, jlong ctx) {
|
||||||
|
uc_err err = uc_context_free((uc_context*)ctx);
|
||||||
|
if (err != UC_ERR_OK) {
|
||||||
|
throwException(env, err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: unicorn_Unicorn
|
||||||
|
* Method: context_save
|
||||||
|
* Signature: (J)V
|
||||||
|
*/
|
||||||
|
JNIEXPORT void JNICALL Java_unicorn_Unicorn_context_1save
|
||||||
|
(JNIEnv *env, jobject self, jlong ctx) {
|
||||||
|
uc_engine *eng = getEngine(env, self);
|
||||||
|
uc_err err = uc_context_save(eng, (uc_context*)ctx);
|
||||||
|
if (err != UC_ERR_OK) {
|
||||||
|
throwException(env, err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: unicorn_Unicorn
|
||||||
|
* Method: context_restore
|
||||||
|
* Signature: (J)V
|
||||||
|
*/
|
||||||
|
JNIEXPORT void JNICALL Java_unicorn_Unicorn_context_1restore
|
||||||
|
(JNIEnv *env, jobject self, jlong ctx) {
|
||||||
|
uc_engine *eng = getEngine(env, self);
|
||||||
|
uc_err err = uc_context_restore(eng, (uc_context*)ctx);
|
||||||
|
if (err != UC_ERR_OK) {
|
||||||
|
throwException(env, err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue