From 9cdb5cb745195695dfd8b0b2b98ac92ea6b1dc78 Mon Sep 17 00:00:00 2001 From: Robert Xiao Date: Fri, 5 May 2023 14:32:56 -0700 Subject: [PATCH 01/25] Reformat Java bindings. --- bindings/const_generator.py | 4 +- bindings/java/eclipse-formatter.xml | 399 ++ .../java/samples/SampleNetworkAuditing.java | 779 ++-- bindings/java/samples/Sample_arm.java | 235 +- bindings/java/samples/Sample_arm64.java | 168 +- bindings/java/samples/Sample_m68k.java | 295 +- bindings/java/samples/Sample_mips.java | 239 +- bindings/java/samples/Sample_sparc.java | 165 +- bindings/java/samples/Sample_x86.java | 1269 +++---- bindings/java/samples/Sample_x86_mmr.java | 84 +- bindings/java/samples/Shellcode.java | 256 +- bindings/java/unicorn/Arm64Const.java | 638 ++-- bindings/java/unicorn/ArmConst.java | 372 +- bindings/java/unicorn/BlockHook.java | 5 +- bindings/java/unicorn/CodeHook.java | 5 +- bindings/java/unicorn/EventMemHook.java | 6 +- bindings/java/unicorn/Hook.java | 1 + bindings/java/unicorn/InHook.java | 5 +- bindings/java/unicorn/InterruptHook.java | 5 +- bindings/java/unicorn/M68kConst.java | 64 +- bindings/java/unicorn/MemHook.java | 3 +- bindings/java/unicorn/MemRegion.java | 19 +- bindings/java/unicorn/MipsConst.java | 444 +-- bindings/java/unicorn/OutHook.java | 5 +- bindings/java/unicorn/PpcConst.java | 792 ++-- bindings/java/unicorn/ReadHook.java | 5 +- bindings/java/unicorn/RiscvConst.java | 548 +-- bindings/java/unicorn/S390xConst.java | 226 +- bindings/java/unicorn/SparcConst.java | 254 +- bindings/java/unicorn/SyscallHook.java | 5 +- bindings/java/unicorn/TriCoreConst.java | 238 +- bindings/java/unicorn/Unicorn.java | 1647 +++++---- bindings/java/unicorn/UnicornConst.java | 270 +- bindings/java/unicorn/UnicornException.java | 14 +- bindings/java/unicorn/WriteHook.java | 6 +- bindings/java/unicorn/X86Const.java | 3242 ++++++++--------- bindings/java/unicorn/X86_MMR.java | 35 +- bindings/java/unicorn_Unicorn.c | 1010 ++--- 38 files changed, 7217 insertions(+), 6540 deletions(-) create mode 100644 bindings/java/eclipse-formatter.xml diff --git a/bindings/const_generator.py b/bindings/const_generator.py index b2607031..00096c6d 100644 --- a/bindings/const_generator.py +++ b/bindings/const_generator.py @@ -72,7 +72,7 @@ template = { 'java': { 'header': "// For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT\n\npackage unicorn;\n\npublic interface %sConst {\n", 'footer': "\n}\n", - 'line_format': ' public static final int UC_%s = %s;\n', + 'line_format': ' public static final int UC_%s = %s;\n', 'out_file': './java/unicorn/%sConst.java', # prefixes for constant filenames of all archs - case sensitive 'arm.h': 'Arm', @@ -86,7 +86,7 @@ template = { 's390x.h' : 'S390x', 'tricore.h' : 'TriCore', 'unicorn.h': 'Unicorn', - 'comment_open': '//', + 'comment_open': ' //', 'comment_close': '', }, 'dotnet': { diff --git a/bindings/java/eclipse-formatter.xml b/bindings/java/eclipse-formatter.xml new file mode 100644 index 00000000..697e35ea --- /dev/null +++ b/bindings/java/eclipse-formatter.xml @@ -0,0 +1,399 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bindings/java/samples/SampleNetworkAuditing.java b/bindings/java/samples/SampleNetworkAuditing.java index 7a822acb..6f572dc2 100644 --- a/bindings/java/samples/SampleNetworkAuditing.java +++ b/bindings/java/samples/SampleNetworkAuditing.java @@ -27,403 +27,446 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import unicorn.*; import java.util.*; - public class SampleNetworkAuditing { - public static long next_id = 3; - public static final int SIZE_REG = 4; + public static long next_id = 3; + public static final int SIZE_REG = 4; - private static LogChain fd_chains = new LogChain(); + private static LogChain fd_chains = new LogChain(); - public static long get_id() { - return next_id++; - } + public static long get_id() { + return next_id++; + } - 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 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 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; + } + private static class MyInterruptHook implements InterruptHook { + // callback for tracing Linux interrupt + public void hook(Unicorn uc, int intno, Object user) { + // System.err.println(String.format("Interrupt 0x%x, from Unicorn 0x%x", intno, u.hashCode())); - private static class MyInterruptHook implements InterruptHook { - // callback for tracing Linux interrupt - public void hook(Unicorn uc, int intno, Object user) { -// System.err.println(String.format("Interrupt 0x%x, from Unicorn 0x%x", intno, u.hashCode())); - - // only handle Linux syscall - if (intno != 0x80) { - return; - } - Long eax = (Long)uc.reg_read(Unicorn.UC_X86_REG_EAX); - Long ebx = (Long)uc.reg_read(Unicorn.UC_X86_REG_EBX); - Long ecx = (Long)uc.reg_read(Unicorn.UC_X86_REG_ECX); - Long edx = (Long)uc.reg_read(Unicorn.UC_X86_REG_EDX); - Long eip = (Long)uc.reg_read(Unicorn.UC_X86_REG_EIP); - - // System.out.printf(">>> INTERRUPT %d\n", toInt(eax)); - - if (eax == 1) { // sys_exit - System.out.printf(">>> SYS_EXIT\n"); - uc.emu_stop(); - } - else if (eax == 3) { // sys_read - long fd = ebx; - long buf = ecx; - long count = edx; - - String uuid = UUID.randomUUID().toString().substring(0, 32); - - byte[] dummy_content = Arrays.copyOfRange(uuid.getBytes(), 0, (int)Math.min(count, uuid.length())); - uc.mem_write(buf, dummy_content); - - String msg = String.format("read %d bytes from fd(%d) with dummy_content(%s)", count, fd, uuid.substring(0, dummy_content.length)); - - fd_chains.add_log(fd, msg); - System.out.printf(">>> %s\n", msg); - } - else if (eax == 4) { // sys_write - long fd = ebx; - long buf = ecx; - long count = edx; - - byte[] content = uc.mem_read(buf, count); - - String msg = String.format("write data=%s count=%d to fd(%d)", new String(content), count, fd); - - System.out.printf(">>> %s\n", msg); - fd_chains.add_log(fd, msg); - } - else if (eax == 5) { // sys_open - long filename_addr = ebx; - long flags = ecx; - long mode = edx; - String filename = read_string(uc, filename_addr); - - Long dummy_fd = get_id(); - 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); - - fd_chains.create_chain(dummy_fd); - fd_chains.add_log(dummy_fd, msg); - System.out.printf(">>> %s\n", msg); - } - else if (eax == 11) { // sys_execv - // System.out.printf(">>> ebx=0x%x, ecx=0x%x, edx=0x%x\n", ebx, ecx, edx)); - String filename = read_string(uc, ebx); - - System.out.printf(">>> SYS_EXECV filename=%s\n", filename); - } - else if (eax == 63) { // sys_dup2 - fd_chains.link_fd(ecx, ebx); - System.out.printf(">>> SYS_DUP2 oldfd=%d newfd=%d\n", ebx, ecx); - } - else if (eax == 102) { // sys_socketcall - // ref: http://www.skyfree.org/linux/kernel_network/socket.html - Long call = (Long)uc.reg_read(Unicorn.UC_X86_REG_EBX); - Long args = (Long)uc.reg_read(Unicorn.UC_X86_REG_ECX); - - // int sys_socketcall(int call, unsigned long *args) - if (call == 1) { // sys_socket - // err = sys_socket(a0,a1,a[2]) - // int sys_socket(int family, int type, int protocol) - long family = toInt(uc.mem_read(args, 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 dummy_fd = get_id(); - uc.reg_write(Unicorn.UC_X86_REG_EAX, dummy_fd); - - 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); - fd_chains.create_chain(dummy_fd); - fd_chains.add_log(dummy_fd, msg); - print_sockcall(msg); - } - else if (family == 3) { // AF_INET6 - } + // only handle Linux syscall + if (intno != 0x80) { + return; } - else if (call == 2) { // sys_bind - long fd = toInt(uc.mem_read(args, SIZE_REG)); - long umyaddr = toInt(uc.mem_read(args + SIZE_REG, SIZE_REG)); - long addrlen = toInt(uc.mem_read(args + SIZE_REG * 2, SIZE_REG)); - - byte[] sock_addr = uc.mem_read(umyaddr, addrlen); - - String msg = String.format("fd(%d) bind to %s", fd, parse_sock_address(sock_addr)); - fd_chains.add_log(fd, msg); - print_sockcall(msg); + Long eax = (Long) uc.reg_read(Unicorn.UC_X86_REG_EAX); + Long ebx = (Long) uc.reg_read(Unicorn.UC_X86_REG_EBX); + Long ecx = (Long) uc.reg_read(Unicorn.UC_X86_REG_ECX); + Long edx = (Long) uc.reg_read(Unicorn.UC_X86_REG_EDX); + Long eip = (Long) uc.reg_read(Unicorn.UC_X86_REG_EIP); + + // System.out.printf(">>> INTERRUPT %d\n", toInt(eax)); + + if (eax == 1) { // sys_exit + System.out.printf(">>> SYS_EXIT\n"); + uc.emu_stop(); + } else if (eax == 3) { // sys_read + long fd = ebx; + long buf = ecx; + long count = edx; + + String uuid = UUID.randomUUID().toString().substring(0, 32); + + byte[] dummy_content = Arrays.copyOfRange(uuid.getBytes(), 0, + (int) Math.min(count, uuid.length())); + uc.mem_write(buf, dummy_content); + + String msg = String.format( + "read %d bytes from fd(%d) with dummy_content(%s)", count, + fd, uuid.substring(0, dummy_content.length)); + + fd_chains.add_log(fd, msg); + System.out.printf(">>> %s\n", msg); + } else if (eax == 4) { // sys_write + long fd = ebx; + long buf = ecx; + long count = edx; + + byte[] content = uc.mem_read(buf, count); + + String msg = String.format("write data=%s count=%d to fd(%d)", + new String(content), count, fd); + + System.out.printf(">>> %s\n", msg); + fd_chains.add_log(fd, msg); + } else if (eax == 5) { // sys_open + long filename_addr = ebx; + long flags = ecx; + long mode = edx; + String filename = read_string(uc, filename_addr); + + Long dummy_fd = get_id(); + 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); + + fd_chains.create_chain(dummy_fd); + fd_chains.add_log(dummy_fd, msg); + System.out.printf(">>> %s\n", msg); + } else if (eax == 11) { // sys_execv + // System.out.printf(">>> ebx=0x%x, ecx=0x%x, edx=0x%x\n", ebx, ecx, edx)); + String filename = read_string(uc, ebx); + + System.out.printf(">>> SYS_EXECV filename=%s\n", filename); + } else if (eax == 63) { // sys_dup2 + fd_chains.link_fd(ecx, ebx); + System.out.printf(">>> SYS_DUP2 oldfd=%d newfd=%d\n", ebx, ecx); + } else if (eax == 102) { // sys_socketcall + // ref: http://www.skyfree.org/linux/kernel_network/socket.html + Long call = (Long) uc.reg_read(Unicorn.UC_X86_REG_EBX); + Long args = (Long) uc.reg_read(Unicorn.UC_X86_REG_ECX); + + // int sys_socketcall(int call, unsigned long *args) + if (call == 1) { // sys_socket + // err = sys_socket(a0,a1,a[2]) + // int sys_socket(int family, int type, int protocol) + long family = toInt(uc.mem_read(args, 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 dummy_fd = get_id(); + uc.reg_write(Unicorn.UC_X86_REG_EAX, dummy_fd); + + 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); + fd_chains.create_chain(dummy_fd); + fd_chains.add_log(dummy_fd, msg); + print_sockcall(msg); + } else if (family == 3) { // AF_INET6 + } + } else if (call == 2) { // sys_bind + long fd = toInt(uc.mem_read(args, SIZE_REG)); + long umyaddr = + toInt(uc.mem_read(args + SIZE_REG, SIZE_REG)); + long addrlen = + toInt(uc.mem_read(args + SIZE_REG * 2, SIZE_REG)); + + byte[] sock_addr = uc.mem_read(umyaddr, addrlen); + + String msg = String.format("fd(%d) bind to %s", fd, + parse_sock_address(sock_addr)); + fd_chains.add_log(fd, msg); + print_sockcall(msg); + } else if (call == 3) { // sys_connect + // err = sys_connect(a0, (struct sockaddr *)a1, a[2]) + // int sys_connect(int fd, struct sockaddr *uservaddr, int addrlen) + long fd = toInt(uc.mem_read(args, SIZE_REG)); + long uservaddr = + toInt(uc.mem_read(args + SIZE_REG, SIZE_REG)); + long addrlen = + toInt(uc.mem_read(args + SIZE_REG * 2, SIZE_REG)); + + byte[] sock_addr = uc.mem_read(uservaddr, addrlen); + String msg = String.format("fd(%d) connect to %s", fd, + parse_sock_address(sock_addr)); + fd_chains.add_log(fd, msg); + print_sockcall(msg); + } else if (call == 4) { // sys_listen + long fd = toInt(uc.mem_read(args, SIZE_REG)); + long backlog = + toInt(uc.mem_read(args + SIZE_REG, SIZE_REG)); + + String msg = String.format( + "fd(%d) listened with backlog=%d", fd, backlog); + fd_chains.add_log(fd, msg); + print_sockcall(msg); + } else if (call == 5) { // sys_accept + long fd = toInt(uc.mem_read(args, SIZE_REG)); + long upeer_sockaddr = + toInt(uc.mem_read(args + SIZE_REG, SIZE_REG)); + long upeer_addrlen = + toInt(uc.mem_read(args + SIZE_REG * 2, SIZE_REG)); + + // System.out.printf(">>> upeer_sockaddr=0x%x, upeer_addrlen=%d\n" % (upeer_sockaddr, upeer_addrlen)) + + if (upeer_sockaddr == 0x0) { + print_sockcall( + String.format("fd(%d) accept client", fd)); + } else { + long upeer_len = toInt(uc.mem_read(upeer_addrlen, 4)); + + byte[] sock_addr = + uc.mem_read(upeer_sockaddr, upeer_len); + + String msg = + String.format("fd(%d) accept client with upeer=%s", + fd, parse_sock_address(sock_addr)); + fd_chains.add_log(fd, msg); + print_sockcall(msg); + } + } else if (call == 9) { // sys_send + long fd = toInt(uc.mem_read(args, SIZE_REG)); + long buff = toInt(uc.mem_read(args + SIZE_REG, SIZE_REG)); + long length = + toInt(uc.mem_read(args + SIZE_REG * 2, SIZE_REG)); + long flags = + toInt(uc.mem_read(args + SIZE_REG * 3, SIZE_REG)); + + byte[] buf = uc.mem_read(buff, length); + String msg = String.format("fd(%d) send data=%s", fd, + new String(buf)); + fd_chains.add_log(fd, msg); + print_sockcall(msg); + } else if (call == 11) { // sys_receive + long fd = toInt(uc.mem_read(args, SIZE_REG)); + long ubuf = toInt(uc.mem_read(args + SIZE_REG, SIZE_REG)); + long size = + toInt(uc.mem_read(args + SIZE_REG * 2, SIZE_REG)); + long flags = + toInt(uc.mem_read(args + SIZE_REG * 3, SIZE_REG)); + + String msg = String.format( + "fd(%d) is gonna receive data with size=%d flags=%d", + fd, size, flags); + fd_chains.add_log(fd, msg); + print_sockcall(msg); + } else if (call == 13) { // sys_shutdown + long fd = toInt(uc.mem_read(args, SIZE_REG)); + long how = toInt(uc.mem_read(args + SIZE_REG, SIZE_REG)); + + String msg = String.format( + "fd(%d) is shutted down because of %d", fd, how); + fd_chains.add_log(fd, msg); + print_sockcall(msg); + } } - else if (call == 3) { // sys_connect - // err = sys_connect(a0, (struct sockaddr *)a1, a[2]) - // int sys_connect(int fd, struct sockaddr *uservaddr, int addrlen) - long fd = toInt(uc.mem_read(args, SIZE_REG)); - long uservaddr = toInt(uc.mem_read(args + SIZE_REG, SIZE_REG)); - long addrlen = toInt(uc.mem_read(args + SIZE_REG * 2, SIZE_REG)); - - byte[] sock_addr = uc.mem_read(uservaddr, addrlen); - String msg = String.format("fd(%d) connect to %s", fd, parse_sock_address(sock_addr)); - fd_chains.add_log(fd, msg); - print_sockcall(msg); + } + } + + public static final Hashtable SOCKET_TYPES; + public static final Hashtable ADDR_FAMILY; + + static { + SOCKET_TYPES = new Hashtable(); + ADDR_FAMILY = new Hashtable(); + SOCKET_TYPES.put(1L, "SOCK_STREAM"); + SOCKET_TYPES.put(2L, "SOCK_DGRAM"); + SOCKET_TYPES.put(3L, "SOCK_RAW"); + SOCKET_TYPES.put(4L, "SOCK_RDM"); + SOCKET_TYPES.put(5L, "SOCK_SEQPACKET"); + SOCKET_TYPES.put(10L, "SOCK_PACKET"); + + ADDR_FAMILY.put(0L, "AF_UNSPEC"); + ADDR_FAMILY.put(1L, "AF_UNIX"); + ADDR_FAMILY.put(2L, "AF_INET"); + ADDR_FAMILY.put(3L, "AF_AX25"); + ADDR_FAMILY.put(4L, "AF_IPX"); + ADDR_FAMILY.put(5L, "AF_APPLETALK"); + ADDR_FAMILY.put(6L, "AF_NETROM"); + ADDR_FAMILY.put(7L, "AF_BRIDGE"); + ADDR_FAMILY.put(8L, "AF_AAL5"); + ADDR_FAMILY.put(9L, "AF_X25"); + ADDR_FAMILY.put(10L, "AF_INET6"); + ADDR_FAMILY.put(12L, "AF_MAX"); + } + + // http://shell-storm.org/shellcode/files/shellcode-861.php + public static final byte[] X86_SEND_ETCPASSWD = { 106, 102, 88, 49, -37, 67, + 49, -46, 82, 106, 1, 106, 2, -119, -31, -51, -128, -119, -58, 106, 102, + 88, 67, 104, 127, 1, 1, 1, 102, 104, 48, 57, 102, 83, -119, -31, 106, + 16, 81, 86, -119, -31, 67, -51, -128, -119, -58, 106, 1, 89, -80, 63, + -51, -128, -21, 39, 106, 5, 88, 91, 49, -55, -51, -128, -119, -61, -80, + 3, -119, -25, -119, -7, 49, -46, -74, -1, -78, -1, -51, -128, -119, -62, + 106, 4, 88, -77, 1, -51, -128, 106, 1, 88, 67, -51, -128, -24, -44, -1, + -1, -1, 47, 101, 116, 99, 47, 112, 97, 115, 115, 119, 100 }; + // http://shell-storm.org/shellcode/files/shellcode-882.php + public static final byte[] X86_BIND_TCP = { 106, 102, 88, 106, 1, 91, 49, + -10, 86, 83, 106, 2, -119, -31, -51, -128, 95, -105, -109, -80, 102, 86, + 102, 104, 5, 57, 102, 83, -119, -31, 106, 16, 81, 87, -119, -31, -51, + -128, -80, 102, -77, 4, 86, 87, -119, -31, -51, -128, -80, 102, 67, 86, + 86, 87, -119, -31, -51, -128, 89, 89, -79, 2, -109, -80, 63, -51, -128, + 73, 121, -7, -80, 11, 104, 47, 47, 115, 104, 104, 47, 98, 105, 110, + -119, -29, 65, -119, -54, -51, -128 }; + // http://shell-storm.org/shellcode/files/shellcode-883.php + public static final byte[] X86_REVERSE_TCP = { 106, 102, 88, 106, 1, 91, 49, + -46, 82, 83, 106, 2, -119, -31, -51, -128, -110, -80, 102, 104, 127, 1, + 1, 1, 102, 104, 5, 57, 67, 102, 83, -119, -31, 106, 16, 81, 82, -119, + -31, 67, -51, -128, 106, 2, 89, -121, -38, -80, 63, -51, -128, 73, 121, + -7, -80, 11, 65, -119, -54, 82, 104, 47, 47, 115, 104, 104, 47, 98, 105, + 110, -119, -29, -51, -128 }; + // http://shell-storm.org/shellcode/files/shellcode-849.php + public static final byte[] X86_REVERSE_TCP_2 = { 49, -64, 49, -37, 49, -55, + 49, -46, -80, 102, -77, 1, 81, 106, 6, 106, 1, 106, 2, -119, -31, -51, + -128, -119, -58, -80, 102, 49, -37, -77, 2, 104, -64, -88, 1, 10, 102, + 104, 122, 105, 102, 83, -2, -61, -119, -31, 106, 16, 81, 86, -119, -31, + -51, -128, 49, -55, -79, 3, -2, -55, -80, 63, -51, -128, 117, -8, 49, + -64, 82, 104, 110, 47, 115, 104, 104, 47, 47, 98, 105, -119, -29, 82, + 83, -119, -31, 82, -119, -30, -80, 11, -51, -128 }; + + // memory address where emulation starts + public static final int ADDRESS = 0x1000000; + + public static String join(ArrayList l, String sep) { + boolean first = true; + StringBuilder res = new StringBuilder(); + for (String s : l) { + if (!first) { + res.append(sep); } - else if (call == 4) { // sys_listen - long fd = toInt(uc.mem_read(args, SIZE_REG)); - long backlog = toInt(uc.mem_read(args + SIZE_REG, SIZE_REG)); - - String msg = String.format("fd(%d) listened with backlog=%d", fd, backlog); - fd_chains.add_log(fd, msg); - print_sockcall(msg); + res.append(s); + first = false; + } + return res.toString(); + } + + private static class LogChain { + public Hashtable> __chains = + new Hashtable>(); + public Hashtable> __linking_fds = + new Hashtable>(); + + public void clean() { + __chains.clear(); + __linking_fds.clear(); + } + + public void create_chain(long id) { + if (!__chains.containsKey(id)) { + __chains.put(id, new ArrayList()); + } else { + System.out.printf("LogChain: id %d existed\n", id); } - else if (call == 5) { // sys_accept - long fd = toInt(uc.mem_read(args, SIZE_REG)); - long upeer_sockaddr = toInt(uc.mem_read(args + SIZE_REG, SIZE_REG)); - long upeer_addrlen = toInt(uc.mem_read(args + SIZE_REG * 2, SIZE_REG)); - - // System.out.printf(">>> upeer_sockaddr=0x%x, upeer_addrlen=%d\n" % (upeer_sockaddr, upeer_addrlen)) - - if (upeer_sockaddr == 0x0) { - print_sockcall(String.format("fd(%d) accept client", fd)); - } - else { - long upeer_len = toInt(uc.mem_read(upeer_addrlen, 4)); - - byte[] sock_addr = uc.mem_read(upeer_sockaddr, upeer_len); - - String msg = String.format("fd(%d) accept client with upeer=%s", fd, parse_sock_address(sock_addr)); - fd_chains.add_log(fd, msg); - print_sockcall(msg); - } + } + + public void add_log(long id, String msg) { + long fd = get_original_fd(id); + + if (fd != -1) { + __chains.get(fd).add(msg); + } else { + System.out.printf("LogChain: id %d doesn't exist\n", id); } - else if (call == 9) { // sys_send - long fd = toInt(uc.mem_read(args, SIZE_REG)); - long buff = toInt(uc.mem_read(args + SIZE_REG, SIZE_REG)); - long length = toInt(uc.mem_read(args + SIZE_REG * 2, SIZE_REG)); - long flags = toInt(uc.mem_read(args + SIZE_REG * 3, SIZE_REG)); - - byte[] buf = uc.mem_read(buff, length); - String msg = String.format("fd(%d) send data=%s", fd, new String(buf)); - fd_chains.add_log(fd, msg); - print_sockcall(msg); + } + + public void link_fd(long from_fd, long to_fd) { + if (!__linking_fds.containsKey(to_fd)) { + __linking_fds.put(to_fd, new ArrayList()); } - else if (call == 11) { // sys_receive - long fd = toInt(uc.mem_read(args, SIZE_REG)); - long ubuf = toInt(uc.mem_read(args + SIZE_REG, SIZE_REG)); - long size = toInt(uc.mem_read(args + SIZE_REG * 2, SIZE_REG)); - long flags = toInt(uc.mem_read(args + SIZE_REG * 3, SIZE_REG)); - - String msg = String.format("fd(%d) is gonna receive data with size=%d flags=%d", fd, size, flags); - fd_chains.add_log(fd, msg); - print_sockcall(msg); + + __linking_fds.get(to_fd).add(from_fd); + } + + public long get_original_fd(long fd) { + if (__chains.containsKey(fd)) { + return fd; } - else if (call == 13) { // sys_shutdown - long fd = toInt(uc.mem_read(args, SIZE_REG)); - long how = toInt(uc.mem_read(args + SIZE_REG, SIZE_REG)); - - String msg = String.format("fd(%d) is shutted down because of %d", fd, how); - fd_chains.add_log(fd, msg); - print_sockcall(msg); - } - } - } - } - - public static final Hashtable SOCKET_TYPES; - public static final Hashtable ADDR_FAMILY; - static { - SOCKET_TYPES = new Hashtable(); - ADDR_FAMILY = new Hashtable(); - SOCKET_TYPES.put(1L, "SOCK_STREAM"); - SOCKET_TYPES.put(2L, "SOCK_DGRAM"); - SOCKET_TYPES.put(3L, "SOCK_RAW"); - SOCKET_TYPES.put(4L, "SOCK_RDM"); - SOCKET_TYPES.put(5L, "SOCK_SEQPACKET"); - SOCKET_TYPES.put(10L, "SOCK_PACKET"); - - ADDR_FAMILY.put(0L, "AF_UNSPEC"); - ADDR_FAMILY.put(1L, "AF_UNIX"); - ADDR_FAMILY.put(2L, "AF_INET"); - ADDR_FAMILY.put(3L, "AF_AX25"); - ADDR_FAMILY.put(4L, "AF_IPX"); - ADDR_FAMILY.put(5L, "AF_APPLETALK"); - ADDR_FAMILY.put(6L, "AF_NETROM"); - ADDR_FAMILY.put(7L, "AF_BRIDGE"); - ADDR_FAMILY.put(8L, "AF_AAL5"); - ADDR_FAMILY.put(9L, "AF_X25"); - ADDR_FAMILY.put(10L, "AF_INET6"); - ADDR_FAMILY.put(12L, "AF_MAX"); - } -// http://shell-storm.org/shellcode/files/shellcode-861.php - public static final byte[] X86_SEND_ETCPASSWD = {106,102,88,49,-37,67,49,-46,82,106,1,106,2,-119,-31,-51,-128,-119,-58,106,102,88,67,104,127,1,1,1,102,104,48,57,102,83,-119,-31,106,16,81,86,-119,-31,67,-51,-128,-119,-58,106,1,89,-80,63,-51,-128,-21,39,106,5,88,91,49,-55,-51,-128,-119,-61,-80,3,-119,-25,-119,-7,49,-46,-74,-1,-78,-1,-51,-128,-119,-62,106,4,88,-77,1,-51,-128,106,1,88,67,-51,-128,-24,-44,-1,-1,-1,47,101,116,99,47,112,97,115,115,119,100}; -// http://shell-storm.org/shellcode/files/shellcode-882.php - public static final byte[] X86_BIND_TCP = {106,102,88,106,1,91,49,-10,86,83,106,2,-119,-31,-51,-128,95,-105,-109,-80,102,86,102,104,5,57,102,83,-119,-31,106,16,81,87,-119,-31,-51,-128,-80,102,-77,4,86,87,-119,-31,-51,-128,-80,102,67,86,86,87,-119,-31,-51,-128,89,89,-79,2,-109,-80,63,-51,-128,73,121,-7,-80,11,104,47,47,115,104,104,47,98,105,110,-119,-29,65,-119,-54,-51,-128}; -// http://shell-storm.org/shellcode/files/shellcode-883.php - public static final byte[] X86_REVERSE_TCP = {106,102,88,106,1,91,49,-46,82,83,106,2,-119,-31,-51,-128,-110,-80,102,104,127,1,1,1,102,104,5,57,67,102,83,-119,-31,106,16,81,82,-119,-31,67,-51,-128,106,2,89,-121,-38,-80,63,-51,-128,73,121,-7,-80,11,65,-119,-54,82,104,47,47,115,104,104,47,98,105,110,-119,-29,-51,-128}; -// http://shell-storm.org/shellcode/files/shellcode-849.php - public static final byte[] X86_REVERSE_TCP_2 = {49,-64,49,-37,49,-55,49,-46,-80,102,-77,1,81,106,6,106,1,106,2,-119,-31,-51,-128,-119,-58,-80,102,49,-37,-77,2,104,-64,-88,1,10,102,104,122,105,102,83,-2,-61,-119,-31,106,16,81,86,-119,-31,-51,-128,49,-55,-79,3,-2,-55,-80,63,-51,-128,117,-8,49,-64,82,104,110,47,115,104,104,47,47,98,105,-119,-29,82,83,-119,-31,82,-119,-30,-80,11,-51,-128}; + for (Long orig_fd : __linking_fds.keySet()) { + if (__linking_fds.get(orig_fd).contains(fd)) + return orig_fd; + } + return -1; + } - // memory address where emulation starts - public static final int ADDRESS = 0x1000000; + public void print_report() { + System.out.printf("\n----------------"); + System.out.printf("\n| START REPORT |"); + System.out.printf("\n----------------\n\n"); + for (Long fd : __chains.keySet()) { + System.out.printf("---- START FD(%d) ----\n", fd); + System.out.println(join(__chains.get(fd), "\n")); + System.out.printf("---- END FD(%d) ----\n", fd); + } + System.out.printf("\n--------------"); + System.out.printf("\n| END REPORT |"); + System.out.printf("\n--------------\n\n"); + } + } + // end supported classes - public static String join(ArrayList l, String sep) { - boolean first = true; - StringBuilder res = new StringBuilder(); - for (String s : l) { - if (!first) { - res.append(sep); - } - res.append(s); - first = false; - } - return res.toString(); - } + // utilities + static String read_string(Unicorn uc, long addr) { + StringBuilder ret = new StringBuilder(); + char c; + do { + c = (char) (uc.mem_read(addr++, 1)[0] & 0xff); + if (c != 0) { + ret.append(c); + } + } while (c != 0); - private static class LogChain { - public Hashtable> __chains = new Hashtable>(); - public Hashtable> __linking_fds = new Hashtable>(); + return ret.toString(); + } - public void clean() { - __chains.clear(); - __linking_fds.clear(); - } + static String parse_sock_address(byte[] sock_addr) { + int sin_family = ((sock_addr[0] & 0xff) + (sock_addr[1] << 8)) & 0xffff; - public void create_chain(long id) { - if (!__chains.containsKey(id)) { - __chains.put(id, new ArrayList()); - } - else { - System.out.printf("LogChain: id %d existed\n", id); - } - } + if (sin_family == 2) { // AF_INET + int sin_port = + ((sock_addr[3] & 0xff) + (sock_addr[2] << 8)) & 0xffff; + return String.format("%d.%d.%d.%d:%d", sock_addr[4] & 0xff, + sock_addr[5] & 0xff, sock_addr[6] & 0xff, sock_addr[7] & 0xff, + sin_port); + } else if (sin_family == 6) // AF_INET6 + return ""; + return null; + } - public void add_log(long id, String msg) { - long fd = get_original_fd(id); - - if (fd != -1) { - __chains.get(fd).add(msg); - } - else { - System.out.printf("LogChain: id %d doesn't exist\n", id); - } - } + static void print_sockcall(String msg) { + System.out.printf(">>> SOCKCALL %s\n", msg); + } + // end utilities - public void link_fd(long from_fd, long to_fd) { - if (!__linking_fds.containsKey(to_fd)) { - __linking_fds.put(to_fd, new ArrayList()); - } - - __linking_fds.get(to_fd).add(from_fd); - } - - public long get_original_fd(long fd) { - if (__chains.containsKey(fd)) { - return fd; - } - - for (Long orig_fd : __linking_fds.keySet()) { - if (__linking_fds.get(orig_fd).contains(fd)) - return orig_fd; - } - return -1; - } + static void test_i386(byte[] code) { + fd_chains.clean(); + System.out.printf("Emulate i386 code\n"); + try { + // Initialize emulator in X86-32bit mode + Unicorn mu = new Unicorn(Unicorn.UC_ARCH_X86, Unicorn.UC_MODE_32); - public void print_report() { - System.out.printf("\n----------------"); - System.out.printf("\n| START REPORT |"); - System.out.printf("\n----------------\n\n"); - for (Long fd : __chains.keySet()) { - System.out.printf("---- START FD(%d) ----\n", fd); - System.out.println(join(__chains.get(fd), "\n")); - System.out.printf("---- END FD(%d) ----\n", fd); - } - System.out.printf("\n--------------"); - System.out.printf("\n| END REPORT |"); - System.out.printf("\n--------------\n\n"); - } - } - // end supported classes + // map 2MB memory for this emulation + mu.mem_map(ADDRESS, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL); - // utilities - static String read_string(Unicorn uc, long addr) { - StringBuilder ret = new StringBuilder(); - char c; - do { - c = (char)(uc.mem_read(addr++, 1)[0] & 0xff); - if (c != 0) { - ret.append(c); - } - } while (c != 0); - - return ret.toString(); - } + // write machine code to be emulated to memory + mu.mem_write(ADDRESS, code); - static String parse_sock_address(byte[] sock_addr) { - int sin_family = ((sock_addr[0] & 0xff) + (sock_addr[1] << 8)) & 0xffff; - - if (sin_family == 2) { // AF_INET - int sin_port = ((sock_addr[3] & 0xff) + (sock_addr[2] << 8)) & 0xffff; - return String.format("%d.%d.%d.%d:%d", sock_addr[4] & 0xff, sock_addr[5] & 0xff, sock_addr[6] & 0xff, sock_addr[7] & 0xff, sin_port); - } - else if (sin_family == 6) // AF_INET6 - return ""; - return null; - } + // initialize stack + mu.reg_write(Unicorn.UC_X86_REG_ESP, ADDRESS + 0x200000L); - static void print_sockcall(String msg) { - System.out.printf(">>> SOCKCALL %s\n", msg); - } - // end utilities + // handle interrupt ourself + mu.hook_add(new MyInterruptHook(), null); - static void test_i386(byte[] code) { - fd_chains.clean(); - System.out.printf("Emulate i386 code\n"); - try { - // Initialize emulator in X86-32bit mode - Unicorn mu = new Unicorn(Unicorn.UC_ARCH_X86, Unicorn.UC_MODE_32); - - // map 2MB memory for this emulation - mu.mem_map(ADDRESS, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL); - - // write machine code to be emulated to memory - mu.mem_write(ADDRESS, code); - - // initialize stack - mu.reg_write(Unicorn.UC_X86_REG_ESP, ADDRESS + 0x200000L); - - // handle interrupt ourself - mu.hook_add(new MyInterruptHook(), null); - - // emulate machine code in infinite time - mu.emu_start(ADDRESS, ADDRESS + code.length, 0, 0); - - // now print out some registers - System.out.printf(">>> Emulation done\n"); + // emulate machine code in infinite time + mu.emu_start(ADDRESS, ADDRESS + code.length, 0, 0); - } catch (UnicornException uex) { - System.out.printf("ERROR: %s\n", uex.getMessage()); - } + // now print out some registers + System.out.printf(">>> Emulation done\n"); - fd_chains.print_report(); - } - - public static void main(String args[]) { - test_i386(X86_SEND_ETCPASSWD); - test_i386(X86_BIND_TCP); - test_i386(X86_REVERSE_TCP); - test_i386(X86_REVERSE_TCP_2); - } + } catch (UnicornException uex) { + System.out.printf("ERROR: %s\n", uex.getMessage()); + } + + fd_chains.print_report(); + } + + public static void main(String args[]) { + test_i386(X86_SEND_ETCPASSWD); + test_i386(X86_BIND_TCP); + test_i386(X86_REVERSE_TCP); + test_i386(X86_REVERSE_TCP_2); + } } diff --git a/bindings/java/samples/Sample_arm.java b/bindings/java/samples/Sample_arm.java index 4d85fb7d..67ba9a6a 100644 --- a/bindings/java/samples/Sample_arm.java +++ b/bindings/java/samples/Sample_arm.java @@ -7,124 +7,125 @@ 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; + // 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 - 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; - } + // memory address where emulation starts + public static final int ADDRESS = 0x10000; - 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() - { - - Long r0 = 0x1234L; // R0 register - Long r2 = 0x6789L; // R1 register - Long r3 = 0x3333L; // R2 register - Long 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, Unicorn.UC_PROT_ALL); - - // 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 = (Long)u.reg_read(Unicorn.UC_ARM_REG_R0); - r1 = (Long)u.reg_read(Unicorn.UC_ARM_REG_R1); - System.out.print(String.format(">>> R0 = 0x%x\n", r0.intValue())); - System.out.print(String.format(">>> R1 = 0x%x\n", r1.intValue())); - - u.close(); - } - - static void test_thumb() - { - - Long sp = 0x1234L; // 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, Unicorn.UC_PROT_ALL); - - // 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 | 1, ADDRESS + THUMB_CODE.length, 0, 0); - - // now print out some registers - System.out.print(">>> Emulation done. Below is the CPU context\n"); - - sp = (Long)u.reg_read(Unicorn.UC_ARM_REG_SP); - System.out.print(String.format(">>> SP = 0x%x\n", sp.intValue())); - - u.close(); - } - - public static void main(String args[]) - { - test_arm(); - System.out.print("==========================\n"); - test_thumb(); - } + 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() { + + Long r0 = 0x1234L; // R0 register + Long r2 = 0x6789L; // R1 register + Long r3 = 0x3333L; // R2 register + Long 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, Unicorn.UC_PROT_ALL); + + // 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 = (Long) u.reg_read(Unicorn.UC_ARM_REG_R0); + r1 = (Long) u.reg_read(Unicorn.UC_ARM_REG_R1); + System.out.print(String.format(">>> R0 = 0x%x\n", r0.intValue())); + System.out.print(String.format(">>> R1 = 0x%x\n", r1.intValue())); + + u.close(); + } + + static void test_thumb() { + + Long sp = 0x1234L; // 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, Unicorn.UC_PROT_ALL); + + // 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 | 1, ADDRESS + THUMB_CODE.length, 0, 0); + + // now print out some registers + System.out.print(">>> Emulation done. Below is the CPU context\n"); + + sp = (Long) u.reg_read(Unicorn.UC_ARM_REG_SP); + System.out.print(String.format(">>> SP = 0x%x\n", sp.intValue())); + + u.close(); + } + + public static void main(String args[]) { + test_arm(); + System.out.print("==========================\n"); + test_thumb(); + } } diff --git a/bindings/java/samples/Sample_arm64.java b/bindings/java/samples/Sample_arm64.java index 0f7e5f32..82e79fcc 100644 --- a/bindings/java/samples/Sample_arm64.java +++ b/bindings/java/samples/Sample_arm64.java @@ -28,88 +28,90 @@ 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; - } + // code to be emulated + public static final byte[] ARM_CODE = { -85, 1, 15, -117 }; // add x11, x13, x15 - 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() - { - - Long x11 = 0x1234L; // X11 register - Long x13 = 0x6789L; // X13 register - Long x15 = 0x3333L; // 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, Unicorn.UC_PROT_ALL); - - // 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 = (Long)u.reg_read(Unicorn.UC_ARM64_REG_X11); - System.out.print(String.format(">>> X11 = 0x%x\n", x11.longValue())); - - u.close(); - } - - public static void main(String args[]) - { - test_arm64(); - } + // 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() { + + Long x11 = 0x1234L; // X11 register + Long x13 = 0x6789L; // X13 register + Long x15 = 0x3333L; // 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, Unicorn.UC_PROT_ALL); + + // 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 = (Long) u.reg_read(Unicorn.UC_ARM64_REG_X11); + System.out.print(String.format(">>> X11 = 0x%x\n", x11.longValue())); + + u.close(); + } + + public static void main(String args[]) { + test_arm64(); + } } diff --git a/bindings/java/samples/Sample_m68k.java b/bindings/java/samples/Sample_m68k.java index f4658aff..9d530084 100644 --- a/bindings/java/samples/Sample_m68k.java +++ b/bindings/java/samples/Sample_m68k.java @@ -28,150 +28,161 @@ 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; - } + // code to be emulated + public static final byte[] M68K_CODE = { 118, -19 }; // movq #-19, %d3 - 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() - { - Long d0 = 0x0000L; // d0 data register - Long d1 = 0x0000L; // d1 data register - Long d2 = 0x0000L; // d2 data register - Long d3 = 0x0000L; // d3 data register - Long d4 = 0x0000L; // d4 data register - Long d5 = 0x0000L; // d5 data register - Long d6 = 0x0000L; // d6 data register - Long d7 = 0x0000L; // d7 data register + // memory address where emulation starts + public static final int ADDRESS = 0x10000; - Long a0 = 0x0000L; // a0 address register - Long a1 = 0x0000L; // a1 address register - Long a2 = 0x0000L; // a2 address register - Long a3 = 0x0000L; // a3 address register - Long a4 = 0x0000L; // a4 address register - Long a5 = 0x0000L; // a5 address register - Long a6 = 0x0000L; // a6 address register - Long a7 = 0x0000L; // a6 address register + 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; + } - Long pc = 0x0000L; // program counter - Long sr = 0x0000L; // 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, Unicorn.UC_PROT_ALL); - - // 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 = (Long)u.reg_read(Unicorn.UC_M68K_REG_D0); - d1 = (Long)u.reg_read(Unicorn.UC_M68K_REG_D1); - d2 = (Long)u.reg_read(Unicorn.UC_M68K_REG_D2); - d3 = (Long)u.reg_read(Unicorn.UC_M68K_REG_D3); - d4 = (Long)u.reg_read(Unicorn.UC_M68K_REG_D4); - d5 = (Long)u.reg_read(Unicorn.UC_M68K_REG_D5); - d6 = (Long)u.reg_read(Unicorn.UC_M68K_REG_D6); - d7 = (Long)u.reg_read(Unicorn.UC_M68K_REG_D7); + 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; + } - a0 = (Long)u.reg_read(Unicorn.UC_M68K_REG_A0); - a1 = (Long)u.reg_read(Unicorn.UC_M68K_REG_A1); - a2 = (Long)u.reg_read(Unicorn.UC_M68K_REG_A2); - a3 = (Long)u.reg_read(Unicorn.UC_M68K_REG_A3); - a4 = (Long)u.reg_read(Unicorn.UC_M68K_REG_A4); - a5 = (Long)u.reg_read(Unicorn.UC_M68K_REG_A5); - a6 = (Long)u.reg_read(Unicorn.UC_M68K_REG_A6); - a7 = (Long)u.reg_read(Unicorn.UC_M68K_REG_A7); - - pc = (Long)u.reg_read(Unicorn.UC_M68K_REG_PC); - sr = (Long)u.reg_read(Unicorn.UC_M68K_REG_SR); - - 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", a1.intValue(), d1.intValue())); - 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", a3.intValue(), d3.intValue())); - 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", a5.intValue(), d5.intValue())); - 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", a7.intValue(), d7.intValue())); - System.out.print(String.format(">>> PC = 0x%x\n", pc.intValue())); - System.out.print(String.format(">>> SR = 0x%x\n", sr.intValue())); - - u.close(); - } - - public static void main(String args[]) - { - test_m68k(); - } + // 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() { + Long d0 = 0x0000L; // d0 data register + Long d1 = 0x0000L; // d1 data register + Long d2 = 0x0000L; // d2 data register + Long d3 = 0x0000L; // d3 data register + Long d4 = 0x0000L; // d4 data register + Long d5 = 0x0000L; // d5 data register + Long d6 = 0x0000L; // d6 data register + Long d7 = 0x0000L; // d7 data register + + Long a0 = 0x0000L; // a0 address register + Long a1 = 0x0000L; // a1 address register + Long a2 = 0x0000L; // a2 address register + Long a3 = 0x0000L; // a3 address register + Long a4 = 0x0000L; // a4 address register + Long a5 = 0x0000L; // a5 address register + Long a6 = 0x0000L; // a6 address register + Long a7 = 0x0000L; // a6 address register + + Long pc = 0x0000L; // program counter + Long sr = 0x0000L; // 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, Unicorn.UC_PROT_ALL); + + // 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 = (Long) u.reg_read(Unicorn.UC_M68K_REG_D0); + d1 = (Long) u.reg_read(Unicorn.UC_M68K_REG_D1); + d2 = (Long) u.reg_read(Unicorn.UC_M68K_REG_D2); + d3 = (Long) u.reg_read(Unicorn.UC_M68K_REG_D3); + d4 = (Long) u.reg_read(Unicorn.UC_M68K_REG_D4); + d5 = (Long) u.reg_read(Unicorn.UC_M68K_REG_D5); + d6 = (Long) u.reg_read(Unicorn.UC_M68K_REG_D6); + d7 = (Long) u.reg_read(Unicorn.UC_M68K_REG_D7); + + a0 = (Long) u.reg_read(Unicorn.UC_M68K_REG_A0); + a1 = (Long) u.reg_read(Unicorn.UC_M68K_REG_A1); + a2 = (Long) u.reg_read(Unicorn.UC_M68K_REG_A2); + a3 = (Long) u.reg_read(Unicorn.UC_M68K_REG_A3); + a4 = (Long) u.reg_read(Unicorn.UC_M68K_REG_A4); + a5 = (Long) u.reg_read(Unicorn.UC_M68K_REG_A5); + a6 = (Long) u.reg_read(Unicorn.UC_M68K_REG_A6); + a7 = (Long) u.reg_read(Unicorn.UC_M68K_REG_A7); + + pc = (Long) u.reg_read(Unicorn.UC_M68K_REG_PC); + sr = (Long) u.reg_read(Unicorn.UC_M68K_REG_SR); + + 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", + a1.intValue(), d1.intValue())); + 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", + a3.intValue(), d3.intValue())); + 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", + a5.intValue(), d5.intValue())); + 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", + a7.intValue(), d7.intValue())); + System.out.print(String.format(">>> PC = 0x%x\n", pc.intValue())); + System.out.print(String.format(">>> SR = 0x%x\n", sr.intValue())); + + u.close(); + } + + public static void main(String args[]) { + test_m68k(); + } } diff --git a/bindings/java/samples/Sample_mips.java b/bindings/java/samples/Sample_mips.java index e338864f..0f0bd8c5 100644 --- a/bindings/java/samples/Sample_mips.java +++ b/bindings/java/samples/Sample_mips.java @@ -28,124 +28,127 @@ 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}; + // 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; - } + // memory address where emulation starts + public static final int ADDRESS = 0x10000; - 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() - { - - Long r1 = 0x6789L; // 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, Unicorn.UC_PROT_ALL); - - // 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 = (Long)u.reg_read(Unicorn.UC_MIPS_REG_1); - System.out.print(String.format(">>> R1 = 0x%x\n", r1.intValue())); - - u.close(); - } - - static void test_mips_el() - { - Long r1 = 0x6789L; // 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 + Unicorn.UC_MODE_LITTLE_ENDIAN); - - // map 2MB memory for this emulation - u.mem_map(ADDRESS, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL); - - // 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 = (Long)u.reg_read(Unicorn.UC_MIPS_REG_1); - System.out.print(String.format(">>> R1 = 0x%x\n", r1.intValue())); - - u.close(); - } - - public static void main(String args[]) - { - test_mips_eb(); - test_mips_el(); - } + 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() { + + Long r1 = 0x6789L; // 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, Unicorn.UC_PROT_ALL); + + // 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 = (Long) u.reg_read(Unicorn.UC_MIPS_REG_1); + System.out.print(String.format(">>> R1 = 0x%x\n", r1.intValue())); + + u.close(); + } + + static void test_mips_el() { + Long r1 = 0x6789L; // 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 + Unicorn.UC_MODE_LITTLE_ENDIAN); + + // map 2MB memory for this emulation + u.mem_map(ADDRESS, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL); + + // 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 = (Long) u.reg_read(Unicorn.UC_MIPS_REG_1); + System.out.print(String.format(">>> R1 = 0x%x\n", r1.intValue())); + + u.close(); + } + + public static void main(String args[]) { + test_mips_eb(); + test_mips_el(); + } } diff --git a/bindings/java/samples/Sample_sparc.java b/bindings/java/samples/Sample_sparc.java index b2849f45..b11eb8d7 100644 --- a/bindings/java/samples/Sample_sparc.java +++ b/bindings/java/samples/Sample_sparc.java @@ -28,88 +28,91 @@ 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; - } + // 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 - 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; - } + // memory address where emulation starts + public static final int ADDRESS = 0x10000; - // 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() - { - Long g1 = 0x1230L; // G1 register - Long g2 = 0x6789L; // G2 register - Long g3 = 0x5555L; // 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_32 + Unicorn.UC_MODE_BIG_ENDIAN); - - // map 2MB memory for this emulation - u.mem_map(ADDRESS, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL); - - // 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); + 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; + } - // 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 = (Long)u.reg_read(Unicorn.UC_SPARC_REG_G3); - System.out.print(String.format(">>> G3 = 0x%x\n", g3.intValue())); - - u.close(); - } - - public static void main(String args[]) - { - test_sparc(); - } + 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() { + Long g1 = 0x1230L; // G1 register + Long g2 = 0x6789L; // G2 register + Long g3 = 0x5555L; // 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_32 + Unicorn.UC_MODE_BIG_ENDIAN); + + // map 2MB memory for this emulation + u.mem_map(ADDRESS, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL); + + // 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 = (Long) u.reg_read(Unicorn.UC_SPARC_REG_G3); + System.out.print(String.format(">>> G3 = 0x%x\n", g3.intValue())); + + u.close(); + } + + public static void main(String args[]) { + test_sparc(); + } } diff --git a/bindings/java/samples/Sample_x86.java b/bindings/java/samples/Sample_x86.java index 652663f8..dcef5623 100644 --- a/bindings/java/samples/Sample_x86.java +++ b/bindings/java/samples/Sample_x86.java @@ -28,642 +28,679 @@ 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}; - public static final byte[] X86_CODE16 = {0, 0}; // add byte ptr [bx + si], al - - // 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; - } + // 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 }; + public static final byte[] X86_CODE16 = { 0, 0 }; // add byte ptr [bx + si], al - 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.printf(">>> 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.printf(">>> Tracing instruction at 0x%x, instruction size = 0x%x\n", address, size); - - Long eflags = (Long)u.reg_read(Unicorn.UC_X86_REG_EFLAGS); - System.out.printf(">>> --- EFLAGS is 0x%x\n", eflags.intValue()); - - // Uncomment below code to stop the emulation using uc_emu_stop() - // if (address == 0x1000009) - // u.emu_stop(); - } - } - - private static class MyWriteInvalidHook implements EventMemHook { - public boolean hook(Unicorn u, long address, int size, long value, Object user) { - System.out.printf(">>> 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, Unicorn.UC_PROT_ALL); - // return true to indicate we want to continue - return true; - } - } - - // callback for tracing instruction - private static class MyCode64Hook implements CodeHook { - public void hook(Unicorn u, long address, int size, Object user_data) { - 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(">>> RIP is 0x%x\n", r_rip.longValue()); - - // Uncomment below code to stop the emulation using uc_emu_stop() - // if (address == 0x1000009) - // uc_emu_stop(handle); - } - } + // memory address where emulation starts + public static final int ADDRESS = 0x1000000; - - private static class MyRead64Hook implements ReadHook { - public void hook(Unicorn u, long address, int size, Object user) { - System.out.printf(">>> Memory is being READ at 0x%x, data size = %d\n", address, size); - } - } + 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 MyWrite64Hook implements WriteHook { - public void hook(Unicorn u, long address, int size, long value, Object user) { - System.out.printf(">>> 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) { - 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, r_eip.intValue()); - - switch(size) { + 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.printf( + ">>> 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.printf( + ">>> Tracing instruction at 0x%x, instruction size = 0x%x\n", + address, size); + + Long eflags = (Long) u.reg_read(Unicorn.UC_X86_REG_EFLAGS); + System.out.printf(">>> --- EFLAGS is 0x%x\n", eflags.intValue()); + + // Uncomment below code to stop the emulation using uc_emu_stop() + // if (address == 0x1000009) + // u.emu_stop(); + } + } + + private static class MyWriteInvalidHook implements EventMemHook { + public boolean hook(Unicorn u, long address, int size, long value, + Object user) { + System.out.printf( + ">>> 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, Unicorn.UC_PROT_ALL); + // return true to indicate we want to continue + return true; + } + } + + // callback for tracing instruction + private static class MyCode64Hook implements CodeHook { + public void hook(Unicorn u, long address, int size, Object user_data) { + 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(">>> RIP is 0x%x\n", r_rip.longValue()); + + // 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.printf( + ">>> 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.printf( + ">>> 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) { + 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, r_eip.intValue()); + + switch (size) { case 1: - // read 1 byte to AL - return 0xf1; + // read 1 byte to AL + return 0xf1; case 2: - // read 2 byte to AX - return 0xf2; + // 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) { - Long eip = (Long)u.reg_read(Unicorn.UC_X86_REG_EIP); - Long tmp = null; - 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 - switch(size) { + // 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) { + Long eip = (Long) u.reg_read(Unicorn.UC_X86_REG_EIP); + Long tmp = null; + 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 + switch (size) { default: - return; // should never reach this + return; // should never reach this case 1: - tmp = (Long)u.reg_read(Unicorn.UC_X86_REG_AL); - break; + tmp = (Long) u.reg_read(Unicorn.UC_X86_REG_AL); + break; case 2: - tmp = (Long)u.reg_read(Unicorn.UC_X86_REG_AX); - break; + tmp = (Long) u.reg_read(Unicorn.UC_X86_REG_AX); + break; case 4: - tmp = (Long)u.reg_read(Unicorn.UC_X86_REG_EAX); - break; - } - - System.out.printf("--- register value = 0x%x\n", tmp.intValue()); - } - } - - static void test_i386() { - Long r_ecx = 0x1234L; // ECX register - Long r_edx = 0x7890L; // 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, Unicorn.UC_PROT_ALL); - - // 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.printf("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 = (Long)uc.reg_read(Unicorn.UC_X86_REG_ECX); - r_edx = (Long)uc.reg_read(Unicorn.UC_X86_REG_EDX); - System.out.printf(">>> ECX = 0x%x\n", r_ecx.intValue()); - System.out.printf(">>> EDX = 0x%x\n", r_edx.intValue()); - - // read from memory - try { - byte[] tmp = uc.mem_read(ADDRESS, 4); - System.out.printf(">>> Read 4 bytes from [0x%x] = 0x%x\n", ADDRESS, toInt(tmp)); + tmp = (Long) u.reg_read(Unicorn.UC_X86_REG_EAX); + break; + } + + System.out.printf("--- register value = 0x%x\n", tmp.intValue()); + } + } + + static void test_i386() { + Long r_ecx = 0x1234L; // ECX register + Long r_edx = 0x7890L; // 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, Unicorn.UC_PROT_ALL); + + // 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.printf("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 = (Long) uc.reg_read(Unicorn.UC_X86_REG_ECX); + r_edx = (Long) uc.reg_read(Unicorn.UC_X86_REG_EDX); + System.out.printf(">>> ECX = 0x%x\n", r_ecx.intValue()); + System.out.printf(">>> EDX = 0x%x\n", r_edx.intValue()); + + // read from memory + try { + byte[] tmp = uc.mem_read(ADDRESS, 4); + System.out.printf(">>> Read 4 bytes from [0x%x] = 0x%x\n", ADDRESS, + toInt(tmp)); } catch (UnicornException ex) { - System.out.printf(">>> Failed to read 4 bytes from [0x%x]\n", ADDRESS); - } - uc.close(); - } + System.out.printf(">>> Failed to read 4 bytes from [0x%x]\n", + ADDRESS); + } + uc.close(); + } - static void test_i386_inout() - { - Long r_eax = 0x1234L; // ECX register - Long r_ecx = 0x6789L; // EDX 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, Unicorn.UC_PROT_ALL); - - // 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 = (Long)u.reg_read(Unicorn.UC_X86_REG_EAX); - r_ecx = (Long)u.reg_read(Unicorn.UC_X86_REG_ECX); - System.out.printf(">>> EAX = 0x%x\n", r_eax.intValue()); - System.out.printf(">>> ECX = 0x%x\n", r_ecx.intValue()); - - u.close(); - } + static void test_i386_inout() { + Long r_eax = 0x1234L; // ECX register + Long r_ecx = 0x6789L; // EDX register - 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, Unicorn.UC_PROT_ALL); - - // 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(); - } + System.out.print("===================================\n"); + System.out.print("Emulate i386 code with IN/OUT instructions\n"); - // emulate code that loop forever - static void test_i386_loop() - { - Long r_ecx = 0x1234L; // ECX register - Long r_edx = 0x7890L; // 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, Unicorn.UC_PROT_ALL); - - // 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 = (Long)u.reg_read(Unicorn.UC_X86_REG_ECX); - r_edx = (Long)u.reg_read(Unicorn.UC_X86_REG_EDX); - System.out.printf(">>> ECX = 0x%x\n", r_ecx.intValue()); - System.out.printf(">>> EDX = 0x%x\n", r_edx.intValue()); - - u.close(); - } - - // emulate code that read invalid memory - static void test_i386_invalid_mem_read() - { - Long r_ecx = 0x1234L; // ECX register - Long r_edx = 0x7890L; // 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, Unicorn.UC_PROT_ALL); - - // 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 - try { - u.emu_start(ADDRESS, ADDRESS + X86_CODE32_MEM_READ.length, 0, 0); - } catch (UnicornException uex) { - int err = u.errno(); - System.out.printf("Failed on u.emu_start() with error returned: %s\n", uex.getMessage()); - } - - // now print out some registers - System.out.print(">>> Emulation done. Below is the CPU context\n"); - - r_ecx = (Long)u.reg_read(Unicorn.UC_X86_REG_ECX); - r_edx = (Long)u.reg_read(Unicorn.UC_X86_REG_EDX); - System.out.printf(">>> ECX = 0x%x\n", r_ecx.intValue()); - System.out.printf(">>> EDX = 0x%x\n", r_edx.intValue()); - - u.close(); - } - - // emulate code that read invalid memory - static void test_i386_invalid_mem_write() - { - Long r_ecx = 0x1234L; // ECX register - Long r_edx = 0x7890L; // 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, Unicorn.UC_PROT_ALL); - - // 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 MyWriteInvalidHook(), Unicorn.UC_HOOK_MEM_WRITE_UNMAPPED, null); - - // emulate machine code in infinite time - try { - u.emu_start(ADDRESS, ADDRESS + X86_CODE32_MEM_WRITE.length, 0, 0); - } catch (UnicornException uex) { - System.out.printf("Failed on uc_emu_start() with error returned: %s\n", uex.getMessage()); - } - - // now print out some registers - System.out.print(">>> Emulation done. Below is the CPU context\n"); - - r_ecx = (Long)u.reg_read(Unicorn.UC_X86_REG_ECX); - r_edx = (Long)u.reg_read(Unicorn.UC_X86_REG_EDX); - System.out.printf(">>> ECX = 0x%x\n", r_ecx.intValue()); - System.out.printf(">>> EDX = 0x%x\n", r_edx.intValue()); - - // read from memory - byte tmp[] = u.mem_read(0xaaaaaaaa, 4); - System.out.printf(">>> Read 4 bytes from [0x%x] = 0x%x\n", 0xaaaaaaaa, toInt(tmp)); - - try { - u.mem_read(0xffffffaa, 4); - System.out.printf(">>> Read 4 bytes from [0x%x] = 0x%x\n", 0xffffffaa, toInt(tmp)); - } catch (UnicornException uex) { - System.out.printf(">>> Failed to read 4 bytes from [0x%x]\n", 0xffffffaa); - } - - u.close(); - } + // Initialize emulator in X86-32bit mode + Unicorn u = new Unicorn(Unicorn.UC_ARCH_X86, Unicorn.UC_MODE_32); - // emulate code that jump to invalid memory - static void test_i386_jump_invalid() - { - Long r_ecx = 0x1234L; // ECX register - Long r_edx = 0x7890L; // 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, Unicorn.UC_PROT_ALL); - - // 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 - try { - u.emu_start(ADDRESS, ADDRESS + X86_CODE32_JMP_INVALID.length, 0, 0); - } catch (UnicornException uex) { - System.out.printf("Failed on uc_emu_start() with error returned: %s\n", uex.getMessage()); - } - - // now print out some registers - System.out.print(">>> Emulation done. Below is the CPU context\n"); - - r_ecx = (Long)u.reg_read(Unicorn.UC_X86_REG_ECX); - r_edx = (Long)u.reg_read(Unicorn.UC_X86_REG_EDX); - System.out.printf(">>> ECX = 0x%x\n", r_ecx.intValue()); - System.out.printf(">>> EDX = 0x%x\n", r_edx.intValue()); - - u.close(); - } + // map 2MB memory for this emulation + u.mem_map(ADDRESS, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL); - 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, Unicorn.UC_PROT_ALL); - - // 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, rsp); + // write machine code to be emulated to memory + u.mem_write(ADDRESS, X86_CODE32_INOUT); - u.reg_write(Unicorn.UC_X86_REG_RAX, rax); - u.reg_write(Unicorn.UC_X86_REG_RBX, rbx); - u.reg_write(Unicorn.UC_X86_REG_RCX, rcx); - u.reg_write(Unicorn.UC_X86_REG_RDX, rdx); - u.reg_write(Unicorn.UC_X86_REG_RSI, rsi); - u.reg_write(Unicorn.UC_X86_REG_RDI, rdi); - u.reg_write(Unicorn.UC_X86_REG_R8, r8); - u.reg_write(Unicorn.UC_X86_REG_R9, r9); - u.reg_write(Unicorn.UC_X86_REG_R10, r10); - u.reg_write(Unicorn.UC_X86_REG_R11, r11); - u.reg_write(Unicorn.UC_X86_REG_R12, r12); - u.reg_write(Unicorn.UC_X86_REG_R13, r13); - u.reg_write(Unicorn.UC_X86_REG_R14, r14); - u.reg_write(Unicorn.UC_X86_REG_R15, 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"); - - Long r_rax = (Long)u.reg_read(Unicorn.UC_X86_REG_RAX); - Long r_rbx = (Long)u.reg_read(Unicorn.UC_X86_REG_RBX); - Long r_rcx = (Long)u.reg_read(Unicorn.UC_X86_REG_RCX); - Long r_rdx = (Long)u.reg_read(Unicorn.UC_X86_REG_RDX); - Long r_rsi = (Long)u.reg_read(Unicorn.UC_X86_REG_RSI); - Long r_rdi = (Long)u.reg_read(Unicorn.UC_X86_REG_RDI); - Long r_r8 = (Long)u.reg_read(Unicorn.UC_X86_REG_R8); - Long r_r9 = (Long)u.reg_read(Unicorn.UC_X86_REG_R9); - Long r_r10 = (Long)u.reg_read(Unicorn.UC_X86_REG_R10); - Long r_r11 = (Long)u.reg_read(Unicorn.UC_X86_REG_R11); - Long r_r12 = (Long)u.reg_read(Unicorn.UC_X86_REG_R12); - Long r_r13 = (Long)u.reg_read(Unicorn.UC_X86_REG_R13); - Long r_r14 = (Long)u.reg_read(Unicorn.UC_X86_REG_R14); - Long r_r15 = (Long)u.reg_read(Unicorn.UC_X86_REG_R15); - - System.out.printf(">>> RAX = 0x%x\n", r_rax.longValue()); - System.out.printf(">>> RBX = 0x%x\n", r_rbx.longValue()); - System.out.printf(">>> RCX = 0x%x\n", r_rcx.longValue()); - System.out.printf(">>> RDX = 0x%x\n", r_rdx.longValue()); - System.out.printf(">>> RSI = 0x%x\n", r_rsi.longValue()); - System.out.printf(">>> RDI = 0x%x\n", r_rdi.longValue()); - System.out.printf(">>> R8 = 0x%x\n", r_r8.longValue()); - System.out.printf(">>> R9 = 0x%x\n", r_r9.longValue()); - System.out.printf(">>> R10 = 0x%x\n", r_r10.longValue()); - System.out.printf(">>> R11 = 0x%x\n", r_r11.longValue()); - System.out.printf(">>> R12 = 0x%x\n", r_r12.longValue()); - System.out.printf(">>> R13 = 0x%x\n", r_r13.longValue()); - System.out.printf(">>> R14 = 0x%x\n", r_r14.longValue()); - System.out.printf(">>> R15 = 0x%x\n", r_r15.longValue()); - - u.close(); - } + // initialize machine registers + u.reg_write(Unicorn.UC_X86_REG_EAX, r_eax); + u.reg_write(Unicorn.UC_X86_REG_ECX, r_ecx); - static void test_x86_16() - { - Long eax = 7L; - Long ebx = 5L; - Long esi = 6L; - - System.out.print("Emulate x86 16-bit code\n"); - - // Initialize emulator in X86-16bit mode - Unicorn u = new Unicorn(Unicorn.UC_ARCH_X86, Unicorn.UC_MODE_16); - - // map 8KB memory for this emulation - u.mem_map(0, 8 * 1024, Unicorn.UC_PROT_ALL); - - // write machine code to be emulated to memory - u.mem_write(0, X86_CODE16); - - // initialize machine registers - u.reg_write(Unicorn.UC_X86_REG_EAX, eax); - u.reg_write(Unicorn.UC_X86_REG_EBX, ebx); - u.reg_write(Unicorn.UC_X86_REG_ESI, esi); - - // emulate machine code in infinite time (last param = 0), or when - // finishing all the code. - u.emu_start(0, X86_CODE16.length, 0, 0); - - // now print out some registers - System.out.print(">>> Emulation done. Below is the CPU context\n"); - - // read from memory - byte[] tmp = u.mem_read(11, 1); - System.out.printf(">>> Read 1 bytes from [0x%x] = 0x%x\n", 11, toInt(tmp)); + // tracing all basic blocks with customized callback + u.hook_add(new MyBlockHook(), 1, 0, null); - u.close(); - } + // tracing all instructions + u.hook_add(new MyCodeHook(), 1, 0, null); - 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(); - } - - if (args[0].equals("-16")) { - test_x86_16(); - } + // handle IN instruction + u.hook_add(new MyInHook(), null); + // handle OUT instruction + u.hook_add(new MyOutHook(), null); - // test memleak - if (args[0].equals("-0")) { - while(true) { - test_i386(); - // test_x86_64(); - } - } - } else { - System.out.print("Syntax: java Sample_x86 <-16|-32|-64>\n"); - } - - } + // 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 = (Long) u.reg_read(Unicorn.UC_X86_REG_EAX); + r_ecx = (Long) u.reg_read(Unicorn.UC_X86_REG_ECX); + System.out.printf(">>> EAX = 0x%x\n", r_eax.intValue()); + System.out.printf(">>> ECX = 0x%x\n", r_ecx.intValue()); + + 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, Unicorn.UC_PROT_ALL); + + // 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() { + Long r_ecx = 0x1234L; // ECX register + Long r_edx = 0x7890L; // 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, Unicorn.UC_PROT_ALL); + + // 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 = (Long) u.reg_read(Unicorn.UC_X86_REG_ECX); + r_edx = (Long) u.reg_read(Unicorn.UC_X86_REG_EDX); + System.out.printf(">>> ECX = 0x%x\n", r_ecx.intValue()); + System.out.printf(">>> EDX = 0x%x\n", r_edx.intValue()); + + u.close(); + } + + // emulate code that read invalid memory + static void test_i386_invalid_mem_read() { + Long r_ecx = 0x1234L; // ECX register + Long r_edx = 0x7890L; // 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, Unicorn.UC_PROT_ALL); + + // 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 + try { + u.emu_start(ADDRESS, ADDRESS + X86_CODE32_MEM_READ.length, 0, 0); + } catch (UnicornException uex) { + int err = u.errno(); + System.out.printf( + "Failed on u.emu_start() with error returned: %s\n", + uex.getMessage()); + } + + // now print out some registers + System.out.print(">>> Emulation done. Below is the CPU context\n"); + + r_ecx = (Long) u.reg_read(Unicorn.UC_X86_REG_ECX); + r_edx = (Long) u.reg_read(Unicorn.UC_X86_REG_EDX); + System.out.printf(">>> ECX = 0x%x\n", r_ecx.intValue()); + System.out.printf(">>> EDX = 0x%x\n", r_edx.intValue()); + + u.close(); + } + + // emulate code that read invalid memory + static void test_i386_invalid_mem_write() { + Long r_ecx = 0x1234L; // ECX register + Long r_edx = 0x7890L; // 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, Unicorn.UC_PROT_ALL); + + // 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 MyWriteInvalidHook(), Unicorn.UC_HOOK_MEM_WRITE_UNMAPPED, + null); + + // emulate machine code in infinite time + try { + u.emu_start(ADDRESS, ADDRESS + X86_CODE32_MEM_WRITE.length, 0, 0); + } catch (UnicornException uex) { + System.out.printf( + "Failed on uc_emu_start() with error returned: %s\n", + uex.getMessage()); + } + + // now print out some registers + System.out.print(">>> Emulation done. Below is the CPU context\n"); + + r_ecx = (Long) u.reg_read(Unicorn.UC_X86_REG_ECX); + r_edx = (Long) u.reg_read(Unicorn.UC_X86_REG_EDX); + System.out.printf(">>> ECX = 0x%x\n", r_ecx.intValue()); + System.out.printf(">>> EDX = 0x%x\n", r_edx.intValue()); + + // read from memory + byte tmp[] = u.mem_read(0xaaaaaaaa, 4); + System.out.printf(">>> Read 4 bytes from [0x%x] = 0x%x\n", 0xaaaaaaaa, + toInt(tmp)); + + try { + u.mem_read(0xffffffaa, 4); + System.out.printf(">>> Read 4 bytes from [0x%x] = 0x%x\n", + 0xffffffaa, toInt(tmp)); + } catch (UnicornException uex) { + System.out.printf(">>> Failed to read 4 bytes from [0x%x]\n", + 0xffffffaa); + } + + u.close(); + } + + // emulate code that jump to invalid memory + static void test_i386_jump_invalid() { + Long r_ecx = 0x1234L; // ECX register + Long r_edx = 0x7890L; // 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, Unicorn.UC_PROT_ALL); + + // 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 + try { + u.emu_start(ADDRESS, ADDRESS + X86_CODE32_JMP_INVALID.length, 0, 0); + } catch (UnicornException uex) { + System.out.printf( + "Failed on uc_emu_start() with error returned: %s\n", + uex.getMessage()); + } + + // now print out some registers + System.out.print(">>> Emulation done. Below is the CPU context\n"); + + r_ecx = (Long) u.reg_read(Unicorn.UC_X86_REG_ECX); + r_edx = (Long) u.reg_read(Unicorn.UC_X86_REG_EDX); + System.out.printf(">>> ECX = 0x%x\n", r_ecx.intValue()); + System.out.printf(">>> EDX = 0x%x\n", r_edx.intValue()); + + 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, Unicorn.UC_PROT_ALL); + + // 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, rsp); + + u.reg_write(Unicorn.UC_X86_REG_RAX, rax); + u.reg_write(Unicorn.UC_X86_REG_RBX, rbx); + u.reg_write(Unicorn.UC_X86_REG_RCX, rcx); + u.reg_write(Unicorn.UC_X86_REG_RDX, rdx); + u.reg_write(Unicorn.UC_X86_REG_RSI, rsi); + u.reg_write(Unicorn.UC_X86_REG_RDI, rdi); + u.reg_write(Unicorn.UC_X86_REG_R8, r8); + u.reg_write(Unicorn.UC_X86_REG_R9, r9); + u.reg_write(Unicorn.UC_X86_REG_R10, r10); + u.reg_write(Unicorn.UC_X86_REG_R11, r11); + u.reg_write(Unicorn.UC_X86_REG_R12, r12); + u.reg_write(Unicorn.UC_X86_REG_R13, r13); + u.reg_write(Unicorn.UC_X86_REG_R14, r14); + u.reg_write(Unicorn.UC_X86_REG_R15, 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"); + + Long r_rax = (Long) u.reg_read(Unicorn.UC_X86_REG_RAX); + Long r_rbx = (Long) u.reg_read(Unicorn.UC_X86_REG_RBX); + Long r_rcx = (Long) u.reg_read(Unicorn.UC_X86_REG_RCX); + Long r_rdx = (Long) u.reg_read(Unicorn.UC_X86_REG_RDX); + Long r_rsi = (Long) u.reg_read(Unicorn.UC_X86_REG_RSI); + Long r_rdi = (Long) u.reg_read(Unicorn.UC_X86_REG_RDI); + Long r_r8 = (Long) u.reg_read(Unicorn.UC_X86_REG_R8); + Long r_r9 = (Long) u.reg_read(Unicorn.UC_X86_REG_R9); + Long r_r10 = (Long) u.reg_read(Unicorn.UC_X86_REG_R10); + Long r_r11 = (Long) u.reg_read(Unicorn.UC_X86_REG_R11); + Long r_r12 = (Long) u.reg_read(Unicorn.UC_X86_REG_R12); + Long r_r13 = (Long) u.reg_read(Unicorn.UC_X86_REG_R13); + Long r_r14 = (Long) u.reg_read(Unicorn.UC_X86_REG_R14); + Long r_r15 = (Long) u.reg_read(Unicorn.UC_X86_REG_R15); + + System.out.printf(">>> RAX = 0x%x\n", r_rax.longValue()); + System.out.printf(">>> RBX = 0x%x\n", r_rbx.longValue()); + System.out.printf(">>> RCX = 0x%x\n", r_rcx.longValue()); + System.out.printf(">>> RDX = 0x%x\n", r_rdx.longValue()); + System.out.printf(">>> RSI = 0x%x\n", r_rsi.longValue()); + System.out.printf(">>> RDI = 0x%x\n", r_rdi.longValue()); + System.out.printf(">>> R8 = 0x%x\n", r_r8.longValue()); + System.out.printf(">>> R9 = 0x%x\n", r_r9.longValue()); + System.out.printf(">>> R10 = 0x%x\n", r_r10.longValue()); + System.out.printf(">>> R11 = 0x%x\n", r_r11.longValue()); + System.out.printf(">>> R12 = 0x%x\n", r_r12.longValue()); + System.out.printf(">>> R13 = 0x%x\n", r_r13.longValue()); + System.out.printf(">>> R14 = 0x%x\n", r_r14.longValue()); + System.out.printf(">>> R15 = 0x%x\n", r_r15.longValue()); + + u.close(); + } + + static void test_x86_16() { + Long eax = 7L; + Long ebx = 5L; + Long esi = 6L; + + System.out.print("Emulate x86 16-bit code\n"); + + // Initialize emulator in X86-16bit mode + Unicorn u = new Unicorn(Unicorn.UC_ARCH_X86, Unicorn.UC_MODE_16); + + // map 8KB memory for this emulation + u.mem_map(0, 8 * 1024, Unicorn.UC_PROT_ALL); + + // write machine code to be emulated to memory + u.mem_write(0, X86_CODE16); + + // initialize machine registers + u.reg_write(Unicorn.UC_X86_REG_EAX, eax); + u.reg_write(Unicorn.UC_X86_REG_EBX, ebx); + u.reg_write(Unicorn.UC_X86_REG_ESI, esi); + + // emulate machine code in infinite time (last param = 0), or when + // finishing all the code. + u.emu_start(0, X86_CODE16.length, 0, 0); + + // now print out some registers + System.out.print(">>> Emulation done. Below is the CPU context\n"); + + // read from memory + byte[] tmp = u.mem_read(11, 1); + System.out.printf(">>> Read 1 bytes from [0x%x] = 0x%x\n", 11, + toInt(tmp)); + + 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(); + } + + if (args[0].equals("-16")) { + test_x86_16(); + } + + // test memleak + if (args[0].equals("-0")) { + while (true) { + test_i386(); + // test_x86_64(); + } + } + } else { + System.out.print("Syntax: java Sample_x86 <-16|-32|-64>\n"); + } + + } } diff --git a/bindings/java/samples/Sample_x86_mmr.java b/bindings/java/samples/Sample_x86_mmr.java index 0ecb3a1e..fc2bb08b 100644 --- a/bindings/java/samples/Sample_x86_mmr.java +++ b/bindings/java/samples/Sample_x86_mmr.java @@ -25,53 +25,55 @@ import unicorn.*; public class Sample_x86_mmr { - static void test_x86_mmr() { - // 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 4k - uc.mem_map(0x400000, 0x1000, Unicorn.UC_PROT_ALL); + static void test_x86_mmr() { + // 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; + } - X86_MMR ldtr1 = new X86_MMR(0x1111111122222222L, 0x33333333, 0x44444444, (short)0x5555); - X86_MMR ldtr2; - X86_MMR gdtr1 = new X86_MMR(0x6666666677777777L, 0x88888888, 0x99999999, (short)0xaaaa); - X86_MMR gdtr2, gdtr3, gdtr4; + // map 4k + uc.mem_map(0x400000, 0x1000, Unicorn.UC_PROT_ALL); - int eax; - - // initialize machine registers + X86_MMR ldtr1 = new X86_MMR(0x1111111122222222L, 0x33333333, 0x44444444, + (short) 0x5555); + X86_MMR ldtr2; + X86_MMR gdtr1 = new X86_MMR(0x6666666677777777L, 0x88888888, 0x99999999, + (short) 0xaaaa); + X86_MMR gdtr2, gdtr3, gdtr4; - uc.reg_write(Unicorn.UC_X86_REG_LDTR, ldtr1); - uc.reg_write(Unicorn.UC_X86_REG_GDTR, gdtr1); - uc.reg_write(Unicorn.UC_X86_REG_EAX, 0xddddddddL); - - // read the registers back out - eax = (int)((Long)uc.reg_read(Unicorn.UC_X86_REG_EAX)).longValue(); - ldtr2 = (X86_MMR)uc.reg_read(Unicorn.UC_X86_REG_LDTR); - gdtr2 = (X86_MMR)uc.reg_read(Unicorn.UC_X86_REG_GDTR); + int eax; - System.out.printf(">>> EAX = 0x%x\n", eax); + // initialize machine registers - System.out.printf(">>> LDTR.base = 0x%x\n", ldtr2.base); - System.out.printf(">>> LDTR.limit = 0x%x\n", ldtr2.limit); - System.out.printf(">>> LDTR.flags = 0x%x\n", ldtr2.flags); - System.out.printf(">>> LDTR.selector = 0x%x\n\n", ldtr2.selector); + uc.reg_write(Unicorn.UC_X86_REG_LDTR, ldtr1); + uc.reg_write(Unicorn.UC_X86_REG_GDTR, gdtr1); + uc.reg_write(Unicorn.UC_X86_REG_EAX, 0xddddddddL); - System.out.printf(">>> GDTR.base = 0x%x\n", gdtr2.base); - System.out.printf(">>> GDTR.limit = 0x%x\n", gdtr2.limit); - - uc.close(); - } + // read the registers back out + eax = (int) ((Long) uc.reg_read(Unicorn.UC_X86_REG_EAX)).longValue(); + ldtr2 = (X86_MMR) uc.reg_read(Unicorn.UC_X86_REG_LDTR); + gdtr2 = (X86_MMR) uc.reg_read(Unicorn.UC_X86_REG_GDTR); - public static void main(String args[]) - { - test_x86_mmr(); - } + System.out.printf(">>> EAX = 0x%x\n", eax); + + System.out.printf(">>> LDTR.base = 0x%x\n", ldtr2.base); + System.out.printf(">>> LDTR.limit = 0x%x\n", ldtr2.limit); + System.out.printf(">>> LDTR.flags = 0x%x\n", ldtr2.flags); + System.out.printf(">>> LDTR.selector = 0x%x\n\n", ldtr2.selector); + + System.out.printf(">>> GDTR.base = 0x%x\n", gdtr2.base); + System.out.printf(">>> GDTR.limit = 0x%x\n", gdtr2.limit); + + uc.close(); + } + + public static void main(String args[]) { + test_x86_mmr(); + } } diff --git a/bindings/java/samples/Shellcode.java b/bindings/java/samples/Shellcode.java index e75d922b..be9b701c 100644 --- a/bindings/java/samples/Shellcode.java +++ b/bindings/java/samples/Shellcode.java @@ -25,137 +25,149 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. /* 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[] 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 }; - 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)); - - Long r_eip = (Long)u.reg_read(Unicorn.UC_X86_REG_EIP); - System.out.print(String.format("*** EIP = %x ***: ", r_eip.intValue())); - - size = Math.min(16, size); + // memory address where emulation starts + public static final int ADDRESS = 0x1000000; - 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 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 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 = (Long)u.reg_read(Unicorn.UC_X86_REG_EAX); - Long r_eip = (Long)u.reg_read(Unicorn.UC_X86_REG_EIP); - - switch (r_eax.intValue()) { + 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)); + + Long r_eip = (Long) u.reg_read(Unicorn.UC_X86_REG_EIP); + System.out.print( + String.format("*** EIP = %x ***: ", r_eip.intValue())); + + 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 = (Long) u.reg_read(Unicorn.UC_X86_REG_EAX); + Long r_eip = (Long) u.reg_read(Unicorn.UC_X86_REG_EIP); + + switch (r_eax.intValue()) { default: - System.out.print(String.format(">>> 0x%x: interrupt 0x%x, EAX = 0x%x\n", r_eip.intValue(), intno, r_eax.intValue())); - break; + System.out.print( + String.format(">>> 0x%x: interrupt 0x%x, EAX = 0x%x\n", + r_eip.intValue(), intno, r_eax.intValue())); + break; case 1: // sys_exit - System.out.print(String.format(">>> 0x%x: interrupt 0x%x, SYS_EXIT. quit!\n\n", r_eip.intValue(), intno)); - u.emu_stop(); - break; + System.out.print(String.format( + ">>> 0x%x: interrupt 0x%x, SYS_EXIT. quit!\n\n", + r_eip.intValue(), intno)); + u.emu_stop(); + break; case 4: // sys_write - // ECX = buffer address - r_ecx = (Long)u.reg_read(Unicorn.UC_X86_REG_ECX); - - // EDX = buffer size - r_edx = (Long)u.reg_read(Unicorn.UC_X86_REG_EDX); - - // 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.intValue(), intno, r_ecx.intValue(), r_edx.intValue(), new String(buffer))); - break; - } - } - } + // ECX = buffer address + r_ecx = (Long) u.reg_read(Unicorn.UC_X86_REG_ECX); - static void test_i386() - { - Long r_esp = ADDRESS + 0x200000L; // 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, Unicorn.UC_PROT_ALL); - - // 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, 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"); - } - - } + // EDX = buffer size + r_edx = (Long) u.reg_read(Unicorn.UC_X86_REG_EDX); + + // 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.intValue(), intno, r_ecx.intValue(), + r_edx.intValue(), new String(buffer))); + break; + } + } + } + + static void test_i386() { + Long r_esp = ADDRESS + 0x200000L; // 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, Unicorn.UC_PROT_ALL); + + // 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, 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"); + } + + } } diff --git a/bindings/java/unicorn/Arm64Const.java b/bindings/java/unicorn/Arm64Const.java index bb196037..5add7e11 100644 --- a/bindings/java/unicorn/Arm64Const.java +++ b/bindings/java/unicorn/Arm64Const.java @@ -4,336 +4,336 @@ package unicorn; public interface Arm64Const { -// ARM64 CPU + // ARM64 CPU - public static final int UC_CPU_ARM64_A57 = 0; - public static final int UC_CPU_ARM64_A53 = 1; - public static final int UC_CPU_ARM64_A72 = 2; - public static final int UC_CPU_ARM64_MAX = 3; - public static final int UC_CPU_ARM64_ENDING = 4; + public static final int UC_CPU_ARM64_A57 = 0; + public static final int UC_CPU_ARM64_A53 = 1; + public static final int UC_CPU_ARM64_A72 = 2; + public static final int UC_CPU_ARM64_MAX = 3; + public static final int UC_CPU_ARM64_ENDING = 4; -// ARM64 registers + // ARM64 registers - 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_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; -// pseudo registers - public static final int UC_ARM64_REG_PC = 260; - public static final int UC_ARM64_REG_CPACR_EL1 = 261; + // pseudo registers + public static final int UC_ARM64_REG_PC = 260; + public static final int UC_ARM64_REG_CPACR_EL1 = 261; -// thread registers, depreciated, use UC_ARM64_REG_CP_REG instead - public static final int UC_ARM64_REG_TPIDR_EL0 = 262; - public static final int UC_ARM64_REG_TPIDRRO_EL0 = 263; - public static final int UC_ARM64_REG_TPIDR_EL1 = 264; - public static final int UC_ARM64_REG_PSTATE = 265; + // thread registers, depreciated, use UC_ARM64_REG_CP_REG instead + public static final int UC_ARM64_REG_TPIDR_EL0 = 262; + public static final int UC_ARM64_REG_TPIDRRO_EL0 = 263; + public static final int UC_ARM64_REG_TPIDR_EL1 = 264; + public static final int UC_ARM64_REG_PSTATE = 265; -// exception link registers, depreciated, use UC_ARM64_REG_CP_REG instead - public static final int UC_ARM64_REG_ELR_EL0 = 266; - public static final int UC_ARM64_REG_ELR_EL1 = 267; - public static final int UC_ARM64_REG_ELR_EL2 = 268; - public static final int UC_ARM64_REG_ELR_EL3 = 269; + // exception link registers, depreciated, use UC_ARM64_REG_CP_REG instead + public static final int UC_ARM64_REG_ELR_EL0 = 266; + public static final int UC_ARM64_REG_ELR_EL1 = 267; + public static final int UC_ARM64_REG_ELR_EL2 = 268; + public static final int UC_ARM64_REG_ELR_EL3 = 269; -// stack pointers registers, depreciated, use UC_ARM64_REG_CP_REG instead - public static final int UC_ARM64_REG_SP_EL0 = 270; - public static final int UC_ARM64_REG_SP_EL1 = 271; - public static final int UC_ARM64_REG_SP_EL2 = 272; - public static final int UC_ARM64_REG_SP_EL3 = 273; + // stack pointers registers, depreciated, use UC_ARM64_REG_CP_REG instead + public static final int UC_ARM64_REG_SP_EL0 = 270; + public static final int UC_ARM64_REG_SP_EL1 = 271; + public static final int UC_ARM64_REG_SP_EL2 = 272; + public static final int UC_ARM64_REG_SP_EL3 = 273; -// other CP15 registers, depreciated, use UC_ARM64_REG_CP_REG instead - public static final int UC_ARM64_REG_TTBR0_EL1 = 274; - public static final int UC_ARM64_REG_TTBR1_EL1 = 275; - public static final int UC_ARM64_REG_ESR_EL0 = 276; - public static final int UC_ARM64_REG_ESR_EL1 = 277; - public static final int UC_ARM64_REG_ESR_EL2 = 278; - public static final int UC_ARM64_REG_ESR_EL3 = 279; - public static final int UC_ARM64_REG_FAR_EL0 = 280; - public static final int UC_ARM64_REG_FAR_EL1 = 281; - public static final int UC_ARM64_REG_FAR_EL2 = 282; - public static final int UC_ARM64_REG_FAR_EL3 = 283; - public static final int UC_ARM64_REG_PAR_EL1 = 284; - public static final int UC_ARM64_REG_MAIR_EL1 = 285; - public static final int UC_ARM64_REG_VBAR_EL0 = 286; - public static final int UC_ARM64_REG_VBAR_EL1 = 287; - public static final int UC_ARM64_REG_VBAR_EL2 = 288; - public static final int UC_ARM64_REG_VBAR_EL3 = 289; - public static final int UC_ARM64_REG_CP_REG = 290; + // other CP15 registers, depreciated, use UC_ARM64_REG_CP_REG instead + public static final int UC_ARM64_REG_TTBR0_EL1 = 274; + public static final int UC_ARM64_REG_TTBR1_EL1 = 275; + public static final int UC_ARM64_REG_ESR_EL0 = 276; + public static final int UC_ARM64_REG_ESR_EL1 = 277; + public static final int UC_ARM64_REG_ESR_EL2 = 278; + public static final int UC_ARM64_REG_ESR_EL3 = 279; + public static final int UC_ARM64_REG_FAR_EL0 = 280; + public static final int UC_ARM64_REG_FAR_EL1 = 281; + public static final int UC_ARM64_REG_FAR_EL2 = 282; + public static final int UC_ARM64_REG_FAR_EL3 = 283; + public static final int UC_ARM64_REG_PAR_EL1 = 284; + public static final int UC_ARM64_REG_MAIR_EL1 = 285; + public static final int UC_ARM64_REG_VBAR_EL0 = 286; + public static final int UC_ARM64_REG_VBAR_EL1 = 287; + public static final int UC_ARM64_REG_VBAR_EL2 = 288; + public static final int UC_ARM64_REG_VBAR_EL3 = 289; + public static final int UC_ARM64_REG_CP_REG = 290; -// floating point control and status registers - public static final int UC_ARM64_REG_FPCR = 291; - public static final int UC_ARM64_REG_FPSR = 292; - public static final int UC_ARM64_REG_ENDING = 293; + // floating point control and status registers + public static final int UC_ARM64_REG_FPCR = 291; + public static final int UC_ARM64_REG_FPSR = 292; + public static final int UC_ARM64_REG_ENDING = 293; -// alias registers - public static final int UC_ARM64_REG_IP0 = 215; - public static final int UC_ARM64_REG_IP1 = 216; - public static final int UC_ARM64_REG_FP = 1; - public static final int UC_ARM64_REG_LR = 2; + // alias registers + public static final int UC_ARM64_REG_IP0 = 215; + public static final int UC_ARM64_REG_IP1 = 216; + public static final int UC_ARM64_REG_FP = 1; + public static final int UC_ARM64_REG_LR = 2; -// ARM64 instructions + // ARM64 instructions - public static final int UC_ARM64_INS_INVALID = 0; - public static final int UC_ARM64_INS_MRS = 1; - public static final int UC_ARM64_INS_MSR = 2; - public static final int UC_ARM64_INS_SYS = 3; - public static final int UC_ARM64_INS_SYSL = 4; - public static final int UC_ARM64_INS_ENDING = 5; + public static final int UC_ARM64_INS_INVALID = 0; + public static final int UC_ARM64_INS_MRS = 1; + public static final int UC_ARM64_INS_MSR = 2; + public static final int UC_ARM64_INS_SYS = 3; + public static final int UC_ARM64_INS_SYSL = 4; + public static final int UC_ARM64_INS_ENDING = 5; } diff --git a/bindings/java/unicorn/ArmConst.java b/bindings/java/unicorn/ArmConst.java index 0b56d072..300a8fda 100644 --- a/bindings/java/unicorn/ArmConst.java +++ b/bindings/java/unicorn/ArmConst.java @@ -4,195 +4,195 @@ package unicorn; public interface ArmConst { -// ARM CPU + // ARM CPU - public static final int UC_CPU_ARM_926 = 0; - public static final int UC_CPU_ARM_946 = 1; - public static final int UC_CPU_ARM_1026 = 2; - public static final int UC_CPU_ARM_1136_R2 = 3; - public static final int UC_CPU_ARM_1136 = 4; - public static final int UC_CPU_ARM_1176 = 5; - public static final int UC_CPU_ARM_11MPCORE = 6; - public static final int UC_CPU_ARM_CORTEX_M0 = 7; - public static final int UC_CPU_ARM_CORTEX_M3 = 8; - public static final int UC_CPU_ARM_CORTEX_M4 = 9; - public static final int UC_CPU_ARM_CORTEX_M7 = 10; - public static final int UC_CPU_ARM_CORTEX_M33 = 11; - public static final int UC_CPU_ARM_CORTEX_R5 = 12; - public static final int UC_CPU_ARM_CORTEX_R5F = 13; - public static final int UC_CPU_ARM_CORTEX_A7 = 14; - public static final int UC_CPU_ARM_CORTEX_A8 = 15; - public static final int UC_CPU_ARM_CORTEX_A9 = 16; - public static final int UC_CPU_ARM_CORTEX_A15 = 17; - public static final int UC_CPU_ARM_TI925T = 18; - public static final int UC_CPU_ARM_SA1100 = 19; - public static final int UC_CPU_ARM_SA1110 = 20; - public static final int UC_CPU_ARM_PXA250 = 21; - public static final int UC_CPU_ARM_PXA255 = 22; - public static final int UC_CPU_ARM_PXA260 = 23; - public static final int UC_CPU_ARM_PXA261 = 24; - public static final int UC_CPU_ARM_PXA262 = 25; - public static final int UC_CPU_ARM_PXA270 = 26; - public static final int UC_CPU_ARM_PXA270A0 = 27; - public static final int UC_CPU_ARM_PXA270A1 = 28; - public static final int UC_CPU_ARM_PXA270B0 = 29; - public static final int UC_CPU_ARM_PXA270B1 = 30; - public static final int UC_CPU_ARM_PXA270C0 = 31; - public static final int UC_CPU_ARM_PXA270C5 = 32; - public static final int UC_CPU_ARM_MAX = 33; - public static final int UC_CPU_ARM_ENDING = 34; + public static final int UC_CPU_ARM_926 = 0; + public static final int UC_CPU_ARM_946 = 1; + public static final int UC_CPU_ARM_1026 = 2; + public static final int UC_CPU_ARM_1136_R2 = 3; + public static final int UC_CPU_ARM_1136 = 4; + public static final int UC_CPU_ARM_1176 = 5; + public static final int UC_CPU_ARM_11MPCORE = 6; + public static final int UC_CPU_ARM_CORTEX_M0 = 7; + public static final int UC_CPU_ARM_CORTEX_M3 = 8; + public static final int UC_CPU_ARM_CORTEX_M4 = 9; + public static final int UC_CPU_ARM_CORTEX_M7 = 10; + public static final int UC_CPU_ARM_CORTEX_M33 = 11; + public static final int UC_CPU_ARM_CORTEX_R5 = 12; + public static final int UC_CPU_ARM_CORTEX_R5F = 13; + public static final int UC_CPU_ARM_CORTEX_A7 = 14; + public static final int UC_CPU_ARM_CORTEX_A8 = 15; + public static final int UC_CPU_ARM_CORTEX_A9 = 16; + public static final int UC_CPU_ARM_CORTEX_A15 = 17; + public static final int UC_CPU_ARM_TI925T = 18; + public static final int UC_CPU_ARM_SA1100 = 19; + public static final int UC_CPU_ARM_SA1110 = 20; + public static final int UC_CPU_ARM_PXA250 = 21; + public static final int UC_CPU_ARM_PXA255 = 22; + public static final int UC_CPU_ARM_PXA260 = 23; + public static final int UC_CPU_ARM_PXA261 = 24; + public static final int UC_CPU_ARM_PXA262 = 25; + public static final int UC_CPU_ARM_PXA270 = 26; + public static final int UC_CPU_ARM_PXA270A0 = 27; + public static final int UC_CPU_ARM_PXA270A1 = 28; + public static final int UC_CPU_ARM_PXA270B0 = 29; + public static final int UC_CPU_ARM_PXA270B1 = 30; + public static final int UC_CPU_ARM_PXA270C0 = 31; + public static final int UC_CPU_ARM_PXA270C5 = 32; + public static final int UC_CPU_ARM_MAX = 33; + public static final int UC_CPU_ARM_ENDING = 34; -// ARM registers + // ARM registers - 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_C1_C0_2 = 111; - public static final int UC_ARM_REG_C13_C0_2 = 112; - public static final int UC_ARM_REG_C13_C0_3 = 113; - public static final int UC_ARM_REG_IPSR = 114; - public static final int UC_ARM_REG_MSP = 115; - public static final int UC_ARM_REG_PSP = 116; - public static final int UC_ARM_REG_CONTROL = 117; - public static final int UC_ARM_REG_IAPSR = 118; - public static final int UC_ARM_REG_EAPSR = 119; - public static final int UC_ARM_REG_XPSR = 120; - public static final int UC_ARM_REG_EPSR = 121; - public static final int UC_ARM_REG_IEPSR = 122; - public static final int UC_ARM_REG_PRIMASK = 123; - public static final int UC_ARM_REG_BASEPRI = 124; - public static final int UC_ARM_REG_BASEPRI_MAX = 125; - public static final int UC_ARM_REG_FAULTMASK = 126; - public static final int UC_ARM_REG_APSR_NZCVQ = 127; - public static final int UC_ARM_REG_APSR_G = 128; - public static final int UC_ARM_REG_APSR_NZCVQG = 129; - public static final int UC_ARM_REG_IAPSR_NZCVQ = 130; - public static final int UC_ARM_REG_IAPSR_G = 131; - public static final int UC_ARM_REG_IAPSR_NZCVQG = 132; - public static final int UC_ARM_REG_EAPSR_NZCVQ = 133; - public static final int UC_ARM_REG_EAPSR_G = 134; - public static final int UC_ARM_REG_EAPSR_NZCVQG = 135; - public static final int UC_ARM_REG_XPSR_NZCVQ = 136; - public static final int UC_ARM_REG_XPSR_G = 137; - public static final int UC_ARM_REG_XPSR_NZCVQG = 138; - public static final int UC_ARM_REG_CP_REG = 139; - public static final int UC_ARM_REG_ENDING = 140; + 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_C1_C0_2 = 111; + public static final int UC_ARM_REG_C13_C0_2 = 112; + public static final int UC_ARM_REG_C13_C0_3 = 113; + public static final int UC_ARM_REG_IPSR = 114; + public static final int UC_ARM_REG_MSP = 115; + public static final int UC_ARM_REG_PSP = 116; + public static final int UC_ARM_REG_CONTROL = 117; + public static final int UC_ARM_REG_IAPSR = 118; + public static final int UC_ARM_REG_EAPSR = 119; + public static final int UC_ARM_REG_XPSR = 120; + public static final int UC_ARM_REG_EPSR = 121; + public static final int UC_ARM_REG_IEPSR = 122; + public static final int UC_ARM_REG_PRIMASK = 123; + public static final int UC_ARM_REG_BASEPRI = 124; + public static final int UC_ARM_REG_BASEPRI_MAX = 125; + public static final int UC_ARM_REG_FAULTMASK = 126; + public static final int UC_ARM_REG_APSR_NZCVQ = 127; + public static final int UC_ARM_REG_APSR_G = 128; + public static final int UC_ARM_REG_APSR_NZCVQG = 129; + public static final int UC_ARM_REG_IAPSR_NZCVQ = 130; + public static final int UC_ARM_REG_IAPSR_G = 131; + public static final int UC_ARM_REG_IAPSR_NZCVQG = 132; + public static final int UC_ARM_REG_EAPSR_NZCVQ = 133; + public static final int UC_ARM_REG_EAPSR_G = 134; + public static final int UC_ARM_REG_EAPSR_NZCVQG = 135; + public static final int UC_ARM_REG_XPSR_NZCVQ = 136; + public static final int UC_ARM_REG_XPSR_G = 137; + public static final int UC_ARM_REG_XPSR_NZCVQG = 138; + public static final int UC_ARM_REG_CP_REG = 139; + public static final int UC_ARM_REG_ENDING = 140; -// alias registers - public static final int UC_ARM_REG_R13 = 12; - public static final int UC_ARM_REG_R14 = 10; - public static final int UC_ARM_REG_R15 = 11; - public static final int UC_ARM_REG_SB = 75; - public static final int UC_ARM_REG_SL = 76; - public static final int UC_ARM_REG_FP = 77; - public static final int UC_ARM_REG_IP = 78; + // alias registers + public static final int UC_ARM_REG_R13 = 12; + public static final int UC_ARM_REG_R14 = 10; + public static final int UC_ARM_REG_R15 = 11; + public static final int UC_ARM_REG_SB = 75; + public static final int UC_ARM_REG_SL = 76; + public static final int UC_ARM_REG_FP = 77; + public static final int UC_ARM_REG_IP = 78; } diff --git a/bindings/java/unicorn/BlockHook.java b/bindings/java/unicorn/BlockHook.java index cae5ef9f..1ade7a2b 100644 --- a/bindings/java/unicorn/BlockHook.java +++ b/bindings/java/unicorn/BlockHook.java @@ -22,8 +22,5 @@ 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); - + public void hook(Unicorn u, long address, int size, Object user); } - diff --git a/bindings/java/unicorn/CodeHook.java b/bindings/java/unicorn/CodeHook.java index 6cbfdd4b..e78a9803 100644 --- a/bindings/java/unicorn/CodeHook.java +++ b/bindings/java/unicorn/CodeHook.java @@ -22,8 +22,5 @@ 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); - + public void hook(Unicorn u, long address, int size, Object user); } - diff --git a/bindings/java/unicorn/EventMemHook.java b/bindings/java/unicorn/EventMemHook.java index db1f12d9..8262b179 100644 --- a/bindings/java/unicorn/EventMemHook.java +++ b/bindings/java/unicorn/EventMemHook.java @@ -22,8 +22,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. package unicorn; public interface EventMemHook extends Hook { - - public boolean hook(Unicorn u, long address, int size, long value, Object user); - + public boolean hook(Unicorn u, long address, int size, long value, + Object user); } - diff --git a/bindings/java/unicorn/Hook.java b/bindings/java/unicorn/Hook.java index 003599a3..97e0fc26 100644 --- a/bindings/java/unicorn/Hook.java +++ b/bindings/java/unicorn/Hook.java @@ -26,4 +26,5 @@ package unicorn; */ public interface Hook { + } diff --git a/bindings/java/unicorn/InHook.java b/bindings/java/unicorn/InHook.java index 97653ab3..9f0c978b 100644 --- a/bindings/java/unicorn/InHook.java +++ b/bindings/java/unicorn/InHook.java @@ -22,8 +22,5 @@ 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); - + public int hook(Unicorn u, int port, int size, Object user); } - diff --git a/bindings/java/unicorn/InterruptHook.java b/bindings/java/unicorn/InterruptHook.java index 23bc29f8..3702e887 100644 --- a/bindings/java/unicorn/InterruptHook.java +++ b/bindings/java/unicorn/InterruptHook.java @@ -22,8 +22,5 @@ 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); - + public void hook(Unicorn u, int intno, Object user); } - diff --git a/bindings/java/unicorn/M68kConst.java b/bindings/java/unicorn/M68kConst.java index 17e80e7c..ea2500a3 100644 --- a/bindings/java/unicorn/M68kConst.java +++ b/bindings/java/unicorn/M68kConst.java @@ -4,40 +4,40 @@ package unicorn; public interface M68kConst { -// M68K CPU + // M68K CPU - public static final int UC_CPU_M68K_M5206 = 0; - public static final int UC_CPU_M68K_M68000 = 1; - public static final int UC_CPU_M68K_M68020 = 2; - public static final int UC_CPU_M68K_M68030 = 3; - public static final int UC_CPU_M68K_M68040 = 4; - public static final int UC_CPU_M68K_M68060 = 5; - public static final int UC_CPU_M68K_M5208 = 6; - public static final int UC_CPU_M68K_CFV4E = 7; - public static final int UC_CPU_M68K_ANY = 8; - public static final int UC_CPU_M68K_ENDING = 9; + public static final int UC_CPU_M68K_M5206 = 0; + public static final int UC_CPU_M68K_M68000 = 1; + public static final int UC_CPU_M68K_M68020 = 2; + public static final int UC_CPU_M68K_M68030 = 3; + public static final int UC_CPU_M68K_M68040 = 4; + public static final int UC_CPU_M68K_M68060 = 5; + public static final int UC_CPU_M68K_M5208 = 6; + public static final int UC_CPU_M68K_CFV4E = 7; + public static final int UC_CPU_M68K_ANY = 8; + public static final int UC_CPU_M68K_ENDING = 9; -// M68K registers + // M68K registers - 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; + 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; } diff --git a/bindings/java/unicorn/MemHook.java b/bindings/java/unicorn/MemHook.java index 9f1a1889..3151c84d 100644 --- a/bindings/java/unicorn/MemHook.java +++ b/bindings/java/unicorn/MemHook.java @@ -21,7 +21,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. package unicorn; -public interface MemHook extends ReadHook,WriteHook { +public interface MemHook extends ReadHook, WriteHook { } - diff --git a/bindings/java/unicorn/MemRegion.java b/bindings/java/unicorn/MemRegion.java index b729b3a9..1e4733dd 100644 --- a/bindings/java/unicorn/MemRegion.java +++ b/bindings/java/unicorn/MemRegion.java @@ -22,16 +22,13 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. package unicorn; public class MemRegion { + public long begin; + public long end; + public int perms; - public long begin; - public long end; - public int perms; - - public MemRegion(long begin, long end, int perms) { - this.begin = begin; - this.end = end; - this.perms = perms; - } - + public MemRegion(long begin, long end, int perms) { + this.begin = begin; + this.end = end; + this.perms = perms; + } } - diff --git a/bindings/java/unicorn/MipsConst.java b/bindings/java/unicorn/MipsConst.java index ecb65314..1cd6eb49 100644 --- a/bindings/java/unicorn/MipsConst.java +++ b/bindings/java/unicorn/MipsConst.java @@ -4,238 +4,238 @@ package unicorn; public interface MipsConst { -// MIPS32 CPUS + // MIPS32 CPUS - public static final int UC_CPU_MIPS32_4KC = 0; - public static final int UC_CPU_MIPS32_4KM = 1; - public static final int UC_CPU_MIPS32_4KECR1 = 2; - public static final int UC_CPU_MIPS32_4KEMR1 = 3; - public static final int UC_CPU_MIPS32_4KEC = 4; - public static final int UC_CPU_MIPS32_4KEM = 5; - public static final int UC_CPU_MIPS32_24KC = 6; - public static final int UC_CPU_MIPS32_24KEC = 7; - public static final int UC_CPU_MIPS32_24KF = 8; - public static final int UC_CPU_MIPS32_34KF = 9; - public static final int UC_CPU_MIPS32_74KF = 10; - public static final int UC_CPU_MIPS32_M14K = 11; - public static final int UC_CPU_MIPS32_M14KC = 12; - public static final int UC_CPU_MIPS32_P5600 = 13; - public static final int UC_CPU_MIPS32_MIPS32R6_GENERIC = 14; - public static final int UC_CPU_MIPS32_I7200 = 15; - public static final int UC_CPU_MIPS32_ENDING = 16; + public static final int UC_CPU_MIPS32_4KC = 0; + public static final int UC_CPU_MIPS32_4KM = 1; + public static final int UC_CPU_MIPS32_4KECR1 = 2; + public static final int UC_CPU_MIPS32_4KEMR1 = 3; + public static final int UC_CPU_MIPS32_4KEC = 4; + public static final int UC_CPU_MIPS32_4KEM = 5; + public static final int UC_CPU_MIPS32_24KC = 6; + public static final int UC_CPU_MIPS32_24KEC = 7; + public static final int UC_CPU_MIPS32_24KF = 8; + public static final int UC_CPU_MIPS32_34KF = 9; + public static final int UC_CPU_MIPS32_74KF = 10; + public static final int UC_CPU_MIPS32_M14K = 11; + public static final int UC_CPU_MIPS32_M14KC = 12; + public static final int UC_CPU_MIPS32_P5600 = 13; + public static final int UC_CPU_MIPS32_MIPS32R6_GENERIC = 14; + public static final int UC_CPU_MIPS32_I7200 = 15; + public static final int UC_CPU_MIPS32_ENDING = 16; -// MIPS64 CPUS + // MIPS64 CPUS - public static final int UC_CPU_MIPS64_R4000 = 0; - public static final int UC_CPU_MIPS64_VR5432 = 1; - public static final int UC_CPU_MIPS64_5KC = 2; - public static final int UC_CPU_MIPS64_5KF = 3; - public static final int UC_CPU_MIPS64_20KC = 4; - public static final int UC_CPU_MIPS64_MIPS64R2_GENERIC = 5; - public static final int UC_CPU_MIPS64_5KEC = 6; - public static final int UC_CPU_MIPS64_5KEF = 7; - public static final int UC_CPU_MIPS64_I6400 = 8; - public static final int UC_CPU_MIPS64_I6500 = 9; - public static final int UC_CPU_MIPS64_LOONGSON_2E = 10; - public static final int UC_CPU_MIPS64_LOONGSON_2F = 11; - public static final int UC_CPU_MIPS64_MIPS64DSPR2 = 12; - public static final int UC_CPU_MIPS64_ENDING = 13; + public static final int UC_CPU_MIPS64_R4000 = 0; + public static final int UC_CPU_MIPS64_VR5432 = 1; + public static final int UC_CPU_MIPS64_5KC = 2; + public static final int UC_CPU_MIPS64_5KF = 3; + public static final int UC_CPU_MIPS64_20KC = 4; + public static final int UC_CPU_MIPS64_MIPS64R2_GENERIC = 5; + public static final int UC_CPU_MIPS64_5KEC = 6; + public static final int UC_CPU_MIPS64_5KEF = 7; + public static final int UC_CPU_MIPS64_I6400 = 8; + public static final int UC_CPU_MIPS64_I6500 = 9; + public static final int UC_CPU_MIPS64_LOONGSON_2E = 10; + public static final int UC_CPU_MIPS64_LOONGSON_2F = 11; + public static final int UC_CPU_MIPS64_MIPS64DSPR2 = 12; + public static final int UC_CPU_MIPS64_ENDING = 13; -// MIPS registers + // MIPS registers - public static final int UC_MIPS_REG_INVALID = 0; + public static final int UC_MIPS_REG_INVALID = 0; -// General purpose registers - 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; + // General purpose registers + 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; -// DSP registers - 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; + // DSP registers + 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; -// ACC registers - 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; + // ACC registers + 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; -// COP registers - 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; + // COP registers + 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; -// FPU registers - 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; + // FPU registers + 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; -// AFPR128 - 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_CP0_CONFIG3 = 137; - public static final int UC_MIPS_REG_CP0_USERLOCAL = 138; - public static final int UC_MIPS_REG_CP0_STATUS = 139; - public static final int UC_MIPS_REG_ENDING = 140; - public static final int UC_MIPS_REG_ZERO = 2; - public static final int UC_MIPS_REG_AT = 3; - public static final int UC_MIPS_REG_V0 = 4; - public static final int UC_MIPS_REG_V1 = 5; - public static final int UC_MIPS_REG_A0 = 6; - public static final int UC_MIPS_REG_A1 = 7; - public static final int UC_MIPS_REG_A2 = 8; - public static final int UC_MIPS_REG_A3 = 9; - public static final int UC_MIPS_REG_T0 = 10; - public static final int UC_MIPS_REG_T1 = 11; - public static final int UC_MIPS_REG_T2 = 12; - public static final int UC_MIPS_REG_T3 = 13; - public static final int UC_MIPS_REG_T4 = 14; - public static final int UC_MIPS_REG_T5 = 15; - public static final int UC_MIPS_REG_T6 = 16; - public static final int UC_MIPS_REG_T7 = 17; - public static final int UC_MIPS_REG_S0 = 18; - public static final int UC_MIPS_REG_S1 = 19; - public static final int UC_MIPS_REG_S2 = 20; - public static final int UC_MIPS_REG_S3 = 21; - public static final int UC_MIPS_REG_S4 = 22; - public static final int UC_MIPS_REG_S5 = 23; - public static final int UC_MIPS_REG_S6 = 24; - public static final int UC_MIPS_REG_S7 = 25; - public static final int UC_MIPS_REG_T8 = 26; - public static final int UC_MIPS_REG_T9 = 27; - public static final int UC_MIPS_REG_K0 = 28; - public static final int UC_MIPS_REG_K1 = 29; - public static final int UC_MIPS_REG_GP = 30; - public static final int UC_MIPS_REG_SP = 31; - public static final int UC_MIPS_REG_FP = 32; - public static final int UC_MIPS_REG_S8 = 32; - public static final int UC_MIPS_REG_RA = 33; - public static final int UC_MIPS_REG_HI0 = 45; - public static final int UC_MIPS_REG_HI1 = 46; - public static final int UC_MIPS_REG_HI2 = 47; - public static final int UC_MIPS_REG_HI3 = 48; - public static final int UC_MIPS_REG_LO0 = 45; - public static final int UC_MIPS_REG_LO1 = 46; - public static final int UC_MIPS_REG_LO2 = 47; - public static final int UC_MIPS_REG_LO3 = 48; + // AFPR128 + 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_CP0_CONFIG3 = 137; + public static final int UC_MIPS_REG_CP0_USERLOCAL = 138; + public static final int UC_MIPS_REG_CP0_STATUS = 139; + public static final int UC_MIPS_REG_ENDING = 140; + public static final int UC_MIPS_REG_ZERO = 2; + public static final int UC_MIPS_REG_AT = 3; + public static final int UC_MIPS_REG_V0 = 4; + public static final int UC_MIPS_REG_V1 = 5; + public static final int UC_MIPS_REG_A0 = 6; + public static final int UC_MIPS_REG_A1 = 7; + public static final int UC_MIPS_REG_A2 = 8; + public static final int UC_MIPS_REG_A3 = 9; + public static final int UC_MIPS_REG_T0 = 10; + public static final int UC_MIPS_REG_T1 = 11; + public static final int UC_MIPS_REG_T2 = 12; + public static final int UC_MIPS_REG_T3 = 13; + public static final int UC_MIPS_REG_T4 = 14; + public static final int UC_MIPS_REG_T5 = 15; + public static final int UC_MIPS_REG_T6 = 16; + public static final int UC_MIPS_REG_T7 = 17; + public static final int UC_MIPS_REG_S0 = 18; + public static final int UC_MIPS_REG_S1 = 19; + public static final int UC_MIPS_REG_S2 = 20; + public static final int UC_MIPS_REG_S3 = 21; + public static final int UC_MIPS_REG_S4 = 22; + public static final int UC_MIPS_REG_S5 = 23; + public static final int UC_MIPS_REG_S6 = 24; + public static final int UC_MIPS_REG_S7 = 25; + public static final int UC_MIPS_REG_T8 = 26; + public static final int UC_MIPS_REG_T9 = 27; + public static final int UC_MIPS_REG_K0 = 28; + public static final int UC_MIPS_REG_K1 = 29; + public static final int UC_MIPS_REG_GP = 30; + public static final int UC_MIPS_REG_SP = 31; + public static final int UC_MIPS_REG_FP = 32; + public static final int UC_MIPS_REG_S8 = 32; + public static final int UC_MIPS_REG_RA = 33; + public static final int UC_MIPS_REG_HI0 = 45; + public static final int UC_MIPS_REG_HI1 = 46; + public static final int UC_MIPS_REG_HI2 = 47; + public static final int UC_MIPS_REG_HI3 = 48; + public static final int UC_MIPS_REG_LO0 = 45; + public static final int UC_MIPS_REG_LO1 = 46; + public static final int UC_MIPS_REG_LO2 = 47; + public static final int UC_MIPS_REG_LO3 = 48; } diff --git a/bindings/java/unicorn/OutHook.java b/bindings/java/unicorn/OutHook.java index 94c050f9..674e88e3 100644 --- a/bindings/java/unicorn/OutHook.java +++ b/bindings/java/unicorn/OutHook.java @@ -22,8 +22,5 @@ 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); - + public void hook(Unicorn u, int port, int size, int value, Object user); } - diff --git a/bindings/java/unicorn/PpcConst.java b/bindings/java/unicorn/PpcConst.java index 65ef72a1..594e165b 100644 --- a/bindings/java/unicorn/PpcConst.java +++ b/bindings/java/unicorn/PpcConst.java @@ -4,407 +4,407 @@ package unicorn; public interface PpcConst { -// PPC CPU + // PPC CPU - public static final int UC_CPU_PPC32_401 = 0; - public static final int UC_CPU_PPC32_401A1 = 1; - public static final int UC_CPU_PPC32_401B2 = 2; - public static final int UC_CPU_PPC32_401C2 = 3; - public static final int UC_CPU_PPC32_401D2 = 4; - public static final int UC_CPU_PPC32_401E2 = 5; - public static final int UC_CPU_PPC32_401F2 = 6; - public static final int UC_CPU_PPC32_401G2 = 7; - public static final int UC_CPU_PPC32_IOP480 = 8; - public static final int UC_CPU_PPC32_COBRA = 9; - public static final int UC_CPU_PPC32_403GA = 10; - public static final int UC_CPU_PPC32_403GB = 11; - public static final int UC_CPU_PPC32_403GC = 12; - public static final int UC_CPU_PPC32_403GCX = 13; - public static final int UC_CPU_PPC32_405D2 = 14; - public static final int UC_CPU_PPC32_405D4 = 15; - public static final int UC_CPU_PPC32_405CRA = 16; - public static final int UC_CPU_PPC32_405CRB = 17; - public static final int UC_CPU_PPC32_405CRC = 18; - public static final int UC_CPU_PPC32_405EP = 19; - public static final int UC_CPU_PPC32_405EZ = 20; - public static final int UC_CPU_PPC32_405GPA = 21; - public static final int UC_CPU_PPC32_405GPB = 22; - public static final int UC_CPU_PPC32_405GPC = 23; - public static final int UC_CPU_PPC32_405GPD = 24; - public static final int UC_CPU_PPC32_405GPR = 25; - public static final int UC_CPU_PPC32_405LP = 26; - public static final int UC_CPU_PPC32_NPE405H = 27; - public static final int UC_CPU_PPC32_NPE405H2 = 28; - public static final int UC_CPU_PPC32_NPE405L = 29; - public static final int UC_CPU_PPC32_NPE4GS3 = 30; - public static final int UC_CPU_PPC32_STB03 = 31; - public static final int UC_CPU_PPC32_STB04 = 32; - public static final int UC_CPU_PPC32_STB25 = 33; - public static final int UC_CPU_PPC32_X2VP4 = 34; - public static final int UC_CPU_PPC32_X2VP20 = 35; - public static final int UC_CPU_PPC32_440_XILINX = 36; - public static final int UC_CPU_PPC32_440_XILINX_W_DFPU = 37; - public static final int UC_CPU_PPC32_440EPA = 38; - public static final int UC_CPU_PPC32_440EPB = 39; - public static final int UC_CPU_PPC32_440EPX = 40; - public static final int UC_CPU_PPC32_460EXB = 41; - public static final int UC_CPU_PPC32_G2 = 42; - public static final int UC_CPU_PPC32_G2H4 = 43; - public static final int UC_CPU_PPC32_G2GP = 44; - public static final int UC_CPU_PPC32_G2LS = 45; - public static final int UC_CPU_PPC32_G2HIP3 = 46; - public static final int UC_CPU_PPC32_G2HIP4 = 47; - public static final int UC_CPU_PPC32_MPC603 = 48; - public static final int UC_CPU_PPC32_G2LE = 49; - public static final int UC_CPU_PPC32_G2LEGP = 50; - public static final int UC_CPU_PPC32_G2LELS = 51; - public static final int UC_CPU_PPC32_G2LEGP1 = 52; - public static final int UC_CPU_PPC32_G2LEGP3 = 53; - public static final int UC_CPU_PPC32_MPC5200_V10 = 54; - public static final int UC_CPU_PPC32_MPC5200_V11 = 55; - public static final int UC_CPU_PPC32_MPC5200_V12 = 56; - public static final int UC_CPU_PPC32_MPC5200B_V20 = 57; - public static final int UC_CPU_PPC32_MPC5200B_V21 = 58; - public static final int UC_CPU_PPC32_E200Z5 = 59; - public static final int UC_CPU_PPC32_E200Z6 = 60; - public static final int UC_CPU_PPC32_E300C1 = 61; - public static final int UC_CPU_PPC32_E300C2 = 62; - public static final int UC_CPU_PPC32_E300C3 = 63; - public static final int UC_CPU_PPC32_E300C4 = 64; - public static final int UC_CPU_PPC32_MPC8343 = 65; - public static final int UC_CPU_PPC32_MPC8343A = 66; - public static final int UC_CPU_PPC32_MPC8343E = 67; - public static final int UC_CPU_PPC32_MPC8343EA = 68; - public static final int UC_CPU_PPC32_MPC8347T = 69; - public static final int UC_CPU_PPC32_MPC8347P = 70; - public static final int UC_CPU_PPC32_MPC8347AT = 71; - public static final int UC_CPU_PPC32_MPC8347AP = 72; - public static final int UC_CPU_PPC32_MPC8347ET = 73; - public static final int UC_CPU_PPC32_MPC8347EP = 74; - public static final int UC_CPU_PPC32_MPC8347EAT = 75; - public static final int UC_CPU_PPC32_MPC8347EAP = 76; - public static final int UC_CPU_PPC32_MPC8349 = 77; - public static final int UC_CPU_PPC32_MPC8349A = 78; - public static final int UC_CPU_PPC32_MPC8349E = 79; - public static final int UC_CPU_PPC32_MPC8349EA = 80; - public static final int UC_CPU_PPC32_MPC8377 = 81; - public static final int UC_CPU_PPC32_MPC8377E = 82; - public static final int UC_CPU_PPC32_MPC8378 = 83; - public static final int UC_CPU_PPC32_MPC8378E = 84; - public static final int UC_CPU_PPC32_MPC8379 = 85; - public static final int UC_CPU_PPC32_MPC8379E = 86; - public static final int UC_CPU_PPC32_E500_V10 = 87; - public static final int UC_CPU_PPC32_E500_V20 = 88; - public static final int UC_CPU_PPC32_E500V2_V10 = 89; - public static final int UC_CPU_PPC32_E500V2_V20 = 90; - public static final int UC_CPU_PPC32_E500V2_V21 = 91; - public static final int UC_CPU_PPC32_E500V2_V22 = 92; - public static final int UC_CPU_PPC32_E500V2_V30 = 93; - public static final int UC_CPU_PPC32_E500MC = 94; - public static final int UC_CPU_PPC32_MPC8533_V10 = 95; - public static final int UC_CPU_PPC32_MPC8533_V11 = 96; - public static final int UC_CPU_PPC32_MPC8533E_V10 = 97; - public static final int UC_CPU_PPC32_MPC8533E_V11 = 98; - public static final int UC_CPU_PPC32_MPC8540_V10 = 99; - public static final int UC_CPU_PPC32_MPC8540_V20 = 100; - public static final int UC_CPU_PPC32_MPC8540_V21 = 101; - public static final int UC_CPU_PPC32_MPC8541_V10 = 102; - public static final int UC_CPU_PPC32_MPC8541_V11 = 103; - public static final int UC_CPU_PPC32_MPC8541E_V10 = 104; - public static final int UC_CPU_PPC32_MPC8541E_V11 = 105; - public static final int UC_CPU_PPC32_MPC8543_V10 = 106; - public static final int UC_CPU_PPC32_MPC8543_V11 = 107; - public static final int UC_CPU_PPC32_MPC8543_V20 = 108; - public static final int UC_CPU_PPC32_MPC8543_V21 = 109; - public static final int UC_CPU_PPC32_MPC8543E_V10 = 110; - public static final int UC_CPU_PPC32_MPC8543E_V11 = 111; - public static final int UC_CPU_PPC32_MPC8543E_V20 = 112; - public static final int UC_CPU_PPC32_MPC8543E_V21 = 113; - public static final int UC_CPU_PPC32_MPC8544_V10 = 114; - public static final int UC_CPU_PPC32_MPC8544_V11 = 115; - public static final int UC_CPU_PPC32_MPC8544E_V10 = 116; - public static final int UC_CPU_PPC32_MPC8544E_V11 = 117; - public static final int UC_CPU_PPC32_MPC8545_V20 = 118; - public static final int UC_CPU_PPC32_MPC8545_V21 = 119; - public static final int UC_CPU_PPC32_MPC8545E_V20 = 120; - public static final int UC_CPU_PPC32_MPC8545E_V21 = 121; - public static final int UC_CPU_PPC32_MPC8547E_V20 = 122; - public static final int UC_CPU_PPC32_MPC8547E_V21 = 123; - public static final int UC_CPU_PPC32_MPC8548_V10 = 124; - public static final int UC_CPU_PPC32_MPC8548_V11 = 125; - public static final int UC_CPU_PPC32_MPC8548_V20 = 126; - public static final int UC_CPU_PPC32_MPC8548_V21 = 127; - public static final int UC_CPU_PPC32_MPC8548E_V10 = 128; - public static final int UC_CPU_PPC32_MPC8548E_V11 = 129; - public static final int UC_CPU_PPC32_MPC8548E_V20 = 130; - public static final int UC_CPU_PPC32_MPC8548E_V21 = 131; - public static final int UC_CPU_PPC32_MPC8555_V10 = 132; - public static final int UC_CPU_PPC32_MPC8555_V11 = 133; - public static final int UC_CPU_PPC32_MPC8555E_V10 = 134; - public static final int UC_CPU_PPC32_MPC8555E_V11 = 135; - public static final int UC_CPU_PPC32_MPC8560_V10 = 136; - public static final int UC_CPU_PPC32_MPC8560_V20 = 137; - public static final int UC_CPU_PPC32_MPC8560_V21 = 138; - public static final int UC_CPU_PPC32_MPC8567 = 139; - public static final int UC_CPU_PPC32_MPC8567E = 140; - public static final int UC_CPU_PPC32_MPC8568 = 141; - public static final int UC_CPU_PPC32_MPC8568E = 142; - public static final int UC_CPU_PPC32_MPC8572 = 143; - public static final int UC_CPU_PPC32_MPC8572E = 144; - public static final int UC_CPU_PPC32_E600 = 145; - public static final int UC_CPU_PPC32_MPC8610 = 146; - public static final int UC_CPU_PPC32_MPC8641 = 147; - public static final int UC_CPU_PPC32_MPC8641D = 148; - public static final int UC_CPU_PPC32_601_V0 = 149; - public static final int UC_CPU_PPC32_601_V1 = 150; - public static final int UC_CPU_PPC32_601_V2 = 151; - public static final int UC_CPU_PPC32_602 = 152; - public static final int UC_CPU_PPC32_603 = 153; - public static final int UC_CPU_PPC32_603E_V1_1 = 154; - public static final int UC_CPU_PPC32_603E_V1_2 = 155; - public static final int UC_CPU_PPC32_603E_V1_3 = 156; - public static final int UC_CPU_PPC32_603E_V1_4 = 157; - public static final int UC_CPU_PPC32_603E_V2_2 = 158; - public static final int UC_CPU_PPC32_603E_V3 = 159; - public static final int UC_CPU_PPC32_603E_V4 = 160; - public static final int UC_CPU_PPC32_603E_V4_1 = 161; - public static final int UC_CPU_PPC32_603E7 = 162; - public static final int UC_CPU_PPC32_603E7T = 163; - public static final int UC_CPU_PPC32_603E7V = 164; - public static final int UC_CPU_PPC32_603E7V1 = 165; - public static final int UC_CPU_PPC32_603E7V2 = 166; - public static final int UC_CPU_PPC32_603P = 167; - public static final int UC_CPU_PPC32_604 = 168; - public static final int UC_CPU_PPC32_604E_V1_0 = 169; - public static final int UC_CPU_PPC32_604E_V2_2 = 170; - public static final int UC_CPU_PPC32_604E_V2_4 = 171; - public static final int UC_CPU_PPC32_604R = 172; - public static final int UC_CPU_PPC32_740_V1_0 = 173; - public static final int UC_CPU_PPC32_750_V1_0 = 174; - public static final int UC_CPU_PPC32_740_V2_0 = 175; - public static final int UC_CPU_PPC32_750_V2_0 = 176; - public static final int UC_CPU_PPC32_740_V2_1 = 177; - public static final int UC_CPU_PPC32_750_V2_1 = 178; - public static final int UC_CPU_PPC32_740_V2_2 = 179; - public static final int UC_CPU_PPC32_750_V2_2 = 180; - public static final int UC_CPU_PPC32_740_V3_0 = 181; - public static final int UC_CPU_PPC32_750_V3_0 = 182; - public static final int UC_CPU_PPC32_740_V3_1 = 183; - public static final int UC_CPU_PPC32_750_V3_1 = 184; - public static final int UC_CPU_PPC32_740E = 185; - public static final int UC_CPU_PPC32_750E = 186; - public static final int UC_CPU_PPC32_740P = 187; - public static final int UC_CPU_PPC32_750P = 188; - public static final int UC_CPU_PPC32_750CL_V1_0 = 189; - public static final int UC_CPU_PPC32_750CL_V2_0 = 190; - public static final int UC_CPU_PPC32_750CX_V1_0 = 191; - public static final int UC_CPU_PPC32_750CX_V2_0 = 192; - public static final int UC_CPU_PPC32_750CX_V2_1 = 193; - public static final int UC_CPU_PPC32_750CX_V2_2 = 194; - public static final int UC_CPU_PPC32_750CXE_V2_1 = 195; - public static final int UC_CPU_PPC32_750CXE_V2_2 = 196; - public static final int UC_CPU_PPC32_750CXE_V2_3 = 197; - public static final int UC_CPU_PPC32_750CXE_V2_4 = 198; - public static final int UC_CPU_PPC32_750CXE_V2_4B = 199; - public static final int UC_CPU_PPC32_750CXE_V3_0 = 200; - public static final int UC_CPU_PPC32_750CXE_V3_1 = 201; - public static final int UC_CPU_PPC32_750CXE_V3_1B = 202; - public static final int UC_CPU_PPC32_750CXR = 203; - public static final int UC_CPU_PPC32_750FL = 204; - public static final int UC_CPU_PPC32_750FX_V1_0 = 205; - public static final int UC_CPU_PPC32_750FX_V2_0 = 206; - public static final int UC_CPU_PPC32_750FX_V2_1 = 207; - public static final int UC_CPU_PPC32_750FX_V2_2 = 208; - public static final int UC_CPU_PPC32_750FX_V2_3 = 209; - public static final int UC_CPU_PPC32_750GL = 210; - public static final int UC_CPU_PPC32_750GX_V1_0 = 211; - public static final int UC_CPU_PPC32_750GX_V1_1 = 212; - public static final int UC_CPU_PPC32_750GX_V1_2 = 213; - public static final int UC_CPU_PPC32_750L_V2_0 = 214; - public static final int UC_CPU_PPC32_750L_V2_1 = 215; - public static final int UC_CPU_PPC32_750L_V2_2 = 216; - public static final int UC_CPU_PPC32_750L_V3_0 = 217; - public static final int UC_CPU_PPC32_750L_V3_2 = 218; - public static final int UC_CPU_PPC32_745_V1_0 = 219; - public static final int UC_CPU_PPC32_755_V1_0 = 220; - public static final int UC_CPU_PPC32_745_V1_1 = 221; - public static final int UC_CPU_PPC32_755_V1_1 = 222; - public static final int UC_CPU_PPC32_745_V2_0 = 223; - public static final int UC_CPU_PPC32_755_V2_0 = 224; - public static final int UC_CPU_PPC32_745_V2_1 = 225; - public static final int UC_CPU_PPC32_755_V2_1 = 226; - public static final int UC_CPU_PPC32_745_V2_2 = 227; - public static final int UC_CPU_PPC32_755_V2_2 = 228; - public static final int UC_CPU_PPC32_745_V2_3 = 229; - public static final int UC_CPU_PPC32_755_V2_3 = 230; - public static final int UC_CPU_PPC32_745_V2_4 = 231; - public static final int UC_CPU_PPC32_755_V2_4 = 232; - public static final int UC_CPU_PPC32_745_V2_5 = 233; - public static final int UC_CPU_PPC32_755_V2_5 = 234; - public static final int UC_CPU_PPC32_745_V2_6 = 235; - public static final int UC_CPU_PPC32_755_V2_6 = 236; - public static final int UC_CPU_PPC32_745_V2_7 = 237; - public static final int UC_CPU_PPC32_755_V2_7 = 238; - public static final int UC_CPU_PPC32_745_V2_8 = 239; - public static final int UC_CPU_PPC32_755_V2_8 = 240; - public static final int UC_CPU_PPC32_7400_V1_0 = 241; - public static final int UC_CPU_PPC32_7400_V1_1 = 242; - public static final int UC_CPU_PPC32_7400_V2_0 = 243; - public static final int UC_CPU_PPC32_7400_V2_1 = 244; - public static final int UC_CPU_PPC32_7400_V2_2 = 245; - public static final int UC_CPU_PPC32_7400_V2_6 = 246; - public static final int UC_CPU_PPC32_7400_V2_7 = 247; - public static final int UC_CPU_PPC32_7400_V2_8 = 248; - public static final int UC_CPU_PPC32_7400_V2_9 = 249; - public static final int UC_CPU_PPC32_7410_V1_0 = 250; - public static final int UC_CPU_PPC32_7410_V1_1 = 251; - public static final int UC_CPU_PPC32_7410_V1_2 = 252; - public static final int UC_CPU_PPC32_7410_V1_3 = 253; - public static final int UC_CPU_PPC32_7410_V1_4 = 254; - public static final int UC_CPU_PPC32_7448_V1_0 = 255; - public static final int UC_CPU_PPC32_7448_V1_1 = 256; - public static final int UC_CPU_PPC32_7448_V2_0 = 257; - public static final int UC_CPU_PPC32_7448_V2_1 = 258; - public static final int UC_CPU_PPC32_7450_V1_0 = 259; - public static final int UC_CPU_PPC32_7450_V1_1 = 260; - public static final int UC_CPU_PPC32_7450_V1_2 = 261; - public static final int UC_CPU_PPC32_7450_V2_0 = 262; - public static final int UC_CPU_PPC32_7450_V2_1 = 263; - public static final int UC_CPU_PPC32_7441_V2_1 = 264; - public static final int UC_CPU_PPC32_7441_V2_3 = 265; - public static final int UC_CPU_PPC32_7451_V2_3 = 266; - public static final int UC_CPU_PPC32_7441_V2_10 = 267; - public static final int UC_CPU_PPC32_7451_V2_10 = 268; - public static final int UC_CPU_PPC32_7445_V1_0 = 269; - public static final int UC_CPU_PPC32_7455_V1_0 = 270; - public static final int UC_CPU_PPC32_7445_V2_1 = 271; - public static final int UC_CPU_PPC32_7455_V2_1 = 272; - public static final int UC_CPU_PPC32_7445_V3_2 = 273; - public static final int UC_CPU_PPC32_7455_V3_2 = 274; - public static final int UC_CPU_PPC32_7445_V3_3 = 275; - public static final int UC_CPU_PPC32_7455_V3_3 = 276; - public static final int UC_CPU_PPC32_7445_V3_4 = 277; - public static final int UC_CPU_PPC32_7455_V3_4 = 278; - public static final int UC_CPU_PPC32_7447_V1_0 = 279; - public static final int UC_CPU_PPC32_7457_V1_0 = 280; - public static final int UC_CPU_PPC32_7447_V1_1 = 281; - public static final int UC_CPU_PPC32_7457_V1_1 = 282; - public static final int UC_CPU_PPC32_7457_V1_2 = 283; - public static final int UC_CPU_PPC32_7447A_V1_0 = 284; - public static final int UC_CPU_PPC32_7457A_V1_0 = 285; - public static final int UC_CPU_PPC32_7447A_V1_1 = 286; - public static final int UC_CPU_PPC32_7457A_V1_1 = 287; - public static final int UC_CPU_PPC32_7447A_V1_2 = 288; - public static final int UC_CPU_PPC32_7457A_V1_2 = 289; - public static final int UC_CPU_PPC32_ENDING = 290; + public static final int UC_CPU_PPC32_401 = 0; + public static final int UC_CPU_PPC32_401A1 = 1; + public static final int UC_CPU_PPC32_401B2 = 2; + public static final int UC_CPU_PPC32_401C2 = 3; + public static final int UC_CPU_PPC32_401D2 = 4; + public static final int UC_CPU_PPC32_401E2 = 5; + public static final int UC_CPU_PPC32_401F2 = 6; + public static final int UC_CPU_PPC32_401G2 = 7; + public static final int UC_CPU_PPC32_IOP480 = 8; + public static final int UC_CPU_PPC32_COBRA = 9; + public static final int UC_CPU_PPC32_403GA = 10; + public static final int UC_CPU_PPC32_403GB = 11; + public static final int UC_CPU_PPC32_403GC = 12; + public static final int UC_CPU_PPC32_403GCX = 13; + public static final int UC_CPU_PPC32_405D2 = 14; + public static final int UC_CPU_PPC32_405D4 = 15; + public static final int UC_CPU_PPC32_405CRA = 16; + public static final int UC_CPU_PPC32_405CRB = 17; + public static final int UC_CPU_PPC32_405CRC = 18; + public static final int UC_CPU_PPC32_405EP = 19; + public static final int UC_CPU_PPC32_405EZ = 20; + public static final int UC_CPU_PPC32_405GPA = 21; + public static final int UC_CPU_PPC32_405GPB = 22; + public static final int UC_CPU_PPC32_405GPC = 23; + public static final int UC_CPU_PPC32_405GPD = 24; + public static final int UC_CPU_PPC32_405GPR = 25; + public static final int UC_CPU_PPC32_405LP = 26; + public static final int UC_CPU_PPC32_NPE405H = 27; + public static final int UC_CPU_PPC32_NPE405H2 = 28; + public static final int UC_CPU_PPC32_NPE405L = 29; + public static final int UC_CPU_PPC32_NPE4GS3 = 30; + public static final int UC_CPU_PPC32_STB03 = 31; + public static final int UC_CPU_PPC32_STB04 = 32; + public static final int UC_CPU_PPC32_STB25 = 33; + public static final int UC_CPU_PPC32_X2VP4 = 34; + public static final int UC_CPU_PPC32_X2VP20 = 35; + public static final int UC_CPU_PPC32_440_XILINX = 36; + public static final int UC_CPU_PPC32_440_XILINX_W_DFPU = 37; + public static final int UC_CPU_PPC32_440EPA = 38; + public static final int UC_CPU_PPC32_440EPB = 39; + public static final int UC_CPU_PPC32_440EPX = 40; + public static final int UC_CPU_PPC32_460EXB = 41; + public static final int UC_CPU_PPC32_G2 = 42; + public static final int UC_CPU_PPC32_G2H4 = 43; + public static final int UC_CPU_PPC32_G2GP = 44; + public static final int UC_CPU_PPC32_G2LS = 45; + public static final int UC_CPU_PPC32_G2HIP3 = 46; + public static final int UC_CPU_PPC32_G2HIP4 = 47; + public static final int UC_CPU_PPC32_MPC603 = 48; + public static final int UC_CPU_PPC32_G2LE = 49; + public static final int UC_CPU_PPC32_G2LEGP = 50; + public static final int UC_CPU_PPC32_G2LELS = 51; + public static final int UC_CPU_PPC32_G2LEGP1 = 52; + public static final int UC_CPU_PPC32_G2LEGP3 = 53; + public static final int UC_CPU_PPC32_MPC5200_V10 = 54; + public static final int UC_CPU_PPC32_MPC5200_V11 = 55; + public static final int UC_CPU_PPC32_MPC5200_V12 = 56; + public static final int UC_CPU_PPC32_MPC5200B_V20 = 57; + public static final int UC_CPU_PPC32_MPC5200B_V21 = 58; + public static final int UC_CPU_PPC32_E200Z5 = 59; + public static final int UC_CPU_PPC32_E200Z6 = 60; + public static final int UC_CPU_PPC32_E300C1 = 61; + public static final int UC_CPU_PPC32_E300C2 = 62; + public static final int UC_CPU_PPC32_E300C3 = 63; + public static final int UC_CPU_PPC32_E300C4 = 64; + public static final int UC_CPU_PPC32_MPC8343 = 65; + public static final int UC_CPU_PPC32_MPC8343A = 66; + public static final int UC_CPU_PPC32_MPC8343E = 67; + public static final int UC_CPU_PPC32_MPC8343EA = 68; + public static final int UC_CPU_PPC32_MPC8347T = 69; + public static final int UC_CPU_PPC32_MPC8347P = 70; + public static final int UC_CPU_PPC32_MPC8347AT = 71; + public static final int UC_CPU_PPC32_MPC8347AP = 72; + public static final int UC_CPU_PPC32_MPC8347ET = 73; + public static final int UC_CPU_PPC32_MPC8347EP = 74; + public static final int UC_CPU_PPC32_MPC8347EAT = 75; + public static final int UC_CPU_PPC32_MPC8347EAP = 76; + public static final int UC_CPU_PPC32_MPC8349 = 77; + public static final int UC_CPU_PPC32_MPC8349A = 78; + public static final int UC_CPU_PPC32_MPC8349E = 79; + public static final int UC_CPU_PPC32_MPC8349EA = 80; + public static final int UC_CPU_PPC32_MPC8377 = 81; + public static final int UC_CPU_PPC32_MPC8377E = 82; + public static final int UC_CPU_PPC32_MPC8378 = 83; + public static final int UC_CPU_PPC32_MPC8378E = 84; + public static final int UC_CPU_PPC32_MPC8379 = 85; + public static final int UC_CPU_PPC32_MPC8379E = 86; + public static final int UC_CPU_PPC32_E500_V10 = 87; + public static final int UC_CPU_PPC32_E500_V20 = 88; + public static final int UC_CPU_PPC32_E500V2_V10 = 89; + public static final int UC_CPU_PPC32_E500V2_V20 = 90; + public static final int UC_CPU_PPC32_E500V2_V21 = 91; + public static final int UC_CPU_PPC32_E500V2_V22 = 92; + public static final int UC_CPU_PPC32_E500V2_V30 = 93; + public static final int UC_CPU_PPC32_E500MC = 94; + public static final int UC_CPU_PPC32_MPC8533_V10 = 95; + public static final int UC_CPU_PPC32_MPC8533_V11 = 96; + public static final int UC_CPU_PPC32_MPC8533E_V10 = 97; + public static final int UC_CPU_PPC32_MPC8533E_V11 = 98; + public static final int UC_CPU_PPC32_MPC8540_V10 = 99; + public static final int UC_CPU_PPC32_MPC8540_V20 = 100; + public static final int UC_CPU_PPC32_MPC8540_V21 = 101; + public static final int UC_CPU_PPC32_MPC8541_V10 = 102; + public static final int UC_CPU_PPC32_MPC8541_V11 = 103; + public static final int UC_CPU_PPC32_MPC8541E_V10 = 104; + public static final int UC_CPU_PPC32_MPC8541E_V11 = 105; + public static final int UC_CPU_PPC32_MPC8543_V10 = 106; + public static final int UC_CPU_PPC32_MPC8543_V11 = 107; + public static final int UC_CPU_PPC32_MPC8543_V20 = 108; + public static final int UC_CPU_PPC32_MPC8543_V21 = 109; + public static final int UC_CPU_PPC32_MPC8543E_V10 = 110; + public static final int UC_CPU_PPC32_MPC8543E_V11 = 111; + public static final int UC_CPU_PPC32_MPC8543E_V20 = 112; + public static final int UC_CPU_PPC32_MPC8543E_V21 = 113; + public static final int UC_CPU_PPC32_MPC8544_V10 = 114; + public static final int UC_CPU_PPC32_MPC8544_V11 = 115; + public static final int UC_CPU_PPC32_MPC8544E_V10 = 116; + public static final int UC_CPU_PPC32_MPC8544E_V11 = 117; + public static final int UC_CPU_PPC32_MPC8545_V20 = 118; + public static final int UC_CPU_PPC32_MPC8545_V21 = 119; + public static final int UC_CPU_PPC32_MPC8545E_V20 = 120; + public static final int UC_CPU_PPC32_MPC8545E_V21 = 121; + public static final int UC_CPU_PPC32_MPC8547E_V20 = 122; + public static final int UC_CPU_PPC32_MPC8547E_V21 = 123; + public static final int UC_CPU_PPC32_MPC8548_V10 = 124; + public static final int UC_CPU_PPC32_MPC8548_V11 = 125; + public static final int UC_CPU_PPC32_MPC8548_V20 = 126; + public static final int UC_CPU_PPC32_MPC8548_V21 = 127; + public static final int UC_CPU_PPC32_MPC8548E_V10 = 128; + public static final int UC_CPU_PPC32_MPC8548E_V11 = 129; + public static final int UC_CPU_PPC32_MPC8548E_V20 = 130; + public static final int UC_CPU_PPC32_MPC8548E_V21 = 131; + public static final int UC_CPU_PPC32_MPC8555_V10 = 132; + public static final int UC_CPU_PPC32_MPC8555_V11 = 133; + public static final int UC_CPU_PPC32_MPC8555E_V10 = 134; + public static final int UC_CPU_PPC32_MPC8555E_V11 = 135; + public static final int UC_CPU_PPC32_MPC8560_V10 = 136; + public static final int UC_CPU_PPC32_MPC8560_V20 = 137; + public static final int UC_CPU_PPC32_MPC8560_V21 = 138; + public static final int UC_CPU_PPC32_MPC8567 = 139; + public static final int UC_CPU_PPC32_MPC8567E = 140; + public static final int UC_CPU_PPC32_MPC8568 = 141; + public static final int UC_CPU_PPC32_MPC8568E = 142; + public static final int UC_CPU_PPC32_MPC8572 = 143; + public static final int UC_CPU_PPC32_MPC8572E = 144; + public static final int UC_CPU_PPC32_E600 = 145; + public static final int UC_CPU_PPC32_MPC8610 = 146; + public static final int UC_CPU_PPC32_MPC8641 = 147; + public static final int UC_CPU_PPC32_MPC8641D = 148; + public static final int UC_CPU_PPC32_601_V0 = 149; + public static final int UC_CPU_PPC32_601_V1 = 150; + public static final int UC_CPU_PPC32_601_V2 = 151; + public static final int UC_CPU_PPC32_602 = 152; + public static final int UC_CPU_PPC32_603 = 153; + public static final int UC_CPU_PPC32_603E_V1_1 = 154; + public static final int UC_CPU_PPC32_603E_V1_2 = 155; + public static final int UC_CPU_PPC32_603E_V1_3 = 156; + public static final int UC_CPU_PPC32_603E_V1_4 = 157; + public static final int UC_CPU_PPC32_603E_V2_2 = 158; + public static final int UC_CPU_PPC32_603E_V3 = 159; + public static final int UC_CPU_PPC32_603E_V4 = 160; + public static final int UC_CPU_PPC32_603E_V4_1 = 161; + public static final int UC_CPU_PPC32_603E7 = 162; + public static final int UC_CPU_PPC32_603E7T = 163; + public static final int UC_CPU_PPC32_603E7V = 164; + public static final int UC_CPU_PPC32_603E7V1 = 165; + public static final int UC_CPU_PPC32_603E7V2 = 166; + public static final int UC_CPU_PPC32_603P = 167; + public static final int UC_CPU_PPC32_604 = 168; + public static final int UC_CPU_PPC32_604E_V1_0 = 169; + public static final int UC_CPU_PPC32_604E_V2_2 = 170; + public static final int UC_CPU_PPC32_604E_V2_4 = 171; + public static final int UC_CPU_PPC32_604R = 172; + public static final int UC_CPU_PPC32_740_V1_0 = 173; + public static final int UC_CPU_PPC32_750_V1_0 = 174; + public static final int UC_CPU_PPC32_740_V2_0 = 175; + public static final int UC_CPU_PPC32_750_V2_0 = 176; + public static final int UC_CPU_PPC32_740_V2_1 = 177; + public static final int UC_CPU_PPC32_750_V2_1 = 178; + public static final int UC_CPU_PPC32_740_V2_2 = 179; + public static final int UC_CPU_PPC32_750_V2_2 = 180; + public static final int UC_CPU_PPC32_740_V3_0 = 181; + public static final int UC_CPU_PPC32_750_V3_0 = 182; + public static final int UC_CPU_PPC32_740_V3_1 = 183; + public static final int UC_CPU_PPC32_750_V3_1 = 184; + public static final int UC_CPU_PPC32_740E = 185; + public static final int UC_CPU_PPC32_750E = 186; + public static final int UC_CPU_PPC32_740P = 187; + public static final int UC_CPU_PPC32_750P = 188; + public static final int UC_CPU_PPC32_750CL_V1_0 = 189; + public static final int UC_CPU_PPC32_750CL_V2_0 = 190; + public static final int UC_CPU_PPC32_750CX_V1_0 = 191; + public static final int UC_CPU_PPC32_750CX_V2_0 = 192; + public static final int UC_CPU_PPC32_750CX_V2_1 = 193; + public static final int UC_CPU_PPC32_750CX_V2_2 = 194; + public static final int UC_CPU_PPC32_750CXE_V2_1 = 195; + public static final int UC_CPU_PPC32_750CXE_V2_2 = 196; + public static final int UC_CPU_PPC32_750CXE_V2_3 = 197; + public static final int UC_CPU_PPC32_750CXE_V2_4 = 198; + public static final int UC_CPU_PPC32_750CXE_V2_4B = 199; + public static final int UC_CPU_PPC32_750CXE_V3_0 = 200; + public static final int UC_CPU_PPC32_750CXE_V3_1 = 201; + public static final int UC_CPU_PPC32_750CXE_V3_1B = 202; + public static final int UC_CPU_PPC32_750CXR = 203; + public static final int UC_CPU_PPC32_750FL = 204; + public static final int UC_CPU_PPC32_750FX_V1_0 = 205; + public static final int UC_CPU_PPC32_750FX_V2_0 = 206; + public static final int UC_CPU_PPC32_750FX_V2_1 = 207; + public static final int UC_CPU_PPC32_750FX_V2_2 = 208; + public static final int UC_CPU_PPC32_750FX_V2_3 = 209; + public static final int UC_CPU_PPC32_750GL = 210; + public static final int UC_CPU_PPC32_750GX_V1_0 = 211; + public static final int UC_CPU_PPC32_750GX_V1_1 = 212; + public static final int UC_CPU_PPC32_750GX_V1_2 = 213; + public static final int UC_CPU_PPC32_750L_V2_0 = 214; + public static final int UC_CPU_PPC32_750L_V2_1 = 215; + public static final int UC_CPU_PPC32_750L_V2_2 = 216; + public static final int UC_CPU_PPC32_750L_V3_0 = 217; + public static final int UC_CPU_PPC32_750L_V3_2 = 218; + public static final int UC_CPU_PPC32_745_V1_0 = 219; + public static final int UC_CPU_PPC32_755_V1_0 = 220; + public static final int UC_CPU_PPC32_745_V1_1 = 221; + public static final int UC_CPU_PPC32_755_V1_1 = 222; + public static final int UC_CPU_PPC32_745_V2_0 = 223; + public static final int UC_CPU_PPC32_755_V2_0 = 224; + public static final int UC_CPU_PPC32_745_V2_1 = 225; + public static final int UC_CPU_PPC32_755_V2_1 = 226; + public static final int UC_CPU_PPC32_745_V2_2 = 227; + public static final int UC_CPU_PPC32_755_V2_2 = 228; + public static final int UC_CPU_PPC32_745_V2_3 = 229; + public static final int UC_CPU_PPC32_755_V2_3 = 230; + public static final int UC_CPU_PPC32_745_V2_4 = 231; + public static final int UC_CPU_PPC32_755_V2_4 = 232; + public static final int UC_CPU_PPC32_745_V2_5 = 233; + public static final int UC_CPU_PPC32_755_V2_5 = 234; + public static final int UC_CPU_PPC32_745_V2_6 = 235; + public static final int UC_CPU_PPC32_755_V2_6 = 236; + public static final int UC_CPU_PPC32_745_V2_7 = 237; + public static final int UC_CPU_PPC32_755_V2_7 = 238; + public static final int UC_CPU_PPC32_745_V2_8 = 239; + public static final int UC_CPU_PPC32_755_V2_8 = 240; + public static final int UC_CPU_PPC32_7400_V1_0 = 241; + public static final int UC_CPU_PPC32_7400_V1_1 = 242; + public static final int UC_CPU_PPC32_7400_V2_0 = 243; + public static final int UC_CPU_PPC32_7400_V2_1 = 244; + public static final int UC_CPU_PPC32_7400_V2_2 = 245; + public static final int UC_CPU_PPC32_7400_V2_6 = 246; + public static final int UC_CPU_PPC32_7400_V2_7 = 247; + public static final int UC_CPU_PPC32_7400_V2_8 = 248; + public static final int UC_CPU_PPC32_7400_V2_9 = 249; + public static final int UC_CPU_PPC32_7410_V1_0 = 250; + public static final int UC_CPU_PPC32_7410_V1_1 = 251; + public static final int UC_CPU_PPC32_7410_V1_2 = 252; + public static final int UC_CPU_PPC32_7410_V1_3 = 253; + public static final int UC_CPU_PPC32_7410_V1_4 = 254; + public static final int UC_CPU_PPC32_7448_V1_0 = 255; + public static final int UC_CPU_PPC32_7448_V1_1 = 256; + public static final int UC_CPU_PPC32_7448_V2_0 = 257; + public static final int UC_CPU_PPC32_7448_V2_1 = 258; + public static final int UC_CPU_PPC32_7450_V1_0 = 259; + public static final int UC_CPU_PPC32_7450_V1_1 = 260; + public static final int UC_CPU_PPC32_7450_V1_2 = 261; + public static final int UC_CPU_PPC32_7450_V2_0 = 262; + public static final int UC_CPU_PPC32_7450_V2_1 = 263; + public static final int UC_CPU_PPC32_7441_V2_1 = 264; + public static final int UC_CPU_PPC32_7441_V2_3 = 265; + public static final int UC_CPU_PPC32_7451_V2_3 = 266; + public static final int UC_CPU_PPC32_7441_V2_10 = 267; + public static final int UC_CPU_PPC32_7451_V2_10 = 268; + public static final int UC_CPU_PPC32_7445_V1_0 = 269; + public static final int UC_CPU_PPC32_7455_V1_0 = 270; + public static final int UC_CPU_PPC32_7445_V2_1 = 271; + public static final int UC_CPU_PPC32_7455_V2_1 = 272; + public static final int UC_CPU_PPC32_7445_V3_2 = 273; + public static final int UC_CPU_PPC32_7455_V3_2 = 274; + public static final int UC_CPU_PPC32_7445_V3_3 = 275; + public static final int UC_CPU_PPC32_7455_V3_3 = 276; + public static final int UC_CPU_PPC32_7445_V3_4 = 277; + public static final int UC_CPU_PPC32_7455_V3_4 = 278; + public static final int UC_CPU_PPC32_7447_V1_0 = 279; + public static final int UC_CPU_PPC32_7457_V1_0 = 280; + public static final int UC_CPU_PPC32_7447_V1_1 = 281; + public static final int UC_CPU_PPC32_7457_V1_1 = 282; + public static final int UC_CPU_PPC32_7457_V1_2 = 283; + public static final int UC_CPU_PPC32_7447A_V1_0 = 284; + public static final int UC_CPU_PPC32_7457A_V1_0 = 285; + public static final int UC_CPU_PPC32_7447A_V1_1 = 286; + public static final int UC_CPU_PPC32_7457A_V1_1 = 287; + public static final int UC_CPU_PPC32_7447A_V1_2 = 288; + public static final int UC_CPU_PPC32_7457A_V1_2 = 289; + public static final int UC_CPU_PPC32_ENDING = 290; -// PPC64 CPU + // PPC64 CPU - public static final int UC_CPU_PPC64_E5500 = 0; - public static final int UC_CPU_PPC64_E6500 = 1; - public static final int UC_CPU_PPC64_970_V2_2 = 2; - public static final int UC_CPU_PPC64_970FX_V1_0 = 3; - public static final int UC_CPU_PPC64_970FX_V2_0 = 4; - public static final int UC_CPU_PPC64_970FX_V2_1 = 5; - public static final int UC_CPU_PPC64_970FX_V3_0 = 6; - public static final int UC_CPU_PPC64_970FX_V3_1 = 7; - public static final int UC_CPU_PPC64_970MP_V1_0 = 8; - public static final int UC_CPU_PPC64_970MP_V1_1 = 9; - public static final int UC_CPU_PPC64_POWER5_V2_1 = 10; - public static final int UC_CPU_PPC64_POWER7_V2_3 = 11; - public static final int UC_CPU_PPC64_POWER7_V2_1 = 12; - public static final int UC_CPU_PPC64_POWER8E_V2_1 = 13; - public static final int UC_CPU_PPC64_POWER8_V2_0 = 14; - public static final int UC_CPU_PPC64_POWER8NVL_V1_0 = 15; - public static final int UC_CPU_PPC64_POWER9_V1_0 = 16; - public static final int UC_CPU_PPC64_POWER9_V2_0 = 17; - public static final int UC_CPU_PPC64_POWER10_V1_0 = 18; - public static final int UC_CPU_PPC64_ENDING = 19; + public static final int UC_CPU_PPC64_E5500 = 0; + public static final int UC_CPU_PPC64_E6500 = 1; + public static final int UC_CPU_PPC64_970_V2_2 = 2; + public static final int UC_CPU_PPC64_970FX_V1_0 = 3; + public static final int UC_CPU_PPC64_970FX_V2_0 = 4; + public static final int UC_CPU_PPC64_970FX_V2_1 = 5; + public static final int UC_CPU_PPC64_970FX_V3_0 = 6; + public static final int UC_CPU_PPC64_970FX_V3_1 = 7; + public static final int UC_CPU_PPC64_970MP_V1_0 = 8; + public static final int UC_CPU_PPC64_970MP_V1_1 = 9; + public static final int UC_CPU_PPC64_POWER5_V2_1 = 10; + public static final int UC_CPU_PPC64_POWER7_V2_3 = 11; + public static final int UC_CPU_PPC64_POWER7_V2_1 = 12; + public static final int UC_CPU_PPC64_POWER8E_V2_1 = 13; + public static final int UC_CPU_PPC64_POWER8_V2_0 = 14; + public static final int UC_CPU_PPC64_POWER8NVL_V1_0 = 15; + public static final int UC_CPU_PPC64_POWER9_V1_0 = 16; + public static final int UC_CPU_PPC64_POWER9_V2_0 = 17; + public static final int UC_CPU_PPC64_POWER10_V1_0 = 18; + public static final int UC_CPU_PPC64_ENDING = 19; -// PPC registers + // PPC registers - public static final int UC_PPC_REG_INVALID = 0; + public static final int UC_PPC_REG_INVALID = 0; -// General purpose registers - public static final int UC_PPC_REG_PC = 1; - public static final int UC_PPC_REG_0 = 2; - public static final int UC_PPC_REG_1 = 3; - public static final int UC_PPC_REG_2 = 4; - public static final int UC_PPC_REG_3 = 5; - public static final int UC_PPC_REG_4 = 6; - public static final int UC_PPC_REG_5 = 7; - public static final int UC_PPC_REG_6 = 8; - public static final int UC_PPC_REG_7 = 9; - public static final int UC_PPC_REG_8 = 10; - public static final int UC_PPC_REG_9 = 11; - public static final int UC_PPC_REG_10 = 12; - public static final int UC_PPC_REG_11 = 13; - public static final int UC_PPC_REG_12 = 14; - public static final int UC_PPC_REG_13 = 15; - public static final int UC_PPC_REG_14 = 16; - public static final int UC_PPC_REG_15 = 17; - public static final int UC_PPC_REG_16 = 18; - public static final int UC_PPC_REG_17 = 19; - public static final int UC_PPC_REG_18 = 20; - public static final int UC_PPC_REG_19 = 21; - public static final int UC_PPC_REG_20 = 22; - public static final int UC_PPC_REG_21 = 23; - public static final int UC_PPC_REG_22 = 24; - public static final int UC_PPC_REG_23 = 25; - public static final int UC_PPC_REG_24 = 26; - public static final int UC_PPC_REG_25 = 27; - public static final int UC_PPC_REG_26 = 28; - public static final int UC_PPC_REG_27 = 29; - public static final int UC_PPC_REG_28 = 30; - public static final int UC_PPC_REG_29 = 31; - public static final int UC_PPC_REG_30 = 32; - public static final int UC_PPC_REG_31 = 33; - public static final int UC_PPC_REG_CR0 = 34; - public static final int UC_PPC_REG_CR1 = 35; - public static final int UC_PPC_REG_CR2 = 36; - public static final int UC_PPC_REG_CR3 = 37; - public static final int UC_PPC_REG_CR4 = 38; - public static final int UC_PPC_REG_CR5 = 39; - public static final int UC_PPC_REG_CR6 = 40; - public static final int UC_PPC_REG_CR7 = 41; - public static final int UC_PPC_REG_FPR0 = 42; - public static final int UC_PPC_REG_FPR1 = 43; - public static final int UC_PPC_REG_FPR2 = 44; - public static final int UC_PPC_REG_FPR3 = 45; - public static final int UC_PPC_REG_FPR4 = 46; - public static final int UC_PPC_REG_FPR5 = 47; - public static final int UC_PPC_REG_FPR6 = 48; - public static final int UC_PPC_REG_FPR7 = 49; - public static final int UC_PPC_REG_FPR8 = 50; - public static final int UC_PPC_REG_FPR9 = 51; - public static final int UC_PPC_REG_FPR10 = 52; - public static final int UC_PPC_REG_FPR11 = 53; - public static final int UC_PPC_REG_FPR12 = 54; - public static final int UC_PPC_REG_FPR13 = 55; - public static final int UC_PPC_REG_FPR14 = 56; - public static final int UC_PPC_REG_FPR15 = 57; - public static final int UC_PPC_REG_FPR16 = 58; - public static final int UC_PPC_REG_FPR17 = 59; - public static final int UC_PPC_REG_FPR18 = 60; - public static final int UC_PPC_REG_FPR19 = 61; - public static final int UC_PPC_REG_FPR20 = 62; - public static final int UC_PPC_REG_FPR21 = 63; - public static final int UC_PPC_REG_FPR22 = 64; - public static final int UC_PPC_REG_FPR23 = 65; - public static final int UC_PPC_REG_FPR24 = 66; - public static final int UC_PPC_REG_FPR25 = 67; - public static final int UC_PPC_REG_FPR26 = 68; - public static final int UC_PPC_REG_FPR27 = 69; - public static final int UC_PPC_REG_FPR28 = 70; - public static final int UC_PPC_REG_FPR29 = 71; - public static final int UC_PPC_REG_FPR30 = 72; - public static final int UC_PPC_REG_FPR31 = 73; - public static final int UC_PPC_REG_LR = 74; - public static final int UC_PPC_REG_XER = 75; - public static final int UC_PPC_REG_CTR = 76; - public static final int UC_PPC_REG_MSR = 77; - public static final int UC_PPC_REG_FPSCR = 78; - public static final int UC_PPC_REG_CR = 79; - public static final int UC_PPC_REG_ENDING = 80; + // General purpose registers + public static final int UC_PPC_REG_PC = 1; + public static final int UC_PPC_REG_0 = 2; + public static final int UC_PPC_REG_1 = 3; + public static final int UC_PPC_REG_2 = 4; + public static final int UC_PPC_REG_3 = 5; + public static final int UC_PPC_REG_4 = 6; + public static final int UC_PPC_REG_5 = 7; + public static final int UC_PPC_REG_6 = 8; + public static final int UC_PPC_REG_7 = 9; + public static final int UC_PPC_REG_8 = 10; + public static final int UC_PPC_REG_9 = 11; + public static final int UC_PPC_REG_10 = 12; + public static final int UC_PPC_REG_11 = 13; + public static final int UC_PPC_REG_12 = 14; + public static final int UC_PPC_REG_13 = 15; + public static final int UC_PPC_REG_14 = 16; + public static final int UC_PPC_REG_15 = 17; + public static final int UC_PPC_REG_16 = 18; + public static final int UC_PPC_REG_17 = 19; + public static final int UC_PPC_REG_18 = 20; + public static final int UC_PPC_REG_19 = 21; + public static final int UC_PPC_REG_20 = 22; + public static final int UC_PPC_REG_21 = 23; + public static final int UC_PPC_REG_22 = 24; + public static final int UC_PPC_REG_23 = 25; + public static final int UC_PPC_REG_24 = 26; + public static final int UC_PPC_REG_25 = 27; + public static final int UC_PPC_REG_26 = 28; + public static final int UC_PPC_REG_27 = 29; + public static final int UC_PPC_REG_28 = 30; + public static final int UC_PPC_REG_29 = 31; + public static final int UC_PPC_REG_30 = 32; + public static final int UC_PPC_REG_31 = 33; + public static final int UC_PPC_REG_CR0 = 34; + public static final int UC_PPC_REG_CR1 = 35; + public static final int UC_PPC_REG_CR2 = 36; + public static final int UC_PPC_REG_CR3 = 37; + public static final int UC_PPC_REG_CR4 = 38; + public static final int UC_PPC_REG_CR5 = 39; + public static final int UC_PPC_REG_CR6 = 40; + public static final int UC_PPC_REG_CR7 = 41; + public static final int UC_PPC_REG_FPR0 = 42; + public static final int UC_PPC_REG_FPR1 = 43; + public static final int UC_PPC_REG_FPR2 = 44; + public static final int UC_PPC_REG_FPR3 = 45; + public static final int UC_PPC_REG_FPR4 = 46; + public static final int UC_PPC_REG_FPR5 = 47; + public static final int UC_PPC_REG_FPR6 = 48; + public static final int UC_PPC_REG_FPR7 = 49; + public static final int UC_PPC_REG_FPR8 = 50; + public static final int UC_PPC_REG_FPR9 = 51; + public static final int UC_PPC_REG_FPR10 = 52; + public static final int UC_PPC_REG_FPR11 = 53; + public static final int UC_PPC_REG_FPR12 = 54; + public static final int UC_PPC_REG_FPR13 = 55; + public static final int UC_PPC_REG_FPR14 = 56; + public static final int UC_PPC_REG_FPR15 = 57; + public static final int UC_PPC_REG_FPR16 = 58; + public static final int UC_PPC_REG_FPR17 = 59; + public static final int UC_PPC_REG_FPR18 = 60; + public static final int UC_PPC_REG_FPR19 = 61; + public static final int UC_PPC_REG_FPR20 = 62; + public static final int UC_PPC_REG_FPR21 = 63; + public static final int UC_PPC_REG_FPR22 = 64; + public static final int UC_PPC_REG_FPR23 = 65; + public static final int UC_PPC_REG_FPR24 = 66; + public static final int UC_PPC_REG_FPR25 = 67; + public static final int UC_PPC_REG_FPR26 = 68; + public static final int UC_PPC_REG_FPR27 = 69; + public static final int UC_PPC_REG_FPR28 = 70; + public static final int UC_PPC_REG_FPR29 = 71; + public static final int UC_PPC_REG_FPR30 = 72; + public static final int UC_PPC_REG_FPR31 = 73; + public static final int UC_PPC_REG_LR = 74; + public static final int UC_PPC_REG_XER = 75; + public static final int UC_PPC_REG_CTR = 76; + public static final int UC_PPC_REG_MSR = 77; + public static final int UC_PPC_REG_FPSCR = 78; + public static final int UC_PPC_REG_CR = 79; + public static final int UC_PPC_REG_ENDING = 80; } diff --git a/bindings/java/unicorn/ReadHook.java b/bindings/java/unicorn/ReadHook.java index d522a63f..28b6ca34 100644 --- a/bindings/java/unicorn/ReadHook.java +++ b/bindings/java/unicorn/ReadHook.java @@ -22,8 +22,5 @@ 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); - + public void hook(Unicorn u, long address, int size, Object user); } - diff --git a/bindings/java/unicorn/RiscvConst.java b/bindings/java/unicorn/RiscvConst.java index 17a17825..27b65bd4 100644 --- a/bindings/java/unicorn/RiscvConst.java +++ b/bindings/java/unicorn/RiscvConst.java @@ -4,288 +4,288 @@ package unicorn; public interface RiscvConst { -// RISCV32 CPU + // RISCV32 CPU - public static final int UC_CPU_RISCV32_ANY = 0; - public static final int UC_CPU_RISCV32_BASE32 = 1; - public static final int UC_CPU_RISCV32_SIFIVE_E31 = 2; - public static final int UC_CPU_RISCV32_SIFIVE_U34 = 3; - public static final int UC_CPU_RISCV32_ENDING = 4; + public static final int UC_CPU_RISCV32_ANY = 0; + public static final int UC_CPU_RISCV32_BASE32 = 1; + public static final int UC_CPU_RISCV32_SIFIVE_E31 = 2; + public static final int UC_CPU_RISCV32_SIFIVE_U34 = 3; + public static final int UC_CPU_RISCV32_ENDING = 4; -// RISCV64 CPU + // RISCV64 CPU - public static final int UC_CPU_RISCV64_ANY = 0; - public static final int UC_CPU_RISCV64_BASE64 = 1; - public static final int UC_CPU_RISCV64_SIFIVE_E51 = 2; - public static final int UC_CPU_RISCV64_SIFIVE_U54 = 3; - public static final int UC_CPU_RISCV64_ENDING = 4; + public static final int UC_CPU_RISCV64_ANY = 0; + public static final int UC_CPU_RISCV64_BASE64 = 1; + public static final int UC_CPU_RISCV64_SIFIVE_E51 = 2; + public static final int UC_CPU_RISCV64_SIFIVE_U54 = 3; + public static final int UC_CPU_RISCV64_ENDING = 4; -// RISCV registers + // RISCV registers - public static final int UC_RISCV_REG_INVALID = 0; + public static final int UC_RISCV_REG_INVALID = 0; -// General purpose registers - public static final int UC_RISCV_REG_X0 = 1; - public static final int UC_RISCV_REG_X1 = 2; - public static final int UC_RISCV_REG_X2 = 3; - public static final int UC_RISCV_REG_X3 = 4; - public static final int UC_RISCV_REG_X4 = 5; - public static final int UC_RISCV_REG_X5 = 6; - public static final int UC_RISCV_REG_X6 = 7; - public static final int UC_RISCV_REG_X7 = 8; - public static final int UC_RISCV_REG_X8 = 9; - public static final int UC_RISCV_REG_X9 = 10; - public static final int UC_RISCV_REG_X10 = 11; - public static final int UC_RISCV_REG_X11 = 12; - public static final int UC_RISCV_REG_X12 = 13; - public static final int UC_RISCV_REG_X13 = 14; - public static final int UC_RISCV_REG_X14 = 15; - public static final int UC_RISCV_REG_X15 = 16; - public static final int UC_RISCV_REG_X16 = 17; - public static final int UC_RISCV_REG_X17 = 18; - public static final int UC_RISCV_REG_X18 = 19; - public static final int UC_RISCV_REG_X19 = 20; - public static final int UC_RISCV_REG_X20 = 21; - public static final int UC_RISCV_REG_X21 = 22; - public static final int UC_RISCV_REG_X22 = 23; - public static final int UC_RISCV_REG_X23 = 24; - public static final int UC_RISCV_REG_X24 = 25; - public static final int UC_RISCV_REG_X25 = 26; - public static final int UC_RISCV_REG_X26 = 27; - public static final int UC_RISCV_REG_X27 = 28; - public static final int UC_RISCV_REG_X28 = 29; - public static final int UC_RISCV_REG_X29 = 30; - public static final int UC_RISCV_REG_X30 = 31; - public static final int UC_RISCV_REG_X31 = 32; + // General purpose registers + public static final int UC_RISCV_REG_X0 = 1; + public static final int UC_RISCV_REG_X1 = 2; + public static final int UC_RISCV_REG_X2 = 3; + public static final int UC_RISCV_REG_X3 = 4; + public static final int UC_RISCV_REG_X4 = 5; + public static final int UC_RISCV_REG_X5 = 6; + public static final int UC_RISCV_REG_X6 = 7; + public static final int UC_RISCV_REG_X7 = 8; + public static final int UC_RISCV_REG_X8 = 9; + public static final int UC_RISCV_REG_X9 = 10; + public static final int UC_RISCV_REG_X10 = 11; + public static final int UC_RISCV_REG_X11 = 12; + public static final int UC_RISCV_REG_X12 = 13; + public static final int UC_RISCV_REG_X13 = 14; + public static final int UC_RISCV_REG_X14 = 15; + public static final int UC_RISCV_REG_X15 = 16; + public static final int UC_RISCV_REG_X16 = 17; + public static final int UC_RISCV_REG_X17 = 18; + public static final int UC_RISCV_REG_X18 = 19; + public static final int UC_RISCV_REG_X19 = 20; + public static final int UC_RISCV_REG_X20 = 21; + public static final int UC_RISCV_REG_X21 = 22; + public static final int UC_RISCV_REG_X22 = 23; + public static final int UC_RISCV_REG_X23 = 24; + public static final int UC_RISCV_REG_X24 = 25; + public static final int UC_RISCV_REG_X25 = 26; + public static final int UC_RISCV_REG_X26 = 27; + public static final int UC_RISCV_REG_X27 = 28; + public static final int UC_RISCV_REG_X28 = 29; + public static final int UC_RISCV_REG_X29 = 30; + public static final int UC_RISCV_REG_X30 = 31; + public static final int UC_RISCV_REG_X31 = 32; -// RISCV CSR - public static final int UC_RISCV_REG_USTATUS = 33; - public static final int UC_RISCV_REG_UIE = 34; - public static final int UC_RISCV_REG_UTVEC = 35; - public static final int UC_RISCV_REG_USCRATCH = 36; - public static final int UC_RISCV_REG_UEPC = 37; - public static final int UC_RISCV_REG_UCAUSE = 38; - public static final int UC_RISCV_REG_UTVAL = 39; - public static final int UC_RISCV_REG_UIP = 40; - public static final int UC_RISCV_REG_FFLAGS = 41; - public static final int UC_RISCV_REG_FRM = 42; - public static final int UC_RISCV_REG_FCSR = 43; - public static final int UC_RISCV_REG_CYCLE = 44; - public static final int UC_RISCV_REG_TIME = 45; - public static final int UC_RISCV_REG_INSTRET = 46; - public static final int UC_RISCV_REG_HPMCOUNTER3 = 47; - public static final int UC_RISCV_REG_HPMCOUNTER4 = 48; - public static final int UC_RISCV_REG_HPMCOUNTER5 = 49; - public static final int UC_RISCV_REG_HPMCOUNTER6 = 50; - public static final int UC_RISCV_REG_HPMCOUNTER7 = 51; - public static final int UC_RISCV_REG_HPMCOUNTER8 = 52; - public static final int UC_RISCV_REG_HPMCOUNTER9 = 53; - public static final int UC_RISCV_REG_HPMCOUNTER10 = 54; - public static final int UC_RISCV_REG_HPMCOUNTER11 = 55; - public static final int UC_RISCV_REG_HPMCOUNTER12 = 56; - public static final int UC_RISCV_REG_HPMCOUNTER13 = 57; - public static final int UC_RISCV_REG_HPMCOUNTER14 = 58; - public static final int UC_RISCV_REG_HPMCOUNTER15 = 59; - public static final int UC_RISCV_REG_HPMCOUNTER16 = 60; - public static final int UC_RISCV_REG_HPMCOUNTER17 = 61; - public static final int UC_RISCV_REG_HPMCOUNTER18 = 62; - public static final int UC_RISCV_REG_HPMCOUNTER19 = 63; - public static final int UC_RISCV_REG_HPMCOUNTER20 = 64; - public static final int UC_RISCV_REG_HPMCOUNTER21 = 65; - public static final int UC_RISCV_REG_HPMCOUNTER22 = 66; - public static final int UC_RISCV_REG_HPMCOUNTER23 = 67; - public static final int UC_RISCV_REG_HPMCOUNTER24 = 68; - public static final int UC_RISCV_REG_HPMCOUNTER25 = 69; - public static final int UC_RISCV_REG_HPMCOUNTER26 = 70; - public static final int UC_RISCV_REG_HPMCOUNTER27 = 71; - public static final int UC_RISCV_REG_HPMCOUNTER28 = 72; - public static final int UC_RISCV_REG_HPMCOUNTER29 = 73; - public static final int UC_RISCV_REG_HPMCOUNTER30 = 74; - public static final int UC_RISCV_REG_HPMCOUNTER31 = 75; - public static final int UC_RISCV_REG_CYCLEH = 76; - public static final int UC_RISCV_REG_TIMEH = 77; - public static final int UC_RISCV_REG_INSTRETH = 78; - public static final int UC_RISCV_REG_HPMCOUNTER3H = 79; - public static final int UC_RISCV_REG_HPMCOUNTER4H = 80; - public static final int UC_RISCV_REG_HPMCOUNTER5H = 81; - public static final int UC_RISCV_REG_HPMCOUNTER6H = 82; - public static final int UC_RISCV_REG_HPMCOUNTER7H = 83; - public static final int UC_RISCV_REG_HPMCOUNTER8H = 84; - public static final int UC_RISCV_REG_HPMCOUNTER9H = 85; - public static final int UC_RISCV_REG_HPMCOUNTER10H = 86; - public static final int UC_RISCV_REG_HPMCOUNTER11H = 87; - public static final int UC_RISCV_REG_HPMCOUNTER12H = 88; - public static final int UC_RISCV_REG_HPMCOUNTER13H = 89; - public static final int UC_RISCV_REG_HPMCOUNTER14H = 90; - public static final int UC_RISCV_REG_HPMCOUNTER15H = 91; - public static final int UC_RISCV_REG_HPMCOUNTER16H = 92; - public static final int UC_RISCV_REG_HPMCOUNTER17H = 93; - public static final int UC_RISCV_REG_HPMCOUNTER18H = 94; - public static final int UC_RISCV_REG_HPMCOUNTER19H = 95; - public static final int UC_RISCV_REG_HPMCOUNTER20H = 96; - public static final int UC_RISCV_REG_HPMCOUNTER21H = 97; - public static final int UC_RISCV_REG_HPMCOUNTER22H = 98; - public static final int UC_RISCV_REG_HPMCOUNTER23H = 99; - public static final int UC_RISCV_REG_HPMCOUNTER24H = 100; - public static final int UC_RISCV_REG_HPMCOUNTER25H = 101; - public static final int UC_RISCV_REG_HPMCOUNTER26H = 102; - public static final int UC_RISCV_REG_HPMCOUNTER27H = 103; - public static final int UC_RISCV_REG_HPMCOUNTER28H = 104; - public static final int UC_RISCV_REG_HPMCOUNTER29H = 105; - public static final int UC_RISCV_REG_HPMCOUNTER30H = 106; - public static final int UC_RISCV_REG_HPMCOUNTER31H = 107; - public static final int UC_RISCV_REG_MCYCLE = 108; - public static final int UC_RISCV_REG_MINSTRET = 109; - public static final int UC_RISCV_REG_MCYCLEH = 110; - public static final int UC_RISCV_REG_MINSTRETH = 111; - public static final int UC_RISCV_REG_MVENDORID = 112; - public static final int UC_RISCV_REG_MARCHID = 113; - public static final int UC_RISCV_REG_MIMPID = 114; - public static final int UC_RISCV_REG_MHARTID = 115; - public static final int UC_RISCV_REG_MSTATUS = 116; - public static final int UC_RISCV_REG_MISA = 117; - public static final int UC_RISCV_REG_MEDELEG = 118; - public static final int UC_RISCV_REG_MIDELEG = 119; - public static final int UC_RISCV_REG_MIE = 120; - public static final int UC_RISCV_REG_MTVEC = 121; - public static final int UC_RISCV_REG_MCOUNTEREN = 122; - public static final int UC_RISCV_REG_MSTATUSH = 123; - public static final int UC_RISCV_REG_MUCOUNTEREN = 124; - public static final int UC_RISCV_REG_MSCOUNTEREN = 125; - public static final int UC_RISCV_REG_MHCOUNTEREN = 126; - public static final int UC_RISCV_REG_MSCRATCH = 127; - public static final int UC_RISCV_REG_MEPC = 128; - public static final int UC_RISCV_REG_MCAUSE = 129; - public static final int UC_RISCV_REG_MTVAL = 130; - public static final int UC_RISCV_REG_MIP = 131; - public static final int UC_RISCV_REG_MBADADDR = 132; - public static final int UC_RISCV_REG_SSTATUS = 133; - public static final int UC_RISCV_REG_SEDELEG = 134; - public static final int UC_RISCV_REG_SIDELEG = 135; - public static final int UC_RISCV_REG_SIE = 136; - public static final int UC_RISCV_REG_STVEC = 137; - public static final int UC_RISCV_REG_SCOUNTEREN = 138; - public static final int UC_RISCV_REG_SSCRATCH = 139; - public static final int UC_RISCV_REG_SEPC = 140; - public static final int UC_RISCV_REG_SCAUSE = 141; - public static final int UC_RISCV_REG_STVAL = 142; - public static final int UC_RISCV_REG_SIP = 143; - public static final int UC_RISCV_REG_SBADADDR = 144; - public static final int UC_RISCV_REG_SPTBR = 145; - public static final int UC_RISCV_REG_SATP = 146; - public static final int UC_RISCV_REG_HSTATUS = 147; - public static final int UC_RISCV_REG_HEDELEG = 148; - public static final int UC_RISCV_REG_HIDELEG = 149; - public static final int UC_RISCV_REG_HIE = 150; - public static final int UC_RISCV_REG_HCOUNTEREN = 151; - public static final int UC_RISCV_REG_HTVAL = 152; - public static final int UC_RISCV_REG_HIP = 153; - public static final int UC_RISCV_REG_HTINST = 154; - public static final int UC_RISCV_REG_HGATP = 155; - public static final int UC_RISCV_REG_HTIMEDELTA = 156; - public static final int UC_RISCV_REG_HTIMEDELTAH = 157; + // RISCV CSR + public static final int UC_RISCV_REG_USTATUS = 33; + public static final int UC_RISCV_REG_UIE = 34; + public static final int UC_RISCV_REG_UTVEC = 35; + public static final int UC_RISCV_REG_USCRATCH = 36; + public static final int UC_RISCV_REG_UEPC = 37; + public static final int UC_RISCV_REG_UCAUSE = 38; + public static final int UC_RISCV_REG_UTVAL = 39; + public static final int UC_RISCV_REG_UIP = 40; + public static final int UC_RISCV_REG_FFLAGS = 41; + public static final int UC_RISCV_REG_FRM = 42; + public static final int UC_RISCV_REG_FCSR = 43; + public static final int UC_RISCV_REG_CYCLE = 44; + public static final int UC_RISCV_REG_TIME = 45; + public static final int UC_RISCV_REG_INSTRET = 46; + public static final int UC_RISCV_REG_HPMCOUNTER3 = 47; + public static final int UC_RISCV_REG_HPMCOUNTER4 = 48; + public static final int UC_RISCV_REG_HPMCOUNTER5 = 49; + public static final int UC_RISCV_REG_HPMCOUNTER6 = 50; + public static final int UC_RISCV_REG_HPMCOUNTER7 = 51; + public static final int UC_RISCV_REG_HPMCOUNTER8 = 52; + public static final int UC_RISCV_REG_HPMCOUNTER9 = 53; + public static final int UC_RISCV_REG_HPMCOUNTER10 = 54; + public static final int UC_RISCV_REG_HPMCOUNTER11 = 55; + public static final int UC_RISCV_REG_HPMCOUNTER12 = 56; + public static final int UC_RISCV_REG_HPMCOUNTER13 = 57; + public static final int UC_RISCV_REG_HPMCOUNTER14 = 58; + public static final int UC_RISCV_REG_HPMCOUNTER15 = 59; + public static final int UC_RISCV_REG_HPMCOUNTER16 = 60; + public static final int UC_RISCV_REG_HPMCOUNTER17 = 61; + public static final int UC_RISCV_REG_HPMCOUNTER18 = 62; + public static final int UC_RISCV_REG_HPMCOUNTER19 = 63; + public static final int UC_RISCV_REG_HPMCOUNTER20 = 64; + public static final int UC_RISCV_REG_HPMCOUNTER21 = 65; + public static final int UC_RISCV_REG_HPMCOUNTER22 = 66; + public static final int UC_RISCV_REG_HPMCOUNTER23 = 67; + public static final int UC_RISCV_REG_HPMCOUNTER24 = 68; + public static final int UC_RISCV_REG_HPMCOUNTER25 = 69; + public static final int UC_RISCV_REG_HPMCOUNTER26 = 70; + public static final int UC_RISCV_REG_HPMCOUNTER27 = 71; + public static final int UC_RISCV_REG_HPMCOUNTER28 = 72; + public static final int UC_RISCV_REG_HPMCOUNTER29 = 73; + public static final int UC_RISCV_REG_HPMCOUNTER30 = 74; + public static final int UC_RISCV_REG_HPMCOUNTER31 = 75; + public static final int UC_RISCV_REG_CYCLEH = 76; + public static final int UC_RISCV_REG_TIMEH = 77; + public static final int UC_RISCV_REG_INSTRETH = 78; + public static final int UC_RISCV_REG_HPMCOUNTER3H = 79; + public static final int UC_RISCV_REG_HPMCOUNTER4H = 80; + public static final int UC_RISCV_REG_HPMCOUNTER5H = 81; + public static final int UC_RISCV_REG_HPMCOUNTER6H = 82; + public static final int UC_RISCV_REG_HPMCOUNTER7H = 83; + public static final int UC_RISCV_REG_HPMCOUNTER8H = 84; + public static final int UC_RISCV_REG_HPMCOUNTER9H = 85; + public static final int UC_RISCV_REG_HPMCOUNTER10H = 86; + public static final int UC_RISCV_REG_HPMCOUNTER11H = 87; + public static final int UC_RISCV_REG_HPMCOUNTER12H = 88; + public static final int UC_RISCV_REG_HPMCOUNTER13H = 89; + public static final int UC_RISCV_REG_HPMCOUNTER14H = 90; + public static final int UC_RISCV_REG_HPMCOUNTER15H = 91; + public static final int UC_RISCV_REG_HPMCOUNTER16H = 92; + public static final int UC_RISCV_REG_HPMCOUNTER17H = 93; + public static final int UC_RISCV_REG_HPMCOUNTER18H = 94; + public static final int UC_RISCV_REG_HPMCOUNTER19H = 95; + public static final int UC_RISCV_REG_HPMCOUNTER20H = 96; + public static final int UC_RISCV_REG_HPMCOUNTER21H = 97; + public static final int UC_RISCV_REG_HPMCOUNTER22H = 98; + public static final int UC_RISCV_REG_HPMCOUNTER23H = 99; + public static final int UC_RISCV_REG_HPMCOUNTER24H = 100; + public static final int UC_RISCV_REG_HPMCOUNTER25H = 101; + public static final int UC_RISCV_REG_HPMCOUNTER26H = 102; + public static final int UC_RISCV_REG_HPMCOUNTER27H = 103; + public static final int UC_RISCV_REG_HPMCOUNTER28H = 104; + public static final int UC_RISCV_REG_HPMCOUNTER29H = 105; + public static final int UC_RISCV_REG_HPMCOUNTER30H = 106; + public static final int UC_RISCV_REG_HPMCOUNTER31H = 107; + public static final int UC_RISCV_REG_MCYCLE = 108; + public static final int UC_RISCV_REG_MINSTRET = 109; + public static final int UC_RISCV_REG_MCYCLEH = 110; + public static final int UC_RISCV_REG_MINSTRETH = 111; + public static final int UC_RISCV_REG_MVENDORID = 112; + public static final int UC_RISCV_REG_MARCHID = 113; + public static final int UC_RISCV_REG_MIMPID = 114; + public static final int UC_RISCV_REG_MHARTID = 115; + public static final int UC_RISCV_REG_MSTATUS = 116; + public static final int UC_RISCV_REG_MISA = 117; + public static final int UC_RISCV_REG_MEDELEG = 118; + public static final int UC_RISCV_REG_MIDELEG = 119; + public static final int UC_RISCV_REG_MIE = 120; + public static final int UC_RISCV_REG_MTVEC = 121; + public static final int UC_RISCV_REG_MCOUNTEREN = 122; + public static final int UC_RISCV_REG_MSTATUSH = 123; + public static final int UC_RISCV_REG_MUCOUNTEREN = 124; + public static final int UC_RISCV_REG_MSCOUNTEREN = 125; + public static final int UC_RISCV_REG_MHCOUNTEREN = 126; + public static final int UC_RISCV_REG_MSCRATCH = 127; + public static final int UC_RISCV_REG_MEPC = 128; + public static final int UC_RISCV_REG_MCAUSE = 129; + public static final int UC_RISCV_REG_MTVAL = 130; + public static final int UC_RISCV_REG_MIP = 131; + public static final int UC_RISCV_REG_MBADADDR = 132; + public static final int UC_RISCV_REG_SSTATUS = 133; + public static final int UC_RISCV_REG_SEDELEG = 134; + public static final int UC_RISCV_REG_SIDELEG = 135; + public static final int UC_RISCV_REG_SIE = 136; + public static final int UC_RISCV_REG_STVEC = 137; + public static final int UC_RISCV_REG_SCOUNTEREN = 138; + public static final int UC_RISCV_REG_SSCRATCH = 139; + public static final int UC_RISCV_REG_SEPC = 140; + public static final int UC_RISCV_REG_SCAUSE = 141; + public static final int UC_RISCV_REG_STVAL = 142; + public static final int UC_RISCV_REG_SIP = 143; + public static final int UC_RISCV_REG_SBADADDR = 144; + public static final int UC_RISCV_REG_SPTBR = 145; + public static final int UC_RISCV_REG_SATP = 146; + public static final int UC_RISCV_REG_HSTATUS = 147; + public static final int UC_RISCV_REG_HEDELEG = 148; + public static final int UC_RISCV_REG_HIDELEG = 149; + public static final int UC_RISCV_REG_HIE = 150; + public static final int UC_RISCV_REG_HCOUNTEREN = 151; + public static final int UC_RISCV_REG_HTVAL = 152; + public static final int UC_RISCV_REG_HIP = 153; + public static final int UC_RISCV_REG_HTINST = 154; + public static final int UC_RISCV_REG_HGATP = 155; + public static final int UC_RISCV_REG_HTIMEDELTA = 156; + public static final int UC_RISCV_REG_HTIMEDELTAH = 157; -// Floating-point registers - public static final int UC_RISCV_REG_F0 = 158; - public static final int UC_RISCV_REG_F1 = 159; - public static final int UC_RISCV_REG_F2 = 160; - public static final int UC_RISCV_REG_F3 = 161; - public static final int UC_RISCV_REG_F4 = 162; - public static final int UC_RISCV_REG_F5 = 163; - public static final int UC_RISCV_REG_F6 = 164; - public static final int UC_RISCV_REG_F7 = 165; - public static final int UC_RISCV_REG_F8 = 166; - public static final int UC_RISCV_REG_F9 = 167; - public static final int UC_RISCV_REG_F10 = 168; - public static final int UC_RISCV_REG_F11 = 169; - public static final int UC_RISCV_REG_F12 = 170; - public static final int UC_RISCV_REG_F13 = 171; - public static final int UC_RISCV_REG_F14 = 172; - public static final int UC_RISCV_REG_F15 = 173; - public static final int UC_RISCV_REG_F16 = 174; - public static final int UC_RISCV_REG_F17 = 175; - public static final int UC_RISCV_REG_F18 = 176; - public static final int UC_RISCV_REG_F19 = 177; - public static final int UC_RISCV_REG_F20 = 178; - public static final int UC_RISCV_REG_F21 = 179; - public static final int UC_RISCV_REG_F22 = 180; - public static final int UC_RISCV_REG_F23 = 181; - public static final int UC_RISCV_REG_F24 = 182; - public static final int UC_RISCV_REG_F25 = 183; - public static final int UC_RISCV_REG_F26 = 184; - public static final int UC_RISCV_REG_F27 = 185; - public static final int UC_RISCV_REG_F28 = 186; - public static final int UC_RISCV_REG_F29 = 187; - public static final int UC_RISCV_REG_F30 = 188; - public static final int UC_RISCV_REG_F31 = 189; - public static final int UC_RISCV_REG_PC = 190; - public static final int UC_RISCV_REG_ENDING = 191; + // Floating-point registers + public static final int UC_RISCV_REG_F0 = 158; + public static final int UC_RISCV_REG_F1 = 159; + public static final int UC_RISCV_REG_F2 = 160; + public static final int UC_RISCV_REG_F3 = 161; + public static final int UC_RISCV_REG_F4 = 162; + public static final int UC_RISCV_REG_F5 = 163; + public static final int UC_RISCV_REG_F6 = 164; + public static final int UC_RISCV_REG_F7 = 165; + public static final int UC_RISCV_REG_F8 = 166; + public static final int UC_RISCV_REG_F9 = 167; + public static final int UC_RISCV_REG_F10 = 168; + public static final int UC_RISCV_REG_F11 = 169; + public static final int UC_RISCV_REG_F12 = 170; + public static final int UC_RISCV_REG_F13 = 171; + public static final int UC_RISCV_REG_F14 = 172; + public static final int UC_RISCV_REG_F15 = 173; + public static final int UC_RISCV_REG_F16 = 174; + public static final int UC_RISCV_REG_F17 = 175; + public static final int UC_RISCV_REG_F18 = 176; + public static final int UC_RISCV_REG_F19 = 177; + public static final int UC_RISCV_REG_F20 = 178; + public static final int UC_RISCV_REG_F21 = 179; + public static final int UC_RISCV_REG_F22 = 180; + public static final int UC_RISCV_REG_F23 = 181; + public static final int UC_RISCV_REG_F24 = 182; + public static final int UC_RISCV_REG_F25 = 183; + public static final int UC_RISCV_REG_F26 = 184; + public static final int UC_RISCV_REG_F27 = 185; + public static final int UC_RISCV_REG_F28 = 186; + public static final int UC_RISCV_REG_F29 = 187; + public static final int UC_RISCV_REG_F30 = 188; + public static final int UC_RISCV_REG_F31 = 189; + public static final int UC_RISCV_REG_PC = 190; + public static final int UC_RISCV_REG_ENDING = 191; -// Alias registers - public static final int UC_RISCV_REG_ZERO = 1; - public static final int UC_RISCV_REG_RA = 2; - public static final int UC_RISCV_REG_SP = 3; - public static final int UC_RISCV_REG_GP = 4; - public static final int UC_RISCV_REG_TP = 5; - public static final int UC_RISCV_REG_T0 = 6; - public static final int UC_RISCV_REG_T1 = 7; - public static final int UC_RISCV_REG_T2 = 8; - public static final int UC_RISCV_REG_S0 = 9; - public static final int UC_RISCV_REG_FP = 9; - public static final int UC_RISCV_REG_S1 = 10; - public static final int UC_RISCV_REG_A0 = 11; - public static final int UC_RISCV_REG_A1 = 12; - public static final int UC_RISCV_REG_A2 = 13; - public static final int UC_RISCV_REG_A3 = 14; - public static final int UC_RISCV_REG_A4 = 15; - public static final int UC_RISCV_REG_A5 = 16; - public static final int UC_RISCV_REG_A6 = 17; - public static final int UC_RISCV_REG_A7 = 18; - public static final int UC_RISCV_REG_S2 = 19; - public static final int UC_RISCV_REG_S3 = 20; - public static final int UC_RISCV_REG_S4 = 21; - public static final int UC_RISCV_REG_S5 = 22; - public static final int UC_RISCV_REG_S6 = 23; - public static final int UC_RISCV_REG_S7 = 24; - public static final int UC_RISCV_REG_S8 = 25; - public static final int UC_RISCV_REG_S9 = 26; - public static final int UC_RISCV_REG_S10 = 27; - public static final int UC_RISCV_REG_S11 = 28; - public static final int UC_RISCV_REG_T3 = 29; - public static final int UC_RISCV_REG_T4 = 30; - public static final int UC_RISCV_REG_T5 = 31; - public static final int UC_RISCV_REG_T6 = 32; - public static final int UC_RISCV_REG_FT0 = 158; - public static final int UC_RISCV_REG_FT1 = 159; - public static final int UC_RISCV_REG_FT2 = 160; - public static final int UC_RISCV_REG_FT3 = 161; - public static final int UC_RISCV_REG_FT4 = 162; - public static final int UC_RISCV_REG_FT5 = 163; - public static final int UC_RISCV_REG_FT6 = 164; - public static final int UC_RISCV_REG_FT7 = 165; - public static final int UC_RISCV_REG_FS0 = 166; - public static final int UC_RISCV_REG_FS1 = 167; - public static final int UC_RISCV_REG_FA0 = 168; - public static final int UC_RISCV_REG_FA1 = 169; - public static final int UC_RISCV_REG_FA2 = 170; - public static final int UC_RISCV_REG_FA3 = 171; - public static final int UC_RISCV_REG_FA4 = 172; - public static final int UC_RISCV_REG_FA5 = 173; - public static final int UC_RISCV_REG_FA6 = 174; - public static final int UC_RISCV_REG_FA7 = 175; - public static final int UC_RISCV_REG_FS2 = 176; - public static final int UC_RISCV_REG_FS3 = 177; - public static final int UC_RISCV_REG_FS4 = 178; - public static final int UC_RISCV_REG_FS5 = 179; - public static final int UC_RISCV_REG_FS6 = 180; - public static final int UC_RISCV_REG_FS7 = 181; - public static final int UC_RISCV_REG_FS8 = 182; - public static final int UC_RISCV_REG_FS9 = 183; - public static final int UC_RISCV_REG_FS10 = 184; - public static final int UC_RISCV_REG_FS11 = 185; - public static final int UC_RISCV_REG_FT8 = 186; - public static final int UC_RISCV_REG_FT9 = 187; - public static final int UC_RISCV_REG_FT10 = 188; - public static final int UC_RISCV_REG_FT11 = 189; + // Alias registers + public static final int UC_RISCV_REG_ZERO = 1; + public static final int UC_RISCV_REG_RA = 2; + public static final int UC_RISCV_REG_SP = 3; + public static final int UC_RISCV_REG_GP = 4; + public static final int UC_RISCV_REG_TP = 5; + public static final int UC_RISCV_REG_T0 = 6; + public static final int UC_RISCV_REG_T1 = 7; + public static final int UC_RISCV_REG_T2 = 8; + public static final int UC_RISCV_REG_S0 = 9; + public static final int UC_RISCV_REG_FP = 9; + public static final int UC_RISCV_REG_S1 = 10; + public static final int UC_RISCV_REG_A0 = 11; + public static final int UC_RISCV_REG_A1 = 12; + public static final int UC_RISCV_REG_A2 = 13; + public static final int UC_RISCV_REG_A3 = 14; + public static final int UC_RISCV_REG_A4 = 15; + public static final int UC_RISCV_REG_A5 = 16; + public static final int UC_RISCV_REG_A6 = 17; + public static final int UC_RISCV_REG_A7 = 18; + public static final int UC_RISCV_REG_S2 = 19; + public static final int UC_RISCV_REG_S3 = 20; + public static final int UC_RISCV_REG_S4 = 21; + public static final int UC_RISCV_REG_S5 = 22; + public static final int UC_RISCV_REG_S6 = 23; + public static final int UC_RISCV_REG_S7 = 24; + public static final int UC_RISCV_REG_S8 = 25; + public static final int UC_RISCV_REG_S9 = 26; + public static final int UC_RISCV_REG_S10 = 27; + public static final int UC_RISCV_REG_S11 = 28; + public static final int UC_RISCV_REG_T3 = 29; + public static final int UC_RISCV_REG_T4 = 30; + public static final int UC_RISCV_REG_T5 = 31; + public static final int UC_RISCV_REG_T6 = 32; + public static final int UC_RISCV_REG_FT0 = 158; + public static final int UC_RISCV_REG_FT1 = 159; + public static final int UC_RISCV_REG_FT2 = 160; + public static final int UC_RISCV_REG_FT3 = 161; + public static final int UC_RISCV_REG_FT4 = 162; + public static final int UC_RISCV_REG_FT5 = 163; + public static final int UC_RISCV_REG_FT6 = 164; + public static final int UC_RISCV_REG_FT7 = 165; + public static final int UC_RISCV_REG_FS0 = 166; + public static final int UC_RISCV_REG_FS1 = 167; + public static final int UC_RISCV_REG_FA0 = 168; + public static final int UC_RISCV_REG_FA1 = 169; + public static final int UC_RISCV_REG_FA2 = 170; + public static final int UC_RISCV_REG_FA3 = 171; + public static final int UC_RISCV_REG_FA4 = 172; + public static final int UC_RISCV_REG_FA5 = 173; + public static final int UC_RISCV_REG_FA6 = 174; + public static final int UC_RISCV_REG_FA7 = 175; + public static final int UC_RISCV_REG_FS2 = 176; + public static final int UC_RISCV_REG_FS3 = 177; + public static final int UC_RISCV_REG_FS4 = 178; + public static final int UC_RISCV_REG_FS5 = 179; + public static final int UC_RISCV_REG_FS6 = 180; + public static final int UC_RISCV_REG_FS7 = 181; + public static final int UC_RISCV_REG_FS8 = 182; + public static final int UC_RISCV_REG_FS9 = 183; + public static final int UC_RISCV_REG_FS10 = 184; + public static final int UC_RISCV_REG_FS11 = 185; + public static final int UC_RISCV_REG_FT8 = 186; + public static final int UC_RISCV_REG_FT9 = 187; + public static final int UC_RISCV_REG_FT10 = 188; + public static final int UC_RISCV_REG_FT11 = 189; } diff --git a/bindings/java/unicorn/S390xConst.java b/bindings/java/unicorn/S390xConst.java index 57b4c588..fb422f51 100644 --- a/bindings/java/unicorn/S390xConst.java +++ b/bindings/java/unicorn/S390xConst.java @@ -4,125 +4,125 @@ package unicorn; public interface S390xConst { -// S390X CPU + // S390X CPU - public static final int UC_CPU_S390X_Z900 = 0; - public static final int UC_CPU_S390X_Z900_2 = 1; - public static final int UC_CPU_S390X_Z900_3 = 2; - public static final int UC_CPU_S390X_Z800 = 3; - public static final int UC_CPU_S390X_Z990 = 4; - public static final int UC_CPU_S390X_Z990_2 = 5; - public static final int UC_CPU_S390X_Z990_3 = 6; - public static final int UC_CPU_S390X_Z890 = 7; - public static final int UC_CPU_S390X_Z990_4 = 8; - public static final int UC_CPU_S390X_Z890_2 = 9; - public static final int UC_CPU_S390X_Z990_5 = 10; - public static final int UC_CPU_S390X_Z890_3 = 11; - public static final int UC_CPU_S390X_Z9EC = 12; - public static final int UC_CPU_S390X_Z9EC_2 = 13; - public static final int UC_CPU_S390X_Z9BC = 14; - public static final int UC_CPU_S390X_Z9EC_3 = 15; - public static final int UC_CPU_S390X_Z9BC_2 = 16; - public static final int UC_CPU_S390X_Z10EC = 17; - public static final int UC_CPU_S390X_Z10EC_2 = 18; - public static final int UC_CPU_S390X_Z10BC = 19; - public static final int UC_CPU_S390X_Z10EC_3 = 20; - public static final int UC_CPU_S390X_Z10BC_2 = 21; - public static final int UC_CPU_S390X_Z196 = 22; - public static final int UC_CPU_S390X_Z196_2 = 23; - public static final int UC_CPU_S390X_Z114 = 24; - public static final int UC_CPU_S390X_ZEC12 = 25; - public static final int UC_CPU_S390X_ZEC12_2 = 26; - public static final int UC_CPU_S390X_ZBC12 = 27; - public static final int UC_CPU_S390X_Z13 = 28; - public static final int UC_CPU_S390X_Z13_2 = 29; - public static final int UC_CPU_S390X_Z13S = 30; - public static final int UC_CPU_S390X_Z14 = 31; - public static final int UC_CPU_S390X_Z14_2 = 32; - public static final int UC_CPU_S390X_Z14ZR1 = 33; - public static final int UC_CPU_S390X_GEN15A = 34; - public static final int UC_CPU_S390X_GEN15B = 35; - public static final int UC_CPU_S390X_QEMU = 36; - public static final int UC_CPU_S390X_MAX = 37; - public static final int UC_CPU_S390X_ENDING = 38; + public static final int UC_CPU_S390X_Z900 = 0; + public static final int UC_CPU_S390X_Z900_2 = 1; + public static final int UC_CPU_S390X_Z900_3 = 2; + public static final int UC_CPU_S390X_Z800 = 3; + public static final int UC_CPU_S390X_Z990 = 4; + public static final int UC_CPU_S390X_Z990_2 = 5; + public static final int UC_CPU_S390X_Z990_3 = 6; + public static final int UC_CPU_S390X_Z890 = 7; + public static final int UC_CPU_S390X_Z990_4 = 8; + public static final int UC_CPU_S390X_Z890_2 = 9; + public static final int UC_CPU_S390X_Z990_5 = 10; + public static final int UC_CPU_S390X_Z890_3 = 11; + public static final int UC_CPU_S390X_Z9EC = 12; + public static final int UC_CPU_S390X_Z9EC_2 = 13; + public static final int UC_CPU_S390X_Z9BC = 14; + public static final int UC_CPU_S390X_Z9EC_3 = 15; + public static final int UC_CPU_S390X_Z9BC_2 = 16; + public static final int UC_CPU_S390X_Z10EC = 17; + public static final int UC_CPU_S390X_Z10EC_2 = 18; + public static final int UC_CPU_S390X_Z10BC = 19; + public static final int UC_CPU_S390X_Z10EC_3 = 20; + public static final int UC_CPU_S390X_Z10BC_2 = 21; + public static final int UC_CPU_S390X_Z196 = 22; + public static final int UC_CPU_S390X_Z196_2 = 23; + public static final int UC_CPU_S390X_Z114 = 24; + public static final int UC_CPU_S390X_ZEC12 = 25; + public static final int UC_CPU_S390X_ZEC12_2 = 26; + public static final int UC_CPU_S390X_ZBC12 = 27; + public static final int UC_CPU_S390X_Z13 = 28; + public static final int UC_CPU_S390X_Z13_2 = 29; + public static final int UC_CPU_S390X_Z13S = 30; + public static final int UC_CPU_S390X_Z14 = 31; + public static final int UC_CPU_S390X_Z14_2 = 32; + public static final int UC_CPU_S390X_Z14ZR1 = 33; + public static final int UC_CPU_S390X_GEN15A = 34; + public static final int UC_CPU_S390X_GEN15B = 35; + public static final int UC_CPU_S390X_QEMU = 36; + public static final int UC_CPU_S390X_MAX = 37; + public static final int UC_CPU_S390X_ENDING = 38; -// S390X registers + // S390X registers - public static final int UC_S390X_REG_INVALID = 0; + public static final int UC_S390X_REG_INVALID = 0; -// General purpose registers - public static final int UC_S390X_REG_R0 = 1; - public static final int UC_S390X_REG_R1 = 2; - public static final int UC_S390X_REG_R2 = 3; - public static final int UC_S390X_REG_R3 = 4; - public static final int UC_S390X_REG_R4 = 5; - public static final int UC_S390X_REG_R5 = 6; - public static final int UC_S390X_REG_R6 = 7; - public static final int UC_S390X_REG_R7 = 8; - public static final int UC_S390X_REG_R8 = 9; - public static final int UC_S390X_REG_R9 = 10; - public static final int UC_S390X_REG_R10 = 11; - public static final int UC_S390X_REG_R11 = 12; - public static final int UC_S390X_REG_R12 = 13; - public static final int UC_S390X_REG_R13 = 14; - public static final int UC_S390X_REG_R14 = 15; - public static final int UC_S390X_REG_R15 = 16; + // General purpose registers + public static final int UC_S390X_REG_R0 = 1; + public static final int UC_S390X_REG_R1 = 2; + public static final int UC_S390X_REG_R2 = 3; + public static final int UC_S390X_REG_R3 = 4; + public static final int UC_S390X_REG_R4 = 5; + public static final int UC_S390X_REG_R5 = 6; + public static final int UC_S390X_REG_R6 = 7; + public static final int UC_S390X_REG_R7 = 8; + public static final int UC_S390X_REG_R8 = 9; + public static final int UC_S390X_REG_R9 = 10; + public static final int UC_S390X_REG_R10 = 11; + public static final int UC_S390X_REG_R11 = 12; + public static final int UC_S390X_REG_R12 = 13; + public static final int UC_S390X_REG_R13 = 14; + public static final int UC_S390X_REG_R14 = 15; + public static final int UC_S390X_REG_R15 = 16; -// Floating point registers - public static final int UC_S390X_REG_F0 = 17; - public static final int UC_S390X_REG_F1 = 18; - public static final int UC_S390X_REG_F2 = 19; - public static final int UC_S390X_REG_F3 = 20; - public static final int UC_S390X_REG_F4 = 21; - public static final int UC_S390X_REG_F5 = 22; - public static final int UC_S390X_REG_F6 = 23; - public static final int UC_S390X_REG_F7 = 24; - public static final int UC_S390X_REG_F8 = 25; - public static final int UC_S390X_REG_F9 = 26; - public static final int UC_S390X_REG_F10 = 27; - public static final int UC_S390X_REG_F11 = 28; - public static final int UC_S390X_REG_F12 = 29; - public static final int UC_S390X_REG_F13 = 30; - public static final int UC_S390X_REG_F14 = 31; - public static final int UC_S390X_REG_F15 = 32; - public static final int UC_S390X_REG_F16 = 33; - public static final int UC_S390X_REG_F17 = 34; - public static final int UC_S390X_REG_F18 = 35; - public static final int UC_S390X_REG_F19 = 36; - public static final int UC_S390X_REG_F20 = 37; - public static final int UC_S390X_REG_F21 = 38; - public static final int UC_S390X_REG_F22 = 39; - public static final int UC_S390X_REG_F23 = 40; - public static final int UC_S390X_REG_F24 = 41; - public static final int UC_S390X_REG_F25 = 42; - public static final int UC_S390X_REG_F26 = 43; - public static final int UC_S390X_REG_F27 = 44; - public static final int UC_S390X_REG_F28 = 45; - public static final int UC_S390X_REG_F29 = 46; - public static final int UC_S390X_REG_F30 = 47; - public static final int UC_S390X_REG_F31 = 48; + // Floating point registers + public static final int UC_S390X_REG_F0 = 17; + public static final int UC_S390X_REG_F1 = 18; + public static final int UC_S390X_REG_F2 = 19; + public static final int UC_S390X_REG_F3 = 20; + public static final int UC_S390X_REG_F4 = 21; + public static final int UC_S390X_REG_F5 = 22; + public static final int UC_S390X_REG_F6 = 23; + public static final int UC_S390X_REG_F7 = 24; + public static final int UC_S390X_REG_F8 = 25; + public static final int UC_S390X_REG_F9 = 26; + public static final int UC_S390X_REG_F10 = 27; + public static final int UC_S390X_REG_F11 = 28; + public static final int UC_S390X_REG_F12 = 29; + public static final int UC_S390X_REG_F13 = 30; + public static final int UC_S390X_REG_F14 = 31; + public static final int UC_S390X_REG_F15 = 32; + public static final int UC_S390X_REG_F16 = 33; + public static final int UC_S390X_REG_F17 = 34; + public static final int UC_S390X_REG_F18 = 35; + public static final int UC_S390X_REG_F19 = 36; + public static final int UC_S390X_REG_F20 = 37; + public static final int UC_S390X_REG_F21 = 38; + public static final int UC_S390X_REG_F22 = 39; + public static final int UC_S390X_REG_F23 = 40; + public static final int UC_S390X_REG_F24 = 41; + public static final int UC_S390X_REG_F25 = 42; + public static final int UC_S390X_REG_F26 = 43; + public static final int UC_S390X_REG_F27 = 44; + public static final int UC_S390X_REG_F28 = 45; + public static final int UC_S390X_REG_F29 = 46; + public static final int UC_S390X_REG_F30 = 47; + public static final int UC_S390X_REG_F31 = 48; -// Access registers - public static final int UC_S390X_REG_A0 = 49; - public static final int UC_S390X_REG_A1 = 50; - public static final int UC_S390X_REG_A2 = 51; - public static final int UC_S390X_REG_A3 = 52; - public static final int UC_S390X_REG_A4 = 53; - public static final int UC_S390X_REG_A5 = 54; - public static final int UC_S390X_REG_A6 = 55; - public static final int UC_S390X_REG_A7 = 56; - public static final int UC_S390X_REG_A8 = 57; - public static final int UC_S390X_REG_A9 = 58; - public static final int UC_S390X_REG_A10 = 59; - public static final int UC_S390X_REG_A11 = 60; - public static final int UC_S390X_REG_A12 = 61; - public static final int UC_S390X_REG_A13 = 62; - public static final int UC_S390X_REG_A14 = 63; - public static final int UC_S390X_REG_A15 = 64; - public static final int UC_S390X_REG_PC = 65; - public static final int UC_S390X_REG_PSWM = 66; - public static final int UC_S390X_REG_ENDING = 67; + // Access registers + public static final int UC_S390X_REG_A0 = 49; + public static final int UC_S390X_REG_A1 = 50; + public static final int UC_S390X_REG_A2 = 51; + public static final int UC_S390X_REG_A3 = 52; + public static final int UC_S390X_REG_A4 = 53; + public static final int UC_S390X_REG_A5 = 54; + public static final int UC_S390X_REG_A6 = 55; + public static final int UC_S390X_REG_A7 = 56; + public static final int UC_S390X_REG_A8 = 57; + public static final int UC_S390X_REG_A9 = 58; + public static final int UC_S390X_REG_A10 = 59; + public static final int UC_S390X_REG_A11 = 60; + public static final int UC_S390X_REG_A12 = 61; + public static final int UC_S390X_REG_A13 = 62; + public static final int UC_S390X_REG_A14 = 63; + public static final int UC_S390X_REG_A15 = 64; + public static final int UC_S390X_REG_PC = 65; + public static final int UC_S390X_REG_PSWM = 66; + public static final int UC_S390X_REG_ENDING = 67; -// Alias registers + // Alias registers } diff --git a/bindings/java/unicorn/SparcConst.java b/bindings/java/unicorn/SparcConst.java index e2a71eb4..5a407642 100644 --- a/bindings/java/unicorn/SparcConst.java +++ b/bindings/java/unicorn/SparcConst.java @@ -4,137 +4,137 @@ package unicorn; public interface SparcConst { -// SPARC32 CPU + // SPARC32 CPU - public static final int UC_CPU_SPARC32_FUJITSU_MB86904 = 0; - public static final int UC_CPU_SPARC32_FUJITSU_MB86907 = 1; - public static final int UC_CPU_SPARC32_TI_MICROSPARC_I = 2; - public static final int UC_CPU_SPARC32_TI_MICROSPARC_II = 3; - public static final int UC_CPU_SPARC32_TI_MICROSPARC_IIEP = 4; - public static final int UC_CPU_SPARC32_TI_SUPERSPARC_40 = 5; - public static final int UC_CPU_SPARC32_TI_SUPERSPARC_50 = 6; - public static final int UC_CPU_SPARC32_TI_SUPERSPARC_51 = 7; - public static final int UC_CPU_SPARC32_TI_SUPERSPARC_60 = 8; - public static final int UC_CPU_SPARC32_TI_SUPERSPARC_61 = 9; - public static final int UC_CPU_SPARC32_TI_SUPERSPARC_II = 10; - public static final int UC_CPU_SPARC32_LEON2 = 11; - public static final int UC_CPU_SPARC32_LEON3 = 12; - public static final int UC_CPU_SPARC32_ENDING = 13; + public static final int UC_CPU_SPARC32_FUJITSU_MB86904 = 0; + public static final int UC_CPU_SPARC32_FUJITSU_MB86907 = 1; + public static final int UC_CPU_SPARC32_TI_MICROSPARC_I = 2; + public static final int UC_CPU_SPARC32_TI_MICROSPARC_II = 3; + public static final int UC_CPU_SPARC32_TI_MICROSPARC_IIEP = 4; + public static final int UC_CPU_SPARC32_TI_SUPERSPARC_40 = 5; + public static final int UC_CPU_SPARC32_TI_SUPERSPARC_50 = 6; + public static final int UC_CPU_SPARC32_TI_SUPERSPARC_51 = 7; + public static final int UC_CPU_SPARC32_TI_SUPERSPARC_60 = 8; + public static final int UC_CPU_SPARC32_TI_SUPERSPARC_61 = 9; + public static final int UC_CPU_SPARC32_TI_SUPERSPARC_II = 10; + public static final int UC_CPU_SPARC32_LEON2 = 11; + public static final int UC_CPU_SPARC32_LEON3 = 12; + public static final int UC_CPU_SPARC32_ENDING = 13; -// SPARC64 CPU + // SPARC64 CPU - public static final int UC_CPU_SPARC64_FUJITSU = 0; - public static final int UC_CPU_SPARC64_FUJITSU_III = 1; - public static final int UC_CPU_SPARC64_FUJITSU_IV = 2; - public static final int UC_CPU_SPARC64_FUJITSU_V = 3; - public static final int UC_CPU_SPARC64_TI_ULTRASPARC_I = 4; - public static final int UC_CPU_SPARC64_TI_ULTRASPARC_II = 5; - public static final int UC_CPU_SPARC64_TI_ULTRASPARC_III = 6; - public static final int UC_CPU_SPARC64_TI_ULTRASPARC_IIE = 7; - public static final int UC_CPU_SPARC64_SUN_ULTRASPARC_III = 8; - public static final int UC_CPU_SPARC64_SUN_ULTRASPARC_III_CU = 9; - public static final int UC_CPU_SPARC64_SUN_ULTRASPARC_IIII = 10; - public static final int UC_CPU_SPARC64_SUN_ULTRASPARC_IV = 11; - public static final int UC_CPU_SPARC64_SUN_ULTRASPARC_IV_PLUS = 12; - public static final int UC_CPU_SPARC64_SUN_ULTRASPARC_IIII_PLUS = 13; - public static final int UC_CPU_SPARC64_SUN_ULTRASPARC_T1 = 14; - public static final int UC_CPU_SPARC64_SUN_ULTRASPARC_T2 = 15; - public static final int UC_CPU_SPARC64_NEC_ULTRASPARC_I = 16; - public static final int UC_CPU_SPARC64_ENDING = 17; + public static final int UC_CPU_SPARC64_FUJITSU = 0; + public static final int UC_CPU_SPARC64_FUJITSU_III = 1; + public static final int UC_CPU_SPARC64_FUJITSU_IV = 2; + public static final int UC_CPU_SPARC64_FUJITSU_V = 3; + public static final int UC_CPU_SPARC64_TI_ULTRASPARC_I = 4; + public static final int UC_CPU_SPARC64_TI_ULTRASPARC_II = 5; + public static final int UC_CPU_SPARC64_TI_ULTRASPARC_III = 6; + public static final int UC_CPU_SPARC64_TI_ULTRASPARC_IIE = 7; + public static final int UC_CPU_SPARC64_SUN_ULTRASPARC_III = 8; + public static final int UC_CPU_SPARC64_SUN_ULTRASPARC_III_CU = 9; + public static final int UC_CPU_SPARC64_SUN_ULTRASPARC_IIII = 10; + public static final int UC_CPU_SPARC64_SUN_ULTRASPARC_IV = 11; + public static final int UC_CPU_SPARC64_SUN_ULTRASPARC_IV_PLUS = 12; + public static final int UC_CPU_SPARC64_SUN_ULTRASPARC_IIII_PLUS = 13; + public static final int UC_CPU_SPARC64_SUN_ULTRASPARC_T1 = 14; + public static final int UC_CPU_SPARC64_SUN_ULTRASPARC_T2 = 15; + public static final int UC_CPU_SPARC64_NEC_ULTRASPARC_I = 16; + public static final int UC_CPU_SPARC64_ENDING = 17; -// SPARC registers + // SPARC registers - 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_G0 = 53; - public static final int UC_SPARC_REG_G1 = 54; - public static final int UC_SPARC_REG_G2 = 55; - public static final int UC_SPARC_REG_G3 = 56; - public static final int UC_SPARC_REG_G4 = 57; - public static final int UC_SPARC_REG_G5 = 58; - public static final int UC_SPARC_REG_G6 = 59; - public static final int UC_SPARC_REG_G7 = 60; - public static final int UC_SPARC_REG_I0 = 61; - public static final int UC_SPARC_REG_I1 = 62; - public static final int UC_SPARC_REG_I2 = 63; - public static final int UC_SPARC_REG_I3 = 64; - public static final int UC_SPARC_REG_I4 = 65; - public static final int UC_SPARC_REG_I5 = 66; - public static final int UC_SPARC_REG_FP = 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_SP = 84; - public static final int UC_SPARC_REG_O7 = 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 = 84; - public static final int UC_SPARC_REG_I6 = 67; + 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_G0 = 53; + public static final int UC_SPARC_REG_G1 = 54; + public static final int UC_SPARC_REG_G2 = 55; + public static final int UC_SPARC_REG_G3 = 56; + public static final int UC_SPARC_REG_G4 = 57; + public static final int UC_SPARC_REG_G5 = 58; + public static final int UC_SPARC_REG_G6 = 59; + public static final int UC_SPARC_REG_G7 = 60; + public static final int UC_SPARC_REG_I0 = 61; + public static final int UC_SPARC_REG_I1 = 62; + public static final int UC_SPARC_REG_I2 = 63; + public static final int UC_SPARC_REG_I3 = 64; + public static final int UC_SPARC_REG_I4 = 65; + public static final int UC_SPARC_REG_I5 = 66; + public static final int UC_SPARC_REG_FP = 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_SP = 84; + public static final int UC_SPARC_REG_O7 = 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 = 84; + public static final int UC_SPARC_REG_I6 = 67; } diff --git a/bindings/java/unicorn/SyscallHook.java b/bindings/java/unicorn/SyscallHook.java index 5b08a113..bf6476db 100644 --- a/bindings/java/unicorn/SyscallHook.java +++ b/bindings/java/unicorn/SyscallHook.java @@ -22,8 +22,5 @@ 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); - + public void hook(Unicorn u, Object user); } - diff --git a/bindings/java/unicorn/TriCoreConst.java b/bindings/java/unicorn/TriCoreConst.java index 4154abad..2cf10b0c 100644 --- a/bindings/java/unicorn/TriCoreConst.java +++ b/bindings/java/unicorn/TriCoreConst.java @@ -4,127 +4,127 @@ package unicorn; public interface TriCoreConst { -// TRICORE CPU + // TRICORE CPU - public static final int UC_CPU_TRICORE_TC1796 = 0; - public static final int UC_CPU_TRICORE_TC1797 = 1; - public static final int UC_CPU_TRICORE_TC27X = 2; - public static final int UC_CPU_TRICORE_ENDING = 3; + public static final int UC_CPU_TRICORE_TC1796 = 0; + public static final int UC_CPU_TRICORE_TC1797 = 1; + public static final int UC_CPU_TRICORE_TC27X = 2; + public static final int UC_CPU_TRICORE_ENDING = 3; -// TRICORE registers + // TRICORE registers - public static final int UC_TRICORE_REG_INVALID = 0; - public static final int UC_TRICORE_REG_A0 = 1; - public static final int UC_TRICORE_REG_A1 = 2; - public static final int UC_TRICORE_REG_A2 = 3; - public static final int UC_TRICORE_REG_A3 = 4; - public static final int UC_TRICORE_REG_A4 = 5; - public static final int UC_TRICORE_REG_A5 = 6; - public static final int UC_TRICORE_REG_A6 = 7; - public static final int UC_TRICORE_REG_A7 = 8; - public static final int UC_TRICORE_REG_A8 = 9; - public static final int UC_TRICORE_REG_A9 = 10; - public static final int UC_TRICORE_REG_A10 = 11; - public static final int UC_TRICORE_REG_A11 = 12; - public static final int UC_TRICORE_REG_A12 = 13; - public static final int UC_TRICORE_REG_A13 = 14; - public static final int UC_TRICORE_REG_A14 = 15; - public static final int UC_TRICORE_REG_A15 = 16; - public static final int UC_TRICORE_REG_D0 = 17; - public static final int UC_TRICORE_REG_D1 = 18; - public static final int UC_TRICORE_REG_D2 = 19; - public static final int UC_TRICORE_REG_D3 = 20; - public static final int UC_TRICORE_REG_D4 = 21; - public static final int UC_TRICORE_REG_D5 = 22; - public static final int UC_TRICORE_REG_D6 = 23; - public static final int UC_TRICORE_REG_D7 = 24; - public static final int UC_TRICORE_REG_D8 = 25; - public static final int UC_TRICORE_REG_D9 = 26; - public static final int UC_TRICORE_REG_D10 = 27; - public static final int UC_TRICORE_REG_D11 = 28; - public static final int UC_TRICORE_REG_D12 = 29; - public static final int UC_TRICORE_REG_D13 = 30; - public static final int UC_TRICORE_REG_D14 = 31; - public static final int UC_TRICORE_REG_D15 = 32; - public static final int UC_TRICORE_REG_PCXI = 33; - public static final int UC_TRICORE_REG_PSW = 34; - public static final int UC_TRICORE_REG_PSW_USB_C = 35; - public static final int UC_TRICORE_REG_PSW_USB_V = 36; - public static final int UC_TRICORE_REG_PSW_USB_SV = 37; - public static final int UC_TRICORE_REG_PSW_USB_AV = 38; - public static final int UC_TRICORE_REG_PSW_USB_SAV = 39; - public static final int UC_TRICORE_REG_PC = 40; - public static final int UC_TRICORE_REG_SYSCON = 41; - public static final int UC_TRICORE_REG_CPU_ID = 42; - public static final int UC_TRICORE_REG_BIV = 43; - public static final int UC_TRICORE_REG_BTV = 44; - public static final int UC_TRICORE_REG_ISP = 45; - public static final int UC_TRICORE_REG_ICR = 46; - public static final int UC_TRICORE_REG_FCX = 47; - public static final int UC_TRICORE_REG_LCX = 48; - public static final int UC_TRICORE_REG_COMPAT = 49; - public static final int UC_TRICORE_REG_DPR0_U = 50; - public static final int UC_TRICORE_REG_DPR1_U = 51; - public static final int UC_TRICORE_REG_DPR2_U = 52; - public static final int UC_TRICORE_REG_DPR3_U = 53; - public static final int UC_TRICORE_REG_DPR0_L = 54; - public static final int UC_TRICORE_REG_DPR1_L = 55; - public static final int UC_TRICORE_REG_DPR2_L = 56; - public static final int UC_TRICORE_REG_DPR3_L = 57; - public static final int UC_TRICORE_REG_CPR0_U = 58; - public static final int UC_TRICORE_REG_CPR1_U = 59; - public static final int UC_TRICORE_REG_CPR2_U = 60; - public static final int UC_TRICORE_REG_CPR3_U = 61; - public static final int UC_TRICORE_REG_CPR0_L = 62; - public static final int UC_TRICORE_REG_CPR1_L = 63; - public static final int UC_TRICORE_REG_CPR2_L = 64; - public static final int UC_TRICORE_REG_CPR3_L = 65; - public static final int UC_TRICORE_REG_DPM0 = 66; - public static final int UC_TRICORE_REG_DPM1 = 67; - public static final int UC_TRICORE_REG_DPM2 = 68; - public static final int UC_TRICORE_REG_DPM3 = 69; - public static final int UC_TRICORE_REG_CPM0 = 70; - public static final int UC_TRICORE_REG_CPM1 = 71; - public static final int UC_TRICORE_REG_CPM2 = 72; - public static final int UC_TRICORE_REG_CPM3 = 73; - public static final int UC_TRICORE_REG_MMU_CON = 74; - public static final int UC_TRICORE_REG_MMU_ASI = 75; - public static final int UC_TRICORE_REG_MMU_TVA = 76; - public static final int UC_TRICORE_REG_MMU_TPA = 77; - public static final int UC_TRICORE_REG_MMU_TPX = 78; - public static final int UC_TRICORE_REG_MMU_TFA = 79; - public static final int UC_TRICORE_REG_BMACON = 80; - public static final int UC_TRICORE_REG_SMACON = 81; - public static final int UC_TRICORE_REG_DIEAR = 82; - public static final int UC_TRICORE_REG_DIETR = 83; - public static final int UC_TRICORE_REG_CCDIER = 84; - public static final int UC_TRICORE_REG_MIECON = 85; - public static final int UC_TRICORE_REG_PIEAR = 86; - public static final int UC_TRICORE_REG_PIETR = 87; - public static final int UC_TRICORE_REG_CCPIER = 88; - public static final int UC_TRICORE_REG_DBGSR = 89; - public static final int UC_TRICORE_REG_EXEVT = 90; - public static final int UC_TRICORE_REG_CREVT = 91; - public static final int UC_TRICORE_REG_SWEVT = 92; - public static final int UC_TRICORE_REG_TR0EVT = 93; - public static final int UC_TRICORE_REG_TR1EVT = 94; - public static final int UC_TRICORE_REG_DMS = 95; - public static final int UC_TRICORE_REG_DCX = 96; - public static final int UC_TRICORE_REG_DBGTCR = 97; - public static final int UC_TRICORE_REG_CCTRL = 98; - public static final int UC_TRICORE_REG_CCNT = 99; - public static final int UC_TRICORE_REG_ICNT = 100; - public static final int UC_TRICORE_REG_M1CNT = 101; - public static final int UC_TRICORE_REG_M2CNT = 102; - public static final int UC_TRICORE_REG_M3CNT = 103; - public static final int UC_TRICORE_REG_ENDING = 104; - public static final int UC_TRICORE_REG_GA0 = 1; - public static final int UC_TRICORE_REG_GA1 = 2; - public static final int UC_TRICORE_REG_GA8 = 9; - public static final int UC_TRICORE_REG_GA9 = 10; - public static final int UC_TRICORE_REG_SP = 11; - public static final int UC_TRICORE_REG_LR = 12; - public static final int UC_TRICORE_REG_IA = 16; - public static final int UC_TRICORE_REG_ID = 32; + public static final int UC_TRICORE_REG_INVALID = 0; + public static final int UC_TRICORE_REG_A0 = 1; + public static final int UC_TRICORE_REG_A1 = 2; + public static final int UC_TRICORE_REG_A2 = 3; + public static final int UC_TRICORE_REG_A3 = 4; + public static final int UC_TRICORE_REG_A4 = 5; + public static final int UC_TRICORE_REG_A5 = 6; + public static final int UC_TRICORE_REG_A6 = 7; + public static final int UC_TRICORE_REG_A7 = 8; + public static final int UC_TRICORE_REG_A8 = 9; + public static final int UC_TRICORE_REG_A9 = 10; + public static final int UC_TRICORE_REG_A10 = 11; + public static final int UC_TRICORE_REG_A11 = 12; + public static final int UC_TRICORE_REG_A12 = 13; + public static final int UC_TRICORE_REG_A13 = 14; + public static final int UC_TRICORE_REG_A14 = 15; + public static final int UC_TRICORE_REG_A15 = 16; + public static final int UC_TRICORE_REG_D0 = 17; + public static final int UC_TRICORE_REG_D1 = 18; + public static final int UC_TRICORE_REG_D2 = 19; + public static final int UC_TRICORE_REG_D3 = 20; + public static final int UC_TRICORE_REG_D4 = 21; + public static final int UC_TRICORE_REG_D5 = 22; + public static final int UC_TRICORE_REG_D6 = 23; + public static final int UC_TRICORE_REG_D7 = 24; + public static final int UC_TRICORE_REG_D8 = 25; + public static final int UC_TRICORE_REG_D9 = 26; + public static final int UC_TRICORE_REG_D10 = 27; + public static final int UC_TRICORE_REG_D11 = 28; + public static final int UC_TRICORE_REG_D12 = 29; + public static final int UC_TRICORE_REG_D13 = 30; + public static final int UC_TRICORE_REG_D14 = 31; + public static final int UC_TRICORE_REG_D15 = 32; + public static final int UC_TRICORE_REG_PCXI = 33; + public static final int UC_TRICORE_REG_PSW = 34; + public static final int UC_TRICORE_REG_PSW_USB_C = 35; + public static final int UC_TRICORE_REG_PSW_USB_V = 36; + public static final int UC_TRICORE_REG_PSW_USB_SV = 37; + public static final int UC_TRICORE_REG_PSW_USB_AV = 38; + public static final int UC_TRICORE_REG_PSW_USB_SAV = 39; + public static final int UC_TRICORE_REG_PC = 40; + public static final int UC_TRICORE_REG_SYSCON = 41; + public static final int UC_TRICORE_REG_CPU_ID = 42; + public static final int UC_TRICORE_REG_BIV = 43; + public static final int UC_TRICORE_REG_BTV = 44; + public static final int UC_TRICORE_REG_ISP = 45; + public static final int UC_TRICORE_REG_ICR = 46; + public static final int UC_TRICORE_REG_FCX = 47; + public static final int UC_TRICORE_REG_LCX = 48; + public static final int UC_TRICORE_REG_COMPAT = 49; + public static final int UC_TRICORE_REG_DPR0_U = 50; + public static final int UC_TRICORE_REG_DPR1_U = 51; + public static final int UC_TRICORE_REG_DPR2_U = 52; + public static final int UC_TRICORE_REG_DPR3_U = 53; + public static final int UC_TRICORE_REG_DPR0_L = 54; + public static final int UC_TRICORE_REG_DPR1_L = 55; + public static final int UC_TRICORE_REG_DPR2_L = 56; + public static final int UC_TRICORE_REG_DPR3_L = 57; + public static final int UC_TRICORE_REG_CPR0_U = 58; + public static final int UC_TRICORE_REG_CPR1_U = 59; + public static final int UC_TRICORE_REG_CPR2_U = 60; + public static final int UC_TRICORE_REG_CPR3_U = 61; + public static final int UC_TRICORE_REG_CPR0_L = 62; + public static final int UC_TRICORE_REG_CPR1_L = 63; + public static final int UC_TRICORE_REG_CPR2_L = 64; + public static final int UC_TRICORE_REG_CPR3_L = 65; + public static final int UC_TRICORE_REG_DPM0 = 66; + public static final int UC_TRICORE_REG_DPM1 = 67; + public static final int UC_TRICORE_REG_DPM2 = 68; + public static final int UC_TRICORE_REG_DPM3 = 69; + public static final int UC_TRICORE_REG_CPM0 = 70; + public static final int UC_TRICORE_REG_CPM1 = 71; + public static final int UC_TRICORE_REG_CPM2 = 72; + public static final int UC_TRICORE_REG_CPM3 = 73; + public static final int UC_TRICORE_REG_MMU_CON = 74; + public static final int UC_TRICORE_REG_MMU_ASI = 75; + public static final int UC_TRICORE_REG_MMU_TVA = 76; + public static final int UC_TRICORE_REG_MMU_TPA = 77; + public static final int UC_TRICORE_REG_MMU_TPX = 78; + public static final int UC_TRICORE_REG_MMU_TFA = 79; + public static final int UC_TRICORE_REG_BMACON = 80; + public static final int UC_TRICORE_REG_SMACON = 81; + public static final int UC_TRICORE_REG_DIEAR = 82; + public static final int UC_TRICORE_REG_DIETR = 83; + public static final int UC_TRICORE_REG_CCDIER = 84; + public static final int UC_TRICORE_REG_MIECON = 85; + public static final int UC_TRICORE_REG_PIEAR = 86; + public static final int UC_TRICORE_REG_PIETR = 87; + public static final int UC_TRICORE_REG_CCPIER = 88; + public static final int UC_TRICORE_REG_DBGSR = 89; + public static final int UC_TRICORE_REG_EXEVT = 90; + public static final int UC_TRICORE_REG_CREVT = 91; + public static final int UC_TRICORE_REG_SWEVT = 92; + public static final int UC_TRICORE_REG_TR0EVT = 93; + public static final int UC_TRICORE_REG_TR1EVT = 94; + public static final int UC_TRICORE_REG_DMS = 95; + public static final int UC_TRICORE_REG_DCX = 96; + public static final int UC_TRICORE_REG_DBGTCR = 97; + public static final int UC_TRICORE_REG_CCTRL = 98; + public static final int UC_TRICORE_REG_CCNT = 99; + public static final int UC_TRICORE_REG_ICNT = 100; + public static final int UC_TRICORE_REG_M1CNT = 101; + public static final int UC_TRICORE_REG_M2CNT = 102; + public static final int UC_TRICORE_REG_M3CNT = 103; + public static final int UC_TRICORE_REG_ENDING = 104; + public static final int UC_TRICORE_REG_GA0 = 1; + public static final int UC_TRICORE_REG_GA1 = 2; + public static final int UC_TRICORE_REG_GA8 = 9; + public static final int UC_TRICORE_REG_GA9 = 10; + public static final int UC_TRICORE_REG_SP = 11; + public static final int UC_TRICORE_REG_LR = 12; + public static final int UC_TRICORE_REG_IA = 16; + public static final int UC_TRICORE_REG_ID = 32; } diff --git a/bindings/java/unicorn/Unicorn.java b/bindings/java/unicorn/Unicorn.java index 7e8aee05..e1477a48 100644 --- a/bindings/java/unicorn/Unicorn.java +++ b/bindings/java/unicorn/Unicorn.java @@ -21,811 +21,902 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. package unicorn; -import java.util.*; +import java.util.ArrayList; +import java.util.Hashtable; -public class Unicorn implements UnicornConst, ArmConst, Arm64Const, M68kConst, SparcConst, MipsConst, X86Const { +public class Unicorn + implements UnicornConst, ArmConst, Arm64Const, M68kConst, SparcConst, + MipsConst, X86Const { - public long eng; - private int arch; - private int mode; + public long eng; + private int arch; + private int mode; - private long blockHandle = 0; - private long interruptHandle = 0; - private long codeHandle = 0; + private long blockHandle = 0; + private long interruptHandle = 0; + private long codeHandle = 0; - private Hashtable eventMemHandles = new Hashtable(); - private long readInvalidHandle = 0; - private long writeInvalidHandle = 0; - private long fetchProtHandle = 0; - private long readProtHandle = 0; - private long writeProtHandle = 0; + private Hashtable eventMemHandles = + new Hashtable(); + private long readInvalidHandle = 0; + private long writeInvalidHandle = 0; + private long fetchProtHandle = 0; + private long readProtHandle = 0; + private long writeProtHandle = 0; - private long readHandle = 0; - private long writeHandle = 0; - private long inHandle = 0; - private long outHandle = 0; - private long syscallHandle = 0; + private long readHandle = 0; + private long writeHandle = 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 class Tuple { + public Hook function; + public Object data; - private ArrayList blockList = new ArrayList(); - private ArrayList intrList = new ArrayList(); - private ArrayList codeList = new ArrayList(); - private ArrayList readList = new ArrayList(); - private ArrayList writeList = new ArrayList(); - private ArrayList inList = new ArrayList(); - private ArrayList outList = new ArrayList(); - private ArrayList syscallList = new ArrayList(); + public Tuple(Hook f, Object d) { + function = f; + data = d; + } + } - private Hashtable > eventMemLists = new Hashtable >(); + private ArrayList blockList = new ArrayList(); + private ArrayList intrList = new ArrayList(); + private ArrayList codeList = new ArrayList(); + private ArrayList readList = new ArrayList(); + private ArrayList writeList = new ArrayList(); + private ArrayList inList = new ArrayList(); + private ArrayList outList = new ArrayList(); + private ArrayList syscallList = new ArrayList(); - private ArrayList> allLists = new ArrayList>(); + private Hashtable> eventMemLists = + new Hashtable>(); - private static Hashtable eventMemMap = new Hashtable(); - private static Hashtable unicorns = new Hashtable(); + private ArrayList> allLists = + new ArrayList>(); - //required to load native method implementations - static { - 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_WRITE_UNMAPPED, UC_MEM_WRITE_UNMAPPED); - eventMemMap.put(UC_HOOK_MEM_FETCH_UNMAPPED, UC_MEM_FETCH_UNMAPPED); - 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_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); - } + private static Hashtable eventMemMap = + new Hashtable(); + private static Hashtable unicorns = + new Hashtable(); -/** - * 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 eng A Unicorn uc_engine* eng 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 - */ + // required to load native method implementations + static { + 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_WRITE_UNMAPPED, UC_MEM_WRITE_UNMAPPED); + eventMemMap.put(UC_HOOK_MEM_FETCH_UNMAPPED, UC_MEM_FETCH_UNMAPPED); + 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_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. + * This function gets invoked from the native C callback registered for + * for UC_HOOK_BLOCK + * + * @param eng A Unicorn uc_engine* eng 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 eng, long address, int size) { - Unicorn u = unicorns.get(eng); - 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 eng A Unicorn uc_engine* eng returned by uc_open - * @param intno The interrupt number - * @see hook_add, unicorn.InterruptHook - */ - private static void invokeInterruptCallbacks(long eng, int intno) { - Unicorn u = unicorns.get(eng); - 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 eng A Unicorn uc_engine* eng 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 eng, long address, int size) { - Unicorn u = unicorns.get(eng); - 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_XXX_UNMAPPED and/or UC_HOOK_MEM_XXX_PROT callbacks registered - * for a specific Unicorn. - * This function gets invoked from the native C callback registered for - * for UC_HOOK_MEM_XXX_UNMAPPED or UC_HOOK_MEM_XXX_PROT - * - * @param eng A Unicorn uc_engine* eng returned by uc_open - * @param type The type of event that is taking place - * @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.EventMemHook - */ - private static boolean invokeEventMemCallbacks(long eng, int type, long address, int size, long value) { - Unicorn u = unicorns.get(eng); - boolean result = true; - if (u != null) { - ArrayList funcList = u.eventMemLists.get(type); - if (funcList != null) { - for (Tuple p : funcList) { - EventMemHook emh = (EventMemHook)p.function; - result &= emh.hook(u, address, size, value, p.data); + Unicorn u = unicorns.get(eng); + if (u != null) { + for (Tuple p : u.blockList) { + BlockHook bh = (BlockHook) p.function; + bh.hook(u, address, size, 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 eng A Unicorn uc_engine* eng 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 eng, long address, int size) { - Unicorn u = unicorns.get(eng); - 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 eng A Unicorn uc_engine* eng 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 eng, long address, int size, long value) { - Unicorn u = unicorns.get(eng); - 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_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 eng A Unicorn uc_engine* eng 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 eng, int port, int size) { - Unicorn u = unicorns.get(eng); - 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 eng A Unicorn uc_engine* eng 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 eng, int port, int size, int value) { - Unicorn u = unicorns.get(eng); - 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 eng A Unicorn uc_engine* eng returned by uc_open - * @see hook_add, unicorn.SyscallHook - */ - private static void invokeSyscallCallbacks(long eng) { - Unicorn u = unicorns.get(eng); - int result = 0; - if (u != null) { - for (Tuple p : u.syscallList) { - SyscallHook sh = (SyscallHook)p.function; - sh.hook(u, p.data); - } - } - } - -/** - * Write to register. - * - * @param regid Register ID that is to be modified. - * @param value Number containing the new register value - */ - private native void reg_write_num(int regid, Number value) throws UnicornException; - -/** - * Write to register. - * - * @param regid Register ID that is to be modified. - * @param value X86 specific memory management register containing the new register value - */ - private native void reg_write_mmr(int regid, X86_MMR value) throws UnicornException; - -/** - * Read register value. - * - * @param regid Register ID that is to be retrieved. - * @return Number containing the requested register value. - */ - private native Number reg_read_num(int regid) throws UnicornException; - -/** - * Read register value. - * - * @param regid Register ID that is to be retrieved. - * @return X86_MMR containing the requested register value. - */ - private native Number reg_read_mmr(int regid) throws UnicornException; - -/** - * 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; - -/** - * Create a new Unicorn object - * - * @param arch Architecture type (UC_ARCH_*) - * @param mode Hardware mode. This is combined of UC_MODE_* - * @see unicorn.UnicornConst - * - */ - public Unicorn(int arch, int mode) throws UnicornException { - //remember these in case we need arch specific code - this.arch = arch; - this.mode = mode; - eng = open(arch, mode); - unicorns.put(eng, this); - allLists.add(blockList); - allLists.add(intrList); - allLists.add(codeList); - allLists.add(readList); - allLists.add(writeList); - allLists.add(inList); - allLists.add(outList); - allLists.add(syscallList); - } - -/** - * Perform native cleanup tasks associated with a Unicorn object - * - */ - protected void finalize() { - unicorns.remove(eng); - 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.UnicornConst - */ - public native static boolean arch_supported(int arch); - -/** - * Close the underlying uc_engine* eng associated with this Unicorn object - * - */ - public native void close() throws UnicornException; - -/** - * Query internal status of engine. - * - * @param type query type. See UC_QUERY_* - * @param result save the internal status queried - * - * @return: error code. see UC_ERR_* - * @see unicorn.UnicornConst - */ - public native int query(int type) 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.UnicornConst - */ - 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.UnicornConst - */ - public native static String strerror(int code); - -/** - * Write to register. - * - * @deprecated use reg_write(int regid, Object value) instead - * @param regid Register ID that is to be modified. - * @param value Array containing value that will be written into register @regid - */ -@Deprecated - public native void reg_write(int regid, byte[] value) throws UnicornException; - -/** - * Write to register. - * - * @param regid Register ID that is to be modified. - * @param value Object containing the new register value. Long, BigInteger, or - * other custom class used to represent register values - */ - public void reg_write(int regid, Object value) throws UnicornException { - if (value instanceof Number) { - reg_write_num(regid, (Number)value); - } - else if (arch == UC_ARCH_X86 && value instanceof X86_MMR) { - if (regid >= UC_X86_REG_IDTR && regid <= UC_X86_REG_TR) { - reg_write_mmr(regid, (X86_MMR)value); - } - } - else { - throw new ClassCastException("Invalid value type"); - } - } - -/** - * Read register value. - * - * @deprecated use Object reg_read(int regid) instead - * @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. - */ -@Deprecated - public native byte[] reg_read(int regid, int regsz) throws UnicornException; - -/** - * Read register value. - * - * @param regid Register ID that is to be retrieved. - * @return Object containing the requested register value. Long, BigInteger, or - * other custom class used to represent register values - */ - public Object reg_read(int regid) throws UnicornException { - if (arch == UC_ARCH_X86 && regid >= UC_X86_REG_IDTR && regid <= UC_X86_REG_TR) { - return reg_read_mmr(regid); - } - else { - return reg_read_num(regid); - } - } - -/** - * 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. - * - * @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 eng Internal unicorn uc_engine* eng 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 eng, int type); - -/** - * Hook registration helper for hook types that require one additional argument. - * - * @param eng Internal unicorn uc_engine* eng 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 eng, int type, int arg1); - -/** - * Hook registration helper for hook types that require two additional arguments. - * - * @param eng Internal unicorn uc_engine* eng 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 eng, 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(eng, 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(eng, 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(eng, 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(eng, 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(eng, UC_HOOK_MEM_WRITE, begin, end); - } - 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 - * invoked whenever a memory write or read is performed within the address range begin <= addr <= end. For - * the special case in which begin > end, the callback will be invoked for ALL memory writes. - * - * @param callback Implementation of a MemHook interface - * @param begin Start address of memory range - * @param end End address of memory range - * @param user_data User data to be passed to the callback function each time the event is triggered - */ - public void hook_add(MemHook callback, long begin, long end, Object user_data) throws UnicornException { - hook_add((ReadHook)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. - * The registered callback function will be invoked whenever a read or write is - * attempted from an invalid or protected memory address. - * - * @param callback Implementation of a EventMemHook interface - * @param type Type of memory event being hooked such as UC_HOOK_MEM_READ_UNMAPPED or UC_HOOK_MEM_WRITE_PROT - * @param user_data User data to be passed to the callback function each time the event is triggered - */ - public void hook_add(EventMemHook callback, int type, Object user_data) throws UnicornException { - //test all of the EventMem related bits in type - for (Integer htype : eventMemMap.keySet()) { - if ((type & htype) != 0) { //the 'htype' bit is set in type - Long handle = eventMemHandles.get(htype); - if (handle == null) { - eventMemHandles.put(htype, registerHook(eng, htype)); + /** + * 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 eng A Unicorn uc_engine* eng returned by uc_open + * @param intno The interrupt number + * @see hook_add, unicorn.InterruptHook + */ + private static void invokeInterruptCallbacks(long eng, int intno) { + Unicorn u = unicorns.get(eng); + if (u != null) { + for (Tuple p : u.intrList) { + InterruptHook ih = (InterruptHook) p.function; + ih.hook(u, intno, p.data); } - int cbType = eventMemMap.get(htype); - ArrayList flist = eventMemLists.get(cbType); - if (flist == null) { - flist = new ArrayList(); - allLists.add(flist); - eventMemLists.put(cbType, flist); + } + } + + /** + * 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 eng A Unicorn uc_engine* eng 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 eng, long address, int size) { + Unicorn u = unicorns.get(eng); + if (u != null) { + for (Tuple p : u.codeList) { + CodeHook ch = (CodeHook) p.function; + ch.hook(u, address, size, p.data); } - flist.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(eng, 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(eng, 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(eng, 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 l : allLists) { - for (Tuple t : l) { - if (t.function.equals(hook)) { - allLists.remove(t); - return; + /** + * Invoke all UC_HOOK_MEM_XXX_UNMAPPED and/or UC_HOOK_MEM_XXX_PROT callbacks + * registered + * for a specific Unicorn. + * This function gets invoked from the native C callback registered for + * for UC_HOOK_MEM_XXX_UNMAPPED or UC_HOOK_MEM_XXX_PROT + * + * @param eng A Unicorn uc_engine* eng returned by uc_open + * @param type The type of event that is taking place + * @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.EventMemHook + */ + private static boolean invokeEventMemCallbacks(long eng, int type, + long address, int size, + long value) { + Unicorn u = unicorns.get(eng); + boolean result = true; + if (u != null) { + ArrayList funcList = u.eventMemLists.get(type); + if (funcList != null) { + for (Tuple p : funcList) { + EventMemHook emh = (EventMemHook) p.function; + result &= emh.hook(u, address, size, value, p.data); + } } - } - } - } + } + return result; + } -/** - * Map a range of memory. - * - * @param address Base address of the memory range - * @param size Size of the memory block. - * @param perms Permissions on the memory block. A combination of UC_PROT_READ, UC_PROT_WRITE, UC_PROT_EXEC - */ - public native void mem_map(long address, long size, int perms) throws UnicornException; + /** + * 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 eng A Unicorn uc_engine* eng 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 eng, long address, int size) { + Unicorn u = unicorns.get(eng); + if (u != null) { + for (Tuple p : u.readList) { + ReadHook rh = (ReadHook) p.function; + rh.hook(u, address, size, p.data); + } + } + } -/** - * Map existing host memory in for emulation. - * This API adds a memory region that can be used by emulation. - * - * @param address Base address of the memory range - * @param size Size of the memory block. - * @param perms Permissions on the memory block. A combination of UC_PROT_READ, UC_PROT_WRITE, UC_PROT_EXEC - * @param ptr Block of host memory backing the newly mapped memory. This block is - * expected to be an equal or larger size than provided, and be mapped with at - * least PROT_READ | PROT_WRITE. If it is not, the resulting behavior is undefined. - */ - public native void mem_map_ptr(long address, long size, int perms, byte[] block) throws UnicornException; + /** + * 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 eng A Unicorn uc_engine* eng 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 eng, long address, int size, + long value) { + Unicorn u = unicorns.get(eng); + if (u != null) { + for (Tuple p : u.writeList) { + WriteHook wh = (WriteHook) p.function; + wh.hook(u, address, size, value, p.data); + } + } + } -/** - * Unmap a range of memory. - * - * @param address Base address of the memory range - * @param size Size of the memory block. - */ - public native void mem_unmap(long address, long size) throws UnicornException; + /** + * 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 eng A Unicorn uc_engine* eng 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 eng, int port, int size) { + Unicorn u = unicorns.get(eng); + 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; + } -/** - * Change permissions on a range of memory. - * - * @param address Base address of the memory range - * @param size Size of the memory block. - * @param perms New permissions on the memory block. A combination of UC_PROT_READ, UC_PROT_WRITE, UC_PROT_EXEC - */ - public native void mem_protect(long address, long size, int perms) throws UnicornException; + /** + * 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 eng A Unicorn uc_engine* eng 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 eng, int port, int size, + int value) { + Unicorn u = unicorns.get(eng); + int result = 0; + if (u != null) { + for (Tuple p : u.outList) { + OutHook oh = (OutHook) p.function; + oh.hook(u, port, size, value, p.data); + } + } + } -/** - * Retrieve all memory regions mapped by mem_map() and mem_map_ptr() - * NOTE: memory regions may be split by mem_unmap() - * - * @return list of mapped regions. -*/ - public native MemRegion[] mem_regions() throws UnicornException; + /** + * 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 eng A Unicorn uc_engine* eng returned by uc_open + * @see hook_add, unicorn.SyscallHook + */ + private static void invokeSyscallCallbacks(long eng) { + Unicorn u = unicorns.get(eng); + int result = 0; + if (u != null) { + for (Tuple p : u.syscallList) { + SyscallHook sh = (SyscallHook) p.function; + sh.hook(u, p.data); + } + } + } -/** - * 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(); + /** + * Write to register. + * + * @param regid Register ID that is to be modified. + * @param value Number containing the new register value + */ + private native void reg_write_num(int regid, Number value) + throws UnicornException; -/** - * Free a resource allocated within Unicorn. Use for handles - * allocated by context_alloc. - * - * @param Previously allocated Unicorn object handle. -*/ - public native void free(long handle); + /** + * Write to register. + * + * @param regid Register ID that is to be modified. + * @param value X86 specific memory management register containing the new + * register value + */ + private native void reg_write_mmr(int regid, X86_MMR value) + throws UnicornException; -/** - * 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); + /** + * Read register value. + * + * @param regid Register ID that is to be retrieved. + * @return Number containing the requested register value. + */ + private native Number reg_read_num(int regid) throws UnicornException; -/** - * 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); + /** + * Read register value. + * + * @param regid Register ID that is to be retrieved. + * @return X86_MMR containing the requested register value. + */ + private native Number reg_read_mmr(int regid) throws UnicornException; - /** - * Set the emulated cpu model. - * - * @param cpu_model CPU model type (see UC_CPU_*). -*/ - public native void ctl_set_cpu_model(int cpu_model); + /** + * 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; + + /** + * Create a new Unicorn object + * + * @param arch Architecture type (UC_ARCH_*) + * @param mode Hardware mode. This is combined of UC_MODE_* + * @see unicorn.UnicornConst + * + */ + public Unicorn(int arch, int mode) throws UnicornException { + // remember these in case we need arch specific code + this.arch = arch; + this.mode = mode; + eng = open(arch, mode); + unicorns.put(eng, this); + allLists.add(blockList); + allLists.add(intrList); + allLists.add(codeList); + allLists.add(readList); + allLists.add(writeList); + allLists.add(inList); + allLists.add(outList); + allLists.add(syscallList); + } + + /** + * Perform native cleanup tasks associated with a Unicorn object + * + */ + protected void finalize() { + unicorns.remove(eng); + 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.UnicornConst + */ + public native static boolean arch_supported(int arch); + + /** + * Close the underlying uc_engine* eng associated with this Unicorn object + * + */ + public native void close() throws UnicornException; + + /** + * Query internal status of engine. + * + * @param type query type. See UC_QUERY_* + * @param result save the internal status queried + * + * @return: error code. see UC_ERR_* + * @see unicorn.UnicornConst + */ + public native int query(int type) 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.UnicornConst + */ + 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.UnicornConst + */ + public native static String strerror(int code); + + /** + * Write to register. + * + * @deprecated use reg_write(int regid, Object value) instead + * @param regid Register ID that is to be modified. + * @param value Array containing value that will be written into register @regid + */ + @Deprecated + public native void reg_write(int regid, byte[] value) + throws UnicornException; + + /** + * Write to register. + * + * @param regid Register ID that is to be modified. + * @param value Object containing the new register value. Long, BigInteger, or + * other custom class used to represent register values + */ + public void reg_write(int regid, Object value) throws UnicornException { + if (value instanceof Number) { + reg_write_num(regid, (Number) value); + } else if (arch == UC_ARCH_X86 && value instanceof X86_MMR) { + if (regid >= UC_X86_REG_IDTR && regid <= UC_X86_REG_TR) { + reg_write_mmr(regid, (X86_MMR) value); + } + } else { + throw new ClassCastException("Invalid value type"); + } + } + + /** + * Read register value. + * + * @deprecated use Object reg_read(int regid) instead + * @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. + */ + @Deprecated + public native byte[] reg_read(int regid, int regsz) throws UnicornException; + + /** + * Read register value. + * + * @param regid Register ID that is to be retrieved. + * @return Object containing the requested register value. Long, BigInteger, or + * other custom class used to represent register values + */ + public Object reg_read(int regid) throws UnicornException { + if (arch == UC_ARCH_X86 && regid >= UC_X86_REG_IDTR && + regid <= UC_X86_REG_TR) { + return reg_read_mmr(regid); + } else { + return reg_read_num(regid); + } + } + + /** + * 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. + * + * @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 eng Internal unicorn uc_engine* eng 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 eng, int type); + + /** + * Hook registration helper for hook types that require one additional argument. + * + * @param eng Internal unicorn uc_engine* eng 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 eng, int type, int arg1); + + /** + * Hook registration helper for hook types that require two additional + * arguments. + * + * @param eng Internal unicorn uc_engine* eng 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 eng, 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(eng, 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(eng, 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(eng, 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(eng, 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(eng, UC_HOOK_MEM_WRITE, begin, end); + } + 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 + * invoked whenever a memory write or read is performed within the address range + * begin <= addr <= end. For + * the special case in which begin > end, the callback will be invoked for ALL + * memory writes. + * + * @param callback Implementation of a MemHook interface + * @param begin Start address of memory range + * @param end End address of memory range + * @param user_data User data to be passed to the callback function each time + * the event is triggered + */ + public void hook_add(MemHook callback, long begin, long end, + Object user_data) + throws UnicornException { + hook_add((ReadHook) 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. + * The registered callback function will be invoked whenever a read or write is + * attempted from an invalid or protected memory address. + * + * @param callback Implementation of a EventMemHook interface + * @param type Type of memory event being hooked such as + * UC_HOOK_MEM_READ_UNMAPPED or UC_HOOK_MEM_WRITE_PROT + * @param user_data User data to be passed to the callback function each time + * the event is triggered + */ + public void hook_add(EventMemHook callback, int type, Object user_data) + throws UnicornException { + // test all of the EventMem related bits in type + for (Integer htype : eventMemMap.keySet()) { + if ((type & htype) != 0) { // the 'htype' bit is set in type + Long handle = eventMemHandles.get(htype); + if (handle == null) { + eventMemHandles.put(htype, registerHook(eng, htype)); + } + int cbType = eventMemMap.get(htype); + ArrayList flist = eventMemLists.get(cbType); + if (flist == null) { + flist = new ArrayList(); + allLists.add(flist); + eventMemLists.put(cbType, flist); + } + flist.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(eng, 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(eng, 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(eng, 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 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. + * @param perms Permissions on the memory block. A combination of + * UC_PROT_READ, UC_PROT_WRITE, UC_PROT_EXEC + */ + public native void mem_map(long address, long size, int perms) + throws UnicornException; + + /** + * Map existing host memory in for emulation. + * This API adds a memory region that can be used by emulation. + * + * @param address Base address of the memory range + * @param size Size of the memory block. + * @param perms Permissions on the memory block. A combination of + * UC_PROT_READ, UC_PROT_WRITE, UC_PROT_EXEC + * @param ptr Block of host memory backing the newly mapped memory. This + * block is + * expected to be an equal or larger size than provided, and be + * mapped with at + * least PROT_READ | PROT_WRITE. If it is not, the resulting + * behavior is undefined. + */ + public native void mem_map_ptr(long address, long size, int perms, + byte[] block) + throws UnicornException; + + /** + * Unmap a range of memory. + * + * @param address Base address of the memory range + * @param size Size of the memory block. + */ + public native void mem_unmap(long address, long size) + throws UnicornException; + + /** + * Change permissions on a range of memory. + * + * @param address Base address of the memory range + * @param size Size of the memory block. + * @param perms New permissions on the memory block. A combination of + * UC_PROT_READ, UC_PROT_WRITE, UC_PROT_EXEC + */ + public native void mem_protect(long address, long size, int perms) + throws UnicornException; + + /** + * Retrieve all memory regions mapped by mem_map() and mem_map_ptr() + * NOTE: memory regions may be split by mem_unmap() + * + * @return list of mapped regions. + */ + 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 a resource allocated within Unicorn. Use for handles + * allocated by context_alloc. + * + * @param Previously allocated Unicorn object handle. + */ + public native void free(long handle); + + /** + * 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); + + /** + * Set the emulated cpu model. + * + * @param cpu_model CPU model type (see UC_CPU_*). + */ + public native void ctl_set_cpu_model(int cpu_model); } - diff --git a/bindings/java/unicorn/UnicornConst.java b/bindings/java/unicorn/UnicornConst.java index afd0580e..24d58c26 100644 --- a/bindings/java/unicorn/UnicornConst.java +++ b/bindings/java/unicorn/UnicornConst.java @@ -3,150 +3,150 @@ package unicorn; public interface UnicornConst { - public static final int UC_API_MAJOR = 2; + public static final int UC_API_MAJOR = 2; - public static final int UC_API_MINOR = 0; - public static final int UC_API_PATCH = 2; - public static final int UC_API_EXTRA = 1; - public static final int UC_VERSION_MAJOR = 2; + public static final int UC_API_MINOR = 0; + public static final int UC_API_PATCH = 2; + public static final int UC_API_EXTRA = 1; + public static final int UC_VERSION_MAJOR = 2; - public static final int UC_VERSION_MINOR = 0; - public static final int UC_VERSION_PATCH = 2; - public static final int UC_VERSION_EXTRA = 1; - public static final int UC_SECOND_SCALE = 1000000; - public static final int UC_MILISECOND_SCALE = 1000; - public static final int UC_ARCH_ARM = 1; - public static final int UC_ARCH_ARM64 = 2; - public static final int UC_ARCH_MIPS = 3; - public static final int UC_ARCH_X86 = 4; - public static final int UC_ARCH_PPC = 5; - public static final int UC_ARCH_SPARC = 6; - public static final int UC_ARCH_M68K = 7; - public static final int UC_ARCH_RISCV = 8; - public static final int UC_ARCH_S390X = 9; - public static final int UC_ARCH_TRICORE = 10; - public static final int UC_ARCH_MAX = 11; + public static final int UC_VERSION_MINOR = 0; + public static final int UC_VERSION_PATCH = 2; + public static final int UC_VERSION_EXTRA = 1; + public static final int UC_SECOND_SCALE = 1000000; + public static final int UC_MILISECOND_SCALE = 1000; + public static final int UC_ARCH_ARM = 1; + public static final int UC_ARCH_ARM64 = 2; + public static final int UC_ARCH_MIPS = 3; + public static final int UC_ARCH_X86 = 4; + public static final int UC_ARCH_PPC = 5; + public static final int UC_ARCH_SPARC = 6; + public static final int UC_ARCH_M68K = 7; + public static final int UC_ARCH_RISCV = 8; + public static final int UC_ARCH_S390X = 9; + public static final int UC_ARCH_TRICORE = 10; + public static final int UC_ARCH_MAX = 11; - public static final int UC_MODE_LITTLE_ENDIAN = 0; - public static final int UC_MODE_BIG_ENDIAN = 1073741824; + public static final int UC_MODE_LITTLE_ENDIAN = 0; + public static final int UC_MODE_BIG_ENDIAN = 1073741824; - public static final int UC_MODE_ARM = 0; - public static final int UC_MODE_THUMB = 16; - public static final int UC_MODE_MCLASS = 32; - public static final int UC_MODE_V8 = 64; - public static final int UC_MODE_ARMBE8 = 1024; - public static final int UC_MODE_ARM926 = 128; - public static final int UC_MODE_ARM946 = 256; - public static final int UC_MODE_ARM1176 = 512; - public static final int UC_MODE_MICRO = 16; - public static final int UC_MODE_MIPS3 = 32; - public static final int UC_MODE_MIPS32R6 = 64; - public static final int UC_MODE_MIPS32 = 4; - public static final int UC_MODE_MIPS64 = 8; - public static final int UC_MODE_16 = 2; - public static final int UC_MODE_32 = 4; - public static final int UC_MODE_64 = 8; - public static final int UC_MODE_PPC32 = 4; - public static final int UC_MODE_PPC64 = 8; - public static final int UC_MODE_QPX = 16; - public static final int UC_MODE_SPARC32 = 4; - public static final int UC_MODE_SPARC64 = 8; - public static final int UC_MODE_V9 = 16; - public static final int UC_MODE_RISCV32 = 4; - public static final int UC_MODE_RISCV64 = 8; + public static final int UC_MODE_ARM = 0; + public static final int UC_MODE_THUMB = 16; + public static final int UC_MODE_MCLASS = 32; + public static final int UC_MODE_V8 = 64; + public static final int UC_MODE_ARMBE8 = 1024; + public static final int UC_MODE_ARM926 = 128; + public static final int UC_MODE_ARM946 = 256; + public static final int UC_MODE_ARM1176 = 512; + public static final int UC_MODE_MICRO = 16; + public static final int UC_MODE_MIPS3 = 32; + public static final int UC_MODE_MIPS32R6 = 64; + public static final int UC_MODE_MIPS32 = 4; + public static final int UC_MODE_MIPS64 = 8; + public static final int UC_MODE_16 = 2; + public static final int UC_MODE_32 = 4; + public static final int UC_MODE_64 = 8; + public static final int UC_MODE_PPC32 = 4; + public static final int UC_MODE_PPC64 = 8; + public static final int UC_MODE_QPX = 16; + public static final int UC_MODE_SPARC32 = 4; + public static final int UC_MODE_SPARC64 = 8; + public static final int UC_MODE_V9 = 16; + public static final int UC_MODE_RISCV32 = 4; + public static final int UC_MODE_RISCV64 = 8; - public static final int UC_ERR_OK = 0; - public static final int UC_ERR_NOMEM = 1; - public static final int UC_ERR_ARCH = 2; - public static final int UC_ERR_HANDLE = 3; - public static final int UC_ERR_MODE = 4; - public static final int UC_ERR_VERSION = 5; - public static final int UC_ERR_READ_UNMAPPED = 6; - public static final int UC_ERR_WRITE_UNMAPPED = 7; - public static final int UC_ERR_FETCH_UNMAPPED = 8; - public static final int UC_ERR_HOOK = 9; - public static final int UC_ERR_INSN_INVALID = 10; - public static final int UC_ERR_MAP = 11; - public static final int UC_ERR_WRITE_PROT = 12; - public static final int UC_ERR_READ_PROT = 13; - public static final int UC_ERR_FETCH_PROT = 14; - public static final int UC_ERR_ARG = 15; - public static final int UC_ERR_READ_UNALIGNED = 16; - public static final int UC_ERR_WRITE_UNALIGNED = 17; - public static final int UC_ERR_FETCH_UNALIGNED = 18; - public static final int UC_ERR_HOOK_EXIST = 19; - public static final int UC_ERR_RESOURCE = 20; - public static final int UC_ERR_EXCEPTION = 21; - public static final int UC_MEM_READ = 16; - public static final int UC_MEM_WRITE = 17; - public static final int UC_MEM_FETCH = 18; - public static final int UC_MEM_READ_UNMAPPED = 19; - public static final int UC_MEM_WRITE_UNMAPPED = 20; - public static final int UC_MEM_FETCH_UNMAPPED = 21; - public static final int UC_MEM_WRITE_PROT = 22; - public static final int UC_MEM_READ_PROT = 23; - public static final int UC_MEM_FETCH_PROT = 24; - public static final int UC_MEM_READ_AFTER = 25; + public static final int UC_ERR_OK = 0; + public static final int UC_ERR_NOMEM = 1; + public static final int UC_ERR_ARCH = 2; + public static final int UC_ERR_HANDLE = 3; + public static final int UC_ERR_MODE = 4; + public static final int UC_ERR_VERSION = 5; + public static final int UC_ERR_READ_UNMAPPED = 6; + public static final int UC_ERR_WRITE_UNMAPPED = 7; + public static final int UC_ERR_FETCH_UNMAPPED = 8; + public static final int UC_ERR_HOOK = 9; + public static final int UC_ERR_INSN_INVALID = 10; + public static final int UC_ERR_MAP = 11; + public static final int UC_ERR_WRITE_PROT = 12; + public static final int UC_ERR_READ_PROT = 13; + public static final int UC_ERR_FETCH_PROT = 14; + public static final int UC_ERR_ARG = 15; + public static final int UC_ERR_READ_UNALIGNED = 16; + public static final int UC_ERR_WRITE_UNALIGNED = 17; + public static final int UC_ERR_FETCH_UNALIGNED = 18; + public static final int UC_ERR_HOOK_EXIST = 19; + public static final int UC_ERR_RESOURCE = 20; + public static final int UC_ERR_EXCEPTION = 21; + public static final int UC_MEM_READ = 16; + public static final int UC_MEM_WRITE = 17; + public static final int UC_MEM_FETCH = 18; + public static final int UC_MEM_READ_UNMAPPED = 19; + public static final int UC_MEM_WRITE_UNMAPPED = 20; + public static final int UC_MEM_FETCH_UNMAPPED = 21; + public static final int UC_MEM_WRITE_PROT = 22; + public static final int UC_MEM_READ_PROT = 23; + public static final int UC_MEM_FETCH_PROT = 24; + public static final int UC_MEM_READ_AFTER = 25; - public static final int UC_TCG_OP_SUB = 0; - public static final int UC_TCG_OP_FLAG_CMP = 1; - public static final int UC_TCG_OP_FLAG_DIRECT = 2; - public static final int UC_HOOK_INTR = 1; - public static final int UC_HOOK_INSN = 2; - public static final int UC_HOOK_CODE = 4; - public static final int UC_HOOK_BLOCK = 8; - public static final int UC_HOOK_MEM_READ_UNMAPPED = 16; - public static final int UC_HOOK_MEM_WRITE_UNMAPPED = 32; - public static final int UC_HOOK_MEM_FETCH_UNMAPPED = 64; - public static final int UC_HOOK_MEM_READ_PROT = 128; - public static final int UC_HOOK_MEM_WRITE_PROT = 256; - public static final int UC_HOOK_MEM_FETCH_PROT = 512; - public static final int UC_HOOK_MEM_READ = 1024; - public static final int UC_HOOK_MEM_WRITE = 2048; - public static final int UC_HOOK_MEM_FETCH = 4096; - public static final int UC_HOOK_MEM_READ_AFTER = 8192; - public static final int UC_HOOK_INSN_INVALID = 16384; - public static final int UC_HOOK_EDGE_GENERATED = 32768; - public static final int UC_HOOK_TCG_OPCODE = 65536; - public static final int UC_HOOK_TLB_FILL = 131072; - public static final int UC_HOOK_MEM_UNMAPPED = 112; - public static final int UC_HOOK_MEM_PROT = 896; - public static final int UC_HOOK_MEM_READ_INVALID = 144; - public static final int UC_HOOK_MEM_WRITE_INVALID = 288; - public static final int UC_HOOK_MEM_FETCH_INVALID = 576; - public static final int UC_HOOK_MEM_INVALID = 1008; - public static final int UC_HOOK_MEM_VALID = 7168; - public static final int UC_QUERY_MODE = 1; - public static final int UC_QUERY_PAGE_SIZE = 2; - public static final int UC_QUERY_ARCH = 3; - public static final int UC_QUERY_TIMEOUT = 4; + public static final int UC_TCG_OP_SUB = 0; + public static final int UC_TCG_OP_FLAG_CMP = 1; + public static final int UC_TCG_OP_FLAG_DIRECT = 2; + public static final int UC_HOOK_INTR = 1; + public static final int UC_HOOK_INSN = 2; + public static final int UC_HOOK_CODE = 4; + public static final int UC_HOOK_BLOCK = 8; + public static final int UC_HOOK_MEM_READ_UNMAPPED = 16; + public static final int UC_HOOK_MEM_WRITE_UNMAPPED = 32; + public static final int UC_HOOK_MEM_FETCH_UNMAPPED = 64; + public static final int UC_HOOK_MEM_READ_PROT = 128; + public static final int UC_HOOK_MEM_WRITE_PROT = 256; + public static final int UC_HOOK_MEM_FETCH_PROT = 512; + public static final int UC_HOOK_MEM_READ = 1024; + public static final int UC_HOOK_MEM_WRITE = 2048; + public static final int UC_HOOK_MEM_FETCH = 4096; + public static final int UC_HOOK_MEM_READ_AFTER = 8192; + public static final int UC_HOOK_INSN_INVALID = 16384; + public static final int UC_HOOK_EDGE_GENERATED = 32768; + public static final int UC_HOOK_TCG_OPCODE = 65536; + public static final int UC_HOOK_TLB_FILL = 131072; + public static final int UC_HOOK_MEM_UNMAPPED = 112; + public static final int UC_HOOK_MEM_PROT = 896; + public static final int UC_HOOK_MEM_READ_INVALID = 144; + public static final int UC_HOOK_MEM_WRITE_INVALID = 288; + public static final int UC_HOOK_MEM_FETCH_INVALID = 576; + public static final int UC_HOOK_MEM_INVALID = 1008; + public static final int UC_HOOK_MEM_VALID = 7168; + public static final int UC_QUERY_MODE = 1; + public static final int UC_QUERY_PAGE_SIZE = 2; + public static final int UC_QUERY_ARCH = 3; + public static final int UC_QUERY_TIMEOUT = 4; - public static final int UC_CTL_IO_NONE = 0; - public static final int UC_CTL_IO_WRITE = 1; - public static final int UC_CTL_IO_READ = 2; - public static final int UC_CTL_IO_READ_WRITE = 3; + public static final int UC_CTL_IO_NONE = 0; + public static final int UC_CTL_IO_WRITE = 1; + public static final int UC_CTL_IO_READ = 2; + public static final int UC_CTL_IO_READ_WRITE = 3; - public static final int UC_TLB_CPU = 0; - public static final int UC_TLB_VIRTUAL = 1; + public static final int UC_TLB_CPU = 0; + public static final int UC_TLB_VIRTUAL = 1; - public static final int UC_CTL_UC_MODE = 0; - public static final int UC_CTL_UC_PAGE_SIZE = 1; - public static final int UC_CTL_UC_ARCH = 2; - public static final int UC_CTL_UC_TIMEOUT = 3; - public static final int UC_CTL_UC_USE_EXITS = 4; - public static final int UC_CTL_UC_EXITS_CNT = 5; - public static final int UC_CTL_UC_EXITS = 6; - public static final int UC_CTL_CPU_MODEL = 7; - public static final int UC_CTL_TB_REQUEST_CACHE = 8; - public static final int UC_CTL_TB_REMOVE_CACHE = 9; - public static final int UC_CTL_TB_FLUSH = 10; - public static final int UC_CTL_TLB_FLUSH = 11; - public static final int UC_CTL_TLB_TYPE = 12; + public static final int UC_CTL_UC_MODE = 0; + public static final int UC_CTL_UC_PAGE_SIZE = 1; + public static final int UC_CTL_UC_ARCH = 2; + public static final int UC_CTL_UC_TIMEOUT = 3; + public static final int UC_CTL_UC_USE_EXITS = 4; + public static final int UC_CTL_UC_EXITS_CNT = 5; + public static final int UC_CTL_UC_EXITS = 6; + public static final int UC_CTL_CPU_MODEL = 7; + public static final int UC_CTL_TB_REQUEST_CACHE = 8; + public static final int UC_CTL_TB_REMOVE_CACHE = 9; + public static final int UC_CTL_TB_FLUSH = 10; + public static final int UC_CTL_TLB_FLUSH = 11; + public static final int UC_CTL_TLB_TYPE = 12; - public static final int UC_PROT_NONE = 0; - public static final int UC_PROT_READ = 1; - public static final int UC_PROT_WRITE = 2; - public static final int UC_PROT_EXEC = 4; - public static final int UC_PROT_ALL = 7; + public static final int UC_PROT_NONE = 0; + public static final int UC_PROT_READ = 1; + public static final int UC_PROT_WRITE = 2; + public static final int UC_PROT_EXEC = 4; + public static final int UC_PROT_ALL = 7; } diff --git a/bindings/java/unicorn/UnicornException.java b/bindings/java/unicorn/UnicornException.java index 175775c2..84777fc3 100644 --- a/bindings/java/unicorn/UnicornException.java +++ b/bindings/java/unicorn/UnicornException.java @@ -22,13 +22,11 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. package unicorn; public class UnicornException extends RuntimeException { + public UnicornException() { + super(); + } - public UnicornException() { - super(); - } - - public UnicornException(String msg) { - super(msg); - } - + public UnicornException(String msg) { + super(msg); + } } diff --git a/bindings/java/unicorn/WriteHook.java b/bindings/java/unicorn/WriteHook.java index ee0f79c4..25c0208a 100644 --- a/bindings/java/unicorn/WriteHook.java +++ b/bindings/java/unicorn/WriteHook.java @@ -22,8 +22,6 @@ 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); - + public void hook(Unicorn u, long address, int size, long value, + Object user); } - diff --git a/bindings/java/unicorn/X86Const.java b/bindings/java/unicorn/X86Const.java index 7054f787..9c0446c8 100644 --- a/bindings/java/unicorn/X86Const.java +++ b/bindings/java/unicorn/X86Const.java @@ -4,1631 +4,1631 @@ package unicorn; public interface X86Const { -// X86 CPU + // X86 CPU - public static final int UC_CPU_X86_QEMU64 = 0; - public static final int UC_CPU_X86_PHENOM = 1; - public static final int UC_CPU_X86_CORE2DUO = 2; - public static final int UC_CPU_X86_KVM64 = 3; - public static final int UC_CPU_X86_QEMU32 = 4; - public static final int UC_CPU_X86_KVM32 = 5; - public static final int UC_CPU_X86_COREDUO = 6; - public static final int UC_CPU_X86_486 = 7; - public static final int UC_CPU_X86_PENTIUM = 8; - public static final int UC_CPU_X86_PENTIUM2 = 9; - public static final int UC_CPU_X86_PENTIUM3 = 10; - public static final int UC_CPU_X86_ATHLON = 11; - public static final int UC_CPU_X86_N270 = 12; - public static final int UC_CPU_X86_CONROE = 13; - public static final int UC_CPU_X86_PENRYN = 14; - public static final int UC_CPU_X86_NEHALEM = 15; - public static final int UC_CPU_X86_WESTMERE = 16; - public static final int UC_CPU_X86_SANDYBRIDGE = 17; - public static final int UC_CPU_X86_IVYBRIDGE = 18; - public static final int UC_CPU_X86_HASWELL = 19; - public static final int UC_CPU_X86_BROADWELL = 20; - public static final int UC_CPU_X86_SKYLAKE_CLIENT = 21; - public static final int UC_CPU_X86_SKYLAKE_SERVER = 22; - public static final int UC_CPU_X86_CASCADELAKE_SERVER = 23; - public static final int UC_CPU_X86_COOPERLAKE = 24; - public static final int UC_CPU_X86_ICELAKE_CLIENT = 25; - public static final int UC_CPU_X86_ICELAKE_SERVER = 26; - public static final int UC_CPU_X86_DENVERTON = 27; - public static final int UC_CPU_X86_SNOWRIDGE = 28; - public static final int UC_CPU_X86_KNIGHTSMILL = 29; - public static final int UC_CPU_X86_OPTERON_G1 = 30; - public static final int UC_CPU_X86_OPTERON_G2 = 31; - public static final int UC_CPU_X86_OPTERON_G3 = 32; - public static final int UC_CPU_X86_OPTERON_G4 = 33; - public static final int UC_CPU_X86_OPTERON_G5 = 34; - public static final int UC_CPU_X86_EPYC = 35; - public static final int UC_CPU_X86_DHYANA = 36; - public static final int UC_CPU_X86_EPYC_ROME = 37; - public static final int UC_CPU_X86_ENDING = 38; + public static final int UC_CPU_X86_QEMU64 = 0; + public static final int UC_CPU_X86_PHENOM = 1; + public static final int UC_CPU_X86_CORE2DUO = 2; + public static final int UC_CPU_X86_KVM64 = 3; + public static final int UC_CPU_X86_QEMU32 = 4; + public static final int UC_CPU_X86_KVM32 = 5; + public static final int UC_CPU_X86_COREDUO = 6; + public static final int UC_CPU_X86_486 = 7; + public static final int UC_CPU_X86_PENTIUM = 8; + public static final int UC_CPU_X86_PENTIUM2 = 9; + public static final int UC_CPU_X86_PENTIUM3 = 10; + public static final int UC_CPU_X86_ATHLON = 11; + public static final int UC_CPU_X86_N270 = 12; + public static final int UC_CPU_X86_CONROE = 13; + public static final int UC_CPU_X86_PENRYN = 14; + public static final int UC_CPU_X86_NEHALEM = 15; + public static final int UC_CPU_X86_WESTMERE = 16; + public static final int UC_CPU_X86_SANDYBRIDGE = 17; + public static final int UC_CPU_X86_IVYBRIDGE = 18; + public static final int UC_CPU_X86_HASWELL = 19; + public static final int UC_CPU_X86_BROADWELL = 20; + public static final int UC_CPU_X86_SKYLAKE_CLIENT = 21; + public static final int UC_CPU_X86_SKYLAKE_SERVER = 22; + public static final int UC_CPU_X86_CASCADELAKE_SERVER = 23; + public static final int UC_CPU_X86_COOPERLAKE = 24; + public static final int UC_CPU_X86_ICELAKE_CLIENT = 25; + public static final int UC_CPU_X86_ICELAKE_SERVER = 26; + public static final int UC_CPU_X86_DENVERTON = 27; + public static final int UC_CPU_X86_SNOWRIDGE = 28; + public static final int UC_CPU_X86_KNIGHTSMILL = 29; + public static final int UC_CPU_X86_OPTERON_G1 = 30; + public static final int UC_CPU_X86_OPTERON_G2 = 31; + public static final int UC_CPU_X86_OPTERON_G3 = 32; + public static final int UC_CPU_X86_OPTERON_G4 = 33; + public static final int UC_CPU_X86_OPTERON_G5 = 34; + public static final int UC_CPU_X86_EPYC = 35; + public static final int UC_CPU_X86_DHYANA = 36; + public static final int UC_CPU_X86_EPYC_ROME = 37; + public static final int UC_CPU_X86_ENDING = 38; -// X86 registers + // X86 registers - 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_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_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_CR8 = 58; - 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_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_IDTR = 242; - public static final int UC_X86_REG_GDTR = 243; - public static final int UC_X86_REG_LDTR = 244; - public static final int UC_X86_REG_TR = 245; - public static final int UC_X86_REG_FPCW = 246; - public static final int UC_X86_REG_FPTAG = 247; - public static final int UC_X86_REG_MSR = 248; - public static final int UC_X86_REG_MXCSR = 249; - public static final int UC_X86_REG_FS_BASE = 250; - public static final int UC_X86_REG_GS_BASE = 251; - public static final int UC_X86_REG_FLAGS = 252; - public static final int UC_X86_REG_RFLAGS = 253; - public static final int UC_X86_REG_FIP = 254; - public static final int UC_X86_REG_FCS = 255; - public static final int UC_X86_REG_FDP = 256; - public static final int UC_X86_REG_FDS = 257; - public static final int UC_X86_REG_FOP = 258; - public static final int UC_X86_REG_ENDING = 259; + 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_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_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_CR8 = 58; + 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_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_IDTR = 242; + public static final int UC_X86_REG_GDTR = 243; + public static final int UC_X86_REG_LDTR = 244; + public static final int UC_X86_REG_TR = 245; + public static final int UC_X86_REG_FPCW = 246; + public static final int UC_X86_REG_FPTAG = 247; + public static final int UC_X86_REG_MSR = 248; + public static final int UC_X86_REG_MXCSR = 249; + public static final int UC_X86_REG_FS_BASE = 250; + public static final int UC_X86_REG_GS_BASE = 251; + public static final int UC_X86_REG_FLAGS = 252; + public static final int UC_X86_REG_RFLAGS = 253; + public static final int UC_X86_REG_FIP = 254; + public static final int UC_X86_REG_FCS = 255; + public static final int UC_X86_REG_FDP = 256; + public static final int UC_X86_REG_FDS = 257; + public static final int UC_X86_REG_FOP = 258; + public static final int UC_X86_REG_ENDING = 259; -// X86 instructions + // X86 instructions - public static final int UC_X86_INS_INVALID = 0; - public static final int UC_X86_INS_AAA = 1; - public static final int UC_X86_INS_AAD = 2; - public static final int UC_X86_INS_AAM = 3; - public static final int UC_X86_INS_AAS = 4; - public static final int UC_X86_INS_FABS = 5; - public static final int UC_X86_INS_ADC = 6; - public static final int UC_X86_INS_ADCX = 7; - public static final int UC_X86_INS_ADD = 8; - public static final int UC_X86_INS_ADDPD = 9; - public static final int UC_X86_INS_ADDPS = 10; - public static final int UC_X86_INS_ADDSD = 11; - public static final int UC_X86_INS_ADDSS = 12; - public static final int UC_X86_INS_ADDSUBPD = 13; - public static final int UC_X86_INS_ADDSUBPS = 14; - public static final int UC_X86_INS_FADD = 15; - public static final int UC_X86_INS_FIADD = 16; - public static final int UC_X86_INS_FADDP = 17; - public static final int UC_X86_INS_ADOX = 18; - public static final int UC_X86_INS_AESDECLAST = 19; - public static final int UC_X86_INS_AESDEC = 20; - public static final int UC_X86_INS_AESENCLAST = 21; - public static final int UC_X86_INS_AESENC = 22; - public static final int UC_X86_INS_AESIMC = 23; - public static final int UC_X86_INS_AESKEYGENASSIST = 24; - public static final int UC_X86_INS_AND = 25; - public static final int UC_X86_INS_ANDN = 26; - public static final int UC_X86_INS_ANDNPD = 27; - public static final int UC_X86_INS_ANDNPS = 28; - public static final int UC_X86_INS_ANDPD = 29; - public static final int UC_X86_INS_ANDPS = 30; - public static final int UC_X86_INS_ARPL = 31; - public static final int UC_X86_INS_BEXTR = 32; - public static final int UC_X86_INS_BLCFILL = 33; - public static final int UC_X86_INS_BLCI = 34; - public static final int UC_X86_INS_BLCIC = 35; - public static final int UC_X86_INS_BLCMSK = 36; - public static final int UC_X86_INS_BLCS = 37; - public static final int UC_X86_INS_BLENDPD = 38; - public static final int UC_X86_INS_BLENDPS = 39; - public static final int UC_X86_INS_BLENDVPD = 40; - public static final int UC_X86_INS_BLENDVPS = 41; - public static final int UC_X86_INS_BLSFILL = 42; - public static final int UC_X86_INS_BLSI = 43; - public static final int UC_X86_INS_BLSIC = 44; - public static final int UC_X86_INS_BLSMSK = 45; - public static final int UC_X86_INS_BLSR = 46; - public static final int UC_X86_INS_BOUND = 47; - public static final int UC_X86_INS_BSF = 48; - public static final int UC_X86_INS_BSR = 49; - public static final int UC_X86_INS_BSWAP = 50; - public static final int UC_X86_INS_BT = 51; - public static final int UC_X86_INS_BTC = 52; - public static final int UC_X86_INS_BTR = 53; - public static final int UC_X86_INS_BTS = 54; - public static final int UC_X86_INS_BZHI = 55; - public static final int UC_X86_INS_CALL = 56; - public static final int UC_X86_INS_CBW = 57; - public static final int UC_X86_INS_CDQ = 58; - public static final int UC_X86_INS_CDQE = 59; - public static final int UC_X86_INS_FCHS = 60; - public static final int UC_X86_INS_CLAC = 61; - public static final int UC_X86_INS_CLC = 62; - public static final int UC_X86_INS_CLD = 63; - public static final int UC_X86_INS_CLFLUSH = 64; - public static final int UC_X86_INS_CLFLUSHOPT = 65; - public static final int UC_X86_INS_CLGI = 66; - public static final int UC_X86_INS_CLI = 67; - public static final int UC_X86_INS_CLTS = 68; - public static final int UC_X86_INS_CLWB = 69; - public static final int UC_X86_INS_CMC = 70; - public static final int UC_X86_INS_CMOVA = 71; - public static final int UC_X86_INS_CMOVAE = 72; - public static final int UC_X86_INS_CMOVB = 73; - public static final int UC_X86_INS_CMOVBE = 74; - public static final int UC_X86_INS_FCMOVBE = 75; - public static final int UC_X86_INS_FCMOVB = 76; - public static final int UC_X86_INS_CMOVE = 77; - public static final int UC_X86_INS_FCMOVE = 78; - public static final int UC_X86_INS_CMOVG = 79; - public static final int UC_X86_INS_CMOVGE = 80; - public static final int UC_X86_INS_CMOVL = 81; - public static final int UC_X86_INS_CMOVLE = 82; - public static final int UC_X86_INS_FCMOVNBE = 83; - public static final int UC_X86_INS_FCMOVNB = 84; - public static final int UC_X86_INS_CMOVNE = 85; - public static final int UC_X86_INS_FCMOVNE = 86; - public static final int UC_X86_INS_CMOVNO = 87; - public static final int UC_X86_INS_CMOVNP = 88; - public static final int UC_X86_INS_FCMOVNU = 89; - public static final int UC_X86_INS_CMOVNS = 90; - public static final int UC_X86_INS_CMOVO = 91; - public static final int UC_X86_INS_CMOVP = 92; - public static final int UC_X86_INS_FCMOVU = 93; - public static final int UC_X86_INS_CMOVS = 94; - public static final int UC_X86_INS_CMP = 95; - public static final int UC_X86_INS_CMPPD = 96; - public static final int UC_X86_INS_CMPPS = 97; - public static final int UC_X86_INS_CMPSB = 98; - public static final int UC_X86_INS_CMPSD = 99; - public static final int UC_X86_INS_CMPSQ = 100; - public static final int UC_X86_INS_CMPSS = 101; - public static final int UC_X86_INS_CMPSW = 102; - public static final int UC_X86_INS_CMPXCHG16B = 103; - public static final int UC_X86_INS_CMPXCHG = 104; - public static final int UC_X86_INS_CMPXCHG8B = 105; - public static final int UC_X86_INS_COMISD = 106; - public static final int UC_X86_INS_COMISS = 107; - public static final int UC_X86_INS_FCOMP = 108; - public static final int UC_X86_INS_FCOMPI = 109; - public static final int UC_X86_INS_FCOMI = 110; - public static final int UC_X86_INS_FCOM = 111; - public static final int UC_X86_INS_FCOS = 112; - public static final int UC_X86_INS_CPUID = 113; - public static final int UC_X86_INS_CQO = 114; - public static final int UC_X86_INS_CRC32 = 115; - public static final int UC_X86_INS_CVTDQ2PD = 116; - public static final int UC_X86_INS_CVTDQ2PS = 117; - public static final int UC_X86_INS_CVTPD2DQ = 118; - public static final int UC_X86_INS_CVTPD2PS = 119; - public static final int UC_X86_INS_CVTPS2DQ = 120; - public static final int UC_X86_INS_CVTPS2PD = 121; - public static final int UC_X86_INS_CVTSD2SI = 122; - public static final int UC_X86_INS_CVTSD2SS = 123; - public static final int UC_X86_INS_CVTSI2SD = 124; - public static final int UC_X86_INS_CVTSI2SS = 125; - public static final int UC_X86_INS_CVTSS2SD = 126; - public static final int UC_X86_INS_CVTSS2SI = 127; - public static final int UC_X86_INS_CVTTPD2DQ = 128; - public static final int UC_X86_INS_CVTTPS2DQ = 129; - public static final int UC_X86_INS_CVTTSD2SI = 130; - public static final int UC_X86_INS_CVTTSS2SI = 131; - public static final int UC_X86_INS_CWD = 132; - public static final int UC_X86_INS_CWDE = 133; - public static final int UC_X86_INS_DAA = 134; - public static final int UC_X86_INS_DAS = 135; - public static final int UC_X86_INS_DATA16 = 136; - public static final int UC_X86_INS_DEC = 137; - public static final int UC_X86_INS_DIV = 138; - public static final int UC_X86_INS_DIVPD = 139; - public static final int UC_X86_INS_DIVPS = 140; - public static final int UC_X86_INS_FDIVR = 141; - public static final int UC_X86_INS_FIDIVR = 142; - public static final int UC_X86_INS_FDIVRP = 143; - public static final int UC_X86_INS_DIVSD = 144; - public static final int UC_X86_INS_DIVSS = 145; - public static final int UC_X86_INS_FDIV = 146; - public static final int UC_X86_INS_FIDIV = 147; - public static final int UC_X86_INS_FDIVP = 148; - public static final int UC_X86_INS_DPPD = 149; - public static final int UC_X86_INS_DPPS = 150; - public static final int UC_X86_INS_RET = 151; - public static final int UC_X86_INS_ENCLS = 152; - public static final int UC_X86_INS_ENCLU = 153; - public static final int UC_X86_INS_ENTER = 154; - public static final int UC_X86_INS_EXTRACTPS = 155; - public static final int UC_X86_INS_EXTRQ = 156; - public static final int UC_X86_INS_F2XM1 = 157; - public static final int UC_X86_INS_LCALL = 158; - public static final int UC_X86_INS_LJMP = 159; - public static final int UC_X86_INS_FBLD = 160; - public static final int UC_X86_INS_FBSTP = 161; - public static final int UC_X86_INS_FCOMPP = 162; - public static final int UC_X86_INS_FDECSTP = 163; - public static final int UC_X86_INS_FEMMS = 164; - public static final int UC_X86_INS_FFREE = 165; - public static final int UC_X86_INS_FICOM = 166; - public static final int UC_X86_INS_FICOMP = 167; - public static final int UC_X86_INS_FINCSTP = 168; - public static final int UC_X86_INS_FLDCW = 169; - public static final int UC_X86_INS_FLDENV = 170; - public static final int UC_X86_INS_FLDL2E = 171; - public static final int UC_X86_INS_FLDL2T = 172; - public static final int UC_X86_INS_FLDLG2 = 173; - public static final int UC_X86_INS_FLDLN2 = 174; - public static final int UC_X86_INS_FLDPI = 175; - public static final int UC_X86_INS_FNCLEX = 176; - public static final int UC_X86_INS_FNINIT = 177; - public static final int UC_X86_INS_FNOP = 178; - public static final int UC_X86_INS_FNSTCW = 179; - public static final int UC_X86_INS_FNSTSW = 180; - public static final int UC_X86_INS_FPATAN = 181; - public static final int UC_X86_INS_FPREM = 182; - public static final int UC_X86_INS_FPREM1 = 183; - public static final int UC_X86_INS_FPTAN = 184; - public static final int UC_X86_INS_FFREEP = 185; - public static final int UC_X86_INS_FRNDINT = 186; - public static final int UC_X86_INS_FRSTOR = 187; - public static final int UC_X86_INS_FNSAVE = 188; - public static final int UC_X86_INS_FSCALE = 189; - public static final int UC_X86_INS_FSETPM = 190; - public static final int UC_X86_INS_FSINCOS = 191; - public static final int UC_X86_INS_FNSTENV = 192; - public static final int UC_X86_INS_FXAM = 193; - public static final int UC_X86_INS_FXRSTOR = 194; - public static final int UC_X86_INS_FXRSTOR64 = 195; - public static final int UC_X86_INS_FXSAVE = 196; - public static final int UC_X86_INS_FXSAVE64 = 197; - public static final int UC_X86_INS_FXTRACT = 198; - public static final int UC_X86_INS_FYL2X = 199; - public static final int UC_X86_INS_FYL2XP1 = 200; - public static final int UC_X86_INS_MOVAPD = 201; - public static final int UC_X86_INS_MOVAPS = 202; - public static final int UC_X86_INS_ORPD = 203; - public static final int UC_X86_INS_ORPS = 204; - public static final int UC_X86_INS_VMOVAPD = 205; - public static final int UC_X86_INS_VMOVAPS = 206; - public static final int UC_X86_INS_XORPD = 207; - public static final int UC_X86_INS_XORPS = 208; - public static final int UC_X86_INS_GETSEC = 209; - public static final int UC_X86_INS_HADDPD = 210; - public static final int UC_X86_INS_HADDPS = 211; - public static final int UC_X86_INS_HLT = 212; - public static final int UC_X86_INS_HSUBPD = 213; - public static final int UC_X86_INS_HSUBPS = 214; - public static final int UC_X86_INS_IDIV = 215; - public static final int UC_X86_INS_FILD = 216; - public static final int UC_X86_INS_IMUL = 217; - public static final int UC_X86_INS_IN = 218; - public static final int UC_X86_INS_INC = 219; - public static final int UC_X86_INS_INSB = 220; - public static final int UC_X86_INS_INSERTPS = 221; - public static final int UC_X86_INS_INSERTQ = 222; - public static final int UC_X86_INS_INSD = 223; - public static final int UC_X86_INS_INSW = 224; - public static final int UC_X86_INS_INT = 225; - public static final int UC_X86_INS_INT1 = 226; - public static final int UC_X86_INS_INT3 = 227; - public static final int UC_X86_INS_INTO = 228; - public static final int UC_X86_INS_INVD = 229; - public static final int UC_X86_INS_INVEPT = 230; - public static final int UC_X86_INS_INVLPG = 231; - public static final int UC_X86_INS_INVLPGA = 232; - public static final int UC_X86_INS_INVPCID = 233; - public static final int UC_X86_INS_INVVPID = 234; - public static final int UC_X86_INS_IRET = 235; - public static final int UC_X86_INS_IRETD = 236; - public static final int UC_X86_INS_IRETQ = 237; - public static final int UC_X86_INS_FISTTP = 238; - public static final int UC_X86_INS_FIST = 239; - public static final int UC_X86_INS_FISTP = 240; - public static final int UC_X86_INS_UCOMISD = 241; - public static final int UC_X86_INS_UCOMISS = 242; - public static final int UC_X86_INS_VCOMISD = 243; - public static final int UC_X86_INS_VCOMISS = 244; - public static final int UC_X86_INS_VCVTSD2SS = 245; - public static final int UC_X86_INS_VCVTSI2SD = 246; - public static final int UC_X86_INS_VCVTSI2SS = 247; - public static final int UC_X86_INS_VCVTSS2SD = 248; - public static final int UC_X86_INS_VCVTTSD2SI = 249; - public static final int UC_X86_INS_VCVTTSD2USI = 250; - public static final int UC_X86_INS_VCVTTSS2SI = 251; - public static final int UC_X86_INS_VCVTTSS2USI = 252; - public static final int UC_X86_INS_VCVTUSI2SD = 253; - public static final int UC_X86_INS_VCVTUSI2SS = 254; - public static final int UC_X86_INS_VUCOMISD = 255; - public static final int UC_X86_INS_VUCOMISS = 256; - public static final int UC_X86_INS_JAE = 257; - public static final int UC_X86_INS_JA = 258; - public static final int UC_X86_INS_JBE = 259; - public static final int UC_X86_INS_JB = 260; - public static final int UC_X86_INS_JCXZ = 261; - public static final int UC_X86_INS_JECXZ = 262; - public static final int UC_X86_INS_JE = 263; - public static final int UC_X86_INS_JGE = 264; - public static final int UC_X86_INS_JG = 265; - public static final int UC_X86_INS_JLE = 266; - public static final int UC_X86_INS_JL = 267; - public static final int UC_X86_INS_JMP = 268; - public static final int UC_X86_INS_JNE = 269; - public static final int UC_X86_INS_JNO = 270; - public static final int UC_X86_INS_JNP = 271; - public static final int UC_X86_INS_JNS = 272; - public static final int UC_X86_INS_JO = 273; - public static final int UC_X86_INS_JP = 274; - public static final int UC_X86_INS_JRCXZ = 275; - public static final int UC_X86_INS_JS = 276; - public static final int UC_X86_INS_KANDB = 277; - public static final int UC_X86_INS_KANDD = 278; - public static final int UC_X86_INS_KANDNB = 279; - public static final int UC_X86_INS_KANDND = 280; - public static final int UC_X86_INS_KANDNQ = 281; - public static final int UC_X86_INS_KANDNW = 282; - public static final int UC_X86_INS_KANDQ = 283; - public static final int UC_X86_INS_KANDW = 284; - public static final int UC_X86_INS_KMOVB = 285; - public static final int UC_X86_INS_KMOVD = 286; - public static final int UC_X86_INS_KMOVQ = 287; - public static final int UC_X86_INS_KMOVW = 288; - public static final int UC_X86_INS_KNOTB = 289; - public static final int UC_X86_INS_KNOTD = 290; - public static final int UC_X86_INS_KNOTQ = 291; - public static final int UC_X86_INS_KNOTW = 292; - public static final int UC_X86_INS_KORB = 293; - public static final int UC_X86_INS_KORD = 294; - public static final int UC_X86_INS_KORQ = 295; - public static final int UC_X86_INS_KORTESTB = 296; - public static final int UC_X86_INS_KORTESTD = 297; - public static final int UC_X86_INS_KORTESTQ = 298; - public static final int UC_X86_INS_KORTESTW = 299; - public static final int UC_X86_INS_KORW = 300; - public static final int UC_X86_INS_KSHIFTLB = 301; - public static final int UC_X86_INS_KSHIFTLD = 302; - public static final int UC_X86_INS_KSHIFTLQ = 303; - public static final int UC_X86_INS_KSHIFTLW = 304; - public static final int UC_X86_INS_KSHIFTRB = 305; - public static final int UC_X86_INS_KSHIFTRD = 306; - public static final int UC_X86_INS_KSHIFTRQ = 307; - public static final int UC_X86_INS_KSHIFTRW = 308; - public static final int UC_X86_INS_KUNPCKBW = 309; - public static final int UC_X86_INS_KXNORB = 310; - public static final int UC_X86_INS_KXNORD = 311; - public static final int UC_X86_INS_KXNORQ = 312; - public static final int UC_X86_INS_KXNORW = 313; - public static final int UC_X86_INS_KXORB = 314; - public static final int UC_X86_INS_KXORD = 315; - public static final int UC_X86_INS_KXORQ = 316; - public static final int UC_X86_INS_KXORW = 317; - public static final int UC_X86_INS_LAHF = 318; - public static final int UC_X86_INS_LAR = 319; - public static final int UC_X86_INS_LDDQU = 320; - public static final int UC_X86_INS_LDMXCSR = 321; - public static final int UC_X86_INS_LDS = 322; - public static final int UC_X86_INS_FLDZ = 323; - public static final int UC_X86_INS_FLD1 = 324; - public static final int UC_X86_INS_FLD = 325; - public static final int UC_X86_INS_LEA = 326; - public static final int UC_X86_INS_LEAVE = 327; - public static final int UC_X86_INS_LES = 328; - public static final int UC_X86_INS_LFENCE = 329; - public static final int UC_X86_INS_LFS = 330; - public static final int UC_X86_INS_LGDT = 331; - public static final int UC_X86_INS_LGS = 332; - public static final int UC_X86_INS_LIDT = 333; - public static final int UC_X86_INS_LLDT = 334; - public static final int UC_X86_INS_LMSW = 335; - public static final int UC_X86_INS_OR = 336; - public static final int UC_X86_INS_SUB = 337; - public static final int UC_X86_INS_XOR = 338; - public static final int UC_X86_INS_LODSB = 339; - public static final int UC_X86_INS_LODSD = 340; - public static final int UC_X86_INS_LODSQ = 341; - public static final int UC_X86_INS_LODSW = 342; - public static final int UC_X86_INS_LOOP = 343; - public static final int UC_X86_INS_LOOPE = 344; - public static final int UC_X86_INS_LOOPNE = 345; - public static final int UC_X86_INS_RETF = 346; - public static final int UC_X86_INS_RETFQ = 347; - public static final int UC_X86_INS_LSL = 348; - public static final int UC_X86_INS_LSS = 349; - public static final int UC_X86_INS_LTR = 350; - public static final int UC_X86_INS_XADD = 351; - public static final int UC_X86_INS_LZCNT = 352; - public static final int UC_X86_INS_MASKMOVDQU = 353; - public static final int UC_X86_INS_MAXPD = 354; - public static final int UC_X86_INS_MAXPS = 355; - public static final int UC_X86_INS_MAXSD = 356; - public static final int UC_X86_INS_MAXSS = 357; - public static final int UC_X86_INS_MFENCE = 358; - public static final int UC_X86_INS_MINPD = 359; - public static final int UC_X86_INS_MINPS = 360; - public static final int UC_X86_INS_MINSD = 361; - public static final int UC_X86_INS_MINSS = 362; - public static final int UC_X86_INS_CVTPD2PI = 363; - public static final int UC_X86_INS_CVTPI2PD = 364; - public static final int UC_X86_INS_CVTPI2PS = 365; - public static final int UC_X86_INS_CVTPS2PI = 366; - public static final int UC_X86_INS_CVTTPD2PI = 367; - public static final int UC_X86_INS_CVTTPS2PI = 368; - public static final int UC_X86_INS_EMMS = 369; - public static final int UC_X86_INS_MASKMOVQ = 370; - public static final int UC_X86_INS_MOVD = 371; - public static final int UC_X86_INS_MOVDQ2Q = 372; - public static final int UC_X86_INS_MOVNTQ = 373; - public static final int UC_X86_INS_MOVQ2DQ = 374; - public static final int UC_X86_INS_MOVQ = 375; - public static final int UC_X86_INS_PABSB = 376; - public static final int UC_X86_INS_PABSD = 377; - public static final int UC_X86_INS_PABSW = 378; - public static final int UC_X86_INS_PACKSSDW = 379; - public static final int UC_X86_INS_PACKSSWB = 380; - public static final int UC_X86_INS_PACKUSWB = 381; - public static final int UC_X86_INS_PADDB = 382; - public static final int UC_X86_INS_PADDD = 383; - public static final int UC_X86_INS_PADDQ = 384; - public static final int UC_X86_INS_PADDSB = 385; - public static final int UC_X86_INS_PADDSW = 386; - public static final int UC_X86_INS_PADDUSB = 387; - public static final int UC_X86_INS_PADDUSW = 388; - public static final int UC_X86_INS_PADDW = 389; - public static final int UC_X86_INS_PALIGNR = 390; - public static final int UC_X86_INS_PANDN = 391; - public static final int UC_X86_INS_PAND = 392; - public static final int UC_X86_INS_PAVGB = 393; - public static final int UC_X86_INS_PAVGW = 394; - public static final int UC_X86_INS_PCMPEQB = 395; - public static final int UC_X86_INS_PCMPEQD = 396; - public static final int UC_X86_INS_PCMPEQW = 397; - public static final int UC_X86_INS_PCMPGTB = 398; - public static final int UC_X86_INS_PCMPGTD = 399; - public static final int UC_X86_INS_PCMPGTW = 400; - public static final int UC_X86_INS_PEXTRW = 401; - public static final int UC_X86_INS_PHADDSW = 402; - public static final int UC_X86_INS_PHADDW = 403; - public static final int UC_X86_INS_PHADDD = 404; - public static final int UC_X86_INS_PHSUBD = 405; - public static final int UC_X86_INS_PHSUBSW = 406; - public static final int UC_X86_INS_PHSUBW = 407; - public static final int UC_X86_INS_PINSRW = 408; - public static final int UC_X86_INS_PMADDUBSW = 409; - public static final int UC_X86_INS_PMADDWD = 410; - public static final int UC_X86_INS_PMAXSW = 411; - public static final int UC_X86_INS_PMAXUB = 412; - public static final int UC_X86_INS_PMINSW = 413; - public static final int UC_X86_INS_PMINUB = 414; - public static final int UC_X86_INS_PMOVMSKB = 415; - public static final int UC_X86_INS_PMULHRSW = 416; - public static final int UC_X86_INS_PMULHUW = 417; - public static final int UC_X86_INS_PMULHW = 418; - public static final int UC_X86_INS_PMULLW = 419; - public static final int UC_X86_INS_PMULUDQ = 420; - public static final int UC_X86_INS_POR = 421; - public static final int UC_X86_INS_PSADBW = 422; - public static final int UC_X86_INS_PSHUFB = 423; - public static final int UC_X86_INS_PSHUFW = 424; - public static final int UC_X86_INS_PSIGNB = 425; - public static final int UC_X86_INS_PSIGND = 426; - public static final int UC_X86_INS_PSIGNW = 427; - public static final int UC_X86_INS_PSLLD = 428; - public static final int UC_X86_INS_PSLLQ = 429; - public static final int UC_X86_INS_PSLLW = 430; - public static final int UC_X86_INS_PSRAD = 431; - public static final int UC_X86_INS_PSRAW = 432; - public static final int UC_X86_INS_PSRLD = 433; - public static final int UC_X86_INS_PSRLQ = 434; - public static final int UC_X86_INS_PSRLW = 435; - public static final int UC_X86_INS_PSUBB = 436; - public static final int UC_X86_INS_PSUBD = 437; - public static final int UC_X86_INS_PSUBQ = 438; - public static final int UC_X86_INS_PSUBSB = 439; - public static final int UC_X86_INS_PSUBSW = 440; - public static final int UC_X86_INS_PSUBUSB = 441; - public static final int UC_X86_INS_PSUBUSW = 442; - public static final int UC_X86_INS_PSUBW = 443; - public static final int UC_X86_INS_PUNPCKHBW = 444; - public static final int UC_X86_INS_PUNPCKHDQ = 445; - public static final int UC_X86_INS_PUNPCKHWD = 446; - public static final int UC_X86_INS_PUNPCKLBW = 447; - public static final int UC_X86_INS_PUNPCKLDQ = 448; - public static final int UC_X86_INS_PUNPCKLWD = 449; - public static final int UC_X86_INS_PXOR = 450; - public static final int UC_X86_INS_MONITOR = 451; - public static final int UC_X86_INS_MONTMUL = 452; - public static final int UC_X86_INS_MOV = 453; - public static final int UC_X86_INS_MOVABS = 454; - public static final int UC_X86_INS_MOVBE = 455; - public static final int UC_X86_INS_MOVDDUP = 456; - public static final int UC_X86_INS_MOVDQA = 457; - public static final int UC_X86_INS_MOVDQU = 458; - public static final int UC_X86_INS_MOVHLPS = 459; - public static final int UC_X86_INS_MOVHPD = 460; - public static final int UC_X86_INS_MOVHPS = 461; - public static final int UC_X86_INS_MOVLHPS = 462; - public static final int UC_X86_INS_MOVLPD = 463; - public static final int UC_X86_INS_MOVLPS = 464; - public static final int UC_X86_INS_MOVMSKPD = 465; - public static final int UC_X86_INS_MOVMSKPS = 466; - public static final int UC_X86_INS_MOVNTDQA = 467; - public static final int UC_X86_INS_MOVNTDQ = 468; - public static final int UC_X86_INS_MOVNTI = 469; - public static final int UC_X86_INS_MOVNTPD = 470; - public static final int UC_X86_INS_MOVNTPS = 471; - public static final int UC_X86_INS_MOVNTSD = 472; - public static final int UC_X86_INS_MOVNTSS = 473; - public static final int UC_X86_INS_MOVSB = 474; - public static final int UC_X86_INS_MOVSD = 475; - public static final int UC_X86_INS_MOVSHDUP = 476; - public static final int UC_X86_INS_MOVSLDUP = 477; - public static final int UC_X86_INS_MOVSQ = 478; - public static final int UC_X86_INS_MOVSS = 479; - public static final int UC_X86_INS_MOVSW = 480; - public static final int UC_X86_INS_MOVSX = 481; - public static final int UC_X86_INS_MOVSXD = 482; - public static final int UC_X86_INS_MOVUPD = 483; - public static final int UC_X86_INS_MOVUPS = 484; - public static final int UC_X86_INS_MOVZX = 485; - public static final int UC_X86_INS_MPSADBW = 486; - public static final int UC_X86_INS_MUL = 487; - public static final int UC_X86_INS_MULPD = 488; - public static final int UC_X86_INS_MULPS = 489; - public static final int UC_X86_INS_MULSD = 490; - public static final int UC_X86_INS_MULSS = 491; - public static final int UC_X86_INS_MULX = 492; - public static final int UC_X86_INS_FMUL = 493; - public static final int UC_X86_INS_FIMUL = 494; - public static final int UC_X86_INS_FMULP = 495; - public static final int UC_X86_INS_MWAIT = 496; - public static final int UC_X86_INS_NEG = 497; - public static final int UC_X86_INS_NOP = 498; - public static final int UC_X86_INS_NOT = 499; - public static final int UC_X86_INS_OUT = 500; - public static final int UC_X86_INS_OUTSB = 501; - public static final int UC_X86_INS_OUTSD = 502; - public static final int UC_X86_INS_OUTSW = 503; - public static final int UC_X86_INS_PACKUSDW = 504; - public static final int UC_X86_INS_PAUSE = 505; - public static final int UC_X86_INS_PAVGUSB = 506; - public static final int UC_X86_INS_PBLENDVB = 507; - public static final int UC_X86_INS_PBLENDW = 508; - public static final int UC_X86_INS_PCLMULQDQ = 509; - public static final int UC_X86_INS_PCMPEQQ = 510; - public static final int UC_X86_INS_PCMPESTRI = 511; - public static final int UC_X86_INS_PCMPESTRM = 512; - public static final int UC_X86_INS_PCMPGTQ = 513; - public static final int UC_X86_INS_PCMPISTRI = 514; - public static final int UC_X86_INS_PCMPISTRM = 515; - public static final int UC_X86_INS_PCOMMIT = 516; - public static final int UC_X86_INS_PDEP = 517; - public static final int UC_X86_INS_PEXT = 518; - public static final int UC_X86_INS_PEXTRB = 519; - public static final int UC_X86_INS_PEXTRD = 520; - public static final int UC_X86_INS_PEXTRQ = 521; - public static final int UC_X86_INS_PF2ID = 522; - public static final int UC_X86_INS_PF2IW = 523; - public static final int UC_X86_INS_PFACC = 524; - public static final int UC_X86_INS_PFADD = 525; - public static final int UC_X86_INS_PFCMPEQ = 526; - public static final int UC_X86_INS_PFCMPGE = 527; - public static final int UC_X86_INS_PFCMPGT = 528; - public static final int UC_X86_INS_PFMAX = 529; - public static final int UC_X86_INS_PFMIN = 530; - public static final int UC_X86_INS_PFMUL = 531; - public static final int UC_X86_INS_PFNACC = 532; - public static final int UC_X86_INS_PFPNACC = 533; - public static final int UC_X86_INS_PFRCPIT1 = 534; - public static final int UC_X86_INS_PFRCPIT2 = 535; - public static final int UC_X86_INS_PFRCP = 536; - public static final int UC_X86_INS_PFRSQIT1 = 537; - public static final int UC_X86_INS_PFRSQRT = 538; - public static final int UC_X86_INS_PFSUBR = 539; - public static final int UC_X86_INS_PFSUB = 540; - public static final int UC_X86_INS_PHMINPOSUW = 541; - public static final int UC_X86_INS_PI2FD = 542; - public static final int UC_X86_INS_PI2FW = 543; - public static final int UC_X86_INS_PINSRB = 544; - public static final int UC_X86_INS_PINSRD = 545; - public static final int UC_X86_INS_PINSRQ = 546; - public static final int UC_X86_INS_PMAXSB = 547; - public static final int UC_X86_INS_PMAXSD = 548; - public static final int UC_X86_INS_PMAXUD = 549; - public static final int UC_X86_INS_PMAXUW = 550; - public static final int UC_X86_INS_PMINSB = 551; - public static final int UC_X86_INS_PMINSD = 552; - public static final int UC_X86_INS_PMINUD = 553; - public static final int UC_X86_INS_PMINUW = 554; - public static final int UC_X86_INS_PMOVSXBD = 555; - public static final int UC_X86_INS_PMOVSXBQ = 556; - public static final int UC_X86_INS_PMOVSXBW = 557; - public static final int UC_X86_INS_PMOVSXDQ = 558; - public static final int UC_X86_INS_PMOVSXWD = 559; - public static final int UC_X86_INS_PMOVSXWQ = 560; - public static final int UC_X86_INS_PMOVZXBD = 561; - public static final int UC_X86_INS_PMOVZXBQ = 562; - public static final int UC_X86_INS_PMOVZXBW = 563; - public static final int UC_X86_INS_PMOVZXDQ = 564; - public static final int UC_X86_INS_PMOVZXWD = 565; - public static final int UC_X86_INS_PMOVZXWQ = 566; - public static final int UC_X86_INS_PMULDQ = 567; - public static final int UC_X86_INS_PMULHRW = 568; - public static final int UC_X86_INS_PMULLD = 569; - public static final int UC_X86_INS_POP = 570; - public static final int UC_X86_INS_POPAW = 571; - public static final int UC_X86_INS_POPAL = 572; - public static final int UC_X86_INS_POPCNT = 573; - public static final int UC_X86_INS_POPF = 574; - public static final int UC_X86_INS_POPFD = 575; - public static final int UC_X86_INS_POPFQ = 576; - public static final int UC_X86_INS_PREFETCH = 577; - public static final int UC_X86_INS_PREFETCHNTA = 578; - public static final int UC_X86_INS_PREFETCHT0 = 579; - public static final int UC_X86_INS_PREFETCHT1 = 580; - public static final int UC_X86_INS_PREFETCHT2 = 581; - public static final int UC_X86_INS_PREFETCHW = 582; - public static final int UC_X86_INS_PSHUFD = 583; - public static final int UC_X86_INS_PSHUFHW = 584; - public static final int UC_X86_INS_PSHUFLW = 585; - public static final int UC_X86_INS_PSLLDQ = 586; - public static final int UC_X86_INS_PSRLDQ = 587; - public static final int UC_X86_INS_PSWAPD = 588; - public static final int UC_X86_INS_PTEST = 589; - public static final int UC_X86_INS_PUNPCKHQDQ = 590; - public static final int UC_X86_INS_PUNPCKLQDQ = 591; - public static final int UC_X86_INS_PUSH = 592; - public static final int UC_X86_INS_PUSHAW = 593; - public static final int UC_X86_INS_PUSHAL = 594; - public static final int UC_X86_INS_PUSHF = 595; - public static final int UC_X86_INS_PUSHFD = 596; - public static final int UC_X86_INS_PUSHFQ = 597; - public static final int UC_X86_INS_RCL = 598; - public static final int UC_X86_INS_RCPPS = 599; - public static final int UC_X86_INS_RCPSS = 600; - public static final int UC_X86_INS_RCR = 601; - public static final int UC_X86_INS_RDFSBASE = 602; - public static final int UC_X86_INS_RDGSBASE = 603; - public static final int UC_X86_INS_RDMSR = 604; - public static final int UC_X86_INS_RDPMC = 605; - public static final int UC_X86_INS_RDRAND = 606; - public static final int UC_X86_INS_RDSEED = 607; - public static final int UC_X86_INS_RDTSC = 608; - public static final int UC_X86_INS_RDTSCP = 609; - public static final int UC_X86_INS_ROL = 610; - public static final int UC_X86_INS_ROR = 611; - public static final int UC_X86_INS_RORX = 612; - public static final int UC_X86_INS_ROUNDPD = 613; - public static final int UC_X86_INS_ROUNDPS = 614; - public static final int UC_X86_INS_ROUNDSD = 615; - public static final int UC_X86_INS_ROUNDSS = 616; - public static final int UC_X86_INS_RSM = 617; - public static final int UC_X86_INS_RSQRTPS = 618; - public static final int UC_X86_INS_RSQRTSS = 619; - public static final int UC_X86_INS_SAHF = 620; - public static final int UC_X86_INS_SAL = 621; - public static final int UC_X86_INS_SALC = 622; - public static final int UC_X86_INS_SAR = 623; - public static final int UC_X86_INS_SARX = 624; - public static final int UC_X86_INS_SBB = 625; - public static final int UC_X86_INS_SCASB = 626; - public static final int UC_X86_INS_SCASD = 627; - public static final int UC_X86_INS_SCASQ = 628; - public static final int UC_X86_INS_SCASW = 629; - public static final int UC_X86_INS_SETAE = 630; - public static final int UC_X86_INS_SETA = 631; - public static final int UC_X86_INS_SETBE = 632; - public static final int UC_X86_INS_SETB = 633; - public static final int UC_X86_INS_SETE = 634; - public static final int UC_X86_INS_SETGE = 635; - public static final int UC_X86_INS_SETG = 636; - public static final int UC_X86_INS_SETLE = 637; - public static final int UC_X86_INS_SETL = 638; - public static final int UC_X86_INS_SETNE = 639; - public static final int UC_X86_INS_SETNO = 640; - public static final int UC_X86_INS_SETNP = 641; - public static final int UC_X86_INS_SETNS = 642; - public static final int UC_X86_INS_SETO = 643; - public static final int UC_X86_INS_SETP = 644; - public static final int UC_X86_INS_SETS = 645; - public static final int UC_X86_INS_SFENCE = 646; - public static final int UC_X86_INS_SGDT = 647; - public static final int UC_X86_INS_SHA1MSG1 = 648; - public static final int UC_X86_INS_SHA1MSG2 = 649; - public static final int UC_X86_INS_SHA1NEXTE = 650; - public static final int UC_X86_INS_SHA1RNDS4 = 651; - public static final int UC_X86_INS_SHA256MSG1 = 652; - public static final int UC_X86_INS_SHA256MSG2 = 653; - public static final int UC_X86_INS_SHA256RNDS2 = 654; - public static final int UC_X86_INS_SHL = 655; - public static final int UC_X86_INS_SHLD = 656; - public static final int UC_X86_INS_SHLX = 657; - public static final int UC_X86_INS_SHR = 658; - public static final int UC_X86_INS_SHRD = 659; - public static final int UC_X86_INS_SHRX = 660; - public static final int UC_X86_INS_SHUFPD = 661; - public static final int UC_X86_INS_SHUFPS = 662; - public static final int UC_X86_INS_SIDT = 663; - public static final int UC_X86_INS_FSIN = 664; - public static final int UC_X86_INS_SKINIT = 665; - public static final int UC_X86_INS_SLDT = 666; - public static final int UC_X86_INS_SMSW = 667; - public static final int UC_X86_INS_SQRTPD = 668; - public static final int UC_X86_INS_SQRTPS = 669; - public static final int UC_X86_INS_SQRTSD = 670; - public static final int UC_X86_INS_SQRTSS = 671; - public static final int UC_X86_INS_FSQRT = 672; - public static final int UC_X86_INS_STAC = 673; - public static final int UC_X86_INS_STC = 674; - public static final int UC_X86_INS_STD = 675; - public static final int UC_X86_INS_STGI = 676; - public static final int UC_X86_INS_STI = 677; - public static final int UC_X86_INS_STMXCSR = 678; - public static final int UC_X86_INS_STOSB = 679; - public static final int UC_X86_INS_STOSD = 680; - public static final int UC_X86_INS_STOSQ = 681; - public static final int UC_X86_INS_STOSW = 682; - public static final int UC_X86_INS_STR = 683; - public static final int UC_X86_INS_FST = 684; - public static final int UC_X86_INS_FSTP = 685; - public static final int UC_X86_INS_FSTPNCE = 686; - public static final int UC_X86_INS_FXCH = 687; - public static final int UC_X86_INS_SUBPD = 688; - public static final int UC_X86_INS_SUBPS = 689; - public static final int UC_X86_INS_FSUBR = 690; - public static final int UC_X86_INS_FISUBR = 691; - public static final int UC_X86_INS_FSUBRP = 692; - public static final int UC_X86_INS_SUBSD = 693; - public static final int UC_X86_INS_SUBSS = 694; - public static final int UC_X86_INS_FSUB = 695; - public static final int UC_X86_INS_FISUB = 696; - public static final int UC_X86_INS_FSUBP = 697; - public static final int UC_X86_INS_SWAPGS = 698; - public static final int UC_X86_INS_SYSCALL = 699; - public static final int UC_X86_INS_SYSENTER = 700; - public static final int UC_X86_INS_SYSEXIT = 701; - public static final int UC_X86_INS_SYSRET = 702; - public static final int UC_X86_INS_T1MSKC = 703; - public static final int UC_X86_INS_TEST = 704; - public static final int UC_X86_INS_UD2 = 705; - public static final int UC_X86_INS_FTST = 706; - public static final int UC_X86_INS_TZCNT = 707; - public static final int UC_X86_INS_TZMSK = 708; - public static final int UC_X86_INS_FUCOMPI = 709; - public static final int UC_X86_INS_FUCOMI = 710; - public static final int UC_X86_INS_FUCOMPP = 711; - public static final int UC_X86_INS_FUCOMP = 712; - public static final int UC_X86_INS_FUCOM = 713; - public static final int UC_X86_INS_UD2B = 714; - public static final int UC_X86_INS_UNPCKHPD = 715; - public static final int UC_X86_INS_UNPCKHPS = 716; - public static final int UC_X86_INS_UNPCKLPD = 717; - public static final int UC_X86_INS_UNPCKLPS = 718; - public static final int UC_X86_INS_VADDPD = 719; - public static final int UC_X86_INS_VADDPS = 720; - public static final int UC_X86_INS_VADDSD = 721; - public static final int UC_X86_INS_VADDSS = 722; - public static final int UC_X86_INS_VADDSUBPD = 723; - public static final int UC_X86_INS_VADDSUBPS = 724; - public static final int UC_X86_INS_VAESDECLAST = 725; - public static final int UC_X86_INS_VAESDEC = 726; - public static final int UC_X86_INS_VAESENCLAST = 727; - public static final int UC_X86_INS_VAESENC = 728; - public static final int UC_X86_INS_VAESIMC = 729; - public static final int UC_X86_INS_VAESKEYGENASSIST = 730; - public static final int UC_X86_INS_VALIGND = 731; - public static final int UC_X86_INS_VALIGNQ = 732; - public static final int UC_X86_INS_VANDNPD = 733; - public static final int UC_X86_INS_VANDNPS = 734; - public static final int UC_X86_INS_VANDPD = 735; - public static final int UC_X86_INS_VANDPS = 736; - public static final int UC_X86_INS_VBLENDMPD = 737; - public static final int UC_X86_INS_VBLENDMPS = 738; - public static final int UC_X86_INS_VBLENDPD = 739; - public static final int UC_X86_INS_VBLENDPS = 740; - public static final int UC_X86_INS_VBLENDVPD = 741; - public static final int UC_X86_INS_VBLENDVPS = 742; - public static final int UC_X86_INS_VBROADCASTF128 = 743; - public static final int UC_X86_INS_VBROADCASTI32X4 = 744; - public static final int UC_X86_INS_VBROADCASTI64X4 = 745; - public static final int UC_X86_INS_VBROADCASTSD = 746; - public static final int UC_X86_INS_VBROADCASTSS = 747; - public static final int UC_X86_INS_VCMPPD = 748; - public static final int UC_X86_INS_VCMPPS = 749; - public static final int UC_X86_INS_VCMPSD = 750; - public static final int UC_X86_INS_VCMPSS = 751; - public static final int UC_X86_INS_VCOMPRESSPD = 752; - public static final int UC_X86_INS_VCOMPRESSPS = 753; - public static final int UC_X86_INS_VCVTDQ2PD = 754; - public static final int UC_X86_INS_VCVTDQ2PS = 755; - public static final int UC_X86_INS_VCVTPD2DQX = 756; - public static final int UC_X86_INS_VCVTPD2DQ = 757; - public static final int UC_X86_INS_VCVTPD2PSX = 758; - public static final int UC_X86_INS_VCVTPD2PS = 759; - public static final int UC_X86_INS_VCVTPD2UDQ = 760; - public static final int UC_X86_INS_VCVTPH2PS = 761; - public static final int UC_X86_INS_VCVTPS2DQ = 762; - public static final int UC_X86_INS_VCVTPS2PD = 763; - public static final int UC_X86_INS_VCVTPS2PH = 764; - public static final int UC_X86_INS_VCVTPS2UDQ = 765; - public static final int UC_X86_INS_VCVTSD2SI = 766; - public static final int UC_X86_INS_VCVTSD2USI = 767; - public static final int UC_X86_INS_VCVTSS2SI = 768; - public static final int UC_X86_INS_VCVTSS2USI = 769; - public static final int UC_X86_INS_VCVTTPD2DQX = 770; - public static final int UC_X86_INS_VCVTTPD2DQ = 771; - public static final int UC_X86_INS_VCVTTPD2UDQ = 772; - public static final int UC_X86_INS_VCVTTPS2DQ = 773; - public static final int UC_X86_INS_VCVTTPS2UDQ = 774; - public static final int UC_X86_INS_VCVTUDQ2PD = 775; - public static final int UC_X86_INS_VCVTUDQ2PS = 776; - public static final int UC_X86_INS_VDIVPD = 777; - public static final int UC_X86_INS_VDIVPS = 778; - public static final int UC_X86_INS_VDIVSD = 779; - public static final int UC_X86_INS_VDIVSS = 780; - public static final int UC_X86_INS_VDPPD = 781; - public static final int UC_X86_INS_VDPPS = 782; - public static final int UC_X86_INS_VERR = 783; - public static final int UC_X86_INS_VERW = 784; - public static final int UC_X86_INS_VEXP2PD = 785; - public static final int UC_X86_INS_VEXP2PS = 786; - public static final int UC_X86_INS_VEXPANDPD = 787; - public static final int UC_X86_INS_VEXPANDPS = 788; - public static final int UC_X86_INS_VEXTRACTF128 = 789; - public static final int UC_X86_INS_VEXTRACTF32X4 = 790; - public static final int UC_X86_INS_VEXTRACTF64X4 = 791; - public static final int UC_X86_INS_VEXTRACTI128 = 792; - public static final int UC_X86_INS_VEXTRACTI32X4 = 793; - public static final int UC_X86_INS_VEXTRACTI64X4 = 794; - public static final int UC_X86_INS_VEXTRACTPS = 795; - public static final int UC_X86_INS_VFMADD132PD = 796; - public static final int UC_X86_INS_VFMADD132PS = 797; - public static final int UC_X86_INS_VFMADDPD = 798; - public static final int UC_X86_INS_VFMADD213PD = 799; - public static final int UC_X86_INS_VFMADD231PD = 800; - public static final int UC_X86_INS_VFMADDPS = 801; - public static final int UC_X86_INS_VFMADD213PS = 802; - public static final int UC_X86_INS_VFMADD231PS = 803; - public static final int UC_X86_INS_VFMADDSD = 804; - public static final int UC_X86_INS_VFMADD213SD = 805; - public static final int UC_X86_INS_VFMADD132SD = 806; - public static final int UC_X86_INS_VFMADD231SD = 807; - public static final int UC_X86_INS_VFMADDSS = 808; - public static final int UC_X86_INS_VFMADD213SS = 809; - public static final int UC_X86_INS_VFMADD132SS = 810; - public static final int UC_X86_INS_VFMADD231SS = 811; - public static final int UC_X86_INS_VFMADDSUB132PD = 812; - public static final int UC_X86_INS_VFMADDSUB132PS = 813; - public static final int UC_X86_INS_VFMADDSUBPD = 814; - public static final int UC_X86_INS_VFMADDSUB213PD = 815; - public static final int UC_X86_INS_VFMADDSUB231PD = 816; - public static final int UC_X86_INS_VFMADDSUBPS = 817; - public static final int UC_X86_INS_VFMADDSUB213PS = 818; - public static final int UC_X86_INS_VFMADDSUB231PS = 819; - public static final int UC_X86_INS_VFMSUB132PD = 820; - public static final int UC_X86_INS_VFMSUB132PS = 821; - public static final int UC_X86_INS_VFMSUBADD132PD = 822; - public static final int UC_X86_INS_VFMSUBADD132PS = 823; - public static final int UC_X86_INS_VFMSUBADDPD = 824; - public static final int UC_X86_INS_VFMSUBADD213PD = 825; - public static final int UC_X86_INS_VFMSUBADD231PD = 826; - public static final int UC_X86_INS_VFMSUBADDPS = 827; - public static final int UC_X86_INS_VFMSUBADD213PS = 828; - public static final int UC_X86_INS_VFMSUBADD231PS = 829; - public static final int UC_X86_INS_VFMSUBPD = 830; - public static final int UC_X86_INS_VFMSUB213PD = 831; - public static final int UC_X86_INS_VFMSUB231PD = 832; - public static final int UC_X86_INS_VFMSUBPS = 833; - public static final int UC_X86_INS_VFMSUB213PS = 834; - public static final int UC_X86_INS_VFMSUB231PS = 835; - public static final int UC_X86_INS_VFMSUBSD = 836; - public static final int UC_X86_INS_VFMSUB213SD = 837; - public static final int UC_X86_INS_VFMSUB132SD = 838; - public static final int UC_X86_INS_VFMSUB231SD = 839; - public static final int UC_X86_INS_VFMSUBSS = 840; - public static final int UC_X86_INS_VFMSUB213SS = 841; - public static final int UC_X86_INS_VFMSUB132SS = 842; - public static final int UC_X86_INS_VFMSUB231SS = 843; - public static final int UC_X86_INS_VFNMADD132PD = 844; - public static final int UC_X86_INS_VFNMADD132PS = 845; - public static final int UC_X86_INS_VFNMADDPD = 846; - public static final int UC_X86_INS_VFNMADD213PD = 847; - public static final int UC_X86_INS_VFNMADD231PD = 848; - public static final int UC_X86_INS_VFNMADDPS = 849; - public static final int UC_X86_INS_VFNMADD213PS = 850; - public static final int UC_X86_INS_VFNMADD231PS = 851; - public static final int UC_X86_INS_VFNMADDSD = 852; - public static final int UC_X86_INS_VFNMADD213SD = 853; - public static final int UC_X86_INS_VFNMADD132SD = 854; - public static final int UC_X86_INS_VFNMADD231SD = 855; - public static final int UC_X86_INS_VFNMADDSS = 856; - public static final int UC_X86_INS_VFNMADD213SS = 857; - public static final int UC_X86_INS_VFNMADD132SS = 858; - public static final int UC_X86_INS_VFNMADD231SS = 859; - public static final int UC_X86_INS_VFNMSUB132PD = 860; - public static final int UC_X86_INS_VFNMSUB132PS = 861; - public static final int UC_X86_INS_VFNMSUBPD = 862; - public static final int UC_X86_INS_VFNMSUB213PD = 863; - public static final int UC_X86_INS_VFNMSUB231PD = 864; - public static final int UC_X86_INS_VFNMSUBPS = 865; - public static final int UC_X86_INS_VFNMSUB213PS = 866; - public static final int UC_X86_INS_VFNMSUB231PS = 867; - public static final int UC_X86_INS_VFNMSUBSD = 868; - public static final int UC_X86_INS_VFNMSUB213SD = 869; - public static final int UC_X86_INS_VFNMSUB132SD = 870; - public static final int UC_X86_INS_VFNMSUB231SD = 871; - public static final int UC_X86_INS_VFNMSUBSS = 872; - public static final int UC_X86_INS_VFNMSUB213SS = 873; - public static final int UC_X86_INS_VFNMSUB132SS = 874; - public static final int UC_X86_INS_VFNMSUB231SS = 875; - public static final int UC_X86_INS_VFRCZPD = 876; - public static final int UC_X86_INS_VFRCZPS = 877; - public static final int UC_X86_INS_VFRCZSD = 878; - public static final int UC_X86_INS_VFRCZSS = 879; - public static final int UC_X86_INS_VORPD = 880; - public static final int UC_X86_INS_VORPS = 881; - public static final int UC_X86_INS_VXORPD = 882; - public static final int UC_X86_INS_VXORPS = 883; - public static final int UC_X86_INS_VGATHERDPD = 884; - public static final int UC_X86_INS_VGATHERDPS = 885; - public static final int UC_X86_INS_VGATHERPF0DPD = 886; - public static final int UC_X86_INS_VGATHERPF0DPS = 887; - public static final int UC_X86_INS_VGATHERPF0QPD = 888; - public static final int UC_X86_INS_VGATHERPF0QPS = 889; - public static final int UC_X86_INS_VGATHERPF1DPD = 890; - public static final int UC_X86_INS_VGATHERPF1DPS = 891; - public static final int UC_X86_INS_VGATHERPF1QPD = 892; - public static final int UC_X86_INS_VGATHERPF1QPS = 893; - public static final int UC_X86_INS_VGATHERQPD = 894; - public static final int UC_X86_INS_VGATHERQPS = 895; - public static final int UC_X86_INS_VHADDPD = 896; - public static final int UC_X86_INS_VHADDPS = 897; - public static final int UC_X86_INS_VHSUBPD = 898; - public static final int UC_X86_INS_VHSUBPS = 899; - public static final int UC_X86_INS_VINSERTF128 = 900; - public static final int UC_X86_INS_VINSERTF32X4 = 901; - public static final int UC_X86_INS_VINSERTF32X8 = 902; - public static final int UC_X86_INS_VINSERTF64X2 = 903; - public static final int UC_X86_INS_VINSERTF64X4 = 904; - public static final int UC_X86_INS_VINSERTI128 = 905; - public static final int UC_X86_INS_VINSERTI32X4 = 906; - public static final int UC_X86_INS_VINSERTI32X8 = 907; - public static final int UC_X86_INS_VINSERTI64X2 = 908; - public static final int UC_X86_INS_VINSERTI64X4 = 909; - public static final int UC_X86_INS_VINSERTPS = 910; - public static final int UC_X86_INS_VLDDQU = 911; - public static final int UC_X86_INS_VLDMXCSR = 912; - public static final int UC_X86_INS_VMASKMOVDQU = 913; - public static final int UC_X86_INS_VMASKMOVPD = 914; - public static final int UC_X86_INS_VMASKMOVPS = 915; - public static final int UC_X86_INS_VMAXPD = 916; - public static final int UC_X86_INS_VMAXPS = 917; - public static final int UC_X86_INS_VMAXSD = 918; - public static final int UC_X86_INS_VMAXSS = 919; - public static final int UC_X86_INS_VMCALL = 920; - public static final int UC_X86_INS_VMCLEAR = 921; - public static final int UC_X86_INS_VMFUNC = 922; - public static final int UC_X86_INS_VMINPD = 923; - public static final int UC_X86_INS_VMINPS = 924; - public static final int UC_X86_INS_VMINSD = 925; - public static final int UC_X86_INS_VMINSS = 926; - public static final int UC_X86_INS_VMLAUNCH = 927; - public static final int UC_X86_INS_VMLOAD = 928; - public static final int UC_X86_INS_VMMCALL = 929; - public static final int UC_X86_INS_VMOVQ = 930; - public static final int UC_X86_INS_VMOVDDUP = 931; - public static final int UC_X86_INS_VMOVD = 932; - public static final int UC_X86_INS_VMOVDQA32 = 933; - public static final int UC_X86_INS_VMOVDQA64 = 934; - public static final int UC_X86_INS_VMOVDQA = 935; - public static final int UC_X86_INS_VMOVDQU16 = 936; - public static final int UC_X86_INS_VMOVDQU32 = 937; - public static final int UC_X86_INS_VMOVDQU64 = 938; - public static final int UC_X86_INS_VMOVDQU8 = 939; - public static final int UC_X86_INS_VMOVDQU = 940; - public static final int UC_X86_INS_VMOVHLPS = 941; - public static final int UC_X86_INS_VMOVHPD = 942; - public static final int UC_X86_INS_VMOVHPS = 943; - public static final int UC_X86_INS_VMOVLHPS = 944; - public static final int UC_X86_INS_VMOVLPD = 945; - public static final int UC_X86_INS_VMOVLPS = 946; - public static final int UC_X86_INS_VMOVMSKPD = 947; - public static final int UC_X86_INS_VMOVMSKPS = 948; - public static final int UC_X86_INS_VMOVNTDQA = 949; - public static final int UC_X86_INS_VMOVNTDQ = 950; - public static final int UC_X86_INS_VMOVNTPD = 951; - public static final int UC_X86_INS_VMOVNTPS = 952; - public static final int UC_X86_INS_VMOVSD = 953; - public static final int UC_X86_INS_VMOVSHDUP = 954; - public static final int UC_X86_INS_VMOVSLDUP = 955; - public static final int UC_X86_INS_VMOVSS = 956; - public static final int UC_X86_INS_VMOVUPD = 957; - public static final int UC_X86_INS_VMOVUPS = 958; - public static final int UC_X86_INS_VMPSADBW = 959; - public static final int UC_X86_INS_VMPTRLD = 960; - public static final int UC_X86_INS_VMPTRST = 961; - public static final int UC_X86_INS_VMREAD = 962; - public static final int UC_X86_INS_VMRESUME = 963; - public static final int UC_X86_INS_VMRUN = 964; - public static final int UC_X86_INS_VMSAVE = 965; - public static final int UC_X86_INS_VMULPD = 966; - public static final int UC_X86_INS_VMULPS = 967; - public static final int UC_X86_INS_VMULSD = 968; - public static final int UC_X86_INS_VMULSS = 969; - public static final int UC_X86_INS_VMWRITE = 970; - public static final int UC_X86_INS_VMXOFF = 971; - public static final int UC_X86_INS_VMXON = 972; - public static final int UC_X86_INS_VPABSB = 973; - public static final int UC_X86_INS_VPABSD = 974; - public static final int UC_X86_INS_VPABSQ = 975; - public static final int UC_X86_INS_VPABSW = 976; - public static final int UC_X86_INS_VPACKSSDW = 977; - public static final int UC_X86_INS_VPACKSSWB = 978; - public static final int UC_X86_INS_VPACKUSDW = 979; - public static final int UC_X86_INS_VPACKUSWB = 980; - public static final int UC_X86_INS_VPADDB = 981; - public static final int UC_X86_INS_VPADDD = 982; - public static final int UC_X86_INS_VPADDQ = 983; - public static final int UC_X86_INS_VPADDSB = 984; - public static final int UC_X86_INS_VPADDSW = 985; - public static final int UC_X86_INS_VPADDUSB = 986; - public static final int UC_X86_INS_VPADDUSW = 987; - public static final int UC_X86_INS_VPADDW = 988; - public static final int UC_X86_INS_VPALIGNR = 989; - public static final int UC_X86_INS_VPANDD = 990; - public static final int UC_X86_INS_VPANDND = 991; - public static final int UC_X86_INS_VPANDNQ = 992; - public static final int UC_X86_INS_VPANDN = 993; - public static final int UC_X86_INS_VPANDQ = 994; - public static final int UC_X86_INS_VPAND = 995; - public static final int UC_X86_INS_VPAVGB = 996; - public static final int UC_X86_INS_VPAVGW = 997; - public static final int UC_X86_INS_VPBLENDD = 998; - public static final int UC_X86_INS_VPBLENDMB = 999; - public static final int UC_X86_INS_VPBLENDMD = 1000; - public static final int UC_X86_INS_VPBLENDMQ = 1001; - public static final int UC_X86_INS_VPBLENDMW = 1002; - public static final int UC_X86_INS_VPBLENDVB = 1003; - public static final int UC_X86_INS_VPBLENDW = 1004; - public static final int UC_X86_INS_VPBROADCASTB = 1005; - public static final int UC_X86_INS_VPBROADCASTD = 1006; - public static final int UC_X86_INS_VPBROADCASTMB2Q = 1007; - public static final int UC_X86_INS_VPBROADCASTMW2D = 1008; - public static final int UC_X86_INS_VPBROADCASTQ = 1009; - public static final int UC_X86_INS_VPBROADCASTW = 1010; - public static final int UC_X86_INS_VPCLMULQDQ = 1011; - public static final int UC_X86_INS_VPCMOV = 1012; - public static final int UC_X86_INS_VPCMPB = 1013; - public static final int UC_X86_INS_VPCMPD = 1014; - public static final int UC_X86_INS_VPCMPEQB = 1015; - public static final int UC_X86_INS_VPCMPEQD = 1016; - public static final int UC_X86_INS_VPCMPEQQ = 1017; - public static final int UC_X86_INS_VPCMPEQW = 1018; - public static final int UC_X86_INS_VPCMPESTRI = 1019; - public static final int UC_X86_INS_VPCMPESTRM = 1020; - public static final int UC_X86_INS_VPCMPGTB = 1021; - public static final int UC_X86_INS_VPCMPGTD = 1022; - public static final int UC_X86_INS_VPCMPGTQ = 1023; - public static final int UC_X86_INS_VPCMPGTW = 1024; - public static final int UC_X86_INS_VPCMPISTRI = 1025; - public static final int UC_X86_INS_VPCMPISTRM = 1026; - public static final int UC_X86_INS_VPCMPQ = 1027; - public static final int UC_X86_INS_VPCMPUB = 1028; - public static final int UC_X86_INS_VPCMPUD = 1029; - public static final int UC_X86_INS_VPCMPUQ = 1030; - public static final int UC_X86_INS_VPCMPUW = 1031; - public static final int UC_X86_INS_VPCMPW = 1032; - public static final int UC_X86_INS_VPCOMB = 1033; - public static final int UC_X86_INS_VPCOMD = 1034; - public static final int UC_X86_INS_VPCOMPRESSD = 1035; - public static final int UC_X86_INS_VPCOMPRESSQ = 1036; - public static final int UC_X86_INS_VPCOMQ = 1037; - public static final int UC_X86_INS_VPCOMUB = 1038; - public static final int UC_X86_INS_VPCOMUD = 1039; - public static final int UC_X86_INS_VPCOMUQ = 1040; - public static final int UC_X86_INS_VPCOMUW = 1041; - public static final int UC_X86_INS_VPCOMW = 1042; - public static final int UC_X86_INS_VPCONFLICTD = 1043; - public static final int UC_X86_INS_VPCONFLICTQ = 1044; - public static final int UC_X86_INS_VPERM2F128 = 1045; - public static final int UC_X86_INS_VPERM2I128 = 1046; - public static final int UC_X86_INS_VPERMD = 1047; - public static final int UC_X86_INS_VPERMI2D = 1048; - public static final int UC_X86_INS_VPERMI2PD = 1049; - public static final int UC_X86_INS_VPERMI2PS = 1050; - public static final int UC_X86_INS_VPERMI2Q = 1051; - public static final int UC_X86_INS_VPERMIL2PD = 1052; - public static final int UC_X86_INS_VPERMIL2PS = 1053; - public static final int UC_X86_INS_VPERMILPD = 1054; - public static final int UC_X86_INS_VPERMILPS = 1055; - public static final int UC_X86_INS_VPERMPD = 1056; - public static final int UC_X86_INS_VPERMPS = 1057; - public static final int UC_X86_INS_VPERMQ = 1058; - public static final int UC_X86_INS_VPERMT2D = 1059; - public static final int UC_X86_INS_VPERMT2PD = 1060; - public static final int UC_X86_INS_VPERMT2PS = 1061; - public static final int UC_X86_INS_VPERMT2Q = 1062; - public static final int UC_X86_INS_VPEXPANDD = 1063; - public static final int UC_X86_INS_VPEXPANDQ = 1064; - public static final int UC_X86_INS_VPEXTRB = 1065; - public static final int UC_X86_INS_VPEXTRD = 1066; - public static final int UC_X86_INS_VPEXTRQ = 1067; - public static final int UC_X86_INS_VPEXTRW = 1068; - public static final int UC_X86_INS_VPGATHERDD = 1069; - public static final int UC_X86_INS_VPGATHERDQ = 1070; - public static final int UC_X86_INS_VPGATHERQD = 1071; - public static final int UC_X86_INS_VPGATHERQQ = 1072; - public static final int UC_X86_INS_VPHADDBD = 1073; - public static final int UC_X86_INS_VPHADDBQ = 1074; - public static final int UC_X86_INS_VPHADDBW = 1075; - public static final int UC_X86_INS_VPHADDDQ = 1076; - public static final int UC_X86_INS_VPHADDD = 1077; - public static final int UC_X86_INS_VPHADDSW = 1078; - public static final int UC_X86_INS_VPHADDUBD = 1079; - public static final int UC_X86_INS_VPHADDUBQ = 1080; - public static final int UC_X86_INS_VPHADDUBW = 1081; - public static final int UC_X86_INS_VPHADDUDQ = 1082; - public static final int UC_X86_INS_VPHADDUWD = 1083; - public static final int UC_X86_INS_VPHADDUWQ = 1084; - public static final int UC_X86_INS_VPHADDWD = 1085; - public static final int UC_X86_INS_VPHADDWQ = 1086; - public static final int UC_X86_INS_VPHADDW = 1087; - public static final int UC_X86_INS_VPHMINPOSUW = 1088; - public static final int UC_X86_INS_VPHSUBBW = 1089; - public static final int UC_X86_INS_VPHSUBDQ = 1090; - public static final int UC_X86_INS_VPHSUBD = 1091; - public static final int UC_X86_INS_VPHSUBSW = 1092; - public static final int UC_X86_INS_VPHSUBWD = 1093; - public static final int UC_X86_INS_VPHSUBW = 1094; - public static final int UC_X86_INS_VPINSRB = 1095; - public static final int UC_X86_INS_VPINSRD = 1096; - public static final int UC_X86_INS_VPINSRQ = 1097; - public static final int UC_X86_INS_VPINSRW = 1098; - public static final int UC_X86_INS_VPLZCNTD = 1099; - public static final int UC_X86_INS_VPLZCNTQ = 1100; - public static final int UC_X86_INS_VPMACSDD = 1101; - public static final int UC_X86_INS_VPMACSDQH = 1102; - public static final int UC_X86_INS_VPMACSDQL = 1103; - public static final int UC_X86_INS_VPMACSSDD = 1104; - public static final int UC_X86_INS_VPMACSSDQH = 1105; - public static final int UC_X86_INS_VPMACSSDQL = 1106; - public static final int UC_X86_INS_VPMACSSWD = 1107; - public static final int UC_X86_INS_VPMACSSWW = 1108; - public static final int UC_X86_INS_VPMACSWD = 1109; - public static final int UC_X86_INS_VPMACSWW = 1110; - public static final int UC_X86_INS_VPMADCSSWD = 1111; - public static final int UC_X86_INS_VPMADCSWD = 1112; - public static final int UC_X86_INS_VPMADDUBSW = 1113; - public static final int UC_X86_INS_VPMADDWD = 1114; - public static final int UC_X86_INS_VPMASKMOVD = 1115; - public static final int UC_X86_INS_VPMASKMOVQ = 1116; - public static final int UC_X86_INS_VPMAXSB = 1117; - public static final int UC_X86_INS_VPMAXSD = 1118; - public static final int UC_X86_INS_VPMAXSQ = 1119; - public static final int UC_X86_INS_VPMAXSW = 1120; - public static final int UC_X86_INS_VPMAXUB = 1121; - public static final int UC_X86_INS_VPMAXUD = 1122; - public static final int UC_X86_INS_VPMAXUQ = 1123; - public static final int UC_X86_INS_VPMAXUW = 1124; - public static final int UC_X86_INS_VPMINSB = 1125; - public static final int UC_X86_INS_VPMINSD = 1126; - public static final int UC_X86_INS_VPMINSQ = 1127; - public static final int UC_X86_INS_VPMINSW = 1128; - public static final int UC_X86_INS_VPMINUB = 1129; - public static final int UC_X86_INS_VPMINUD = 1130; - public static final int UC_X86_INS_VPMINUQ = 1131; - public static final int UC_X86_INS_VPMINUW = 1132; - public static final int UC_X86_INS_VPMOVDB = 1133; - public static final int UC_X86_INS_VPMOVDW = 1134; - public static final int UC_X86_INS_VPMOVM2B = 1135; - public static final int UC_X86_INS_VPMOVM2D = 1136; - public static final int UC_X86_INS_VPMOVM2Q = 1137; - public static final int UC_X86_INS_VPMOVM2W = 1138; - public static final int UC_X86_INS_VPMOVMSKB = 1139; - public static final int UC_X86_INS_VPMOVQB = 1140; - public static final int UC_X86_INS_VPMOVQD = 1141; - public static final int UC_X86_INS_VPMOVQW = 1142; - public static final int UC_X86_INS_VPMOVSDB = 1143; - public static final int UC_X86_INS_VPMOVSDW = 1144; - public static final int UC_X86_INS_VPMOVSQB = 1145; - public static final int UC_X86_INS_VPMOVSQD = 1146; - public static final int UC_X86_INS_VPMOVSQW = 1147; - public static final int UC_X86_INS_VPMOVSXBD = 1148; - public static final int UC_X86_INS_VPMOVSXBQ = 1149; - public static final int UC_X86_INS_VPMOVSXBW = 1150; - public static final int UC_X86_INS_VPMOVSXDQ = 1151; - public static final int UC_X86_INS_VPMOVSXWD = 1152; - public static final int UC_X86_INS_VPMOVSXWQ = 1153; - public static final int UC_X86_INS_VPMOVUSDB = 1154; - public static final int UC_X86_INS_VPMOVUSDW = 1155; - public static final int UC_X86_INS_VPMOVUSQB = 1156; - public static final int UC_X86_INS_VPMOVUSQD = 1157; - public static final int UC_X86_INS_VPMOVUSQW = 1158; - public static final int UC_X86_INS_VPMOVZXBD = 1159; - public static final int UC_X86_INS_VPMOVZXBQ = 1160; - public static final int UC_X86_INS_VPMOVZXBW = 1161; - public static final int UC_X86_INS_VPMOVZXDQ = 1162; - public static final int UC_X86_INS_VPMOVZXWD = 1163; - public static final int UC_X86_INS_VPMOVZXWQ = 1164; - public static final int UC_X86_INS_VPMULDQ = 1165; - public static final int UC_X86_INS_VPMULHRSW = 1166; - public static final int UC_X86_INS_VPMULHUW = 1167; - public static final int UC_X86_INS_VPMULHW = 1168; - public static final int UC_X86_INS_VPMULLD = 1169; - public static final int UC_X86_INS_VPMULLQ = 1170; - public static final int UC_X86_INS_VPMULLW = 1171; - public static final int UC_X86_INS_VPMULUDQ = 1172; - public static final int UC_X86_INS_VPORD = 1173; - public static final int UC_X86_INS_VPORQ = 1174; - public static final int UC_X86_INS_VPOR = 1175; - public static final int UC_X86_INS_VPPERM = 1176; - public static final int UC_X86_INS_VPROTB = 1177; - public static final int UC_X86_INS_VPROTD = 1178; - public static final int UC_X86_INS_VPROTQ = 1179; - public static final int UC_X86_INS_VPROTW = 1180; - public static final int UC_X86_INS_VPSADBW = 1181; - public static final int UC_X86_INS_VPSCATTERDD = 1182; - public static final int UC_X86_INS_VPSCATTERDQ = 1183; - public static final int UC_X86_INS_VPSCATTERQD = 1184; - public static final int UC_X86_INS_VPSCATTERQQ = 1185; - public static final int UC_X86_INS_VPSHAB = 1186; - public static final int UC_X86_INS_VPSHAD = 1187; - public static final int UC_X86_INS_VPSHAQ = 1188; - public static final int UC_X86_INS_VPSHAW = 1189; - public static final int UC_X86_INS_VPSHLB = 1190; - public static final int UC_X86_INS_VPSHLD = 1191; - public static final int UC_X86_INS_VPSHLQ = 1192; - public static final int UC_X86_INS_VPSHLW = 1193; - public static final int UC_X86_INS_VPSHUFB = 1194; - public static final int UC_X86_INS_VPSHUFD = 1195; - public static final int UC_X86_INS_VPSHUFHW = 1196; - public static final int UC_X86_INS_VPSHUFLW = 1197; - public static final int UC_X86_INS_VPSIGNB = 1198; - public static final int UC_X86_INS_VPSIGND = 1199; - public static final int UC_X86_INS_VPSIGNW = 1200; - public static final int UC_X86_INS_VPSLLDQ = 1201; - public static final int UC_X86_INS_VPSLLD = 1202; - public static final int UC_X86_INS_VPSLLQ = 1203; - public static final int UC_X86_INS_VPSLLVD = 1204; - public static final int UC_X86_INS_VPSLLVQ = 1205; - public static final int UC_X86_INS_VPSLLW = 1206; - public static final int UC_X86_INS_VPSRAD = 1207; - public static final int UC_X86_INS_VPSRAQ = 1208; - public static final int UC_X86_INS_VPSRAVD = 1209; - public static final int UC_X86_INS_VPSRAVQ = 1210; - public static final int UC_X86_INS_VPSRAW = 1211; - public static final int UC_X86_INS_VPSRLDQ = 1212; - public static final int UC_X86_INS_VPSRLD = 1213; - public static final int UC_X86_INS_VPSRLQ = 1214; - public static final int UC_X86_INS_VPSRLVD = 1215; - public static final int UC_X86_INS_VPSRLVQ = 1216; - public static final int UC_X86_INS_VPSRLW = 1217; - public static final int UC_X86_INS_VPSUBB = 1218; - public static final int UC_X86_INS_VPSUBD = 1219; - public static final int UC_X86_INS_VPSUBQ = 1220; - public static final int UC_X86_INS_VPSUBSB = 1221; - public static final int UC_X86_INS_VPSUBSW = 1222; - public static final int UC_X86_INS_VPSUBUSB = 1223; - public static final int UC_X86_INS_VPSUBUSW = 1224; - public static final int UC_X86_INS_VPSUBW = 1225; - public static final int UC_X86_INS_VPTESTMD = 1226; - public static final int UC_X86_INS_VPTESTMQ = 1227; - public static final int UC_X86_INS_VPTESTNMD = 1228; - public static final int UC_X86_INS_VPTESTNMQ = 1229; - public static final int UC_X86_INS_VPTEST = 1230; - public static final int UC_X86_INS_VPUNPCKHBW = 1231; - public static final int UC_X86_INS_VPUNPCKHDQ = 1232; - public static final int UC_X86_INS_VPUNPCKHQDQ = 1233; - public static final int UC_X86_INS_VPUNPCKHWD = 1234; - public static final int UC_X86_INS_VPUNPCKLBW = 1235; - public static final int UC_X86_INS_VPUNPCKLDQ = 1236; - public static final int UC_X86_INS_VPUNPCKLQDQ = 1237; - public static final int UC_X86_INS_VPUNPCKLWD = 1238; - public static final int UC_X86_INS_VPXORD = 1239; - public static final int UC_X86_INS_VPXORQ = 1240; - public static final int UC_X86_INS_VPXOR = 1241; - public static final int UC_X86_INS_VRCP14PD = 1242; - public static final int UC_X86_INS_VRCP14PS = 1243; - public static final int UC_X86_INS_VRCP14SD = 1244; - public static final int UC_X86_INS_VRCP14SS = 1245; - public static final int UC_X86_INS_VRCP28PD = 1246; - public static final int UC_X86_INS_VRCP28PS = 1247; - public static final int UC_X86_INS_VRCP28SD = 1248; - public static final int UC_X86_INS_VRCP28SS = 1249; - public static final int UC_X86_INS_VRCPPS = 1250; - public static final int UC_X86_INS_VRCPSS = 1251; - public static final int UC_X86_INS_VRNDSCALEPD = 1252; - public static final int UC_X86_INS_VRNDSCALEPS = 1253; - public static final int UC_X86_INS_VRNDSCALESD = 1254; - public static final int UC_X86_INS_VRNDSCALESS = 1255; - public static final int UC_X86_INS_VROUNDPD = 1256; - public static final int UC_X86_INS_VROUNDPS = 1257; - public static final int UC_X86_INS_VROUNDSD = 1258; - public static final int UC_X86_INS_VROUNDSS = 1259; - public static final int UC_X86_INS_VRSQRT14PD = 1260; - public static final int UC_X86_INS_VRSQRT14PS = 1261; - public static final int UC_X86_INS_VRSQRT14SD = 1262; - public static final int UC_X86_INS_VRSQRT14SS = 1263; - public static final int UC_X86_INS_VRSQRT28PD = 1264; - public static final int UC_X86_INS_VRSQRT28PS = 1265; - public static final int UC_X86_INS_VRSQRT28SD = 1266; - public static final int UC_X86_INS_VRSQRT28SS = 1267; - public static final int UC_X86_INS_VRSQRTPS = 1268; - public static final int UC_X86_INS_VRSQRTSS = 1269; - public static final int UC_X86_INS_VSCATTERDPD = 1270; - public static final int UC_X86_INS_VSCATTERDPS = 1271; - public static final int UC_X86_INS_VSCATTERPF0DPD = 1272; - public static final int UC_X86_INS_VSCATTERPF0DPS = 1273; - public static final int UC_X86_INS_VSCATTERPF0QPD = 1274; - public static final int UC_X86_INS_VSCATTERPF0QPS = 1275; - public static final int UC_X86_INS_VSCATTERPF1DPD = 1276; - public static final int UC_X86_INS_VSCATTERPF1DPS = 1277; - public static final int UC_X86_INS_VSCATTERPF1QPD = 1278; - public static final int UC_X86_INS_VSCATTERPF1QPS = 1279; - public static final int UC_X86_INS_VSCATTERQPD = 1280; - public static final int UC_X86_INS_VSCATTERQPS = 1281; - public static final int UC_X86_INS_VSHUFPD = 1282; - public static final int UC_X86_INS_VSHUFPS = 1283; - public static final int UC_X86_INS_VSQRTPD = 1284; - public static final int UC_X86_INS_VSQRTPS = 1285; - public static final int UC_X86_INS_VSQRTSD = 1286; - public static final int UC_X86_INS_VSQRTSS = 1287; - public static final int UC_X86_INS_VSTMXCSR = 1288; - public static final int UC_X86_INS_VSUBPD = 1289; - public static final int UC_X86_INS_VSUBPS = 1290; - public static final int UC_X86_INS_VSUBSD = 1291; - public static final int UC_X86_INS_VSUBSS = 1292; - public static final int UC_X86_INS_VTESTPD = 1293; - public static final int UC_X86_INS_VTESTPS = 1294; - public static final int UC_X86_INS_VUNPCKHPD = 1295; - public static final int UC_X86_INS_VUNPCKHPS = 1296; - public static final int UC_X86_INS_VUNPCKLPD = 1297; - public static final int UC_X86_INS_VUNPCKLPS = 1298; - public static final int UC_X86_INS_VZEROALL = 1299; - public static final int UC_X86_INS_VZEROUPPER = 1300; - public static final int UC_X86_INS_WAIT = 1301; - public static final int UC_X86_INS_WBINVD = 1302; - public static final int UC_X86_INS_WRFSBASE = 1303; - public static final int UC_X86_INS_WRGSBASE = 1304; - public static final int UC_X86_INS_WRMSR = 1305; - public static final int UC_X86_INS_XABORT = 1306; - public static final int UC_X86_INS_XACQUIRE = 1307; - public static final int UC_X86_INS_XBEGIN = 1308; - public static final int UC_X86_INS_XCHG = 1309; - public static final int UC_X86_INS_XCRYPTCBC = 1310; - public static final int UC_X86_INS_XCRYPTCFB = 1311; - public static final int UC_X86_INS_XCRYPTCTR = 1312; - public static final int UC_X86_INS_XCRYPTECB = 1313; - public static final int UC_X86_INS_XCRYPTOFB = 1314; - public static final int UC_X86_INS_XEND = 1315; - public static final int UC_X86_INS_XGETBV = 1316; - public static final int UC_X86_INS_XLATB = 1317; - public static final int UC_X86_INS_XRELEASE = 1318; - public static final int UC_X86_INS_XRSTOR = 1319; - public static final int UC_X86_INS_XRSTOR64 = 1320; - public static final int UC_X86_INS_XRSTORS = 1321; - public static final int UC_X86_INS_XRSTORS64 = 1322; - public static final int UC_X86_INS_XSAVE = 1323; - public static final int UC_X86_INS_XSAVE64 = 1324; - public static final int UC_X86_INS_XSAVEC = 1325; - public static final int UC_X86_INS_XSAVEC64 = 1326; - public static final int UC_X86_INS_XSAVEOPT = 1327; - public static final int UC_X86_INS_XSAVEOPT64 = 1328; - public static final int UC_X86_INS_XSAVES = 1329; - public static final int UC_X86_INS_XSAVES64 = 1330; - public static final int UC_X86_INS_XSETBV = 1331; - public static final int UC_X86_INS_XSHA1 = 1332; - public static final int UC_X86_INS_XSHA256 = 1333; - public static final int UC_X86_INS_XSTORE = 1334; - public static final int UC_X86_INS_XTEST = 1335; - public static final int UC_X86_INS_FDISI8087_NOP = 1336; - public static final int UC_X86_INS_FENI8087_NOP = 1337; - public static final int UC_X86_INS_ENDING = 1338; + public static final int UC_X86_INS_INVALID = 0; + public static final int UC_X86_INS_AAA = 1; + public static final int UC_X86_INS_AAD = 2; + public static final int UC_X86_INS_AAM = 3; + public static final int UC_X86_INS_AAS = 4; + public static final int UC_X86_INS_FABS = 5; + public static final int UC_X86_INS_ADC = 6; + public static final int UC_X86_INS_ADCX = 7; + public static final int UC_X86_INS_ADD = 8; + public static final int UC_X86_INS_ADDPD = 9; + public static final int UC_X86_INS_ADDPS = 10; + public static final int UC_X86_INS_ADDSD = 11; + public static final int UC_X86_INS_ADDSS = 12; + public static final int UC_X86_INS_ADDSUBPD = 13; + public static final int UC_X86_INS_ADDSUBPS = 14; + public static final int UC_X86_INS_FADD = 15; + public static final int UC_X86_INS_FIADD = 16; + public static final int UC_X86_INS_FADDP = 17; + public static final int UC_X86_INS_ADOX = 18; + public static final int UC_X86_INS_AESDECLAST = 19; + public static final int UC_X86_INS_AESDEC = 20; + public static final int UC_X86_INS_AESENCLAST = 21; + public static final int UC_X86_INS_AESENC = 22; + public static final int UC_X86_INS_AESIMC = 23; + public static final int UC_X86_INS_AESKEYGENASSIST = 24; + public static final int UC_X86_INS_AND = 25; + public static final int UC_X86_INS_ANDN = 26; + public static final int UC_X86_INS_ANDNPD = 27; + public static final int UC_X86_INS_ANDNPS = 28; + public static final int UC_X86_INS_ANDPD = 29; + public static final int UC_X86_INS_ANDPS = 30; + public static final int UC_X86_INS_ARPL = 31; + public static final int UC_X86_INS_BEXTR = 32; + public static final int UC_X86_INS_BLCFILL = 33; + public static final int UC_X86_INS_BLCI = 34; + public static final int UC_X86_INS_BLCIC = 35; + public static final int UC_X86_INS_BLCMSK = 36; + public static final int UC_X86_INS_BLCS = 37; + public static final int UC_X86_INS_BLENDPD = 38; + public static final int UC_X86_INS_BLENDPS = 39; + public static final int UC_X86_INS_BLENDVPD = 40; + public static final int UC_X86_INS_BLENDVPS = 41; + public static final int UC_X86_INS_BLSFILL = 42; + public static final int UC_X86_INS_BLSI = 43; + public static final int UC_X86_INS_BLSIC = 44; + public static final int UC_X86_INS_BLSMSK = 45; + public static final int UC_X86_INS_BLSR = 46; + public static final int UC_X86_INS_BOUND = 47; + public static final int UC_X86_INS_BSF = 48; + public static final int UC_X86_INS_BSR = 49; + public static final int UC_X86_INS_BSWAP = 50; + public static final int UC_X86_INS_BT = 51; + public static final int UC_X86_INS_BTC = 52; + public static final int UC_X86_INS_BTR = 53; + public static final int UC_X86_INS_BTS = 54; + public static final int UC_X86_INS_BZHI = 55; + public static final int UC_X86_INS_CALL = 56; + public static final int UC_X86_INS_CBW = 57; + public static final int UC_X86_INS_CDQ = 58; + public static final int UC_X86_INS_CDQE = 59; + public static final int UC_X86_INS_FCHS = 60; + public static final int UC_X86_INS_CLAC = 61; + public static final int UC_X86_INS_CLC = 62; + public static final int UC_X86_INS_CLD = 63; + public static final int UC_X86_INS_CLFLUSH = 64; + public static final int UC_X86_INS_CLFLUSHOPT = 65; + public static final int UC_X86_INS_CLGI = 66; + public static final int UC_X86_INS_CLI = 67; + public static final int UC_X86_INS_CLTS = 68; + public static final int UC_X86_INS_CLWB = 69; + public static final int UC_X86_INS_CMC = 70; + public static final int UC_X86_INS_CMOVA = 71; + public static final int UC_X86_INS_CMOVAE = 72; + public static final int UC_X86_INS_CMOVB = 73; + public static final int UC_X86_INS_CMOVBE = 74; + public static final int UC_X86_INS_FCMOVBE = 75; + public static final int UC_X86_INS_FCMOVB = 76; + public static final int UC_X86_INS_CMOVE = 77; + public static final int UC_X86_INS_FCMOVE = 78; + public static final int UC_X86_INS_CMOVG = 79; + public static final int UC_X86_INS_CMOVGE = 80; + public static final int UC_X86_INS_CMOVL = 81; + public static final int UC_X86_INS_CMOVLE = 82; + public static final int UC_X86_INS_FCMOVNBE = 83; + public static final int UC_X86_INS_FCMOVNB = 84; + public static final int UC_X86_INS_CMOVNE = 85; + public static final int UC_X86_INS_FCMOVNE = 86; + public static final int UC_X86_INS_CMOVNO = 87; + public static final int UC_X86_INS_CMOVNP = 88; + public static final int UC_X86_INS_FCMOVNU = 89; + public static final int UC_X86_INS_CMOVNS = 90; + public static final int UC_X86_INS_CMOVO = 91; + public static final int UC_X86_INS_CMOVP = 92; + public static final int UC_X86_INS_FCMOVU = 93; + public static final int UC_X86_INS_CMOVS = 94; + public static final int UC_X86_INS_CMP = 95; + public static final int UC_X86_INS_CMPPD = 96; + public static final int UC_X86_INS_CMPPS = 97; + public static final int UC_X86_INS_CMPSB = 98; + public static final int UC_X86_INS_CMPSD = 99; + public static final int UC_X86_INS_CMPSQ = 100; + public static final int UC_X86_INS_CMPSS = 101; + public static final int UC_X86_INS_CMPSW = 102; + public static final int UC_X86_INS_CMPXCHG16B = 103; + public static final int UC_X86_INS_CMPXCHG = 104; + public static final int UC_X86_INS_CMPXCHG8B = 105; + public static final int UC_X86_INS_COMISD = 106; + public static final int UC_X86_INS_COMISS = 107; + public static final int UC_X86_INS_FCOMP = 108; + public static final int UC_X86_INS_FCOMPI = 109; + public static final int UC_X86_INS_FCOMI = 110; + public static final int UC_X86_INS_FCOM = 111; + public static final int UC_X86_INS_FCOS = 112; + public static final int UC_X86_INS_CPUID = 113; + public static final int UC_X86_INS_CQO = 114; + public static final int UC_X86_INS_CRC32 = 115; + public static final int UC_X86_INS_CVTDQ2PD = 116; + public static final int UC_X86_INS_CVTDQ2PS = 117; + public static final int UC_X86_INS_CVTPD2DQ = 118; + public static final int UC_X86_INS_CVTPD2PS = 119; + public static final int UC_X86_INS_CVTPS2DQ = 120; + public static final int UC_X86_INS_CVTPS2PD = 121; + public static final int UC_X86_INS_CVTSD2SI = 122; + public static final int UC_X86_INS_CVTSD2SS = 123; + public static final int UC_X86_INS_CVTSI2SD = 124; + public static final int UC_X86_INS_CVTSI2SS = 125; + public static final int UC_X86_INS_CVTSS2SD = 126; + public static final int UC_X86_INS_CVTSS2SI = 127; + public static final int UC_X86_INS_CVTTPD2DQ = 128; + public static final int UC_X86_INS_CVTTPS2DQ = 129; + public static final int UC_X86_INS_CVTTSD2SI = 130; + public static final int UC_X86_INS_CVTTSS2SI = 131; + public static final int UC_X86_INS_CWD = 132; + public static final int UC_X86_INS_CWDE = 133; + public static final int UC_X86_INS_DAA = 134; + public static final int UC_X86_INS_DAS = 135; + public static final int UC_X86_INS_DATA16 = 136; + public static final int UC_X86_INS_DEC = 137; + public static final int UC_X86_INS_DIV = 138; + public static final int UC_X86_INS_DIVPD = 139; + public static final int UC_X86_INS_DIVPS = 140; + public static final int UC_X86_INS_FDIVR = 141; + public static final int UC_X86_INS_FIDIVR = 142; + public static final int UC_X86_INS_FDIVRP = 143; + public static final int UC_X86_INS_DIVSD = 144; + public static final int UC_X86_INS_DIVSS = 145; + public static final int UC_X86_INS_FDIV = 146; + public static final int UC_X86_INS_FIDIV = 147; + public static final int UC_X86_INS_FDIVP = 148; + public static final int UC_X86_INS_DPPD = 149; + public static final int UC_X86_INS_DPPS = 150; + public static final int UC_X86_INS_RET = 151; + public static final int UC_X86_INS_ENCLS = 152; + public static final int UC_X86_INS_ENCLU = 153; + public static final int UC_X86_INS_ENTER = 154; + public static final int UC_X86_INS_EXTRACTPS = 155; + public static final int UC_X86_INS_EXTRQ = 156; + public static final int UC_X86_INS_F2XM1 = 157; + public static final int UC_X86_INS_LCALL = 158; + public static final int UC_X86_INS_LJMP = 159; + public static final int UC_X86_INS_FBLD = 160; + public static final int UC_X86_INS_FBSTP = 161; + public static final int UC_X86_INS_FCOMPP = 162; + public static final int UC_X86_INS_FDECSTP = 163; + public static final int UC_X86_INS_FEMMS = 164; + public static final int UC_X86_INS_FFREE = 165; + public static final int UC_X86_INS_FICOM = 166; + public static final int UC_X86_INS_FICOMP = 167; + public static final int UC_X86_INS_FINCSTP = 168; + public static final int UC_X86_INS_FLDCW = 169; + public static final int UC_X86_INS_FLDENV = 170; + public static final int UC_X86_INS_FLDL2E = 171; + public static final int UC_X86_INS_FLDL2T = 172; + public static final int UC_X86_INS_FLDLG2 = 173; + public static final int UC_X86_INS_FLDLN2 = 174; + public static final int UC_X86_INS_FLDPI = 175; + public static final int UC_X86_INS_FNCLEX = 176; + public static final int UC_X86_INS_FNINIT = 177; + public static final int UC_X86_INS_FNOP = 178; + public static final int UC_X86_INS_FNSTCW = 179; + public static final int UC_X86_INS_FNSTSW = 180; + public static final int UC_X86_INS_FPATAN = 181; + public static final int UC_X86_INS_FPREM = 182; + public static final int UC_X86_INS_FPREM1 = 183; + public static final int UC_X86_INS_FPTAN = 184; + public static final int UC_X86_INS_FFREEP = 185; + public static final int UC_X86_INS_FRNDINT = 186; + public static final int UC_X86_INS_FRSTOR = 187; + public static final int UC_X86_INS_FNSAVE = 188; + public static final int UC_X86_INS_FSCALE = 189; + public static final int UC_X86_INS_FSETPM = 190; + public static final int UC_X86_INS_FSINCOS = 191; + public static final int UC_X86_INS_FNSTENV = 192; + public static final int UC_X86_INS_FXAM = 193; + public static final int UC_X86_INS_FXRSTOR = 194; + public static final int UC_X86_INS_FXRSTOR64 = 195; + public static final int UC_X86_INS_FXSAVE = 196; + public static final int UC_X86_INS_FXSAVE64 = 197; + public static final int UC_X86_INS_FXTRACT = 198; + public static final int UC_X86_INS_FYL2X = 199; + public static final int UC_X86_INS_FYL2XP1 = 200; + public static final int UC_X86_INS_MOVAPD = 201; + public static final int UC_X86_INS_MOVAPS = 202; + public static final int UC_X86_INS_ORPD = 203; + public static final int UC_X86_INS_ORPS = 204; + public static final int UC_X86_INS_VMOVAPD = 205; + public static final int UC_X86_INS_VMOVAPS = 206; + public static final int UC_X86_INS_XORPD = 207; + public static final int UC_X86_INS_XORPS = 208; + public static final int UC_X86_INS_GETSEC = 209; + public static final int UC_X86_INS_HADDPD = 210; + public static final int UC_X86_INS_HADDPS = 211; + public static final int UC_X86_INS_HLT = 212; + public static final int UC_X86_INS_HSUBPD = 213; + public static final int UC_X86_INS_HSUBPS = 214; + public static final int UC_X86_INS_IDIV = 215; + public static final int UC_X86_INS_FILD = 216; + public static final int UC_X86_INS_IMUL = 217; + public static final int UC_X86_INS_IN = 218; + public static final int UC_X86_INS_INC = 219; + public static final int UC_X86_INS_INSB = 220; + public static final int UC_X86_INS_INSERTPS = 221; + public static final int UC_X86_INS_INSERTQ = 222; + public static final int UC_X86_INS_INSD = 223; + public static final int UC_X86_INS_INSW = 224; + public static final int UC_X86_INS_INT = 225; + public static final int UC_X86_INS_INT1 = 226; + public static final int UC_X86_INS_INT3 = 227; + public static final int UC_X86_INS_INTO = 228; + public static final int UC_X86_INS_INVD = 229; + public static final int UC_X86_INS_INVEPT = 230; + public static final int UC_X86_INS_INVLPG = 231; + public static final int UC_X86_INS_INVLPGA = 232; + public static final int UC_X86_INS_INVPCID = 233; + public static final int UC_X86_INS_INVVPID = 234; + public static final int UC_X86_INS_IRET = 235; + public static final int UC_X86_INS_IRETD = 236; + public static final int UC_X86_INS_IRETQ = 237; + public static final int UC_X86_INS_FISTTP = 238; + public static final int UC_X86_INS_FIST = 239; + public static final int UC_X86_INS_FISTP = 240; + public static final int UC_X86_INS_UCOMISD = 241; + public static final int UC_X86_INS_UCOMISS = 242; + public static final int UC_X86_INS_VCOMISD = 243; + public static final int UC_X86_INS_VCOMISS = 244; + public static final int UC_X86_INS_VCVTSD2SS = 245; + public static final int UC_X86_INS_VCVTSI2SD = 246; + public static final int UC_X86_INS_VCVTSI2SS = 247; + public static final int UC_X86_INS_VCVTSS2SD = 248; + public static final int UC_X86_INS_VCVTTSD2SI = 249; + public static final int UC_X86_INS_VCVTTSD2USI = 250; + public static final int UC_X86_INS_VCVTTSS2SI = 251; + public static final int UC_X86_INS_VCVTTSS2USI = 252; + public static final int UC_X86_INS_VCVTUSI2SD = 253; + public static final int UC_X86_INS_VCVTUSI2SS = 254; + public static final int UC_X86_INS_VUCOMISD = 255; + public static final int UC_X86_INS_VUCOMISS = 256; + public static final int UC_X86_INS_JAE = 257; + public static final int UC_X86_INS_JA = 258; + public static final int UC_X86_INS_JBE = 259; + public static final int UC_X86_INS_JB = 260; + public static final int UC_X86_INS_JCXZ = 261; + public static final int UC_X86_INS_JECXZ = 262; + public static final int UC_X86_INS_JE = 263; + public static final int UC_X86_INS_JGE = 264; + public static final int UC_X86_INS_JG = 265; + public static final int UC_X86_INS_JLE = 266; + public static final int UC_X86_INS_JL = 267; + public static final int UC_X86_INS_JMP = 268; + public static final int UC_X86_INS_JNE = 269; + public static final int UC_X86_INS_JNO = 270; + public static final int UC_X86_INS_JNP = 271; + public static final int UC_X86_INS_JNS = 272; + public static final int UC_X86_INS_JO = 273; + public static final int UC_X86_INS_JP = 274; + public static final int UC_X86_INS_JRCXZ = 275; + public static final int UC_X86_INS_JS = 276; + public static final int UC_X86_INS_KANDB = 277; + public static final int UC_X86_INS_KANDD = 278; + public static final int UC_X86_INS_KANDNB = 279; + public static final int UC_X86_INS_KANDND = 280; + public static final int UC_X86_INS_KANDNQ = 281; + public static final int UC_X86_INS_KANDNW = 282; + public static final int UC_X86_INS_KANDQ = 283; + public static final int UC_X86_INS_KANDW = 284; + public static final int UC_X86_INS_KMOVB = 285; + public static final int UC_X86_INS_KMOVD = 286; + public static final int UC_X86_INS_KMOVQ = 287; + public static final int UC_X86_INS_KMOVW = 288; + public static final int UC_X86_INS_KNOTB = 289; + public static final int UC_X86_INS_KNOTD = 290; + public static final int UC_X86_INS_KNOTQ = 291; + public static final int UC_X86_INS_KNOTW = 292; + public static final int UC_X86_INS_KORB = 293; + public static final int UC_X86_INS_KORD = 294; + public static final int UC_X86_INS_KORQ = 295; + public static final int UC_X86_INS_KORTESTB = 296; + public static final int UC_X86_INS_KORTESTD = 297; + public static final int UC_X86_INS_KORTESTQ = 298; + public static final int UC_X86_INS_KORTESTW = 299; + public static final int UC_X86_INS_KORW = 300; + public static final int UC_X86_INS_KSHIFTLB = 301; + public static final int UC_X86_INS_KSHIFTLD = 302; + public static final int UC_X86_INS_KSHIFTLQ = 303; + public static final int UC_X86_INS_KSHIFTLW = 304; + public static final int UC_X86_INS_KSHIFTRB = 305; + public static final int UC_X86_INS_KSHIFTRD = 306; + public static final int UC_X86_INS_KSHIFTRQ = 307; + public static final int UC_X86_INS_KSHIFTRW = 308; + public static final int UC_X86_INS_KUNPCKBW = 309; + public static final int UC_X86_INS_KXNORB = 310; + public static final int UC_X86_INS_KXNORD = 311; + public static final int UC_X86_INS_KXNORQ = 312; + public static final int UC_X86_INS_KXNORW = 313; + public static final int UC_X86_INS_KXORB = 314; + public static final int UC_X86_INS_KXORD = 315; + public static final int UC_X86_INS_KXORQ = 316; + public static final int UC_X86_INS_KXORW = 317; + public static final int UC_X86_INS_LAHF = 318; + public static final int UC_X86_INS_LAR = 319; + public static final int UC_X86_INS_LDDQU = 320; + public static final int UC_X86_INS_LDMXCSR = 321; + public static final int UC_X86_INS_LDS = 322; + public static final int UC_X86_INS_FLDZ = 323; + public static final int UC_X86_INS_FLD1 = 324; + public static final int UC_X86_INS_FLD = 325; + public static final int UC_X86_INS_LEA = 326; + public static final int UC_X86_INS_LEAVE = 327; + public static final int UC_X86_INS_LES = 328; + public static final int UC_X86_INS_LFENCE = 329; + public static final int UC_X86_INS_LFS = 330; + public static final int UC_X86_INS_LGDT = 331; + public static final int UC_X86_INS_LGS = 332; + public static final int UC_X86_INS_LIDT = 333; + public static final int UC_X86_INS_LLDT = 334; + public static final int UC_X86_INS_LMSW = 335; + public static final int UC_X86_INS_OR = 336; + public static final int UC_X86_INS_SUB = 337; + public static final int UC_X86_INS_XOR = 338; + public static final int UC_X86_INS_LODSB = 339; + public static final int UC_X86_INS_LODSD = 340; + public static final int UC_X86_INS_LODSQ = 341; + public static final int UC_X86_INS_LODSW = 342; + public static final int UC_X86_INS_LOOP = 343; + public static final int UC_X86_INS_LOOPE = 344; + public static final int UC_X86_INS_LOOPNE = 345; + public static final int UC_X86_INS_RETF = 346; + public static final int UC_X86_INS_RETFQ = 347; + public static final int UC_X86_INS_LSL = 348; + public static final int UC_X86_INS_LSS = 349; + public static final int UC_X86_INS_LTR = 350; + public static final int UC_X86_INS_XADD = 351; + public static final int UC_X86_INS_LZCNT = 352; + public static final int UC_X86_INS_MASKMOVDQU = 353; + public static final int UC_X86_INS_MAXPD = 354; + public static final int UC_X86_INS_MAXPS = 355; + public static final int UC_X86_INS_MAXSD = 356; + public static final int UC_X86_INS_MAXSS = 357; + public static final int UC_X86_INS_MFENCE = 358; + public static final int UC_X86_INS_MINPD = 359; + public static final int UC_X86_INS_MINPS = 360; + public static final int UC_X86_INS_MINSD = 361; + public static final int UC_X86_INS_MINSS = 362; + public static final int UC_X86_INS_CVTPD2PI = 363; + public static final int UC_X86_INS_CVTPI2PD = 364; + public static final int UC_X86_INS_CVTPI2PS = 365; + public static final int UC_X86_INS_CVTPS2PI = 366; + public static final int UC_X86_INS_CVTTPD2PI = 367; + public static final int UC_X86_INS_CVTTPS2PI = 368; + public static final int UC_X86_INS_EMMS = 369; + public static final int UC_X86_INS_MASKMOVQ = 370; + public static final int UC_X86_INS_MOVD = 371; + public static final int UC_X86_INS_MOVDQ2Q = 372; + public static final int UC_X86_INS_MOVNTQ = 373; + public static final int UC_X86_INS_MOVQ2DQ = 374; + public static final int UC_X86_INS_MOVQ = 375; + public static final int UC_X86_INS_PABSB = 376; + public static final int UC_X86_INS_PABSD = 377; + public static final int UC_X86_INS_PABSW = 378; + public static final int UC_X86_INS_PACKSSDW = 379; + public static final int UC_X86_INS_PACKSSWB = 380; + public static final int UC_X86_INS_PACKUSWB = 381; + public static final int UC_X86_INS_PADDB = 382; + public static final int UC_X86_INS_PADDD = 383; + public static final int UC_X86_INS_PADDQ = 384; + public static final int UC_X86_INS_PADDSB = 385; + public static final int UC_X86_INS_PADDSW = 386; + public static final int UC_X86_INS_PADDUSB = 387; + public static final int UC_X86_INS_PADDUSW = 388; + public static final int UC_X86_INS_PADDW = 389; + public static final int UC_X86_INS_PALIGNR = 390; + public static final int UC_X86_INS_PANDN = 391; + public static final int UC_X86_INS_PAND = 392; + public static final int UC_X86_INS_PAVGB = 393; + public static final int UC_X86_INS_PAVGW = 394; + public static final int UC_X86_INS_PCMPEQB = 395; + public static final int UC_X86_INS_PCMPEQD = 396; + public static final int UC_X86_INS_PCMPEQW = 397; + public static final int UC_X86_INS_PCMPGTB = 398; + public static final int UC_X86_INS_PCMPGTD = 399; + public static final int UC_X86_INS_PCMPGTW = 400; + public static final int UC_X86_INS_PEXTRW = 401; + public static final int UC_X86_INS_PHADDSW = 402; + public static final int UC_X86_INS_PHADDW = 403; + public static final int UC_X86_INS_PHADDD = 404; + public static final int UC_X86_INS_PHSUBD = 405; + public static final int UC_X86_INS_PHSUBSW = 406; + public static final int UC_X86_INS_PHSUBW = 407; + public static final int UC_X86_INS_PINSRW = 408; + public static final int UC_X86_INS_PMADDUBSW = 409; + public static final int UC_X86_INS_PMADDWD = 410; + public static final int UC_X86_INS_PMAXSW = 411; + public static final int UC_X86_INS_PMAXUB = 412; + public static final int UC_X86_INS_PMINSW = 413; + public static final int UC_X86_INS_PMINUB = 414; + public static final int UC_X86_INS_PMOVMSKB = 415; + public static final int UC_X86_INS_PMULHRSW = 416; + public static final int UC_X86_INS_PMULHUW = 417; + public static final int UC_X86_INS_PMULHW = 418; + public static final int UC_X86_INS_PMULLW = 419; + public static final int UC_X86_INS_PMULUDQ = 420; + public static final int UC_X86_INS_POR = 421; + public static final int UC_X86_INS_PSADBW = 422; + public static final int UC_X86_INS_PSHUFB = 423; + public static final int UC_X86_INS_PSHUFW = 424; + public static final int UC_X86_INS_PSIGNB = 425; + public static final int UC_X86_INS_PSIGND = 426; + public static final int UC_X86_INS_PSIGNW = 427; + public static final int UC_X86_INS_PSLLD = 428; + public static final int UC_X86_INS_PSLLQ = 429; + public static final int UC_X86_INS_PSLLW = 430; + public static final int UC_X86_INS_PSRAD = 431; + public static final int UC_X86_INS_PSRAW = 432; + public static final int UC_X86_INS_PSRLD = 433; + public static final int UC_X86_INS_PSRLQ = 434; + public static final int UC_X86_INS_PSRLW = 435; + public static final int UC_X86_INS_PSUBB = 436; + public static final int UC_X86_INS_PSUBD = 437; + public static final int UC_X86_INS_PSUBQ = 438; + public static final int UC_X86_INS_PSUBSB = 439; + public static final int UC_X86_INS_PSUBSW = 440; + public static final int UC_X86_INS_PSUBUSB = 441; + public static final int UC_X86_INS_PSUBUSW = 442; + public static final int UC_X86_INS_PSUBW = 443; + public static final int UC_X86_INS_PUNPCKHBW = 444; + public static final int UC_X86_INS_PUNPCKHDQ = 445; + public static final int UC_X86_INS_PUNPCKHWD = 446; + public static final int UC_X86_INS_PUNPCKLBW = 447; + public static final int UC_X86_INS_PUNPCKLDQ = 448; + public static final int UC_X86_INS_PUNPCKLWD = 449; + public static final int UC_X86_INS_PXOR = 450; + public static final int UC_X86_INS_MONITOR = 451; + public static final int UC_X86_INS_MONTMUL = 452; + public static final int UC_X86_INS_MOV = 453; + public static final int UC_X86_INS_MOVABS = 454; + public static final int UC_X86_INS_MOVBE = 455; + public static final int UC_X86_INS_MOVDDUP = 456; + public static final int UC_X86_INS_MOVDQA = 457; + public static final int UC_X86_INS_MOVDQU = 458; + public static final int UC_X86_INS_MOVHLPS = 459; + public static final int UC_X86_INS_MOVHPD = 460; + public static final int UC_X86_INS_MOVHPS = 461; + public static final int UC_X86_INS_MOVLHPS = 462; + public static final int UC_X86_INS_MOVLPD = 463; + public static final int UC_X86_INS_MOVLPS = 464; + public static final int UC_X86_INS_MOVMSKPD = 465; + public static final int UC_X86_INS_MOVMSKPS = 466; + public static final int UC_X86_INS_MOVNTDQA = 467; + public static final int UC_X86_INS_MOVNTDQ = 468; + public static final int UC_X86_INS_MOVNTI = 469; + public static final int UC_X86_INS_MOVNTPD = 470; + public static final int UC_X86_INS_MOVNTPS = 471; + public static final int UC_X86_INS_MOVNTSD = 472; + public static final int UC_X86_INS_MOVNTSS = 473; + public static final int UC_X86_INS_MOVSB = 474; + public static final int UC_X86_INS_MOVSD = 475; + public static final int UC_X86_INS_MOVSHDUP = 476; + public static final int UC_X86_INS_MOVSLDUP = 477; + public static final int UC_X86_INS_MOVSQ = 478; + public static final int UC_X86_INS_MOVSS = 479; + public static final int UC_X86_INS_MOVSW = 480; + public static final int UC_X86_INS_MOVSX = 481; + public static final int UC_X86_INS_MOVSXD = 482; + public static final int UC_X86_INS_MOVUPD = 483; + public static final int UC_X86_INS_MOVUPS = 484; + public static final int UC_X86_INS_MOVZX = 485; + public static final int UC_X86_INS_MPSADBW = 486; + public static final int UC_X86_INS_MUL = 487; + public static final int UC_X86_INS_MULPD = 488; + public static final int UC_X86_INS_MULPS = 489; + public static final int UC_X86_INS_MULSD = 490; + public static final int UC_X86_INS_MULSS = 491; + public static final int UC_X86_INS_MULX = 492; + public static final int UC_X86_INS_FMUL = 493; + public static final int UC_X86_INS_FIMUL = 494; + public static final int UC_X86_INS_FMULP = 495; + public static final int UC_X86_INS_MWAIT = 496; + public static final int UC_X86_INS_NEG = 497; + public static final int UC_X86_INS_NOP = 498; + public static final int UC_X86_INS_NOT = 499; + public static final int UC_X86_INS_OUT = 500; + public static final int UC_X86_INS_OUTSB = 501; + public static final int UC_X86_INS_OUTSD = 502; + public static final int UC_X86_INS_OUTSW = 503; + public static final int UC_X86_INS_PACKUSDW = 504; + public static final int UC_X86_INS_PAUSE = 505; + public static final int UC_X86_INS_PAVGUSB = 506; + public static final int UC_X86_INS_PBLENDVB = 507; + public static final int UC_X86_INS_PBLENDW = 508; + public static final int UC_X86_INS_PCLMULQDQ = 509; + public static final int UC_X86_INS_PCMPEQQ = 510; + public static final int UC_X86_INS_PCMPESTRI = 511; + public static final int UC_X86_INS_PCMPESTRM = 512; + public static final int UC_X86_INS_PCMPGTQ = 513; + public static final int UC_X86_INS_PCMPISTRI = 514; + public static final int UC_X86_INS_PCMPISTRM = 515; + public static final int UC_X86_INS_PCOMMIT = 516; + public static final int UC_X86_INS_PDEP = 517; + public static final int UC_X86_INS_PEXT = 518; + public static final int UC_X86_INS_PEXTRB = 519; + public static final int UC_X86_INS_PEXTRD = 520; + public static final int UC_X86_INS_PEXTRQ = 521; + public static final int UC_X86_INS_PF2ID = 522; + public static final int UC_X86_INS_PF2IW = 523; + public static final int UC_X86_INS_PFACC = 524; + public static final int UC_X86_INS_PFADD = 525; + public static final int UC_X86_INS_PFCMPEQ = 526; + public static final int UC_X86_INS_PFCMPGE = 527; + public static final int UC_X86_INS_PFCMPGT = 528; + public static final int UC_X86_INS_PFMAX = 529; + public static final int UC_X86_INS_PFMIN = 530; + public static final int UC_X86_INS_PFMUL = 531; + public static final int UC_X86_INS_PFNACC = 532; + public static final int UC_X86_INS_PFPNACC = 533; + public static final int UC_X86_INS_PFRCPIT1 = 534; + public static final int UC_X86_INS_PFRCPIT2 = 535; + public static final int UC_X86_INS_PFRCP = 536; + public static final int UC_X86_INS_PFRSQIT1 = 537; + public static final int UC_X86_INS_PFRSQRT = 538; + public static final int UC_X86_INS_PFSUBR = 539; + public static final int UC_X86_INS_PFSUB = 540; + public static final int UC_X86_INS_PHMINPOSUW = 541; + public static final int UC_X86_INS_PI2FD = 542; + public static final int UC_X86_INS_PI2FW = 543; + public static final int UC_X86_INS_PINSRB = 544; + public static final int UC_X86_INS_PINSRD = 545; + public static final int UC_X86_INS_PINSRQ = 546; + public static final int UC_X86_INS_PMAXSB = 547; + public static final int UC_X86_INS_PMAXSD = 548; + public static final int UC_X86_INS_PMAXUD = 549; + public static final int UC_X86_INS_PMAXUW = 550; + public static final int UC_X86_INS_PMINSB = 551; + public static final int UC_X86_INS_PMINSD = 552; + public static final int UC_X86_INS_PMINUD = 553; + public static final int UC_X86_INS_PMINUW = 554; + public static final int UC_X86_INS_PMOVSXBD = 555; + public static final int UC_X86_INS_PMOVSXBQ = 556; + public static final int UC_X86_INS_PMOVSXBW = 557; + public static final int UC_X86_INS_PMOVSXDQ = 558; + public static final int UC_X86_INS_PMOVSXWD = 559; + public static final int UC_X86_INS_PMOVSXWQ = 560; + public static final int UC_X86_INS_PMOVZXBD = 561; + public static final int UC_X86_INS_PMOVZXBQ = 562; + public static final int UC_X86_INS_PMOVZXBW = 563; + public static final int UC_X86_INS_PMOVZXDQ = 564; + public static final int UC_X86_INS_PMOVZXWD = 565; + public static final int UC_X86_INS_PMOVZXWQ = 566; + public static final int UC_X86_INS_PMULDQ = 567; + public static final int UC_X86_INS_PMULHRW = 568; + public static final int UC_X86_INS_PMULLD = 569; + public static final int UC_X86_INS_POP = 570; + public static final int UC_X86_INS_POPAW = 571; + public static final int UC_X86_INS_POPAL = 572; + public static final int UC_X86_INS_POPCNT = 573; + public static final int UC_X86_INS_POPF = 574; + public static final int UC_X86_INS_POPFD = 575; + public static final int UC_X86_INS_POPFQ = 576; + public static final int UC_X86_INS_PREFETCH = 577; + public static final int UC_X86_INS_PREFETCHNTA = 578; + public static final int UC_X86_INS_PREFETCHT0 = 579; + public static final int UC_X86_INS_PREFETCHT1 = 580; + public static final int UC_X86_INS_PREFETCHT2 = 581; + public static final int UC_X86_INS_PREFETCHW = 582; + public static final int UC_X86_INS_PSHUFD = 583; + public static final int UC_X86_INS_PSHUFHW = 584; + public static final int UC_X86_INS_PSHUFLW = 585; + public static final int UC_X86_INS_PSLLDQ = 586; + public static final int UC_X86_INS_PSRLDQ = 587; + public static final int UC_X86_INS_PSWAPD = 588; + public static final int UC_X86_INS_PTEST = 589; + public static final int UC_X86_INS_PUNPCKHQDQ = 590; + public static final int UC_X86_INS_PUNPCKLQDQ = 591; + public static final int UC_X86_INS_PUSH = 592; + public static final int UC_X86_INS_PUSHAW = 593; + public static final int UC_X86_INS_PUSHAL = 594; + public static final int UC_X86_INS_PUSHF = 595; + public static final int UC_X86_INS_PUSHFD = 596; + public static final int UC_X86_INS_PUSHFQ = 597; + public static final int UC_X86_INS_RCL = 598; + public static final int UC_X86_INS_RCPPS = 599; + public static final int UC_X86_INS_RCPSS = 600; + public static final int UC_X86_INS_RCR = 601; + public static final int UC_X86_INS_RDFSBASE = 602; + public static final int UC_X86_INS_RDGSBASE = 603; + public static final int UC_X86_INS_RDMSR = 604; + public static final int UC_X86_INS_RDPMC = 605; + public static final int UC_X86_INS_RDRAND = 606; + public static final int UC_X86_INS_RDSEED = 607; + public static final int UC_X86_INS_RDTSC = 608; + public static final int UC_X86_INS_RDTSCP = 609; + public static final int UC_X86_INS_ROL = 610; + public static final int UC_X86_INS_ROR = 611; + public static final int UC_X86_INS_RORX = 612; + public static final int UC_X86_INS_ROUNDPD = 613; + public static final int UC_X86_INS_ROUNDPS = 614; + public static final int UC_X86_INS_ROUNDSD = 615; + public static final int UC_X86_INS_ROUNDSS = 616; + public static final int UC_X86_INS_RSM = 617; + public static final int UC_X86_INS_RSQRTPS = 618; + public static final int UC_X86_INS_RSQRTSS = 619; + public static final int UC_X86_INS_SAHF = 620; + public static final int UC_X86_INS_SAL = 621; + public static final int UC_X86_INS_SALC = 622; + public static final int UC_X86_INS_SAR = 623; + public static final int UC_X86_INS_SARX = 624; + public static final int UC_X86_INS_SBB = 625; + public static final int UC_X86_INS_SCASB = 626; + public static final int UC_X86_INS_SCASD = 627; + public static final int UC_X86_INS_SCASQ = 628; + public static final int UC_X86_INS_SCASW = 629; + public static final int UC_X86_INS_SETAE = 630; + public static final int UC_X86_INS_SETA = 631; + public static final int UC_X86_INS_SETBE = 632; + public static final int UC_X86_INS_SETB = 633; + public static final int UC_X86_INS_SETE = 634; + public static final int UC_X86_INS_SETGE = 635; + public static final int UC_X86_INS_SETG = 636; + public static final int UC_X86_INS_SETLE = 637; + public static final int UC_X86_INS_SETL = 638; + public static final int UC_X86_INS_SETNE = 639; + public static final int UC_X86_INS_SETNO = 640; + public static final int UC_X86_INS_SETNP = 641; + public static final int UC_X86_INS_SETNS = 642; + public static final int UC_X86_INS_SETO = 643; + public static final int UC_X86_INS_SETP = 644; + public static final int UC_X86_INS_SETS = 645; + public static final int UC_X86_INS_SFENCE = 646; + public static final int UC_X86_INS_SGDT = 647; + public static final int UC_X86_INS_SHA1MSG1 = 648; + public static final int UC_X86_INS_SHA1MSG2 = 649; + public static final int UC_X86_INS_SHA1NEXTE = 650; + public static final int UC_X86_INS_SHA1RNDS4 = 651; + public static final int UC_X86_INS_SHA256MSG1 = 652; + public static final int UC_X86_INS_SHA256MSG2 = 653; + public static final int UC_X86_INS_SHA256RNDS2 = 654; + public static final int UC_X86_INS_SHL = 655; + public static final int UC_X86_INS_SHLD = 656; + public static final int UC_X86_INS_SHLX = 657; + public static final int UC_X86_INS_SHR = 658; + public static final int UC_X86_INS_SHRD = 659; + public static final int UC_X86_INS_SHRX = 660; + public static final int UC_X86_INS_SHUFPD = 661; + public static final int UC_X86_INS_SHUFPS = 662; + public static final int UC_X86_INS_SIDT = 663; + public static final int UC_X86_INS_FSIN = 664; + public static final int UC_X86_INS_SKINIT = 665; + public static final int UC_X86_INS_SLDT = 666; + public static final int UC_X86_INS_SMSW = 667; + public static final int UC_X86_INS_SQRTPD = 668; + public static final int UC_X86_INS_SQRTPS = 669; + public static final int UC_X86_INS_SQRTSD = 670; + public static final int UC_X86_INS_SQRTSS = 671; + public static final int UC_X86_INS_FSQRT = 672; + public static final int UC_X86_INS_STAC = 673; + public static final int UC_X86_INS_STC = 674; + public static final int UC_X86_INS_STD = 675; + public static final int UC_X86_INS_STGI = 676; + public static final int UC_X86_INS_STI = 677; + public static final int UC_X86_INS_STMXCSR = 678; + public static final int UC_X86_INS_STOSB = 679; + public static final int UC_X86_INS_STOSD = 680; + public static final int UC_X86_INS_STOSQ = 681; + public static final int UC_X86_INS_STOSW = 682; + public static final int UC_X86_INS_STR = 683; + public static final int UC_X86_INS_FST = 684; + public static final int UC_X86_INS_FSTP = 685; + public static final int UC_X86_INS_FSTPNCE = 686; + public static final int UC_X86_INS_FXCH = 687; + public static final int UC_X86_INS_SUBPD = 688; + public static final int UC_X86_INS_SUBPS = 689; + public static final int UC_X86_INS_FSUBR = 690; + public static final int UC_X86_INS_FISUBR = 691; + public static final int UC_X86_INS_FSUBRP = 692; + public static final int UC_X86_INS_SUBSD = 693; + public static final int UC_X86_INS_SUBSS = 694; + public static final int UC_X86_INS_FSUB = 695; + public static final int UC_X86_INS_FISUB = 696; + public static final int UC_X86_INS_FSUBP = 697; + public static final int UC_X86_INS_SWAPGS = 698; + public static final int UC_X86_INS_SYSCALL = 699; + public static final int UC_X86_INS_SYSENTER = 700; + public static final int UC_X86_INS_SYSEXIT = 701; + public static final int UC_X86_INS_SYSRET = 702; + public static final int UC_X86_INS_T1MSKC = 703; + public static final int UC_X86_INS_TEST = 704; + public static final int UC_X86_INS_UD2 = 705; + public static final int UC_X86_INS_FTST = 706; + public static final int UC_X86_INS_TZCNT = 707; + public static final int UC_X86_INS_TZMSK = 708; + public static final int UC_X86_INS_FUCOMPI = 709; + public static final int UC_X86_INS_FUCOMI = 710; + public static final int UC_X86_INS_FUCOMPP = 711; + public static final int UC_X86_INS_FUCOMP = 712; + public static final int UC_X86_INS_FUCOM = 713; + public static final int UC_X86_INS_UD2B = 714; + public static final int UC_X86_INS_UNPCKHPD = 715; + public static final int UC_X86_INS_UNPCKHPS = 716; + public static final int UC_X86_INS_UNPCKLPD = 717; + public static final int UC_X86_INS_UNPCKLPS = 718; + public static final int UC_X86_INS_VADDPD = 719; + public static final int UC_X86_INS_VADDPS = 720; + public static final int UC_X86_INS_VADDSD = 721; + public static final int UC_X86_INS_VADDSS = 722; + public static final int UC_X86_INS_VADDSUBPD = 723; + public static final int UC_X86_INS_VADDSUBPS = 724; + public static final int UC_X86_INS_VAESDECLAST = 725; + public static final int UC_X86_INS_VAESDEC = 726; + public static final int UC_X86_INS_VAESENCLAST = 727; + public static final int UC_X86_INS_VAESENC = 728; + public static final int UC_X86_INS_VAESIMC = 729; + public static final int UC_X86_INS_VAESKEYGENASSIST = 730; + public static final int UC_X86_INS_VALIGND = 731; + public static final int UC_X86_INS_VALIGNQ = 732; + public static final int UC_X86_INS_VANDNPD = 733; + public static final int UC_X86_INS_VANDNPS = 734; + public static final int UC_X86_INS_VANDPD = 735; + public static final int UC_X86_INS_VANDPS = 736; + public static final int UC_X86_INS_VBLENDMPD = 737; + public static final int UC_X86_INS_VBLENDMPS = 738; + public static final int UC_X86_INS_VBLENDPD = 739; + public static final int UC_X86_INS_VBLENDPS = 740; + public static final int UC_X86_INS_VBLENDVPD = 741; + public static final int UC_X86_INS_VBLENDVPS = 742; + public static final int UC_X86_INS_VBROADCASTF128 = 743; + public static final int UC_X86_INS_VBROADCASTI32X4 = 744; + public static final int UC_X86_INS_VBROADCASTI64X4 = 745; + public static final int UC_X86_INS_VBROADCASTSD = 746; + public static final int UC_X86_INS_VBROADCASTSS = 747; + public static final int UC_X86_INS_VCMPPD = 748; + public static final int UC_X86_INS_VCMPPS = 749; + public static final int UC_X86_INS_VCMPSD = 750; + public static final int UC_X86_INS_VCMPSS = 751; + public static final int UC_X86_INS_VCOMPRESSPD = 752; + public static final int UC_X86_INS_VCOMPRESSPS = 753; + public static final int UC_X86_INS_VCVTDQ2PD = 754; + public static final int UC_X86_INS_VCVTDQ2PS = 755; + public static final int UC_X86_INS_VCVTPD2DQX = 756; + public static final int UC_X86_INS_VCVTPD2DQ = 757; + public static final int UC_X86_INS_VCVTPD2PSX = 758; + public static final int UC_X86_INS_VCVTPD2PS = 759; + public static final int UC_X86_INS_VCVTPD2UDQ = 760; + public static final int UC_X86_INS_VCVTPH2PS = 761; + public static final int UC_X86_INS_VCVTPS2DQ = 762; + public static final int UC_X86_INS_VCVTPS2PD = 763; + public static final int UC_X86_INS_VCVTPS2PH = 764; + public static final int UC_X86_INS_VCVTPS2UDQ = 765; + public static final int UC_X86_INS_VCVTSD2SI = 766; + public static final int UC_X86_INS_VCVTSD2USI = 767; + public static final int UC_X86_INS_VCVTSS2SI = 768; + public static final int UC_X86_INS_VCVTSS2USI = 769; + public static final int UC_X86_INS_VCVTTPD2DQX = 770; + public static final int UC_X86_INS_VCVTTPD2DQ = 771; + public static final int UC_X86_INS_VCVTTPD2UDQ = 772; + public static final int UC_X86_INS_VCVTTPS2DQ = 773; + public static final int UC_X86_INS_VCVTTPS2UDQ = 774; + public static final int UC_X86_INS_VCVTUDQ2PD = 775; + public static final int UC_X86_INS_VCVTUDQ2PS = 776; + public static final int UC_X86_INS_VDIVPD = 777; + public static final int UC_X86_INS_VDIVPS = 778; + public static final int UC_X86_INS_VDIVSD = 779; + public static final int UC_X86_INS_VDIVSS = 780; + public static final int UC_X86_INS_VDPPD = 781; + public static final int UC_X86_INS_VDPPS = 782; + public static final int UC_X86_INS_VERR = 783; + public static final int UC_X86_INS_VERW = 784; + public static final int UC_X86_INS_VEXP2PD = 785; + public static final int UC_X86_INS_VEXP2PS = 786; + public static final int UC_X86_INS_VEXPANDPD = 787; + public static final int UC_X86_INS_VEXPANDPS = 788; + public static final int UC_X86_INS_VEXTRACTF128 = 789; + public static final int UC_X86_INS_VEXTRACTF32X4 = 790; + public static final int UC_X86_INS_VEXTRACTF64X4 = 791; + public static final int UC_X86_INS_VEXTRACTI128 = 792; + public static final int UC_X86_INS_VEXTRACTI32X4 = 793; + public static final int UC_X86_INS_VEXTRACTI64X4 = 794; + public static final int UC_X86_INS_VEXTRACTPS = 795; + public static final int UC_X86_INS_VFMADD132PD = 796; + public static final int UC_X86_INS_VFMADD132PS = 797; + public static final int UC_X86_INS_VFMADDPD = 798; + public static final int UC_X86_INS_VFMADD213PD = 799; + public static final int UC_X86_INS_VFMADD231PD = 800; + public static final int UC_X86_INS_VFMADDPS = 801; + public static final int UC_X86_INS_VFMADD213PS = 802; + public static final int UC_X86_INS_VFMADD231PS = 803; + public static final int UC_X86_INS_VFMADDSD = 804; + public static final int UC_X86_INS_VFMADD213SD = 805; + public static final int UC_X86_INS_VFMADD132SD = 806; + public static final int UC_X86_INS_VFMADD231SD = 807; + public static final int UC_X86_INS_VFMADDSS = 808; + public static final int UC_X86_INS_VFMADD213SS = 809; + public static final int UC_X86_INS_VFMADD132SS = 810; + public static final int UC_X86_INS_VFMADD231SS = 811; + public static final int UC_X86_INS_VFMADDSUB132PD = 812; + public static final int UC_X86_INS_VFMADDSUB132PS = 813; + public static final int UC_X86_INS_VFMADDSUBPD = 814; + public static final int UC_X86_INS_VFMADDSUB213PD = 815; + public static final int UC_X86_INS_VFMADDSUB231PD = 816; + public static final int UC_X86_INS_VFMADDSUBPS = 817; + public static final int UC_X86_INS_VFMADDSUB213PS = 818; + public static final int UC_X86_INS_VFMADDSUB231PS = 819; + public static final int UC_X86_INS_VFMSUB132PD = 820; + public static final int UC_X86_INS_VFMSUB132PS = 821; + public static final int UC_X86_INS_VFMSUBADD132PD = 822; + public static final int UC_X86_INS_VFMSUBADD132PS = 823; + public static final int UC_X86_INS_VFMSUBADDPD = 824; + public static final int UC_X86_INS_VFMSUBADD213PD = 825; + public static final int UC_X86_INS_VFMSUBADD231PD = 826; + public static final int UC_X86_INS_VFMSUBADDPS = 827; + public static final int UC_X86_INS_VFMSUBADD213PS = 828; + public static final int UC_X86_INS_VFMSUBADD231PS = 829; + public static final int UC_X86_INS_VFMSUBPD = 830; + public static final int UC_X86_INS_VFMSUB213PD = 831; + public static final int UC_X86_INS_VFMSUB231PD = 832; + public static final int UC_X86_INS_VFMSUBPS = 833; + public static final int UC_X86_INS_VFMSUB213PS = 834; + public static final int UC_X86_INS_VFMSUB231PS = 835; + public static final int UC_X86_INS_VFMSUBSD = 836; + public static final int UC_X86_INS_VFMSUB213SD = 837; + public static final int UC_X86_INS_VFMSUB132SD = 838; + public static final int UC_X86_INS_VFMSUB231SD = 839; + public static final int UC_X86_INS_VFMSUBSS = 840; + public static final int UC_X86_INS_VFMSUB213SS = 841; + public static final int UC_X86_INS_VFMSUB132SS = 842; + public static final int UC_X86_INS_VFMSUB231SS = 843; + public static final int UC_X86_INS_VFNMADD132PD = 844; + public static final int UC_X86_INS_VFNMADD132PS = 845; + public static final int UC_X86_INS_VFNMADDPD = 846; + public static final int UC_X86_INS_VFNMADD213PD = 847; + public static final int UC_X86_INS_VFNMADD231PD = 848; + public static final int UC_X86_INS_VFNMADDPS = 849; + public static final int UC_X86_INS_VFNMADD213PS = 850; + public static final int UC_X86_INS_VFNMADD231PS = 851; + public static final int UC_X86_INS_VFNMADDSD = 852; + public static final int UC_X86_INS_VFNMADD213SD = 853; + public static final int UC_X86_INS_VFNMADD132SD = 854; + public static final int UC_X86_INS_VFNMADD231SD = 855; + public static final int UC_X86_INS_VFNMADDSS = 856; + public static final int UC_X86_INS_VFNMADD213SS = 857; + public static final int UC_X86_INS_VFNMADD132SS = 858; + public static final int UC_X86_INS_VFNMADD231SS = 859; + public static final int UC_X86_INS_VFNMSUB132PD = 860; + public static final int UC_X86_INS_VFNMSUB132PS = 861; + public static final int UC_X86_INS_VFNMSUBPD = 862; + public static final int UC_X86_INS_VFNMSUB213PD = 863; + public static final int UC_X86_INS_VFNMSUB231PD = 864; + public static final int UC_X86_INS_VFNMSUBPS = 865; + public static final int UC_X86_INS_VFNMSUB213PS = 866; + public static final int UC_X86_INS_VFNMSUB231PS = 867; + public static final int UC_X86_INS_VFNMSUBSD = 868; + public static final int UC_X86_INS_VFNMSUB213SD = 869; + public static final int UC_X86_INS_VFNMSUB132SD = 870; + public static final int UC_X86_INS_VFNMSUB231SD = 871; + public static final int UC_X86_INS_VFNMSUBSS = 872; + public static final int UC_X86_INS_VFNMSUB213SS = 873; + public static final int UC_X86_INS_VFNMSUB132SS = 874; + public static final int UC_X86_INS_VFNMSUB231SS = 875; + public static final int UC_X86_INS_VFRCZPD = 876; + public static final int UC_X86_INS_VFRCZPS = 877; + public static final int UC_X86_INS_VFRCZSD = 878; + public static final int UC_X86_INS_VFRCZSS = 879; + public static final int UC_X86_INS_VORPD = 880; + public static final int UC_X86_INS_VORPS = 881; + public static final int UC_X86_INS_VXORPD = 882; + public static final int UC_X86_INS_VXORPS = 883; + public static final int UC_X86_INS_VGATHERDPD = 884; + public static final int UC_X86_INS_VGATHERDPS = 885; + public static final int UC_X86_INS_VGATHERPF0DPD = 886; + public static final int UC_X86_INS_VGATHERPF0DPS = 887; + public static final int UC_X86_INS_VGATHERPF0QPD = 888; + public static final int UC_X86_INS_VGATHERPF0QPS = 889; + public static final int UC_X86_INS_VGATHERPF1DPD = 890; + public static final int UC_X86_INS_VGATHERPF1DPS = 891; + public static final int UC_X86_INS_VGATHERPF1QPD = 892; + public static final int UC_X86_INS_VGATHERPF1QPS = 893; + public static final int UC_X86_INS_VGATHERQPD = 894; + public static final int UC_X86_INS_VGATHERQPS = 895; + public static final int UC_X86_INS_VHADDPD = 896; + public static final int UC_X86_INS_VHADDPS = 897; + public static final int UC_X86_INS_VHSUBPD = 898; + public static final int UC_X86_INS_VHSUBPS = 899; + public static final int UC_X86_INS_VINSERTF128 = 900; + public static final int UC_X86_INS_VINSERTF32X4 = 901; + public static final int UC_X86_INS_VINSERTF32X8 = 902; + public static final int UC_X86_INS_VINSERTF64X2 = 903; + public static final int UC_X86_INS_VINSERTF64X4 = 904; + public static final int UC_X86_INS_VINSERTI128 = 905; + public static final int UC_X86_INS_VINSERTI32X4 = 906; + public static final int UC_X86_INS_VINSERTI32X8 = 907; + public static final int UC_X86_INS_VINSERTI64X2 = 908; + public static final int UC_X86_INS_VINSERTI64X4 = 909; + public static final int UC_X86_INS_VINSERTPS = 910; + public static final int UC_X86_INS_VLDDQU = 911; + public static final int UC_X86_INS_VLDMXCSR = 912; + public static final int UC_X86_INS_VMASKMOVDQU = 913; + public static final int UC_X86_INS_VMASKMOVPD = 914; + public static final int UC_X86_INS_VMASKMOVPS = 915; + public static final int UC_X86_INS_VMAXPD = 916; + public static final int UC_X86_INS_VMAXPS = 917; + public static final int UC_X86_INS_VMAXSD = 918; + public static final int UC_X86_INS_VMAXSS = 919; + public static final int UC_X86_INS_VMCALL = 920; + public static final int UC_X86_INS_VMCLEAR = 921; + public static final int UC_X86_INS_VMFUNC = 922; + public static final int UC_X86_INS_VMINPD = 923; + public static final int UC_X86_INS_VMINPS = 924; + public static final int UC_X86_INS_VMINSD = 925; + public static final int UC_X86_INS_VMINSS = 926; + public static final int UC_X86_INS_VMLAUNCH = 927; + public static final int UC_X86_INS_VMLOAD = 928; + public static final int UC_X86_INS_VMMCALL = 929; + public static final int UC_X86_INS_VMOVQ = 930; + public static final int UC_X86_INS_VMOVDDUP = 931; + public static final int UC_X86_INS_VMOVD = 932; + public static final int UC_X86_INS_VMOVDQA32 = 933; + public static final int UC_X86_INS_VMOVDQA64 = 934; + public static final int UC_X86_INS_VMOVDQA = 935; + public static final int UC_X86_INS_VMOVDQU16 = 936; + public static final int UC_X86_INS_VMOVDQU32 = 937; + public static final int UC_X86_INS_VMOVDQU64 = 938; + public static final int UC_X86_INS_VMOVDQU8 = 939; + public static final int UC_X86_INS_VMOVDQU = 940; + public static final int UC_X86_INS_VMOVHLPS = 941; + public static final int UC_X86_INS_VMOVHPD = 942; + public static final int UC_X86_INS_VMOVHPS = 943; + public static final int UC_X86_INS_VMOVLHPS = 944; + public static final int UC_X86_INS_VMOVLPD = 945; + public static final int UC_X86_INS_VMOVLPS = 946; + public static final int UC_X86_INS_VMOVMSKPD = 947; + public static final int UC_X86_INS_VMOVMSKPS = 948; + public static final int UC_X86_INS_VMOVNTDQA = 949; + public static final int UC_X86_INS_VMOVNTDQ = 950; + public static final int UC_X86_INS_VMOVNTPD = 951; + public static final int UC_X86_INS_VMOVNTPS = 952; + public static final int UC_X86_INS_VMOVSD = 953; + public static final int UC_X86_INS_VMOVSHDUP = 954; + public static final int UC_X86_INS_VMOVSLDUP = 955; + public static final int UC_X86_INS_VMOVSS = 956; + public static final int UC_X86_INS_VMOVUPD = 957; + public static final int UC_X86_INS_VMOVUPS = 958; + public static final int UC_X86_INS_VMPSADBW = 959; + public static final int UC_X86_INS_VMPTRLD = 960; + public static final int UC_X86_INS_VMPTRST = 961; + public static final int UC_X86_INS_VMREAD = 962; + public static final int UC_X86_INS_VMRESUME = 963; + public static final int UC_X86_INS_VMRUN = 964; + public static final int UC_X86_INS_VMSAVE = 965; + public static final int UC_X86_INS_VMULPD = 966; + public static final int UC_X86_INS_VMULPS = 967; + public static final int UC_X86_INS_VMULSD = 968; + public static final int UC_X86_INS_VMULSS = 969; + public static final int UC_X86_INS_VMWRITE = 970; + public static final int UC_X86_INS_VMXOFF = 971; + public static final int UC_X86_INS_VMXON = 972; + public static final int UC_X86_INS_VPABSB = 973; + public static final int UC_X86_INS_VPABSD = 974; + public static final int UC_X86_INS_VPABSQ = 975; + public static final int UC_X86_INS_VPABSW = 976; + public static final int UC_X86_INS_VPACKSSDW = 977; + public static final int UC_X86_INS_VPACKSSWB = 978; + public static final int UC_X86_INS_VPACKUSDW = 979; + public static final int UC_X86_INS_VPACKUSWB = 980; + public static final int UC_X86_INS_VPADDB = 981; + public static final int UC_X86_INS_VPADDD = 982; + public static final int UC_X86_INS_VPADDQ = 983; + public static final int UC_X86_INS_VPADDSB = 984; + public static final int UC_X86_INS_VPADDSW = 985; + public static final int UC_X86_INS_VPADDUSB = 986; + public static final int UC_X86_INS_VPADDUSW = 987; + public static final int UC_X86_INS_VPADDW = 988; + public static final int UC_X86_INS_VPALIGNR = 989; + public static final int UC_X86_INS_VPANDD = 990; + public static final int UC_X86_INS_VPANDND = 991; + public static final int UC_X86_INS_VPANDNQ = 992; + public static final int UC_X86_INS_VPANDN = 993; + public static final int UC_X86_INS_VPANDQ = 994; + public static final int UC_X86_INS_VPAND = 995; + public static final int UC_X86_INS_VPAVGB = 996; + public static final int UC_X86_INS_VPAVGW = 997; + public static final int UC_X86_INS_VPBLENDD = 998; + public static final int UC_X86_INS_VPBLENDMB = 999; + public static final int UC_X86_INS_VPBLENDMD = 1000; + public static final int UC_X86_INS_VPBLENDMQ = 1001; + public static final int UC_X86_INS_VPBLENDMW = 1002; + public static final int UC_X86_INS_VPBLENDVB = 1003; + public static final int UC_X86_INS_VPBLENDW = 1004; + public static final int UC_X86_INS_VPBROADCASTB = 1005; + public static final int UC_X86_INS_VPBROADCASTD = 1006; + public static final int UC_X86_INS_VPBROADCASTMB2Q = 1007; + public static final int UC_X86_INS_VPBROADCASTMW2D = 1008; + public static final int UC_X86_INS_VPBROADCASTQ = 1009; + public static final int UC_X86_INS_VPBROADCASTW = 1010; + public static final int UC_X86_INS_VPCLMULQDQ = 1011; + public static final int UC_X86_INS_VPCMOV = 1012; + public static final int UC_X86_INS_VPCMPB = 1013; + public static final int UC_X86_INS_VPCMPD = 1014; + public static final int UC_X86_INS_VPCMPEQB = 1015; + public static final int UC_X86_INS_VPCMPEQD = 1016; + public static final int UC_X86_INS_VPCMPEQQ = 1017; + public static final int UC_X86_INS_VPCMPEQW = 1018; + public static final int UC_X86_INS_VPCMPESTRI = 1019; + public static final int UC_X86_INS_VPCMPESTRM = 1020; + public static final int UC_X86_INS_VPCMPGTB = 1021; + public static final int UC_X86_INS_VPCMPGTD = 1022; + public static final int UC_X86_INS_VPCMPGTQ = 1023; + public static final int UC_X86_INS_VPCMPGTW = 1024; + public static final int UC_X86_INS_VPCMPISTRI = 1025; + public static final int UC_X86_INS_VPCMPISTRM = 1026; + public static final int UC_X86_INS_VPCMPQ = 1027; + public static final int UC_X86_INS_VPCMPUB = 1028; + public static final int UC_X86_INS_VPCMPUD = 1029; + public static final int UC_X86_INS_VPCMPUQ = 1030; + public static final int UC_X86_INS_VPCMPUW = 1031; + public static final int UC_X86_INS_VPCMPW = 1032; + public static final int UC_X86_INS_VPCOMB = 1033; + public static final int UC_X86_INS_VPCOMD = 1034; + public static final int UC_X86_INS_VPCOMPRESSD = 1035; + public static final int UC_X86_INS_VPCOMPRESSQ = 1036; + public static final int UC_X86_INS_VPCOMQ = 1037; + public static final int UC_X86_INS_VPCOMUB = 1038; + public static final int UC_X86_INS_VPCOMUD = 1039; + public static final int UC_X86_INS_VPCOMUQ = 1040; + public static final int UC_X86_INS_VPCOMUW = 1041; + public static final int UC_X86_INS_VPCOMW = 1042; + public static final int UC_X86_INS_VPCONFLICTD = 1043; + public static final int UC_X86_INS_VPCONFLICTQ = 1044; + public static final int UC_X86_INS_VPERM2F128 = 1045; + public static final int UC_X86_INS_VPERM2I128 = 1046; + public static final int UC_X86_INS_VPERMD = 1047; + public static final int UC_X86_INS_VPERMI2D = 1048; + public static final int UC_X86_INS_VPERMI2PD = 1049; + public static final int UC_X86_INS_VPERMI2PS = 1050; + public static final int UC_X86_INS_VPERMI2Q = 1051; + public static final int UC_X86_INS_VPERMIL2PD = 1052; + public static final int UC_X86_INS_VPERMIL2PS = 1053; + public static final int UC_X86_INS_VPERMILPD = 1054; + public static final int UC_X86_INS_VPERMILPS = 1055; + public static final int UC_X86_INS_VPERMPD = 1056; + public static final int UC_X86_INS_VPERMPS = 1057; + public static final int UC_X86_INS_VPERMQ = 1058; + public static final int UC_X86_INS_VPERMT2D = 1059; + public static final int UC_X86_INS_VPERMT2PD = 1060; + public static final int UC_X86_INS_VPERMT2PS = 1061; + public static final int UC_X86_INS_VPERMT2Q = 1062; + public static final int UC_X86_INS_VPEXPANDD = 1063; + public static final int UC_X86_INS_VPEXPANDQ = 1064; + public static final int UC_X86_INS_VPEXTRB = 1065; + public static final int UC_X86_INS_VPEXTRD = 1066; + public static final int UC_X86_INS_VPEXTRQ = 1067; + public static final int UC_X86_INS_VPEXTRW = 1068; + public static final int UC_X86_INS_VPGATHERDD = 1069; + public static final int UC_X86_INS_VPGATHERDQ = 1070; + public static final int UC_X86_INS_VPGATHERQD = 1071; + public static final int UC_X86_INS_VPGATHERQQ = 1072; + public static final int UC_X86_INS_VPHADDBD = 1073; + public static final int UC_X86_INS_VPHADDBQ = 1074; + public static final int UC_X86_INS_VPHADDBW = 1075; + public static final int UC_X86_INS_VPHADDDQ = 1076; + public static final int UC_X86_INS_VPHADDD = 1077; + public static final int UC_X86_INS_VPHADDSW = 1078; + public static final int UC_X86_INS_VPHADDUBD = 1079; + public static final int UC_X86_INS_VPHADDUBQ = 1080; + public static final int UC_X86_INS_VPHADDUBW = 1081; + public static final int UC_X86_INS_VPHADDUDQ = 1082; + public static final int UC_X86_INS_VPHADDUWD = 1083; + public static final int UC_X86_INS_VPHADDUWQ = 1084; + public static final int UC_X86_INS_VPHADDWD = 1085; + public static final int UC_X86_INS_VPHADDWQ = 1086; + public static final int UC_X86_INS_VPHADDW = 1087; + public static final int UC_X86_INS_VPHMINPOSUW = 1088; + public static final int UC_X86_INS_VPHSUBBW = 1089; + public static final int UC_X86_INS_VPHSUBDQ = 1090; + public static final int UC_X86_INS_VPHSUBD = 1091; + public static final int UC_X86_INS_VPHSUBSW = 1092; + public static final int UC_X86_INS_VPHSUBWD = 1093; + public static final int UC_X86_INS_VPHSUBW = 1094; + public static final int UC_X86_INS_VPINSRB = 1095; + public static final int UC_X86_INS_VPINSRD = 1096; + public static final int UC_X86_INS_VPINSRQ = 1097; + public static final int UC_X86_INS_VPINSRW = 1098; + public static final int UC_X86_INS_VPLZCNTD = 1099; + public static final int UC_X86_INS_VPLZCNTQ = 1100; + public static final int UC_X86_INS_VPMACSDD = 1101; + public static final int UC_X86_INS_VPMACSDQH = 1102; + public static final int UC_X86_INS_VPMACSDQL = 1103; + public static final int UC_X86_INS_VPMACSSDD = 1104; + public static final int UC_X86_INS_VPMACSSDQH = 1105; + public static final int UC_X86_INS_VPMACSSDQL = 1106; + public static final int UC_X86_INS_VPMACSSWD = 1107; + public static final int UC_X86_INS_VPMACSSWW = 1108; + public static final int UC_X86_INS_VPMACSWD = 1109; + public static final int UC_X86_INS_VPMACSWW = 1110; + public static final int UC_X86_INS_VPMADCSSWD = 1111; + public static final int UC_X86_INS_VPMADCSWD = 1112; + public static final int UC_X86_INS_VPMADDUBSW = 1113; + public static final int UC_X86_INS_VPMADDWD = 1114; + public static final int UC_X86_INS_VPMASKMOVD = 1115; + public static final int UC_X86_INS_VPMASKMOVQ = 1116; + public static final int UC_X86_INS_VPMAXSB = 1117; + public static final int UC_X86_INS_VPMAXSD = 1118; + public static final int UC_X86_INS_VPMAXSQ = 1119; + public static final int UC_X86_INS_VPMAXSW = 1120; + public static final int UC_X86_INS_VPMAXUB = 1121; + public static final int UC_X86_INS_VPMAXUD = 1122; + public static final int UC_X86_INS_VPMAXUQ = 1123; + public static final int UC_X86_INS_VPMAXUW = 1124; + public static final int UC_X86_INS_VPMINSB = 1125; + public static final int UC_X86_INS_VPMINSD = 1126; + public static final int UC_X86_INS_VPMINSQ = 1127; + public static final int UC_X86_INS_VPMINSW = 1128; + public static final int UC_X86_INS_VPMINUB = 1129; + public static final int UC_X86_INS_VPMINUD = 1130; + public static final int UC_X86_INS_VPMINUQ = 1131; + public static final int UC_X86_INS_VPMINUW = 1132; + public static final int UC_X86_INS_VPMOVDB = 1133; + public static final int UC_X86_INS_VPMOVDW = 1134; + public static final int UC_X86_INS_VPMOVM2B = 1135; + public static final int UC_X86_INS_VPMOVM2D = 1136; + public static final int UC_X86_INS_VPMOVM2Q = 1137; + public static final int UC_X86_INS_VPMOVM2W = 1138; + public static final int UC_X86_INS_VPMOVMSKB = 1139; + public static final int UC_X86_INS_VPMOVQB = 1140; + public static final int UC_X86_INS_VPMOVQD = 1141; + public static final int UC_X86_INS_VPMOVQW = 1142; + public static final int UC_X86_INS_VPMOVSDB = 1143; + public static final int UC_X86_INS_VPMOVSDW = 1144; + public static final int UC_X86_INS_VPMOVSQB = 1145; + public static final int UC_X86_INS_VPMOVSQD = 1146; + public static final int UC_X86_INS_VPMOVSQW = 1147; + public static final int UC_X86_INS_VPMOVSXBD = 1148; + public static final int UC_X86_INS_VPMOVSXBQ = 1149; + public static final int UC_X86_INS_VPMOVSXBW = 1150; + public static final int UC_X86_INS_VPMOVSXDQ = 1151; + public static final int UC_X86_INS_VPMOVSXWD = 1152; + public static final int UC_X86_INS_VPMOVSXWQ = 1153; + public static final int UC_X86_INS_VPMOVUSDB = 1154; + public static final int UC_X86_INS_VPMOVUSDW = 1155; + public static final int UC_X86_INS_VPMOVUSQB = 1156; + public static final int UC_X86_INS_VPMOVUSQD = 1157; + public static final int UC_X86_INS_VPMOVUSQW = 1158; + public static final int UC_X86_INS_VPMOVZXBD = 1159; + public static final int UC_X86_INS_VPMOVZXBQ = 1160; + public static final int UC_X86_INS_VPMOVZXBW = 1161; + public static final int UC_X86_INS_VPMOVZXDQ = 1162; + public static final int UC_X86_INS_VPMOVZXWD = 1163; + public static final int UC_X86_INS_VPMOVZXWQ = 1164; + public static final int UC_X86_INS_VPMULDQ = 1165; + public static final int UC_X86_INS_VPMULHRSW = 1166; + public static final int UC_X86_INS_VPMULHUW = 1167; + public static final int UC_X86_INS_VPMULHW = 1168; + public static final int UC_X86_INS_VPMULLD = 1169; + public static final int UC_X86_INS_VPMULLQ = 1170; + public static final int UC_X86_INS_VPMULLW = 1171; + public static final int UC_X86_INS_VPMULUDQ = 1172; + public static final int UC_X86_INS_VPORD = 1173; + public static final int UC_X86_INS_VPORQ = 1174; + public static final int UC_X86_INS_VPOR = 1175; + public static final int UC_X86_INS_VPPERM = 1176; + public static final int UC_X86_INS_VPROTB = 1177; + public static final int UC_X86_INS_VPROTD = 1178; + public static final int UC_X86_INS_VPROTQ = 1179; + public static final int UC_X86_INS_VPROTW = 1180; + public static final int UC_X86_INS_VPSADBW = 1181; + public static final int UC_X86_INS_VPSCATTERDD = 1182; + public static final int UC_X86_INS_VPSCATTERDQ = 1183; + public static final int UC_X86_INS_VPSCATTERQD = 1184; + public static final int UC_X86_INS_VPSCATTERQQ = 1185; + public static final int UC_X86_INS_VPSHAB = 1186; + public static final int UC_X86_INS_VPSHAD = 1187; + public static final int UC_X86_INS_VPSHAQ = 1188; + public static final int UC_X86_INS_VPSHAW = 1189; + public static final int UC_X86_INS_VPSHLB = 1190; + public static final int UC_X86_INS_VPSHLD = 1191; + public static final int UC_X86_INS_VPSHLQ = 1192; + public static final int UC_X86_INS_VPSHLW = 1193; + public static final int UC_X86_INS_VPSHUFB = 1194; + public static final int UC_X86_INS_VPSHUFD = 1195; + public static final int UC_X86_INS_VPSHUFHW = 1196; + public static final int UC_X86_INS_VPSHUFLW = 1197; + public static final int UC_X86_INS_VPSIGNB = 1198; + public static final int UC_X86_INS_VPSIGND = 1199; + public static final int UC_X86_INS_VPSIGNW = 1200; + public static final int UC_X86_INS_VPSLLDQ = 1201; + public static final int UC_X86_INS_VPSLLD = 1202; + public static final int UC_X86_INS_VPSLLQ = 1203; + public static final int UC_X86_INS_VPSLLVD = 1204; + public static final int UC_X86_INS_VPSLLVQ = 1205; + public static final int UC_X86_INS_VPSLLW = 1206; + public static final int UC_X86_INS_VPSRAD = 1207; + public static final int UC_X86_INS_VPSRAQ = 1208; + public static final int UC_X86_INS_VPSRAVD = 1209; + public static final int UC_X86_INS_VPSRAVQ = 1210; + public static final int UC_X86_INS_VPSRAW = 1211; + public static final int UC_X86_INS_VPSRLDQ = 1212; + public static final int UC_X86_INS_VPSRLD = 1213; + public static final int UC_X86_INS_VPSRLQ = 1214; + public static final int UC_X86_INS_VPSRLVD = 1215; + public static final int UC_X86_INS_VPSRLVQ = 1216; + public static final int UC_X86_INS_VPSRLW = 1217; + public static final int UC_X86_INS_VPSUBB = 1218; + public static final int UC_X86_INS_VPSUBD = 1219; + public static final int UC_X86_INS_VPSUBQ = 1220; + public static final int UC_X86_INS_VPSUBSB = 1221; + public static final int UC_X86_INS_VPSUBSW = 1222; + public static final int UC_X86_INS_VPSUBUSB = 1223; + public static final int UC_X86_INS_VPSUBUSW = 1224; + public static final int UC_X86_INS_VPSUBW = 1225; + public static final int UC_X86_INS_VPTESTMD = 1226; + public static final int UC_X86_INS_VPTESTMQ = 1227; + public static final int UC_X86_INS_VPTESTNMD = 1228; + public static final int UC_X86_INS_VPTESTNMQ = 1229; + public static final int UC_X86_INS_VPTEST = 1230; + public static final int UC_X86_INS_VPUNPCKHBW = 1231; + public static final int UC_X86_INS_VPUNPCKHDQ = 1232; + public static final int UC_X86_INS_VPUNPCKHQDQ = 1233; + public static final int UC_X86_INS_VPUNPCKHWD = 1234; + public static final int UC_X86_INS_VPUNPCKLBW = 1235; + public static final int UC_X86_INS_VPUNPCKLDQ = 1236; + public static final int UC_X86_INS_VPUNPCKLQDQ = 1237; + public static final int UC_X86_INS_VPUNPCKLWD = 1238; + public static final int UC_X86_INS_VPXORD = 1239; + public static final int UC_X86_INS_VPXORQ = 1240; + public static final int UC_X86_INS_VPXOR = 1241; + public static final int UC_X86_INS_VRCP14PD = 1242; + public static final int UC_X86_INS_VRCP14PS = 1243; + public static final int UC_X86_INS_VRCP14SD = 1244; + public static final int UC_X86_INS_VRCP14SS = 1245; + public static final int UC_X86_INS_VRCP28PD = 1246; + public static final int UC_X86_INS_VRCP28PS = 1247; + public static final int UC_X86_INS_VRCP28SD = 1248; + public static final int UC_X86_INS_VRCP28SS = 1249; + public static final int UC_X86_INS_VRCPPS = 1250; + public static final int UC_X86_INS_VRCPSS = 1251; + public static final int UC_X86_INS_VRNDSCALEPD = 1252; + public static final int UC_X86_INS_VRNDSCALEPS = 1253; + public static final int UC_X86_INS_VRNDSCALESD = 1254; + public static final int UC_X86_INS_VRNDSCALESS = 1255; + public static final int UC_X86_INS_VROUNDPD = 1256; + public static final int UC_X86_INS_VROUNDPS = 1257; + public static final int UC_X86_INS_VROUNDSD = 1258; + public static final int UC_X86_INS_VROUNDSS = 1259; + public static final int UC_X86_INS_VRSQRT14PD = 1260; + public static final int UC_X86_INS_VRSQRT14PS = 1261; + public static final int UC_X86_INS_VRSQRT14SD = 1262; + public static final int UC_X86_INS_VRSQRT14SS = 1263; + public static final int UC_X86_INS_VRSQRT28PD = 1264; + public static final int UC_X86_INS_VRSQRT28PS = 1265; + public static final int UC_X86_INS_VRSQRT28SD = 1266; + public static final int UC_X86_INS_VRSQRT28SS = 1267; + public static final int UC_X86_INS_VRSQRTPS = 1268; + public static final int UC_X86_INS_VRSQRTSS = 1269; + public static final int UC_X86_INS_VSCATTERDPD = 1270; + public static final int UC_X86_INS_VSCATTERDPS = 1271; + public static final int UC_X86_INS_VSCATTERPF0DPD = 1272; + public static final int UC_X86_INS_VSCATTERPF0DPS = 1273; + public static final int UC_X86_INS_VSCATTERPF0QPD = 1274; + public static final int UC_X86_INS_VSCATTERPF0QPS = 1275; + public static final int UC_X86_INS_VSCATTERPF1DPD = 1276; + public static final int UC_X86_INS_VSCATTERPF1DPS = 1277; + public static final int UC_X86_INS_VSCATTERPF1QPD = 1278; + public static final int UC_X86_INS_VSCATTERPF1QPS = 1279; + public static final int UC_X86_INS_VSCATTERQPD = 1280; + public static final int UC_X86_INS_VSCATTERQPS = 1281; + public static final int UC_X86_INS_VSHUFPD = 1282; + public static final int UC_X86_INS_VSHUFPS = 1283; + public static final int UC_X86_INS_VSQRTPD = 1284; + public static final int UC_X86_INS_VSQRTPS = 1285; + public static final int UC_X86_INS_VSQRTSD = 1286; + public static final int UC_X86_INS_VSQRTSS = 1287; + public static final int UC_X86_INS_VSTMXCSR = 1288; + public static final int UC_X86_INS_VSUBPD = 1289; + public static final int UC_X86_INS_VSUBPS = 1290; + public static final int UC_X86_INS_VSUBSD = 1291; + public static final int UC_X86_INS_VSUBSS = 1292; + public static final int UC_X86_INS_VTESTPD = 1293; + public static final int UC_X86_INS_VTESTPS = 1294; + public static final int UC_X86_INS_VUNPCKHPD = 1295; + public static final int UC_X86_INS_VUNPCKHPS = 1296; + public static final int UC_X86_INS_VUNPCKLPD = 1297; + public static final int UC_X86_INS_VUNPCKLPS = 1298; + public static final int UC_X86_INS_VZEROALL = 1299; + public static final int UC_X86_INS_VZEROUPPER = 1300; + public static final int UC_X86_INS_WAIT = 1301; + public static final int UC_X86_INS_WBINVD = 1302; + public static final int UC_X86_INS_WRFSBASE = 1303; + public static final int UC_X86_INS_WRGSBASE = 1304; + public static final int UC_X86_INS_WRMSR = 1305; + public static final int UC_X86_INS_XABORT = 1306; + public static final int UC_X86_INS_XACQUIRE = 1307; + public static final int UC_X86_INS_XBEGIN = 1308; + public static final int UC_X86_INS_XCHG = 1309; + public static final int UC_X86_INS_XCRYPTCBC = 1310; + public static final int UC_X86_INS_XCRYPTCFB = 1311; + public static final int UC_X86_INS_XCRYPTCTR = 1312; + public static final int UC_X86_INS_XCRYPTECB = 1313; + public static final int UC_X86_INS_XCRYPTOFB = 1314; + public static final int UC_X86_INS_XEND = 1315; + public static final int UC_X86_INS_XGETBV = 1316; + public static final int UC_X86_INS_XLATB = 1317; + public static final int UC_X86_INS_XRELEASE = 1318; + public static final int UC_X86_INS_XRSTOR = 1319; + public static final int UC_X86_INS_XRSTOR64 = 1320; + public static final int UC_X86_INS_XRSTORS = 1321; + public static final int UC_X86_INS_XRSTORS64 = 1322; + public static final int UC_X86_INS_XSAVE = 1323; + public static final int UC_X86_INS_XSAVE64 = 1324; + public static final int UC_X86_INS_XSAVEC = 1325; + public static final int UC_X86_INS_XSAVEC64 = 1326; + public static final int UC_X86_INS_XSAVEOPT = 1327; + public static final int UC_X86_INS_XSAVEOPT64 = 1328; + public static final int UC_X86_INS_XSAVES = 1329; + public static final int UC_X86_INS_XSAVES64 = 1330; + public static final int UC_X86_INS_XSETBV = 1331; + public static final int UC_X86_INS_XSHA1 = 1332; + public static final int UC_X86_INS_XSHA256 = 1333; + public static final int UC_X86_INS_XSTORE = 1334; + public static final int UC_X86_INS_XTEST = 1335; + public static final int UC_X86_INS_FDISI8087_NOP = 1336; + public static final int UC_X86_INS_FENI8087_NOP = 1337; + public static final int UC_X86_INS_ENDING = 1338; } diff --git a/bindings/java/unicorn/X86_MMR.java b/bindings/java/unicorn/X86_MMR.java index 1c3db2bc..17f3fe33 100644 --- a/bindings/java/unicorn/X86_MMR.java +++ b/bindings/java/unicorn/X86_MMR.java @@ -22,25 +22,22 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. package unicorn; public class X86_MMR { + public long base; + public int limit; + public int flags; + public short selector; - public long base; - public int limit; - public int flags; - public short selector; - - public X86_MMR(long base, int limit, int flags, short selector) { - this.base = base; - this.limit = limit; - this.flags = flags; - this.selector = selector; - } - - public X86_MMR(long base, int limit) { - this.base = base; - this.limit = limit; - selector = 0; - flags = 0; - } + public X86_MMR(long base, int limit, int flags, short selector) { + this.base = base; + this.limit = limit; + this.flags = flags; + this.selector = selector; + } + public X86_MMR(long base, int limit) { + this.base = base; + this.limit = limit; + selector = 0; + flags = 0; + } } - diff --git a/bindings/java/unicorn_Unicorn.c b/bindings/java/unicorn_Unicorn.c index fb7f220f..3ab2e9a5 100644 --- a/bindings/java/unicorn_Unicorn.c +++ b/bindings/java/unicorn_Unicorn.c @@ -28,7 +28,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include #include "unicorn_Unicorn.h" -//cache jmethodID values as we look them up +// cache jmethodID values as we look them up static jmethodID invokeBlockCallbacks = 0; static jmethodID invokeInterruptCallbacks = 0; static jmethodID invokeCodeCallbacks = 0; @@ -40,99 +40,115 @@ static jmethodID invokeInCallbacks = 0; static jmethodID invokeOutCallbacks = 0; static jmethodID invokeSyscallCallbacks = 0; -static JavaVM* cachedJVM; +static JavaVM *cachedJVM; -JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved) { - cachedJVM = jvm; - return JNI_VERSION_1_6; +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(uc_engine *eng, 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)eng, (jlong)address, (int)size); - (*cachedJVM)->DetachCurrentThread(cachedJVM); +static void cb_hookcode(uc_engine *eng, 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)eng, + (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(uc_engine *eng, 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)eng, (jlong)address, (int)size); - (*cachedJVM)->DetachCurrentThread(cachedJVM); +static void cb_hookblock(uc_engine *eng, 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)eng, + (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(uc_engine *eng, 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)eng, (int)intno); - (*cachedJVM)->DetachCurrentThread(cachedJVM); +static void cb_hookintr(uc_engine *eng, 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)eng, + (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(uc_engine *eng, 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)eng, (jint)port, (jint)size); - (*cachedJVM)->DetachCurrentThread(cachedJVM); - return res; +static uint32_t cb_insn_in(uc_engine *eng, 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)eng, (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(uc_engine *eng, 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)eng, (jint)port, (jint)size, (jint)value); - (*cachedJVM)->DetachCurrentThread(cachedJVM); +static void cb_insn_out(uc_engine *eng, 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)eng, + (jint)port, (jint)size, (jint)value); + (*cachedJVM)->DetachCurrentThread(cachedJVM); } // x86's handler for SYSCALL/SYSENTER -static void cb_insn_syscall(uc_engine *eng, 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)eng); - (*cachedJVM)->DetachCurrentThread(cachedJVM); +static void cb_insn_syscall(uc_engine *eng, 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)eng); + (*cachedJVM)->DetachCurrentThread(cachedJVM); } // Callback function for hooking memory (UC_HOOK_MEM_*) @@ -141,23 +157,26 @@ static void cb_insn_syscall(uc_engine *eng, void *user_data) { // @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(uc_engine *eng, 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)eng, (jlong)address, (int)size); - break; - case UC_MEM_WRITE: - (*env)->CallStaticVoidMethod(env, clz, invokeWriteCallbacks, (jlong)eng, (jlong)address, (int)size, (jlong)value); - break; - } - (*cachedJVM)->DetachCurrentThread(cachedJVM); +static void cb_hookmem(uc_engine *eng, 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)eng, + (jlong)address, (int)size); + break; + case UC_MEM_WRITE: + (*env)->CallStaticVoidMethod(env, clz, invokeWriteCallbacks, (jlong)eng, + (jlong)address, (int)size, (jlong)value); + break; + } + (*cachedJVM)->DetachCurrentThread(cachedJVM); } // Callback function for handling memory events (for UC_HOOK_MEM_UNMAPPED) @@ -166,39 +185,45 @@ static void cb_hookmem(uc_engine *eng, uc_mem_type type, // @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(uc_engine *eng, 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, invokeEventMemCallbacks, (jlong)eng, (int)type, (jlong)address, (int)size, (jlong)value); - (*cachedJVM)->DetachCurrentThread(cachedJVM); - return res; +// @return: return true to continue, or false to stop program (due to invalid +// memory). +static bool cb_eventmem(uc_engine *eng, 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, invokeEventMemCallbacks, (jlong)eng, (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 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 uc_engine *getEngine(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, "eng", "J"); - haveFid = 1; - } - return (uc_engine *)(*env)->GetLongField(env, self, fid); +static uc_engine *getEngine(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, "eng", "J"); + haveFid = 1; + } + return (uc_engine *)(*env)->GetLongField(env, self, fid); } /* @@ -206,21 +231,24 @@ static uc_engine *getEngine(JNIEnv *env, jobject self) { * Method: reg_write_num * Signature: (ILjava/lang/Number;)V */ -JNIEXPORT void JNICALL Java_unicorn_Unicorn_reg_1write_1num - (JNIEnv *env, jobject self, jint regid, jobject value) { - uc_engine *eng = getEngine(env, self); +JNIEXPORT void JNICALL Java_unicorn_Unicorn_reg_1write_1num(JNIEnv *env, + jobject self, + jint regid, + jobject value) +{ + uc_engine *eng = getEngine(env, self); - jclass clz = (*env)->FindClass(env, "java/lang/Number"); - if ((*env)->ExceptionCheck(env)) { - return; - } + jclass clz = (*env)->FindClass(env, "java/lang/Number"); + if ((*env)->ExceptionCheck(env)) { + return; + } - jmethodID longValue = (*env)->GetMethodID(env, clz, "longValue", "()J"); - jlong longVal = (*env)->CallLongMethod(env, value, longValue); - uc_err err = uc_reg_write(eng, regid, &longVal); - if (err != UC_ERR_OK) { - throwException(env, err); - } + jmethodID longValue = (*env)->GetMethodID(env, clz, "longValue", "()J"); + jlong longVal = (*env)->CallLongMethod(env, value, longValue); + uc_err err = uc_reg_write(eng, regid, &longVal); + if (err != UC_ERR_OK) { + throwException(env, err); + } } /* @@ -228,32 +256,35 @@ JNIEXPORT void JNICALL Java_unicorn_Unicorn_reg_1write_1num * Method: reg_write_mmr * Signature: (ILunicorn/X86_MMR;)V */ -JNIEXPORT void JNICALL Java_unicorn_Unicorn_reg_1write_1mmr - (JNIEnv *env, jobject self, jint regid, jobject value) { - uc_engine *eng = getEngine(env, self); - uc_x86_mmr mmr; +JNIEXPORT void JNICALL Java_unicorn_Unicorn_reg_1write_1mmr(JNIEnv *env, + jobject self, + jint regid, + jobject value) +{ + uc_engine *eng = getEngine(env, self); + uc_x86_mmr mmr; - jclass clz = (*env)->FindClass(env, "unicorn/X86_MMR"); - if ((*env)->ExceptionCheck(env)) { - return; - } + jclass clz = (*env)->FindClass(env, "unicorn/X86_MMR"); + if ((*env)->ExceptionCheck(env)) { + return; + } - jfieldID fid = (*env)->GetFieldID(env, clz, "base", "J"); - mmr.base = (uint64_t)(*env)->GetLongField(env, value, fid); + jfieldID fid = (*env)->GetFieldID(env, clz, "base", "J"); + mmr.base = (uint64_t)(*env)->GetLongField(env, value, fid); - fid = (*env)->GetFieldID(env, clz, "limit", "I"); - mmr.limit = (uint32_t)(*env)->GetLongField(env, value, fid); + fid = (*env)->GetFieldID(env, clz, "limit", "I"); + mmr.limit = (uint32_t)(*env)->GetLongField(env, value, fid); - fid = (*env)->GetFieldID(env, clz, "flags", "I"); - mmr.flags = (uint32_t)(*env)->GetLongField(env, value, fid); + fid = (*env)->GetFieldID(env, clz, "flags", "I"); + mmr.flags = (uint32_t)(*env)->GetLongField(env, value, fid); - fid = (*env)->GetFieldID(env, clz, "selector", "S"); - mmr.selector = (uint16_t)(*env)->GetLongField(env, value, fid); + fid = (*env)->GetFieldID(env, clz, "selector", "S"); + mmr.selector = (uint16_t)(*env)->GetLongField(env, value, fid); - uc_err err = uc_reg_write(eng, regid, &mmr); - if (err != UC_ERR_OK) { - throwException(env, err); - } + uc_err err = uc_reg_write(eng, regid, &mmr); + if (err != UC_ERR_OK) { + throwException(env, err); + } } /* @@ -261,27 +292,29 @@ JNIEXPORT void JNICALL Java_unicorn_Unicorn_reg_1write_1mmr * Method: reg_read_num * Signature: (I)Ljava/lang/Number; */ -JNIEXPORT jobject JNICALL Java_unicorn_Unicorn_reg_1read_1num - (JNIEnv *env, jobject self, jint regid) { - uc_engine *eng = getEngine(env, self); +JNIEXPORT jobject JNICALL Java_unicorn_Unicorn_reg_1read_1num(JNIEnv *env, + jobject self, + jint regid) +{ + uc_engine *eng = getEngine(env, self); - jclass clz = (*env)->FindClass(env, "java/lang/Long"); - if ((*env)->ExceptionCheck(env)) { - return NULL; - } + jclass clz = (*env)->FindClass(env, "java/lang/Long"); + if ((*env)->ExceptionCheck(env)) { + return NULL; + } - jlong longVal; - uc_err err = uc_reg_read(eng, regid, &longVal); - if (err != UC_ERR_OK) { - throwException(env, err); - } + jlong longVal; + uc_err err = uc_reg_read(eng, regid, &longVal); + if (err != UC_ERR_OK) { + throwException(env, err); + } - jmethodID cons = (*env)->GetMethodID(env, clz, "", "(J)V"); - jobject result = (*env)->NewObject(env, clz, cons, longVal); - if ((*env)->ExceptionCheck(env)) { - return NULL; - } - return result; + jmethodID cons = (*env)->GetMethodID(env, clz, "", "(J)V"); + jobject result = (*env)->NewObject(env, clz, cons, longVal); + if ((*env)->ExceptionCheck(env)) { + return NULL; + } + return result; } /* @@ -289,27 +322,30 @@ JNIEXPORT jobject JNICALL Java_unicorn_Unicorn_reg_1read_1num * Method: reg_read_mmr * Signature: (I)Ljava/lang/Number; */ -JNIEXPORT jobject JNICALL Java_unicorn_Unicorn_reg_1read_1mmr - (JNIEnv *env, jobject self, jint regid) { - uc_engine *eng = getEngine(env, self); +JNIEXPORT jobject JNICALL Java_unicorn_Unicorn_reg_1read_1mmr(JNIEnv *env, + jobject self, + jint regid) +{ + uc_engine *eng = getEngine(env, self); - jclass clz = (*env)->FindClass(env, "unicorn/X86_MMR"); - if ((*env)->ExceptionCheck(env)) { - return NULL; - } + jclass clz = (*env)->FindClass(env, "unicorn/X86_MMR"); + if ((*env)->ExceptionCheck(env)) { + return NULL; + } - uc_x86_mmr mmr; - uc_err err = uc_reg_read(eng, regid, &mmr); - if (err != UC_ERR_OK) { - throwException(env, err); - } + uc_x86_mmr mmr; + uc_err err = uc_reg_read(eng, regid, &mmr); + if (err != UC_ERR_OK) { + throwException(env, err); + } - jmethodID cons = (*env)->GetMethodID(env, clz, "", "(JIIS)V"); - jobject result = (*env)->NewObject(env, clz, cons, mmr.base, mmr.limit, mmr.flags, mmr.selector); - if ((*env)->ExceptionCheck(env)) { - return NULL; - } - return result; + jmethodID cons = (*env)->GetMethodID(env, clz, "", "(JIIS)V"); + jobject result = (*env)->NewObject(env, clz, cons, mmr.base, mmr.limit, + mmr.flags, mmr.selector); + if ((*env)->ExceptionCheck(env)) { + return NULL; + } + return result; } /* @@ -317,14 +353,15 @@ JNIEXPORT jobject JNICALL Java_unicorn_Unicorn_reg_1read_1mmr * Method: open * Signature: (II)J */ -JNIEXPORT jlong JNICALL Java_unicorn_Unicorn_open - (JNIEnv *env, jobject self, jint arch, jint mode) { - uc_engine *eng = NULL; - uc_err err = uc_open((uc_arch)arch, (uc_mode)mode, &eng); - if (err != UC_ERR_OK) { - throwException(env, err); - } - return (jlong)eng; +JNIEXPORT jlong JNICALL Java_unicorn_Unicorn_open(JNIEnv *env, jobject self, + jint arch, jint mode) +{ + uc_engine *eng = NULL; + uc_err err = uc_open((uc_arch)arch, (uc_mode)mode, &eng); + if (err != UC_ERR_OK) { + throwException(env, err); + } + return (jlong)eng; } /* @@ -332,8 +369,8 @@ JNIEXPORT jlong JNICALL Java_unicorn_Unicorn_open * Method: version * Signature: ()I */ -JNIEXPORT jint JNICALL Java_unicorn_Unicorn_version - (JNIEnv *env, jclass clz) { +JNIEXPORT jint JNICALL Java_unicorn_Unicorn_version(JNIEnv *env, jclass clz) +{ return (jint)uc_version(NULL, NULL); } @@ -342,8 +379,10 @@ JNIEXPORT jint JNICALL Java_unicorn_Unicorn_version * Method: arch_supported * Signature: (I)Z */ -JNIEXPORT jboolean JNICALL Java_unicorn_Unicorn_arch_1supported - (JNIEnv *env, jclass clz, jint arch) { +JNIEXPORT jboolean JNICALL Java_unicorn_Unicorn_arch_1supported(JNIEnv *env, + jclass clz, + jint arch) +{ return (jboolean)(uc_arch_supported((uc_arch)arch) != 0); } @@ -352,15 +391,15 @@ JNIEXPORT jboolean JNICALL Java_unicorn_Unicorn_arch_1supported * Method: close * Signature: ()V */ -JNIEXPORT void JNICALL Java_unicorn_Unicorn_close - (JNIEnv *env, jobject self) { - uc_engine *eng = getEngine(env, self); - uc_err err = uc_close(eng); - if (err != UC_ERR_OK) { - throwException(env, err); - } - //We also need to ReleaseByteArrayElements for any regions that - //were mapped with uc_mem_map_ptr +JNIEXPORT void JNICALL Java_unicorn_Unicorn_close(JNIEnv *env, jobject self) +{ + uc_engine *eng = getEngine(env, self); + uc_err err = uc_close(eng); + if (err != UC_ERR_OK) { + throwException(env, err); + } + // We also need to ReleaseByteArrayElements for any regions that + // were mapped with uc_mem_map_ptr } /* @@ -368,15 +407,16 @@ JNIEXPORT void JNICALL Java_unicorn_Unicorn_close * Method: query * Signature: (I)I */ -JNIEXPORT jint JNICALL Java_unicorn_Unicorn_query - (JNIEnv *env, jobject self, jint type) { - uc_engine *eng = getEngine(env, self); - size_t result; - uc_err err = uc_query(eng, type, &result); - if (err != UC_ERR_OK) { - throwException(env, err); - } - return (jint)result; +JNIEXPORT jint JNICALL Java_unicorn_Unicorn_query(JNIEnv *env, jobject self, + jint type) +{ + uc_engine *eng = getEngine(env, self); + size_t result; + uc_err err = uc_query(eng, type, &result); + if (err != UC_ERR_OK) { + throwException(env, err); + } + return (jint)result; } /* @@ -384,10 +424,10 @@ JNIEXPORT jint JNICALL Java_unicorn_Unicorn_query * Method: errno * Signature: ()I */ -JNIEXPORT jint JNICALL Java_unicorn_Unicorn_errno - (JNIEnv *env, jobject self) { - uc_engine *eng = getEngine(env, self); - return (jint)uc_errno(eng); +JNIEXPORT jint JNICALL Java_unicorn_Unicorn_errno(JNIEnv *env, jobject self) +{ + uc_engine *eng = getEngine(env, self); + return (jint)uc_errno(eng); } /* @@ -395,11 +435,12 @@ JNIEXPORT jint JNICALL Java_unicorn_Unicorn_errno * 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; +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; } /* @@ -407,15 +448,17 @@ JNIEXPORT jstring JNICALL Java_unicorn_Unicorn_strerror * Method: reg_write * Signature: (I[B)V */ -JNIEXPORT void JNICALL Java_unicorn_Unicorn_reg_1write - (JNIEnv *env, jobject self, jint regid, jbyteArray value) { - uc_engine *eng = getEngine(env, self); - jbyte *array = (*env)->GetByteArrayElements(env, value, NULL); - uc_err err = uc_reg_write(eng, (int)regid, (void *)array); - if (err != UC_ERR_OK) { - throwException(env, err); - } - (*env)->ReleaseByteArrayElements(env, value, array, JNI_ABORT); +JNIEXPORT void JNICALL Java_unicorn_Unicorn_reg_1write(JNIEnv *env, + jobject self, jint regid, + jbyteArray value) +{ + uc_engine *eng = getEngine(env, self); + jbyte *array = (*env)->GetByteArrayElements(env, value, NULL); + uc_err err = uc_reg_write(eng, (int)regid, (void *)array); + if (err != UC_ERR_OK) { + throwException(env, err); + } + (*env)->ReleaseByteArrayElements(env, value, array, JNI_ABORT); } /* @@ -423,17 +466,20 @@ JNIEXPORT void JNICALL Java_unicorn_Unicorn_reg_1write * Method: reg_read * Signature: (II)[B */ -JNIEXPORT jbyteArray JNICALL Java_unicorn_Unicorn_reg_1read - (JNIEnv *env, jobject self, jint regid, jint regsz) { - uc_engine *eng = getEngine(env, self); - jbyteArray regval = (*env)->NewByteArray(env, (jsize)regsz); - jbyte *array = (*env)->GetByteArrayElements(env, regval, NULL); - uc_err err = uc_reg_read(eng, (int)regid, (void *)array); - if (err != UC_ERR_OK) { - throwException(env, err); - } - (*env)->ReleaseByteArrayElements(env, regval, array, 0); - return regval; +JNIEXPORT jbyteArray JNICALL Java_unicorn_Unicorn_reg_1read(JNIEnv *env, + jobject self, + jint regid, + jint regsz) +{ + uc_engine *eng = getEngine(env, self); + jbyteArray regval = (*env)->NewByteArray(env, (jsize)regsz); + jbyte *array = (*env)->GetByteArrayElements(env, regval, NULL); + uc_err err = uc_reg_read(eng, (int)regid, (void *)array); + if (err != UC_ERR_OK) { + throwException(env, err); + } + (*env)->ReleaseByteArrayElements(env, regval, array, 0); + return regval; } /* @@ -441,19 +487,22 @@ JNIEXPORT jbyteArray JNICALL Java_unicorn_Unicorn_reg_1read * Method: mem_write * Signature: (J[B)V */ -JNIEXPORT void JNICALL Java_unicorn_Unicorn_mem_1write - (JNIEnv *env , jobject self, jlong address, jbyteArray bytes) { +JNIEXPORT void JNICALL Java_unicorn_Unicorn_mem_1write(JNIEnv *env, + jobject self, + jlong address, + jbyteArray bytes) +{ - uc_engine *eng = getEngine(env, self); - jbyte *array = (*env)->GetByteArrayElements(env, bytes, NULL); - jsize size = (*env)->GetArrayLength(env, bytes); - uc_err err = uc_mem_write(eng, (uint64_t)address, array, (size_t)size); + uc_engine *eng = getEngine(env, self); + jbyte *array = (*env)->GetByteArrayElements(env, bytes, NULL); + jsize size = (*env)->GetArrayLength(env, bytes); + uc_err err = uc_mem_write(eng, (uint64_t)address, array, (size_t)size); - if (err != UC_ERR_OK) { - throwException(env, err); - } + if (err != UC_ERR_OK) { + throwException(env, err); + } - (*env)->ReleaseByteArrayElements(env, bytes, array, JNI_ABORT); + (*env)->ReleaseByteArrayElements(env, bytes, array, JNI_ABORT); } /* @@ -461,18 +510,21 @@ JNIEXPORT void JNICALL Java_unicorn_Unicorn_mem_1write * Method: mem_read * Signature: (JJ)[B */ -JNIEXPORT jbyteArray JNICALL Java_unicorn_Unicorn_mem_1read - (JNIEnv *env, jobject self, jlong address, jlong size) { - uc_engine *eng = getEngine(env, self); +JNIEXPORT jbyteArray JNICALL Java_unicorn_Unicorn_mem_1read(JNIEnv *env, + jobject self, + jlong address, + jlong size) +{ + uc_engine *eng = getEngine(env, self); - jbyteArray bytes = (*env)->NewByteArray(env, (jsize)size); - jbyte *array = (*env)->GetByteArrayElements(env, bytes, NULL); - uc_err err = uc_mem_read(eng, (uint64_t)address, array, (size_t)size); - if (err != UC_ERR_OK) { - throwException(env, err); - } - (*env)->ReleaseByteArrayElements(env, bytes, array, 0); - return bytes; + jbyteArray bytes = (*env)->NewByteArray(env, (jsize)size); + jbyte *array = (*env)->GetByteArrayElements(env, bytes, NULL); + uc_err err = uc_mem_read(eng, (uint64_t)address, array, (size_t)size); + if (err != UC_ERR_OK) { + throwException(env, err); + } + (*env)->ReleaseByteArrayElements(env, bytes, array, 0); + return bytes; } /* @@ -480,14 +532,19 @@ JNIEXPORT jbyteArray JNICALL Java_unicorn_Unicorn_mem_1read * 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) { - uc_engine *eng = getEngine(env, self); +JNIEXPORT void JNICALL Java_unicorn_Unicorn_emu_1start(JNIEnv *env, + jobject self, + jlong begin, jlong until, + jlong timeout, + jlong count) +{ + uc_engine *eng = getEngine(env, self); - uc_err err = uc_emu_start(eng, (uint64_t)begin, (uint64_t)until, (uint64_t)timeout, (size_t)count); - if (err != UC_ERR_OK) { - throwException(env, err); - } + uc_err err = uc_emu_start(eng, (uint64_t)begin, (uint64_t)until, + (uint64_t)timeout, (size_t)count); + if (err != UC_ERR_OK) { + throwException(env, err); + } } /* @@ -495,14 +552,14 @@ JNIEXPORT void JNICALL Java_unicorn_Unicorn_emu_1start * Method: emu_stop * Signature: ()V */ -JNIEXPORT void JNICALL Java_unicorn_Unicorn_emu_1stop - (JNIEnv *env, jobject self) { - uc_engine *eng = getEngine(env, self); +JNIEXPORT void JNICALL Java_unicorn_Unicorn_emu_1stop(JNIEnv *env, jobject self) +{ + uc_engine *eng = getEngine(env, self); - uc_err err = uc_emu_stop(eng); - if (err != UC_ERR_OK) { - throwException(env, err); - } + uc_err err = uc_emu_stop(eng); + if (err != UC_ERR_OK) { + throwException(env, err); + } } /* @@ -510,30 +567,39 @@ JNIEXPORT void JNICALL Java_unicorn_Unicorn_emu_1stop * Method: registerHook * Signature: (JI)J */ -JNIEXPORT jlong JNICALL Java_unicorn_Unicorn_registerHook__JI - (JNIEnv *env, jclass clz, jlong eng, jint type) { - uc_hook hh = 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((uc_engine*)eng, &hh, (uc_hook_type)type, cb_hookintr, env, 1, 0); - break; - case UC_HOOK_MEM_FETCH_UNMAPPED: // Hook for all invalid memory access events - case UC_HOOK_MEM_READ_UNMAPPED: // Hook for all invalid memory access events - case UC_HOOK_MEM_WRITE_UNMAPPED: // Hook for all invalid memory access events - case UC_HOOK_MEM_FETCH_PROT: // Hook for all invalid memory access events - case UC_HOOK_MEM_READ_PROT: // Hook for all invalid memory access events - case UC_HOOK_MEM_WRITE_PROT: // Hook for all invalid memory access events - if (invokeEventMemCallbacks == 0) { - invokeEventMemCallbacks = (*env)->GetStaticMethodID(env, clz, "invokeEventMemCallbacks", "(JIJIJ)Z"); - } - err = uc_hook_add((uc_engine*)eng, &hh, (uc_hook_type)type, cb_eventmem, env, 1, 0); - break; - } - return (jlong)hh; +JNIEXPORT jlong JNICALL Java_unicorn_Unicorn_registerHook__JI(JNIEnv *env, + jclass clz, + jlong eng, + jint type) +{ + uc_hook hh = 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((uc_engine *)eng, &hh, (uc_hook_type)type, + cb_hookintr, env, 1, 0); + break; + case UC_HOOK_MEM_FETCH_UNMAPPED: // Hook for all invalid memory access + // events + case UC_HOOK_MEM_READ_UNMAPPED: // Hook for all invalid memory access events + case UC_HOOK_MEM_WRITE_UNMAPPED: // Hook for all invalid memory access + // events + case UC_HOOK_MEM_FETCH_PROT: // Hook for all invalid memory access events + case UC_HOOK_MEM_READ_PROT: // Hook for all invalid memory access events + case UC_HOOK_MEM_WRITE_PROT: // Hook for all invalid memory access events + if (invokeEventMemCallbacks == 0) { + invokeEventMemCallbacks = (*env)->GetStaticMethodID( + env, clz, "invokeEventMemCallbacks", "(JIJIJ)Z"); + } + err = uc_hook_add((uc_engine *)eng, &hh, (uc_hook_type)type, + cb_eventmem, env, 1, 0); + break; + } + return (jlong)hh; } /* @@ -541,33 +607,40 @@ JNIEXPORT jlong JNICALL Java_unicorn_Unicorn_registerHook__JI * Method: registerHook * Signature: (JII)J */ -JNIEXPORT jlong JNICALL Java_unicorn_Unicorn_registerHook__JII - (JNIEnv *env, jclass clz, jlong eng, jint type, jint arg1) { - uc_hook hh = 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((uc_engine*)eng, &hh, (uc_hook_type)type, cb_insn_out, env, 1, 0, arg1); - case UC_X86_INS_IN: - if (invokeInCallbacks == 0) { - invokeInCallbacks = (*env)->GetStaticMethodID(env, clz, "invokeInCallbacks", "(JII)I"); - } - err = uc_hook_add((uc_engine*)eng, &hh, (uc_hook_type)type, cb_insn_in, env, 1, 0, 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((uc_engine*)eng, &hh, (uc_hook_type)type, cb_insn_syscall, env, 1, 0, arg1); - } - break; - } - return (jlong)hh; +JNIEXPORT jlong JNICALL Java_unicorn_Unicorn_registerHook__JII( + JNIEnv *env, jclass clz, jlong eng, jint type, jint arg1) +{ + uc_hook hh = 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((uc_engine *)eng, &hh, (uc_hook_type)type, + cb_insn_out, env, 1, 0, arg1); + case UC_X86_INS_IN: + if (invokeInCallbacks == 0) { + invokeInCallbacks = (*env)->GetStaticMethodID( + env, clz, "invokeInCallbacks", "(JII)I"); + } + err = uc_hook_add((uc_engine *)eng, &hh, (uc_hook_type)type, + cb_insn_in, env, 1, 0, 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((uc_engine *)eng, &hh, (uc_hook_type)type, + cb_insn_syscall, env, 1, 0, arg1); + } + break; + } + return (jlong)hh; } /* @@ -575,37 +648,46 @@ JNIEXPORT jlong JNICALL Java_unicorn_Unicorn_registerHook__JII * Method: registerHook * Signature: (JIJJ)J */ -JNIEXPORT jlong JNICALL Java_unicorn_Unicorn_registerHook__JIJJ - (JNIEnv *env, jclass clz, jlong eng, jint type, jlong arg1, jlong arg2) { - uc_hook hh = 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((uc_engine*)eng, &hh, (uc_hook_type)type, cb_hookcode, env, 1, 0, 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((uc_engine*)eng, &hh, (uc_hook_type)type, cb_hookblock, env, 1, 0, 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((uc_engine*)eng, &hh, (uc_hook_type)type, cb_hookmem, env, 1, 0, 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((uc_engine*)eng, &hh, (uc_hook_type)type, cb_hookmem, env, 1, 0, arg1, arg2); - break; - } - return (jlong)hh; +JNIEXPORT jlong JNICALL Java_unicorn_Unicorn_registerHook__JIJJ( + JNIEnv *env, jclass clz, jlong eng, jint type, jlong arg1, jlong arg2) +{ + uc_hook hh = 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((uc_engine *)eng, &hh, (uc_hook_type)type, + cb_hookcode, env, 1, 0, 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((uc_engine *)eng, &hh, (uc_hook_type)type, + cb_hookblock, env, 1, 0, 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((uc_engine *)eng, &hh, (uc_hook_type)type, cb_hookmem, + env, 1, 0, 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((uc_engine *)eng, &hh, (uc_hook_type)type, cb_hookmem, + env, 1, 0, arg1, arg2); + break; + } + return (jlong)hh; } /* @@ -613,16 +695,17 @@ JNIEXPORT jlong JNICALL Java_unicorn_Unicorn_registerHook__JIJJ * Method: hook_del * Signature: (J)V */ -JNIEXPORT void JNICALL Java_unicorn_Unicorn_hook_1del - (JNIEnv *env, jobject self, jlong hh) { - uc_engine *eng = getEngine(env, self); +JNIEXPORT void JNICALL Java_unicorn_Unicorn_hook_1del(JNIEnv *env, jobject self, + jlong hh) +{ + 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); - if (err != UC_ERR_OK) { - throwException(env, err); - } + uc_err err = uc_hook_del(eng, (uc_hook)hh); + if (err != UC_ERR_OK) { + throwException(env, err); + } } /* @@ -630,14 +713,17 @@ JNIEXPORT void JNICALL Java_unicorn_Unicorn_hook_1del * Method: mem_map * Signature: (JJI)V */ -JNIEXPORT void JNICALL Java_unicorn_Unicorn_mem_1map - (JNIEnv *env, jobject self, jlong address, jlong size, jint perms) { - uc_engine *eng = getEngine(env, self); +JNIEXPORT void JNICALL Java_unicorn_Unicorn_mem_1map(JNIEnv *env, jobject self, + jlong address, jlong size, + jint perms) +{ + uc_engine *eng = getEngine(env, self); - uc_err err = uc_mem_map(eng, (uint64_t)address, (size_t)size, (uint32_t)perms); - if (err != UC_ERR_OK) { - throwException(env, err); - } + uc_err err = + uc_mem_map(eng, (uint64_t)address, (size_t)size, (uint32_t)perms); + if (err != UC_ERR_OK) { + throwException(env, err); + } } /* @@ -645,17 +731,20 @@ JNIEXPORT void JNICALL Java_unicorn_Unicorn_mem_1map * Method: mem_map_ptr * Signature: (JJI[B)V */ -JNIEXPORT void JNICALL Java_unicorn_Unicorn_mem_1map_1ptr - (JNIEnv *env, jobject self, jlong address, jlong size, jint perms, jbyteArray block) { - uc_engine *eng = getEngine(env, self); - jbyte *array = (*env)->GetByteArrayElements(env, block, NULL); - uc_err err = uc_mem_map_ptr(eng, (uint64_t)address, (size_t)size, (uint32_t)perms, (void*)array); - if (err != UC_ERR_OK) { - throwException(env, err); - } - //Need to track address/block/array so that we can ReleaseByteArrayElements when the - //block gets unmapped or when uc_close gets called - //(*env)->ReleaseByteArrayElements(env, block, array, JNI_ABORT); +JNIEXPORT void JNICALL +Java_unicorn_Unicorn_mem_1map_1ptr(JNIEnv *env, jobject self, jlong address, + jlong size, jint perms, jbyteArray block) +{ + uc_engine *eng = getEngine(env, self); + jbyte *array = (*env)->GetByteArrayElements(env, block, NULL); + uc_err err = uc_mem_map_ptr(eng, (uint64_t)address, (size_t)size, + (uint32_t)perms, (void *)array); + if (err != UC_ERR_OK) { + throwException(env, err); + } + // Need to track address/block/array so that we can ReleaseByteArrayElements + // when the block gets unmapped or when uc_close gets called + //(*env)->ReleaseByteArrayElements(env, block, array, JNI_ABORT); } /* @@ -663,17 +752,20 @@ JNIEXPORT void JNICALL Java_unicorn_Unicorn_mem_1map_1ptr * Method: mem_unmap * Signature: (JJ)V */ -JNIEXPORT void JNICALL Java_unicorn_Unicorn_mem_1unmap - (JNIEnv *env, jobject self, jlong address, jlong size) { - uc_engine *eng = getEngine(env, self); +JNIEXPORT void JNICALL Java_unicorn_Unicorn_mem_1unmap(JNIEnv *env, + jobject self, + jlong address, + jlong size) +{ + uc_engine *eng = getEngine(env, self); - uc_err err = uc_mem_unmap(eng, (uint64_t)address, (size_t)size); - if (err != UC_ERR_OK) { - throwException(env, err); - } + uc_err err = uc_mem_unmap(eng, (uint64_t)address, (size_t)size); + if (err != UC_ERR_OK) { + throwException(env, err); + } - //If a region was mapped using uc_mem_map_ptr, we also need to - //ReleaseByteArrayElements for that region + // If a region was mapped using uc_mem_map_ptr, we also need to + // ReleaseByteArrayElements for that region } /* @@ -681,14 +773,18 @@ JNIEXPORT void JNICALL Java_unicorn_Unicorn_mem_1unmap * Method: mem_protect * Signature: (JJI)V */ -JNIEXPORT void JNICALL Java_unicorn_Unicorn_mem_1protect - (JNIEnv *env, jobject self, jlong address, jlong size, jint perms) { - uc_engine *eng = getEngine(env, self); +JNIEXPORT void JNICALL Java_unicorn_Unicorn_mem_1protect(JNIEnv *env, + jobject self, + jlong address, + jlong size, jint perms) +{ + uc_engine *eng = getEngine(env, self); - uc_err err = uc_mem_protect(eng, (uint64_t)address, (size_t)size, (uint32_t)perms); - if (err != UC_ERR_OK) { - throwException(env, err); - } + uc_err err = + uc_mem_protect(eng, (uint64_t)address, (size_t)size, (uint32_t)perms); + if (err != UC_ERR_OK) { + throwException(env, err); + } } /* @@ -696,31 +792,33 @@ JNIEXPORT void JNICALL Java_unicorn_Unicorn_mem_1protect * Method: mem_regions * Signature: ()[Lunicorn/MemRegion; */ -JNIEXPORT jobjectArray JNICALL Java_unicorn_Unicorn_mem_1regions - (JNIEnv *env, jobject self) { - uc_engine *eng = getEngine(env, self); +JNIEXPORT jobjectArray JNICALL Java_unicorn_Unicorn_mem_1regions(JNIEnv *env, + jobject self) +{ + uc_engine *eng = getEngine(env, self); - uc_mem_region *regions = NULL; - uint32_t count = 0; - uint32_t i; + uc_mem_region *regions = NULL; + uint32_t count = 0; + uint32_t i; - uc_err err = uc_mem_regions(eng, ®ions, &count); - if (err != UC_ERR_OK) { - throwException(env, err); - } - jclass clz = (*env)->FindClass(env, "unicorn/MemRegion"); - if ((*env)->ExceptionCheck(env)) { - return NULL; - } - jobjectArray result = (*env)->NewObjectArray(env, (jsize)count, clz, NULL); - jmethodID cons = (*env)->GetMethodID(env, clz, "", "(JJI)V"); - for (i = 0; i < count; i++) { - jobject mr = (*env)->NewObject(env, clz, cons, regions[i].begin, regions[i].end, regions[i].perms); - (*env)->SetObjectArrayElement(env, result, (jsize)i, mr); - } - uc_free(regions); + uc_err err = uc_mem_regions(eng, ®ions, &count); + if (err != UC_ERR_OK) { + throwException(env, err); + } + jclass clz = (*env)->FindClass(env, "unicorn/MemRegion"); + if ((*env)->ExceptionCheck(env)) { + return NULL; + } + jobjectArray result = (*env)->NewObjectArray(env, (jsize)count, clz, NULL); + jmethodID cons = (*env)->GetMethodID(env, clz, "", "(JJI)V"); + for (i = 0; i < count; i++) { + jobject mr = (*env)->NewObject(env, clz, cons, regions[i].begin, + regions[i].end, regions[i].perms); + (*env)->SetObjectArrayElement(env, result, (jsize)i, mr); + } + uc_free(regions); - return result; + return result; } /* @@ -728,15 +826,16 @@ JNIEXPORT jobjectArray JNICALL Java_unicorn_Unicorn_mem_1regions * 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; +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; } /* @@ -744,12 +843,13 @@ JNIEXPORT jlong JNICALL Java_unicorn_Unicorn_context_1alloc * Method: free * Signature: (J)V */ -JNIEXPORT void JNICALL Java_unicorn_Unicorn_free - (JNIEnv *env, jobject self, jlong ctx) { - uc_err err = uc_free((void *)ctx); - if (err != UC_ERR_OK) { - throwException(env, err); - } +JNIEXPORT void JNICALL Java_unicorn_Unicorn_free(JNIEnv *env, jobject self, + jlong ctx) +{ + uc_err err = uc_free((void *)ctx); + if (err != UC_ERR_OK) { + throwException(env, err); + } } /* @@ -757,13 +857,15 @@ JNIEXPORT void JNICALL Java_unicorn_Unicorn_free * 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); - } +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); + } } /* @@ -771,13 +873,15 @@ JNIEXPORT void JNICALL Java_unicorn_Unicorn_context_1save * 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); - } +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); + } } /* @@ -785,11 +889,13 @@ JNIEXPORT void JNICALL Java_unicorn_Unicorn_context_1restore * Method: ctl_set_cpu_model * Signature: (I)V */ -JNIEXPORT void JNICALL Java_unicorn_Unicorn_ctl_1set_1cpu_1model - (JNIEnv *env, jobject self, jint cpu_model) { - uc_engine *eng = getEngine(env, self); - uc_err err = uc_ctl_set_cpu_model(eng, cpu_model); - if (err != UC_ERR_OK) { - throwException(env, err); - } +JNIEXPORT void JNICALL Java_unicorn_Unicorn_ctl_1set_1cpu_1model(JNIEnv *env, + jobject self, + jint cpu_model) +{ + uc_engine *eng = getEngine(env, self); + uc_err err = uc_ctl_set_cpu_model(eng, cpu_model); + if (err != UC_ERR_OK) { + throwException(env, err); + } } From 4b471e16e9ad407aed3fbb2e6295e7ee204b1008 Mon Sep 17 00:00:00 2001 From: Robert Xiao Date: Fri, 5 May 2023 15:31:10 -0700 Subject: [PATCH 02/25] Remove redundant Makefile --- bindings/java/Makefile | 84 ++++++++++++++++++++++++------ bindings/java/Makefile.build | 82 ----------------------------- bindings/java/unicorn/Unicorn.java | 3 +- 3 files changed, 70 insertions(+), 99 deletions(-) delete mode 100644 bindings/java/Makefile.build diff --git a/bindings/java/Makefile b/bindings/java/Makefile index 313db888..8ce5fc0e 100644 --- a/bindings/java/Makefile +++ b/bindings/java/Makefile @@ -1,29 +1,81 @@ -.PHONY: gen_const clean jar all lib samples install +all: jar lib samples -all: gen_const - $(MAKE) -f Makefile.build all +JC=javac -lib: - $(MAKE) -f Makefile.build lib +JAVA_HOME := $(shell readlink -f `which $(JC)` | sed "s:/bin/$(JC)::") -samples: - $(MAKE) -f Makefile.build samples +JAVA_INC := $(shell realpath $(JAVA_HOME)/include) -jar: - $(MAKE) -f Makefile.build jar +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 +else 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) + +CLASSPATH=./ + +.SUFFIXES: .java .class + +%.class: %.java + $(JC) -classpath .:unicorn.jar $(JFLAGS) $< + +OBJS=unicorn_Unicorn.o + +JARFILE=unicorn.jar + +%.o: %.c + $(CC) -c $(CFLAGS) $(INCS) $< -o $@ + +unicorn_Unicorn.h: unicorn/Unicorn.java + javac -h . $< + +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 - $(MAKE) -f Makefile.build install + cp libunicorn_java$(LIB_EXT) /usr/lib + cp $(JARFILE) /usr/share/java uninstall: - $(MAKE) -f Makefile.build uninstall + rm /usr/lib/libunicorn_java$(LIB_EXT) + rm /usr/share/java/$(JARFILE) gen_const: cd .. && python3 const_generator.py java clean: - rm -f unicorn/*.class - rm -f samples/*.class - rm -f *.so - rm -f *.dylib - rm -f *.dll + rm unicorn/*.class + rm samples/*.class + rm *.so + rm *.dylib + rm *.dll + +.PHONY: all lib samples jar install uninstall gen_const clean diff --git a/bindings/java/Makefile.build b/bindings/java/Makefile.build deleted file mode 100644 index 0572120a..00000000 --- a/bindings/java/Makefile.build +++ /dev/null @@ -1,82 +0,0 @@ - -.PHONY: gen_const clean - -JC=javac - -JAVA_HOME := $(shell readlink -f `which $(JC)` | sed "s:/bin/$(JC)::") - -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 -else 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) - -CLASSPATH=./ - -.SUFFIXES: .java .class - -%.class: %.java - $(JC) -classpath .:unicorn.jar $(JFLAGS) $< - -OBJS=unicorn_Unicorn.o - -JARFILE=unicorn.jar - -all: jar lib samples - -%.o: %.c - $(CC) -c $(CFLAGS) $(INCS) $< -o $@ - -unicorn_Unicorn.h: unicorn/Unicorn.java - javac -h . $< - -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) /usr/lib - cp $(JARFILE) /usr/share/java - -uninstall: - rm /usr/lib/libunicorn_java$(LIB_EXT) - rm /usr/share/java/$(JARFILE) - -gen_const: - cd .. && python const_generator.py java - -clean: - rm unicorn/*.class - rm samples/*.class - rm *.so - rm *.dylib - rm *.dll diff --git a/bindings/java/unicorn/Unicorn.java b/bindings/java/unicorn/Unicorn.java index e1477a48..870f31cf 100644 --- a/bindings/java/unicorn/Unicorn.java +++ b/bindings/java/unicorn/Unicorn.java @@ -82,7 +82,8 @@ public class Unicorn // required to load native method implementations static { - System.loadLibrary("unicorn_java"); // loads unicorn.dll or libunicorn.so + // load libunicorn_java.{so,dylib} or unicorn_java.dll + System.loadLibrary("unicorn_java"); 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_FETCH_UNMAPPED, UC_MEM_FETCH_UNMAPPED); From 66c8965f96264a1cad7abfd9ae2c73e6d66316ea Mon Sep 17 00:00:00 2001 From: Robert Xiao Date: Fri, 5 May 2023 16:24:45 -0700 Subject: [PATCH 03/25] Set up testing infrastructure ("make test") --- bindings/java/Makefile | 8 +++ .../java/samples/SampleNetworkAuditing.java | 4 +- bindings/java/samples/Sample_arm.java | 6 +- bindings/java/samples/Sample_arm64.java | 4 +- bindings/java/samples/Sample_m68k.java | 4 +- bindings/java/samples/Sample_mips.java | 6 +- bindings/java/samples/Sample_sparc.java | 4 +- bindings/java/samples/Sample_x86.java | 20 +++--- bindings/java/samples/Sample_x86_mmr.java | 4 +- bindings/java/samples/Shellcode.java | 4 +- bindings/java/testdep/hamcrest-2.2.jar | Bin 0 -> 123360 bytes bindings/java/testdep/junit-4.13.2.jar | Bin 0 -> 384581 bytes bindings/java/tests/RegressionTests.java | 67 ++++++++++++++++++ bindings/java/tests/TestSamples.java | 39 ++++++++++ 14 files changed, 151 insertions(+), 19 deletions(-) create mode 100644 bindings/java/testdep/hamcrest-2.2.jar create mode 100644 bindings/java/testdep/junit-4.13.2.jar create mode 100644 bindings/java/tests/RegressionTests.java create mode 100644 bindings/java/tests/TestSamples.java diff --git a/bindings/java/Makefile b/bindings/java/Makefile index 8ce5fc0e..245bfd35 100644 --- a/bindings/java/Makefile +++ b/bindings/java/Makefile @@ -11,6 +11,7 @@ JAVA_PLATFORM_INC := $(shell dirname `find $(JAVA_INC) -name jni_md.h`) UNICORN_INC=../../include SAMPLES := $(shell ls samples/*.java) +TESTS := $(shell ls tests/*.java) SRC := $(shell ls unicorn/*.java) OS := $(shell uname) @@ -33,6 +34,9 @@ CLASSPATH=./ .SUFFIXES: .java .class +tests/%.class: tests/%.java + $(JC) -classpath .:unicorn.jar:testdep/junit-4.13.2.jar $(JFLAGS) $< + %.class: %.java $(JC) -classpath .:unicorn.jar $(JFLAGS) $< @@ -55,11 +59,15 @@ lib: libunicorn_java$(LIB_EXT) unicorn_Unicorn.h $(CC) -o $< $(LDFLAGS) $(OBJS) $(LIBDIR) $(LIBS) samples: $(SAMPLES:.java=.class) +tests: $(TESTS:.java=.class) jarfiles: $(SRC:.java=.class) jar: jarfiles jar cf $(JARFILE) unicorn/*.class +test: lib samples tests + java -cp .:testdep/hamcrest-2.2.jar:testdep/junit-4.13.2.jar org.junit.runner.JUnitCore $(subst /,.,$(TESTS:.java=)) + install: lib jar cp libunicorn_java$(LIB_EXT) /usr/lib cp $(JARFILE) /usr/share/java diff --git a/bindings/java/samples/SampleNetworkAuditing.java b/bindings/java/samples/SampleNetworkAuditing.java index 6f572dc2..0aa27bc2 100644 --- a/bindings/java/samples/SampleNetworkAuditing.java +++ b/bindings/java/samples/SampleNetworkAuditing.java @@ -24,6 +24,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Nguyen Tan Cong */ +package samples; + import unicorn.*; import java.util.*; @@ -430,7 +432,7 @@ public class SampleNetworkAuditing { } // end utilities - static void test_i386(byte[] code) { + public static void test_i386(byte[] code) { fd_chains.clean(); System.out.printf("Emulate i386 code\n"); try { diff --git a/bindings/java/samples/Sample_arm.java b/bindings/java/samples/Sample_arm.java index 67ba9a6a..a6f8e184 100644 --- a/bindings/java/samples/Sample_arm.java +++ b/bindings/java/samples/Sample_arm.java @@ -3,6 +3,8 @@ /* Sample code to demonstrate how to emulate ARM code */ +package samples; + import unicorn.*; public class Sample_arm { @@ -41,7 +43,7 @@ public class Sample_arm { } } - static void test_arm() { + public static void test_arm() { Long r0 = 0x1234L; // R0 register Long r2 = 0x6789L; // R1 register @@ -85,7 +87,7 @@ public class Sample_arm { u.close(); } - static void test_thumb() { + public static void test_thumb() { Long sp = 0x1234L; // R0 register diff --git a/bindings/java/samples/Sample_arm64.java b/bindings/java/samples/Sample_arm64.java index 82e79fcc..5c137d6b 100644 --- a/bindings/java/samples/Sample_arm64.java +++ b/bindings/java/samples/Sample_arm64.java @@ -24,6 +24,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. /* Sample code to demonstrate how to emulate ARM64 code */ +package samples; + import unicorn.*; public class Sample_arm64 { @@ -70,7 +72,7 @@ public class Sample_arm64 { } } - static void test_arm64() { + public static void test_arm64() { Long x11 = 0x1234L; // X11 register Long x13 = 0x6789L; // X13 register diff --git a/bindings/java/samples/Sample_m68k.java b/bindings/java/samples/Sample_m68k.java index 9d530084..f9ffb19e 100644 --- a/bindings/java/samples/Sample_m68k.java +++ b/bindings/java/samples/Sample_m68k.java @@ -24,6 +24,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. /* Sample code to demonstrate how to emulate m68k code */ +package samples; + import unicorn.*; public class Sample_m68k { @@ -70,7 +72,7 @@ public class Sample_m68k { } } - static void test_m68k() { + public static void test_m68k() { Long d0 = 0x0000L; // d0 data register Long d1 = 0x0000L; // d1 data register Long d2 = 0x0000L; // d2 data register diff --git a/bindings/java/samples/Sample_mips.java b/bindings/java/samples/Sample_mips.java index 0f0bd8c5..60f5abcd 100644 --- a/bindings/java/samples/Sample_mips.java +++ b/bindings/java/samples/Sample_mips.java @@ -24,6 +24,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. /* Sample code to demonstrate how to emulate Mips code (big endian) */ +package samples; + import unicorn.*; public class Sample_mips { @@ -71,7 +73,7 @@ public class Sample_mips { } } - static void test_mips_eb() { + public static void test_mips_eb() { Long r1 = 0x6789L; // R1 register @@ -109,7 +111,7 @@ public class Sample_mips { u.close(); } - static void test_mips_el() { + public static void test_mips_el() { Long r1 = 0x6789L; // R1 register System.out.print("===========================\n"); diff --git a/bindings/java/samples/Sample_sparc.java b/bindings/java/samples/Sample_sparc.java index b11eb8d7..1ecbbd32 100644 --- a/bindings/java/samples/Sample_sparc.java +++ b/bindings/java/samples/Sample_sparc.java @@ -24,6 +24,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. /* Sample code to demonstrate how to emulate Sparc code */ +package samples; + import unicorn.*; public class Sample_sparc { @@ -71,7 +73,7 @@ public class Sample_sparc { } } - static void test_sparc() { + public static void test_sparc() { Long g1 = 0x1230L; // G1 register Long g2 = 0x6789L; // G2 register Long g3 = 0x5555L; // G3 register diff --git a/bindings/java/samples/Sample_x86.java b/bindings/java/samples/Sample_x86.java index dcef5623..53ea1429 100644 --- a/bindings/java/samples/Sample_x86.java +++ b/bindings/java/samples/Sample_x86.java @@ -24,6 +24,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. /* Sample code to demonstrate how to emulate X86 code */ +package samples; + import unicorn.*; public class Sample_x86 { @@ -200,7 +202,7 @@ public class Sample_x86 { } } - static void test_i386() { + public static void test_i386() { Long r_ecx = 0x1234L; // ECX register Long r_edx = 0x7890L; // EDX register @@ -266,7 +268,7 @@ public class Sample_x86 { uc.close(); } - static void test_i386_inout() { + public static void test_i386_inout() { Long r_eax = 0x1234L; // ECX register Long r_ecx = 0x6789L; // EDX register @@ -311,7 +313,7 @@ public class Sample_x86 { u.close(); } - static void test_i386_jump() { + public static void test_i386_jump() { System.out.print("===================================\n"); System.out.print("Emulate i386 code with jump\n"); @@ -339,7 +341,7 @@ public class Sample_x86 { } // emulate code that loop forever - static void test_i386_loop() { + public static void test_i386_loop() { Long r_ecx = 0x1234L; // ECX register Long r_edx = 0x7890L; // EDX register @@ -376,7 +378,7 @@ public class Sample_x86 { } // emulate code that read invalid memory - static void test_i386_invalid_mem_read() { + public static void test_i386_invalid_mem_read() { Long r_ecx = 0x1234L; // ECX register Long r_edx = 0x7890L; // EDX register @@ -424,7 +426,7 @@ public class Sample_x86 { } // emulate code that read invalid memory - static void test_i386_invalid_mem_write() { + public static void test_i386_invalid_mem_write() { Long r_ecx = 0x1234L; // ECX register Long r_edx = 0x7890L; // EDX register @@ -489,7 +491,7 @@ public class Sample_x86 { } // emulate code that jump to invalid memory - static void test_i386_jump_invalid() { + public static void test_i386_jump_invalid() { Long r_ecx = 0x1234L; // ECX register Long r_edx = 0x7890L; // EDX register @@ -535,7 +537,7 @@ public class Sample_x86 { u.close(); } - static void test_x86_64() { + public static void test_x86_64() { long rax = 0x71f3029efd49d41dL; long rbx = 0xd87b45277f133ddbL; long rcx = 0xab40d1ffd8afc461L; @@ -634,7 +636,7 @@ public class Sample_x86 { u.close(); } - static void test_x86_16() { + public static void test_x86_16() { Long eax = 7L; Long ebx = 5L; Long esi = 6L; diff --git a/bindings/java/samples/Sample_x86_mmr.java b/bindings/java/samples/Sample_x86_mmr.java index fc2bb08b..c07b48d3 100644 --- a/bindings/java/samples/Sample_x86_mmr.java +++ b/bindings/java/samples/Sample_x86_mmr.java @@ -21,11 +21,13 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. /* Sample code to demonstrate how to register read/write API */ +package samples; + import unicorn.*; public class Sample_x86_mmr { - static void test_x86_mmr() { + public static void test_x86_mmr() { // Initialize emulator in X86-32bit mode Unicorn uc; try { diff --git a/bindings/java/samples/Shellcode.java b/bindings/java/samples/Shellcode.java index be9b701c..d0199052 100644 --- a/bindings/java/samples/Shellcode.java +++ b/bindings/java/samples/Shellcode.java @@ -24,6 +24,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. /* Sample code to trace code with Linux code with syscall */ +package samples; + import unicorn.*; public class Shellcode { @@ -125,7 +127,7 @@ public class Shellcode { } } - static void test_i386() { + public static void test_i386() { Long r_esp = ADDRESS + 0x200000L; // ESP register System.out.print("Emulate i386 code\n"); diff --git a/bindings/java/testdep/hamcrest-2.2.jar b/bindings/java/testdep/hamcrest-2.2.jar new file mode 100644 index 0000000000000000000000000000000000000000..71065788d5fea769e71107e3f9641e23a48d29c6 GIT binary patch literal 123360 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 z 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 literal 0 HcmV?d00001 diff --git a/bindings/java/testdep/junit-4.13.2.jar b/bindings/java/testdep/junit-4.13.2.jar new file mode 100644 index 0000000000000000000000000000000000000000..6da55d8b8520dcc03c250a605151cc0d23a45518 GIT binary patch literal 384581 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%0A|RLyRTZ?5*b0Kn~9_w90>zXi(v|D#%u(jz#g2 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 oKveFPto?=7N*A1c2%g| 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

`)ZZo?PM~)f*OI;Nlt*N`a@~;G*&9Se} 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

J{i)CW|Vyp#u)ncg$RUOm9KuH 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Π`%iO}aP>9yumW1a!ct~f>0 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 hook_count[0] += 1, + ADDRESS, ADDRESS, null); + + u.emu_start(ADDRESS, ADDRESS + ARM_CODE.length, 0, 0); + assertEquals("Hook should only be called once", 1, hook_count[0]); + + u.close(); + } + + /** Test that close() can be called multiple times without crashing */ + @Test + public void testCloseIdempotent() { + Unicorn u = new Unicorn(Unicorn.UC_ARCH_ARM, Unicorn.UC_MODE_ARM); + u.close(); + u.close(); + } + + /** Test that close() can be called multiple times without crashing */ + @Test + public void testUnicornsWillGC() { + final boolean[] close_called = { false }; + + new Unicorn(Unicorn.UC_ARCH_ARM, Unicorn.UC_MODE_ARM) { + @Override + public void close() throws UnicornException { + close_called[0] = true; + super.close(); + } + }; + System.gc(); + System.runFinalization(); + assertEquals("close() was called", true, close_called[0]); + } +} diff --git a/bindings/java/tests/TestSamples.java b/bindings/java/tests/TestSamples.java new file mode 100644 index 00000000..d6e97b08 --- /dev/null +++ b/bindings/java/tests/TestSamples.java @@ -0,0 +1,39 @@ +package tests; + +import static org.junit.Assert.assertEquals; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import org.junit.Before; +import org.junit.After; +import org.junit.Test; + +public class TestSamples { + private final ByteArrayOutputStream outContent = + new ByteArrayOutputStream(); + private final PrintStream originalOut = System.out; + + @Before + public void setUpStreams() { + outContent.reset(); + System.setOut(new PrintStream(outContent)); + } + + @After + public void restoreStreams() { + System.setOut(originalOut); + } + + @Test + public void testArm() { + samples.Sample_arm.test_arm(); + assertEquals("testArm", + "Emulate ARM code\n" + + ">>> Tracing basic block at 0x10000, block size = 0x8\n" + + ">>> Tracing instruction at 0x10000, instruction size = 0x4\n" + + ">>> Emulation done. Below is the CPU context\n" + + ">>> R0 = 0x37\n" + + ">>> R1 = 0x3456\n", + outContent.toString()); + } +} From 8777bb6ae6c23605bcd9de39e6c677062c11ae04 Mon Sep 17 00:00:00 2001 From: Robert Xiao Date: Fri, 5 May 2023 17:17:44 -0700 Subject: [PATCH 04/25] Make close() idempotent and fix Unicorn memory leak. --- bindings/java/unicorn/Unicorn.java | 48 +++++++++++++++++------------- bindings/java/unicorn_Unicorn.c | 4 +-- 2 files changed, 29 insertions(+), 23 deletions(-) diff --git a/bindings/java/unicorn/Unicorn.java b/bindings/java/unicorn/Unicorn.java index 870f31cf..9488da6a 100644 --- a/bindings/java/unicorn/Unicorn.java +++ b/bindings/java/unicorn/Unicorn.java @@ -21,6 +21,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. package unicorn; +import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Hashtable; @@ -28,7 +29,7 @@ public class Unicorn implements UnicornConst, ArmConst, Arm64Const, M68kConst, SparcConst, MipsConst, X86Const { - public long eng; + private long eng; private int arch; private int mode; @@ -70,15 +71,13 @@ public class Unicorn private ArrayList syscallList = new ArrayList(); private Hashtable> eventMemLists = - new Hashtable>(); + new Hashtable<>(); - private ArrayList> allLists = - new ArrayList>(); + private ArrayList> allLists = new ArrayList<>(); - private static Hashtable eventMemMap = - new Hashtable(); - private static Hashtable unicorns = - new Hashtable(); + private static Hashtable eventMemMap = new Hashtable<>(); + private static Hashtable> unicorns = + new Hashtable<>(); // required to load native method implementations static { @@ -107,7 +106,7 @@ public class Unicorn * @see hook_add, unicorn.BlockHook */ private static void invokeBlockCallbacks(long eng, long address, int size) { - Unicorn u = unicorns.get(eng); + Unicorn u = unicorns.get(eng).get(); if (u != null) { for (Tuple p : u.blockList) { BlockHook bh = (BlockHook) p.function; @@ -126,7 +125,7 @@ public class Unicorn * @see hook_add, unicorn.InterruptHook */ private static void invokeInterruptCallbacks(long eng, int intno) { - Unicorn u = unicorns.get(eng); + Unicorn u = unicorns.get(eng).get(); if (u != null) { for (Tuple p : u.intrList) { InterruptHook ih = (InterruptHook) p.function; @@ -146,7 +145,7 @@ public class Unicorn * @see hook_add, unicorn.CodeHook */ private static void invokeCodeCallbacks(long eng, long address, int size) { - Unicorn u = unicorns.get(eng); + Unicorn u = unicorns.get(eng).get(); if (u != null) { for (Tuple p : u.codeList) { CodeHook ch = (CodeHook) p.function; @@ -174,7 +173,7 @@ public class Unicorn private static boolean invokeEventMemCallbacks(long eng, int type, long address, int size, long value) { - Unicorn u = unicorns.get(eng); + Unicorn u = unicorns.get(eng).get(); boolean result = true; if (u != null) { ArrayList funcList = u.eventMemLists.get(type); @@ -199,7 +198,7 @@ public class Unicorn * @see hook_add, unicorn.ReadHook */ private static void invokeReadCallbacks(long eng, long address, int size) { - Unicorn u = unicorns.get(eng); + Unicorn u = unicorns.get(eng).get(); if (u != null) { for (Tuple p : u.readList) { ReadHook rh = (ReadHook) p.function; @@ -221,7 +220,7 @@ public class Unicorn */ private static void invokeWriteCallbacks(long eng, long address, int size, long value) { - Unicorn u = unicorns.get(eng); + Unicorn u = unicorns.get(eng).get(); if (u != null) { for (Tuple p : u.writeList) { WriteHook wh = (WriteHook) p.function; @@ -243,7 +242,7 @@ public class Unicorn * @see hook_add, unicorn.InHook */ private static int invokeInCallbacks(long eng, int port, int size) { - Unicorn u = unicorns.get(eng); + Unicorn u = unicorns.get(eng).get(); int result = 0; if (u != null) { for (Tuple p : u.inList) { @@ -267,7 +266,7 @@ public class Unicorn */ private static void invokeOutCallbacks(long eng, int port, int size, int value) { - Unicorn u = unicorns.get(eng); + Unicorn u = unicorns.get(eng).get(); int result = 0; if (u != null) { for (Tuple p : u.outList) { @@ -287,7 +286,7 @@ public class Unicorn * @see hook_add, unicorn.SyscallHook */ private static void invokeSyscallCallbacks(long eng) { - Unicorn u = unicorns.get(eng); + Unicorn u = unicorns.get(eng).get(); int result = 0; if (u != null) { for (Tuple p : u.syscallList) { @@ -353,7 +352,7 @@ public class Unicorn this.arch = arch; this.mode = mode; eng = open(arch, mode); - unicorns.put(eng, this); + unicorns.put(eng, new WeakReference<>(this)); allLists.add(blockList); allLists.add(intrList); allLists.add(codeList); @@ -369,7 +368,6 @@ public class Unicorn * */ protected void finalize() { - unicorns.remove(eng); close(); } @@ -379,7 +377,7 @@ public class Unicorn * @return hexadecimal number as (major << 8 | minor), which encodes both major * & minor versions. * - * For example Unicorn version 1.2 whould yield 0x0102 + * For example Unicorn version 1.2 would yield 0x0102 */ public native static int version(); @@ -396,7 +394,15 @@ public class Unicorn * Close the underlying uc_engine* eng associated with this Unicorn object * */ - public native void close() throws UnicornException; + private native void _close() throws UnicornException; + + public void close() throws UnicornException { + if (eng != 0) { + _close(); + unicorns.remove(eng); + eng = 0; + } + } /** * Query internal status of engine. diff --git a/bindings/java/unicorn_Unicorn.c b/bindings/java/unicorn_Unicorn.c index 3ab2e9a5..de45f8ff 100644 --- a/bindings/java/unicorn_Unicorn.c +++ b/bindings/java/unicorn_Unicorn.c @@ -388,10 +388,10 @@ JNIEXPORT jboolean JNICALL Java_unicorn_Unicorn_arch_1supported(JNIEnv *env, /* * Class: unicorn_Unicorn - * Method: close + * Method: _close * Signature: ()V */ -JNIEXPORT void JNICALL Java_unicorn_Unicorn_close(JNIEnv *env, jobject self) +JNIEXPORT void JNICALL Java_unicorn_Unicorn__1close(JNIEnv *env, jobject self) { uc_engine *eng = getEngine(env, self); uc_err err = uc_close(eng); From aa430587ccb2dec83da36fe01aa15ddf52262bf5 Mon Sep 17 00:00:00 2001 From: Robert Xiao Date: Sat, 6 May 2023 17:49:41 -0700 Subject: [PATCH 05/25] Rewrite the Java bindings. This brings the Java API up to par with Python feature-wise and substantially simplifies the hook implementation, enabling proper bounds-checked hooks. The rewrite strives for compatibility with the previous API, but there are some breaking changes. It is possible to push closer to full backwards compatibility if required, at the cost of reintroducing some of the suboptimal designs. Here are the main points of breakage: - ReadHook and WriteHook are gone, replaced simply by MemHook. Hooking valid memory accesses now requires a type parameter. This enables fetch and read-after hooks with a unified API and a single callback object. - mem_read now takes an int, not a long. We are unable to allocate more than 2GB in a single request anyway (Java limitation). - Instruction hooks now require specifying the instruction explicitly, instead of guessing based on the hook type. This is necessary to distinguish sysenter/syscall and ARM64 mrs/msr/sys/sysl, without excessively bloating the library with redundant hook types. Bounds must also be specified, to support bounds-checked instruction hooks. - Reading object-type registers (any register larger than 64 bits, or registers with special formats) requires a second argument to reg_read. This allows us to provide a fast reg_read that returns a long for the common cases, while still supporting a more general reg_read for other registers. - mem_map_ptr is rewritten to take a *direct* java.nio.Buffer, which enables many more use cases than a simple byte array, and improves performance (a byte array cannot really be used as a mapped buffer without GC-pinning it, which hurts the GC performance). - Context handling API is redesigned to be safer and more object-oriented. A lot of bugs are fixed with this implementation: - Unicorn instances can be properly garbage-collected, instead of hanging around forever in the Unicorn.unicorns table. - Hooks no longer fire outside of their bounds (#1164), and in fact, hook bounds are properly respected (previously, all hooks were just registered globally to all addresses). - Hooks are substantially faster, as they are now dispatched directly via a single method call rather than being indirected through invokeCallbacks. - Loading vector registers works now, rather than crashing the VM (#1539). Several features are now enabled in the Java implementation: - All of the current ctl_* calls are implemented. - mmio_map is implemented. - New virtual TLB mode is implemented. - reading/writing Context registers is implemented. - New hook types are added: TcgOpcodeHook, EdgeGeneratedHook, InvalidInstructionHook, TlbFillHook, and the instruction hooks Arm64SysHook, CpuidHook. - All known special registers are supported. --- bindings/java/Makefile | 4 +- .../java/samples/SampleNetworkAuditing.java | 10 +- bindings/java/samples/Sample_x86.java | 22 +- bindings/java/samples/Sample_x86_mmr.java | 4 +- bindings/java/tests/FunctionalityTests.java | 184 ++ bindings/java/tests/RegressionTests.java | 13 +- bindings/java/unicorn/Arm64SysHook.java | 40 + bindings/java/unicorn/Arm64_CP.java | 43 + bindings/java/unicorn/Arm_CP.java | 26 + bindings/java/unicorn/BlockHook.java | 8 + bindings/java/unicorn/CodeHook.java | 8 + bindings/java/unicorn/CpuidHook.java | 34 + ...{WriteHook.java => EdgeGeneratedHook.java} | 9 +- bindings/java/unicorn/EventMemHook.java | 19 +- bindings/java/unicorn/Hook.java | 5 +- bindings/java/unicorn/InHook.java | 11 +- .../{ReadHook.java => InstructionHook.java} | 5 +- bindings/java/unicorn/InterruptHook.java | 7 + .../java/unicorn/InvalidInstructionHook.java | 36 + bindings/java/unicorn/MemHook.java | 20 +- bindings/java/unicorn/MemRegion.java | 6 + bindings/java/unicorn/MmioReadHandler.java | 37 + bindings/java/unicorn/MmioWriteHandler.java | 37 + bindings/java/unicorn/OutHook.java | 10 +- bindings/java/unicorn/SyscallHook.java | 9 +- bindings/java/unicorn/TcgOpcodeHook.java | 40 + bindings/java/unicorn/TlbFillHook.java | 42 + bindings/java/unicorn/TranslationBlock.java | 35 + bindings/java/unicorn/Unicorn.java | 1517 ++++++------ bindings/java/unicorn/X86_Float80.java | 72 + bindings/java/unicorn/X86_MMR.java | 7 + bindings/java/unicorn/X86_MSR.java | 38 + bindings/java/unicorn_Unicorn.c | 2054 +++++++++++------ 33 files changed, 2991 insertions(+), 1421 deletions(-) create mode 100644 bindings/java/tests/FunctionalityTests.java create mode 100644 bindings/java/unicorn/Arm64SysHook.java create mode 100644 bindings/java/unicorn/Arm64_CP.java create mode 100644 bindings/java/unicorn/Arm_CP.java create mode 100644 bindings/java/unicorn/CpuidHook.java rename bindings/java/unicorn/{WriteHook.java => EdgeGeneratedHook.java} (75%) rename bindings/java/unicorn/{ReadHook.java => InstructionHook.java} (86%) create mode 100644 bindings/java/unicorn/InvalidInstructionHook.java create mode 100644 bindings/java/unicorn/MmioReadHandler.java create mode 100644 bindings/java/unicorn/MmioWriteHandler.java create mode 100644 bindings/java/unicorn/TcgOpcodeHook.java create mode 100644 bindings/java/unicorn/TlbFillHook.java create mode 100644 bindings/java/unicorn/TranslationBlock.java create mode 100644 bindings/java/unicorn/X86_Float80.java create mode 100644 bindings/java/unicorn/X86_MSR.java diff --git a/bindings/java/Makefile b/bindings/java/Makefile index 245bfd35..65712f44 100644 --- a/bindings/java/Makefile +++ b/bindings/java/Makefile @@ -51,7 +51,7 @@ unicorn_Unicorn.h: unicorn/Unicorn.java javac -h . $< unicorn_Unicorn.o: unicorn_Unicorn.c unicorn_Unicorn.h - $(CC) -c $(CFLAGS) $(INCS) $< -o $@ + $(CC) -O2 -Wall -Wextra -Wno-unused-parameter -c $(CFLAGS) $(INCS) $< -o $@ libunicorn_java$(LIB_EXT): unicorn_Unicorn.o @@ -66,7 +66,7 @@ jar: jarfiles jar cf $(JARFILE) unicorn/*.class test: lib samples tests - java -cp .:testdep/hamcrest-2.2.jar:testdep/junit-4.13.2.jar org.junit.runner.JUnitCore $(subst /,.,$(TESTS:.java=)) + java -Xcheck:jni -cp .:testdep/hamcrest-2.2.jar:testdep/junit-4.13.2.jar org.junit.runner.JUnitCore $(subst /,.,$(TESTS:.java=)) install: lib jar cp libunicorn_java$(LIB_EXT) /usr/lib diff --git a/bindings/java/samples/SampleNetworkAuditing.java b/bindings/java/samples/SampleNetworkAuditing.java index 0aa27bc2..d41d4061 100644 --- a/bindings/java/samples/SampleNetworkAuditing.java +++ b/bindings/java/samples/SampleNetworkAuditing.java @@ -100,7 +100,7 @@ public class SampleNetworkAuditing { long buf = ecx; long count = edx; - byte[] content = uc.mem_read(buf, count); + byte[] content = uc.mem_read(buf, (int) count); String msg = String.format("write data=%s count=%d to fd(%d)", new String(content), count, fd); @@ -166,7 +166,7 @@ public class SampleNetworkAuditing { long addrlen = toInt(uc.mem_read(args + SIZE_REG * 2, SIZE_REG)); - byte[] sock_addr = uc.mem_read(umyaddr, addrlen); + byte[] sock_addr = uc.mem_read(umyaddr, (int) addrlen); String msg = String.format("fd(%d) bind to %s", fd, parse_sock_address(sock_addr)); @@ -181,7 +181,7 @@ public class SampleNetworkAuditing { long addrlen = toInt(uc.mem_read(args + SIZE_REG * 2, SIZE_REG)); - byte[] sock_addr = uc.mem_read(uservaddr, addrlen); + byte[] sock_addr = uc.mem_read(uservaddr, (int) addrlen); String msg = String.format("fd(%d) connect to %s", fd, parse_sock_address(sock_addr)); fd_chains.add_log(fd, msg); @@ -211,7 +211,7 @@ public class SampleNetworkAuditing { long upeer_len = toInt(uc.mem_read(upeer_addrlen, 4)); byte[] sock_addr = - uc.mem_read(upeer_sockaddr, upeer_len); + uc.mem_read(upeer_sockaddr, (int) upeer_len); String msg = String.format("fd(%d) accept client with upeer=%s", @@ -227,7 +227,7 @@ public class SampleNetworkAuditing { long flags = toInt(uc.mem_read(args + SIZE_REG * 3, SIZE_REG)); - byte[] buf = uc.mem_read(buff, length); + byte[] buf = uc.mem_read(buff, (int) length); String msg = String.format("fd(%d) send data=%s", fd, new String(buf)); fd_chains.add_log(fd, msg); diff --git a/bindings/java/samples/Sample_x86.java b/bindings/java/samples/Sample_x86.java index 53ea1429..6dea2849 100644 --- a/bindings/java/samples/Sample_x86.java +++ b/bindings/java/samples/Sample_x86.java @@ -104,7 +104,8 @@ public class Sample_x86 { } private static class MyWriteInvalidHook implements EventMemHook { - public boolean hook(Unicorn u, long address, int size, long value, + public boolean hook(Unicorn u, int type, long address, int size, + long value, Object user) { System.out.printf( ">>> Missing memory is being WRITE at 0x%x, data size = %d, data value = 0x%x\n", @@ -131,16 +132,18 @@ public class Sample_x86 { } } - private static class MyRead64Hook implements ReadHook { - public void hook(Unicorn u, long address, int size, Object user) { + private static class MyRead64Hook implements MemHook { + public void hook(Unicorn u, int type, long address, int size, + long value, Object user) { System.out.printf( ">>> 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, + private static class MyWrite64Hook implements MemHook { + public void hook(Unicorn u, int type, long address, int size, + long value, Object user) { System.out.printf( ">>> Memory is being WRITE at 0x%x, data size = %d, data value = 0x%x\n", @@ -295,9 +298,9 @@ public class Sample_x86 { u.hook_add(new MyCodeHook(), 1, 0, null); // handle IN instruction - u.hook_add(new MyInHook(), null); + u.hook_add(new MyInHook(), Unicorn.UC_X86_INS_IN, 1, 0, null); // handle OUT instruction - u.hook_add(new MyOutHook(), null); + u.hook_add(new MyOutHook(), Unicorn.UC_X86_INS_OUT, 1, 0, null); // emulate machine code in infinite time u.emu_start(ADDRESS, ADDRESS + X86_CODE32_INOUT.length, 0, 0); @@ -454,6 +457,7 @@ public class Sample_x86 { // intercept invalid memory events u.hook_add(new MyWriteInvalidHook(), Unicorn.UC_HOOK_MEM_WRITE_UNMAPPED, + 1, 0, null); // emulate machine code in infinite time @@ -591,10 +595,10 @@ public class Sample_x86 { 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); + u.hook_add(new MyWrite64Hook(), Unicorn.UC_HOOK_MEM_WRITE, 1, 0, null); // tracing all memory READ access (with @begin > @end) - u.hook_add(new MyRead64Hook(), 1, 0, null); + u.hook_add(new MyRead64Hook(), Unicorn.UC_HOOK_MEM_READ, 1, 0, null); // emulate machine code in infinite time (last param = 0), or when // finishing all the code. diff --git a/bindings/java/samples/Sample_x86_mmr.java b/bindings/java/samples/Sample_x86_mmr.java index c07b48d3..41378d74 100644 --- a/bindings/java/samples/Sample_x86_mmr.java +++ b/bindings/java/samples/Sample_x86_mmr.java @@ -58,8 +58,8 @@ public class Sample_x86_mmr { // read the registers back out eax = (int) ((Long) uc.reg_read(Unicorn.UC_X86_REG_EAX)).longValue(); - ldtr2 = (X86_MMR) uc.reg_read(Unicorn.UC_X86_REG_LDTR); - gdtr2 = (X86_MMR) uc.reg_read(Unicorn.UC_X86_REG_GDTR); + ldtr2 = (X86_MMR) uc.reg_read(Unicorn.UC_X86_REG_LDTR, null); + gdtr2 = (X86_MMR) uc.reg_read(Unicorn.UC_X86_REG_GDTR, null); System.out.printf(">>> EAX = 0x%x\n", eax); diff --git a/bindings/java/tests/FunctionalityTests.java b/bindings/java/tests/FunctionalityTests.java new file mode 100644 index 00000000..ad3d6393 --- /dev/null +++ b/bindings/java/tests/FunctionalityTests.java @@ -0,0 +1,184 @@ +package tests; + +import static org.junit.Assert.assertEquals; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + +import org.junit.Test; + +import unicorn.MemRegion; +import unicorn.TlbFillHook; +import unicorn.Unicorn; +import unicorn.X86_Float80; + +public class FunctionalityTests { + @Test + public void testMemRegions() { + Unicorn uc = new Unicorn(Unicorn.UC_ARCH_ARM64, Unicorn.UC_MODE_ARM); + long ADDR1 = 0x10000; + long ADDR2 = 0xdeadbeeffeed1000L; + uc.mem_map(ADDR1, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL); + uc.mem_map(ADDR2, 4096, Unicorn.UC_PROT_READ); + MemRegion[] arr = uc.mem_regions(); + assertEquals("two memory regions", 2, arr.length); + assertEquals("begin", ADDR1, arr[0].begin); + assertEquals("end", ADDR1 + 2 * 1024 * 1024 - 1, arr[0].end); + assertEquals("perms", Unicorn.UC_PROT_ALL, arr[0].perms); + assertEquals("begin", ADDR2, arr[1].begin); + assertEquals("end", ADDR2 + 4096 - 1, arr[1].end); + assertEquals("perms", Unicorn.UC_PROT_READ, arr[1].perms); + uc.close(); + } + + @Test + public void testContext() { + Unicorn uc = new Unicorn(Unicorn.UC_ARCH_ARM64, Unicorn.UC_MODE_ARM); + uc.reg_write(Unicorn.UC_ARM64_REG_X0, 0xdeadbeef); + Unicorn.Context ctx = uc.context_save(); + uc.reg_write(Unicorn.UC_ARM64_REG_X0, 0xfeedface); + assertEquals("X0 changed", 0xfeedface, + uc.reg_read(Unicorn.UC_ARM64_REG_X0)); + uc.context_restore(ctx); + assertEquals("X0 restored", 0xdeadbeef, + uc.reg_read(Unicorn.UC_ARM64_REG_X0)); + uc.reg_write(Unicorn.UC_ARM64_REG_X0, 0xfee1dead); + uc.context_update(ctx); + assertEquals("X0 changed", 0xfee1dead, + uc.reg_read(Unicorn.UC_ARM64_REG_X0)); + uc.reg_write(Unicorn.UC_ARM64_REG_X0, 0xdeadbeef); + assertEquals("X0 changed", 0xdeadbeef, + uc.reg_read(Unicorn.UC_ARM64_REG_X0)); + uc.context_restore(ctx); + assertEquals("X0 restored", 0xfee1dead, + uc.reg_read(Unicorn.UC_ARM64_REG_X0)); + uc.close(); + } + + @Test + public void testMmio() { + // mov ecx, [0xaaaaaaa8]; inc ecx; dec edx; mov [0xaaaaaaa8], ecx; inc ecx; dec edx + final byte[] X86_CODE32_MEM_READ_WRITE = + { -117, 13, -88, -86, -86, -86, 65, 74, -119, 13, -88, -86, -86, + -86, 65, 74 }; + + long ADDRESS = 0x100000; + + 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, Unicorn.UC_PROT_ALL); + + // write machine code to be emulated to memory + u.mem_write(ADDRESS, X86_CODE32_MEM_READ_WRITE); + + // initialize machine registers + u.reg_write(Unicorn.UC_X86_REG_ECX, 0x12345678); + u.reg_write(Unicorn.UC_X86_REG_EDX, 0x22334455); + + u.mmio_map(0xaaaaa000L, 0x1000, (uc, offset, size, user_data) -> { + assertEquals("read offset", 0xaa8, offset); + assertEquals("read size", 4, size); + assertEquals("read user_data", "read_data", user_data); + return 0x44556677; + }, "read_data", (uc, offset, size, value, user_data) -> { + assertEquals("write offset", 0xaa8, offset); + assertEquals("write size", 4, size); + assertEquals("write value", 0x44556678, value); + assertEquals("write user_data", "write_data", user_data); + }, "write_data"); + + u.emu_start(ADDRESS, ADDRESS + X86_CODE32_MEM_READ_WRITE.length, 0, 0); + + assertEquals("ecx", 0x44556679, u.reg_read(Unicorn.UC_X86_REG_ECX)); + assertEquals("edx", 0x22334453, u.reg_read(Unicorn.UC_X86_REG_EDX)); + + u.close(); + } + + @Test + public void testMemMapPtr() { + ByteBuffer buffer = + ByteBuffer.allocateDirect(0x1000).order(ByteOrder.LITTLE_ENDIAN); + final byte[] X86_CODE32_MEM_WRITE = + { -119, 13, -86, -86, -86, -86, 65, 74 }; + + long ADDRESS = 0x100000; + + Unicorn u = new Unicorn(Unicorn.UC_ARCH_X86, Unicorn.UC_MODE_32); + u.mem_map(ADDRESS, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL); + u.mem_map_ptr(0xaaaaa000L, buffer, Unicorn.UC_PROT_ALL); + u.mem_write(ADDRESS, X86_CODE32_MEM_WRITE); + u.reg_write(Unicorn.UC_X86_REG_ECX, 0x12345678); + u.emu_start(ADDRESS, ADDRESS + X86_CODE32_MEM_WRITE.length, 0, 0); + + assertEquals("buffer contents", 0x12345678, buffer.getInt(0xaaa)); + + u.close(); + } + + @Test + public void testTlbHook() { + // mov ecx, [0xaaaaaaa8] + final byte[] X86_CODE32_MEM_READ = { -117, 13, -88, -86, -86, -86 }; + + long ADDRESS = 0x100000; + + Unicorn u = new Unicorn(Unicorn.UC_ARCH_X86, Unicorn.UC_MODE_32); + u.mem_map(ADDRESS, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL); + u.mem_map(0xbbbbb000L, 0x1000, Unicorn.UC_PROT_READ); + u.hook_add((TlbFillHook) (uc, address, type, user_data) -> { + assertEquals("fill hook address", 0xaaaaa000L, address); + assertEquals("fill hook type", Unicorn.UC_MEM_READ, type); + assertEquals("fill hook user", "fill_hook", user_data); + return 0xbbbbb000L | Unicorn.UC_PROT_READ; + }, 0xaaaaa000L, 0xaaaab000L, "fill_hook"); + u.mem_write(ADDRESS, X86_CODE32_MEM_READ); + u.mem_write(0xbbbbbaa8L, new byte[] { 1, 2, 3, 4 }); + u.reg_write(Unicorn.UC_X86_REG_ECX, 0x12345678); + u.ctl_tlb_mode(Unicorn.UC_TLB_VIRTUAL); + u.emu_start(ADDRESS, ADDRESS + X86_CODE32_MEM_READ.length, 0, 0); + assertEquals("ecx", u.reg_read(Unicorn.UC_X86_REG_ECX), 0x04030201); + + u.close(); + } + + @Test + public void testX86ReadFloat80() { + // fldl2e; fsin + final byte[] X86_CODE = { -39, -22, -39, -2 }; + + long ADDRESS = 0x100000; + + Unicorn u = new Unicorn(Unicorn.UC_ARCH_X86, Unicorn.UC_MODE_32); + u.mem_map(ADDRESS, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL); + u.mem_write(ADDRESS, X86_CODE); + u.emu_start(ADDRESS, ADDRESS + X86_CODE.length, 0, 0); + X86_Float80 reg1 = + (X86_Float80) u.reg_read(Unicorn.UC_X86_REG_ST0, null); + X86_Float80 reg2 = + (X86_Float80) u.reg_read(Unicorn.UC_X86_REG_FP7, null); + assertEquals(null, ADDRESS, ADDRESS, ADDRESS); + assertEquals(Math.sin(Math.log(Math.E) / Math.log(2)), reg1.toDouble(), + 1e-12); + assertEquals(reg1.toDouble(), reg2.toDouble(), 1e-12); + u.close(); + } + + @Test + public void testX86WriteFloat80() { + // fsin + final byte[] X86_CODE = { -39, -2 }; + + long ADDRESS = 0x100000; + + Unicorn u = new Unicorn(Unicorn.UC_ARCH_X86, Unicorn.UC_MODE_32); + u.mem_map(ADDRESS, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL); + u.mem_write(ADDRESS, X86_CODE); + X86_Float80 reg = X86_Float80.fromDouble(-1.1); + u.reg_write(Unicorn.UC_X86_REG_ST0, reg); + u.emu_start(ADDRESS, ADDRESS + X86_CODE.length, 0, 0); + reg = (X86_Float80) u.reg_read(Unicorn.UC_X86_REG_ST0, null); + assertEquals(Math.sin(-1.1), reg.toDouble(), 1e-12); + u.close(); + } +} diff --git a/bindings/java/tests/RegressionTests.java b/bindings/java/tests/RegressionTests.java index 3191b7bf..af5cdb05 100644 --- a/bindings/java/tests/RegressionTests.java +++ b/bindings/java/tests/RegressionTests.java @@ -2,6 +2,8 @@ package tests; import static org.junit.Assert.assertEquals; +import java.math.BigInteger; + import org.junit.Test; import unicorn.Unicorn; @@ -14,9 +16,14 @@ public class RegressionTests { public void testARM64VReg() { Unicorn uc = new Unicorn(Unicorn.UC_ARCH_ARM64, Unicorn.UC_MODE_ARM); uc.reg_write(Unicorn.UC_ARM64_REG_X0, 0x1); - uc.reg_write(Unicorn.UC_ARM64_REG_V0, 0x2); + uc.reg_write(Unicorn.UC_ARM64_REG_V0, BigInteger.valueOf(0x1234)); uc.reg_read(Unicorn.UC_ARM64_REG_X0); - uc.reg_read(Unicorn.UC_ARM64_REG_V0); // should not crash + assertEquals("V0 value", BigInteger.valueOf(0x1234), + uc.reg_read(Unicorn.UC_ARM64_REG_V0, null)); // should not crash + assertEquals("V0 low byte", 0x34, + uc.reg_read(Unicorn.UC_ARM64_REG_B0)); + assertEquals("V0 low halfword", 0x1234, + uc.reg_read(Unicorn.UC_ARM64_REG_H0)); uc.close(); } @@ -48,7 +55,7 @@ public class RegressionTests { u.close(); } - /** Test that close() can be called multiple times without crashing */ + /** Test that Unicorn instances are properly garbage-collected */ @Test public void testUnicornsWillGC() { final boolean[] close_called = { false }; diff --git a/bindings/java/unicorn/Arm64SysHook.java b/bindings/java/unicorn/Arm64SysHook.java new file mode 100644 index 00000000..067fd6e3 --- /dev/null +++ b/bindings/java/unicorn/Arm64SysHook.java @@ -0,0 +1,40 @@ +/* + +Java bindings for the Unicorn Emulator Engine + +Copyright(c) 2023 Robert Xiao + +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; + +/** Callback for {@code UC_HOOK_INSN} with {@code UC_ARM64_INS_MRS}, + * {@code UC_ARM64_INS_MSR}, {@code UC_ARM64_INS_SYS} + * or {@code UC_ARM64_INS_SYSL} */ +public interface Arm64SysHook extends InstructionHook { + /** Called to handle an AArch64 MRS, MSR, SYS or SYSL instruction. + * + * @param u {@link Unicorn} instance firing this hook + * @param reg source or destination register + * ({@code UC_ARM64_REG_X*} constant) + * @param cp_reg coprocessor register specification + * ({@code .val} = current value of {@code reg}) + * @param user user data provided when registering this hook + * @return 1 to skip the instruction (marking it as handled), + * 0 to let QEMU handle it + */ + public int hook(Unicorn u, int reg, Arm64_CP cp_reg, Object user); +} diff --git a/bindings/java/unicorn/Arm64_CP.java b/bindings/java/unicorn/Arm64_CP.java new file mode 100644 index 00000000..6c0e9528 --- /dev/null +++ b/bindings/java/unicorn/Arm64_CP.java @@ -0,0 +1,43 @@ +/* + +Java bindings for the Unicorn Emulator Engine + +Copyright(c) 2023 Robert Xiao + +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; + +/** ARM64 coprocessor registers for instructions MRS, MSR, SYS, SYSL */ +public class Arm64_CP { + public int crn, crm, op0, op1, op2; + public long val; + + public Arm64_CP(int crn, int crm, int op0, int op1, int op2, long val) { + this.crn = crn; + this.crm = crm; + this.op0 = op0; + this.op1 = op1; + this.op2 = op2; + this.val = val; + } + + @Override + public String toString() { + return "Arm64_CP [crn=" + crn + ", crm=" + crm + ", op0=" + op0 + + ", op1=" + op1 + ", op2=" + op2 + ", val=" + val + "]"; + } +} diff --git a/bindings/java/unicorn/Arm_CP.java b/bindings/java/unicorn/Arm_CP.java new file mode 100644 index 00000000..278cc272 --- /dev/null +++ b/bindings/java/unicorn/Arm_CP.java @@ -0,0 +1,26 @@ +package unicorn; + +/** ARM coprocessor register for MRC, MCR, MRRC, MCRR */ +public class Arm_CP { + public int cp, is64, sec, crn, crm, opc1, opc2; + public long val; + + public Arm_CP(int cp, int is64, int sec, int crn, int crm, int opc1, + int opc2, long val) { + this.cp = cp; + this.is64 = is64; + this.sec = sec; + this.crn = crn; + this.crm = crm; + this.opc1 = opc1; + this.opc2 = opc2; + this.val = val; + } + + @Override + public String toString() { + return "Arm_CP [cp=" + cp + ", is64=" + is64 + ", sec=" + sec + + ", crn=" + crn + ", crm=" + crm + ", opc1=" + opc1 + ", opc2=" + + opc2 + ", val=" + val + "]"; + } +} diff --git a/bindings/java/unicorn/BlockHook.java b/bindings/java/unicorn/BlockHook.java index 1ade7a2b..c60b3334 100644 --- a/bindings/java/unicorn/BlockHook.java +++ b/bindings/java/unicorn/BlockHook.java @@ -21,6 +21,14 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. package unicorn; +/** Callback for {@code UC_HOOK_BLOCK} */ public interface BlockHook extends Hook { + /** Called on each basic block within the hooked range. + * + * @param u {@link Unicorn} instance firing this hook + * @param address address of the first instruction in the block + * @param size size of the block, in bytes + * @param user user data provided when registering this hook + */ public void hook(Unicorn u, long address, int size, Object user); } diff --git a/bindings/java/unicorn/CodeHook.java b/bindings/java/unicorn/CodeHook.java index e78a9803..c7bc83bc 100644 --- a/bindings/java/unicorn/CodeHook.java +++ b/bindings/java/unicorn/CodeHook.java @@ -21,6 +21,14 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. package unicorn; +/** Callback for {@code UC_HOOK_CODE} */ public interface CodeHook extends Hook { + /** Called on each instruction within the hooked range. + * + * @param u {@link Unicorn} instance firing this hook + * @param address address of the instruction + * @param size size of the instruction, in bytes + * @param user user data provided when registering this hook + */ public void hook(Unicorn u, long address, int size, Object user); } diff --git a/bindings/java/unicorn/CpuidHook.java b/bindings/java/unicorn/CpuidHook.java new file mode 100644 index 00000000..6ddcab40 --- /dev/null +++ b/bindings/java/unicorn/CpuidHook.java @@ -0,0 +1,34 @@ +/* + +Java bindings for the Unicorn Emulator Engine + +Copyright(c) 2023 Robert Xiao + +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; + +/** Callback for {@code UC_HOOK_INSN} with {@code UC_X86_INS_CPUID} */ +public interface CpuidHook extends InstructionHook { + /** Called to handle an x86 CPUID instruction. + * + * @param u {@link Unicorn} instance firing this hook + * @param user user data provided when registering this hook + * @return 1 to skip the instruction (marking it as handled), + * 0 to let QEMU handle it + */ + public int hook(Unicorn u, Object user); +} diff --git a/bindings/java/unicorn/WriteHook.java b/bindings/java/unicorn/EdgeGeneratedHook.java similarity index 75% rename from bindings/java/unicorn/WriteHook.java rename to bindings/java/unicorn/EdgeGeneratedHook.java index 25c0208a..1564d752 100644 --- a/bindings/java/unicorn/WriteHook.java +++ b/bindings/java/unicorn/EdgeGeneratedHook.java @@ -2,7 +2,7 @@ Java bindings for the Unicorn Emulator Engine -Copyright(c) 2015 Chris Eagle +Copyright(c) 2023 Robert Xiao This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -21,7 +21,8 @@ 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); +/** Callback for UC_HOOK_EDGE_GENERATED */ +public interface EdgeGeneratedHook extends Hook { + public void hook(Unicorn u, TranslationBlock cur_tb, + TranslationBlock prev_tb, Object user); } diff --git a/bindings/java/unicorn/EventMemHook.java b/bindings/java/unicorn/EventMemHook.java index 8262b179..bd110063 100644 --- a/bindings/java/unicorn/EventMemHook.java +++ b/bindings/java/unicorn/EventMemHook.java @@ -21,7 +21,24 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. package unicorn; +/** Callback for {@code UC_HOOK_MEM_INVALID} + * (UC_HOOK_MEM_{READ,WRITE,FETCH}_{UNMAPPED,PROT}) */ public interface EventMemHook extends Hook { - public boolean hook(Unicorn u, long address, int size, long value, + /** Called when an invalid memory access occurs within the registered + * range. + * + * @param u {@link Unicorn} instance firing this hook + * @param type type of the memory access and violation: one of + * UC_MEM_{READ,WRITE,FETCH}_{UNMAPPED,PROT} + * @param address address of the memory access + * @param size size of the memory access + * @param value value written ({@code UC_MEM_WRITE_*} only) + * @param user user data provided when registering this hook + * @return {@code true} to mark the exception as handled, which + * will retry the memory access. If no hooks return + * {@code true}, the memory access will fail and a CPU + * exception will be raised. + */ + public boolean hook(Unicorn u, int type, long address, int size, long value, Object user); } diff --git a/bindings/java/unicorn/Hook.java b/bindings/java/unicorn/Hook.java index 97e0fc26..57168a56 100644 --- a/bindings/java/unicorn/Hook.java +++ b/bindings/java/unicorn/Hook.java @@ -21,10 +21,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. package unicorn; -/** - * Base class for all unicorn hooking interfaces - */ - +/** Base interface for all Unicorn hooks */ public interface Hook { } diff --git a/bindings/java/unicorn/InHook.java b/bindings/java/unicorn/InHook.java index 9f0c978b..cea07886 100644 --- a/bindings/java/unicorn/InHook.java +++ b/bindings/java/unicorn/InHook.java @@ -21,6 +21,15 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. package unicorn; -public interface InHook extends Hook { +/** Callback for {@code UC_HOOK_INSN} with {@code UC_X86_INS_IN} */ +public interface InHook extends InstructionHook { + /** Called to handle an x86 IN instruction. + * + * @param u {@link Unicorn} instance firing this hook + * @param port I/O port number + * @param size size of the request (1, 2, or 4 bytes) + * @param user user data provided when registering this hook + * @return value of the I/O request + */ public int hook(Unicorn u, int port, int size, Object user); } diff --git a/bindings/java/unicorn/ReadHook.java b/bindings/java/unicorn/InstructionHook.java similarity index 86% rename from bindings/java/unicorn/ReadHook.java rename to bindings/java/unicorn/InstructionHook.java index 28b6ca34..5d540070 100644 --- a/bindings/java/unicorn/ReadHook.java +++ b/bindings/java/unicorn/InstructionHook.java @@ -21,6 +21,7 @@ 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); +/** Base interface for {@code UC_HOOK_INSN} hooks */ +public interface InstructionHook extends Hook { + } diff --git a/bindings/java/unicorn/InterruptHook.java b/bindings/java/unicorn/InterruptHook.java index 3702e887..ae670160 100644 --- a/bindings/java/unicorn/InterruptHook.java +++ b/bindings/java/unicorn/InterruptHook.java @@ -21,6 +21,13 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. package unicorn; +/** Callback for {@code UC_HOOK_INTR} */ public interface InterruptHook extends Hook { + /** Called when a CPU interrupt occurs. + * + * @param u {@link Unicorn} instance firing this hook + * @param intno CPU-specific interrupt number + * @param user user data provided when registering this hook + */ public void hook(Unicorn u, int intno, Object user); } diff --git a/bindings/java/unicorn/InvalidInstructionHook.java b/bindings/java/unicorn/InvalidInstructionHook.java new file mode 100644 index 00000000..1edb509a --- /dev/null +++ b/bindings/java/unicorn/InvalidInstructionHook.java @@ -0,0 +1,36 @@ +/* + +Java bindings for the Unicorn Emulator Engine + +Copyright(c) 2023 Robert Xiao + +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; + +/* Callback for {@code UC_HOOK_INSN_INVALID} */ +public interface InvalidInstructionHook extends Hook { + /** Called when an invalid instruction is encountered. + * + * @param u {@link Unicorn} instance firing this hook + * @param user user data provided when registering this hook + * @return {@code true} to mark the exception as handled. Emulation + * will stop without raising an invalid instruction exception. + * If no hooks return {@code true}, emulation will stop with + * an invalid instruction exception. + */ + public boolean hook(Unicorn u, Object user); +} diff --git a/bindings/java/unicorn/MemHook.java b/bindings/java/unicorn/MemHook.java index 3151c84d..4de5ea77 100644 --- a/bindings/java/unicorn/MemHook.java +++ b/bindings/java/unicorn/MemHook.java @@ -21,6 +21,22 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. package unicorn; -public interface MemHook extends ReadHook, WriteHook { - +/** Callback for {@code UC_HOOK_MEM_VALID} + * (UC_HOOK_MEM_{READ,WRITE,FETCH} and/or + * {@code UC_HOOK_MEM_READ_AFTER}) */ +public interface MemHook extends Hook { + /** Called when a valid memory access occurs within the registered range. + * + * @param u {@link Unicorn} instance firing this hook + * @param type type of the memory access: one of {@code UC_MEM_READ}, + * {@code UC_MEM_WRITE} or {@code UC_MEM_READ_AFTER}. + * @param address address of the memory access + * @param size size of the memory access + * @param value value read ({@code UC_MEM_READ_AFTER} only) or written + * ({@code UC_MEM_WRITE} only). Not meaningful for + * {@code UC_MEM_READ} events. + * @param user user data provided when registering this hook + */ + public void hook(Unicorn u, int type, long address, int size, long value, + Object user); } diff --git a/bindings/java/unicorn/MemRegion.java b/bindings/java/unicorn/MemRegion.java index 1e4733dd..20fa9200 100644 --- a/bindings/java/unicorn/MemRegion.java +++ b/bindings/java/unicorn/MemRegion.java @@ -31,4 +31,10 @@ public class MemRegion { this.end = end; this.perms = perms; } + + @Override + public String toString() { + return "MemRegion [begin=" + begin + ", end=" + end + ", perms=" + + perms + "]"; + } } diff --git a/bindings/java/unicorn/MmioReadHandler.java b/bindings/java/unicorn/MmioReadHandler.java new file mode 100644 index 00000000..adfd42ea --- /dev/null +++ b/bindings/java/unicorn/MmioReadHandler.java @@ -0,0 +1,37 @@ +/* + +Java bindings for the Unicorn Emulator Engine + +Copyright(c) 2023 Robert Xiao + +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; + +/** Interface for handling reads from memory-mapped I/O, mapped via + * {@link Unicorn#mmio_map} */ +public interface MmioReadHandler { + /** Called when a memory read is made to an address in the mapped range. + * + * @param u {@link Unicorn} instance firing this hook + * @param offset offset of the request address from the start of the + * mapped range + * @param size size of the memory access, in bytes + * @param user user data provided when registering this hook + * @return value of this I/O request + */ + long read(Unicorn u, long offset, int size, Object user); +} diff --git a/bindings/java/unicorn/MmioWriteHandler.java b/bindings/java/unicorn/MmioWriteHandler.java new file mode 100644 index 00000000..20eb643c --- /dev/null +++ b/bindings/java/unicorn/MmioWriteHandler.java @@ -0,0 +1,37 @@ +/* + +Java bindings for the Unicorn Emulator Engine + +Copyright(c) 2023 Robert Xiao + +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; + +/** Interface for handling writes to memory-mapped I/O, mapped via + * {@link Unicorn#mmio_map} */ +public interface MmioWriteHandler { + /** Called when a memory write is made to an address in the mapped range. + * + * @param u {@link Unicorn} instance firing this hook + * @param offset offset of the request address from the start of the + * mapped range + * @param size size of the memory access, in bytes + * @param value value being written + * @param user user data provided when registering this hook + */ + void write(Unicorn u, long offset, int size, long value, Object user_data); +} diff --git a/bindings/java/unicorn/OutHook.java b/bindings/java/unicorn/OutHook.java index 674e88e3..4f9b33be 100644 --- a/bindings/java/unicorn/OutHook.java +++ b/bindings/java/unicorn/OutHook.java @@ -21,6 +21,14 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. package unicorn; -public interface OutHook extends Hook { +/** Callback for {@code UC_HOOK_INSN} with {@code UC_X86_INS_OUT} */ +public interface OutHook extends InstructionHook { + /** Called to handle an x86 OUT instruction. + * + * @param u {@link Unicorn} instance firing this hook + * @param port I/O port number + * @param size size of the request (1, 2, or 4 bytes) + * @param user user data provided when registering this hook + */ public void hook(Unicorn u, int port, int size, int value, Object user); } diff --git a/bindings/java/unicorn/SyscallHook.java b/bindings/java/unicorn/SyscallHook.java index bf6476db..a05bb5fc 100644 --- a/bindings/java/unicorn/SyscallHook.java +++ b/bindings/java/unicorn/SyscallHook.java @@ -21,6 +21,13 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. package unicorn; -public interface SyscallHook extends Hook { +/** Callback for {@code UC_HOOK_INSN} with {@code UC_X86_INS_SYSCALL} or + * {@code UC_X86_INS_SYSENTER} */ +public interface SyscallHook extends InstructionHook { + /** Called to handle an x86 SYSCALL or SYSENTER instruction. + * + * @param u {@link Unicorn} instance firing this hook + * @param user user data provided when registering this hook + */ public void hook(Unicorn u, Object user); } diff --git a/bindings/java/unicorn/TcgOpcodeHook.java b/bindings/java/unicorn/TcgOpcodeHook.java new file mode 100644 index 00000000..a9e7c423 --- /dev/null +++ b/bindings/java/unicorn/TcgOpcodeHook.java @@ -0,0 +1,40 @@ +/* + +Java bindings for the Unicorn Emulator Engine + +Copyright(c) 2023 Robert Xiao + +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; + +/** Callback for {@code UC_HOOK_TCG_OPCODE} */ +public interface TcgOpcodeHook extends Hook { + /** Called on every instruction of the registered type(s) within the + * registered range. For example, a {@code UC_TCG_OP_SUB} hook fires on + * every instruction that contains a subtraction operation, unless + * otherwise filtered. + * + * @param u {@link Unicorn} instance firing this hook + * @param address address of the instruction + * @param arg1 first argument to the instruction + * @param arg2 second argument to the instruction + * @param size size of the operands (currently, 32 or 64) + * @param user user data provided when registering this hook + */ + public void hook(Unicorn u, long address, long arg1, long arg2, int size, + Object user); +} diff --git a/bindings/java/unicorn/TlbFillHook.java b/bindings/java/unicorn/TlbFillHook.java new file mode 100644 index 00000000..270fc44f --- /dev/null +++ b/bindings/java/unicorn/TlbFillHook.java @@ -0,0 +1,42 @@ +/* + +Java bindings for the Unicorn Emulator Engine + +Copyright(c) 2023 Robert Xiao + +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; + +/** Callback for {@code UC_HOOK_TLB_FILL} */ +public interface TlbFillHook extends Hook { + /** Called to map a virtual address within the registered range to a + * physical address. The resulting mapping is cached in the QEMU TLB. + * These hooks are only called if the TLB mode (set via + * {@link Unicorn#ctl_tlb_mode}) is set to {@code UC_TLB_VIRTUAL}. + * + * @param u {@link Unicorn} instance firing this hook + * @param vaddr virtual address being mapped + * @param type type of memory access ({@code UC_MEM_READ}, + * {@code UC_MEM_WRITE} or {@code UC_MEM_FETCH}). + * @param user user data provided when registering this hook + * @return the page-aligned physical address ORed with the page + * protection bits ({@code UC_PROT_*}). Return -1L to + * indicate an unmapped address; if all hooks return -1L, + * the memory access will fail and raise a CPU exception. + */ + public long hook(Unicorn u, long vaddr, int type, Object user); +} diff --git a/bindings/java/unicorn/TranslationBlock.java b/bindings/java/unicorn/TranslationBlock.java new file mode 100644 index 00000000..755534c1 --- /dev/null +++ b/bindings/java/unicorn/TranslationBlock.java @@ -0,0 +1,35 @@ +/* + +Java bindings for the Unicorn Emulator Engine + +Copyright(c) 2023 Robert Xiao + +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; + +/** uc_tb */ +public class TranslationBlock { + public long pc; + public int icount; + public int size; + + public TranslationBlock(long pc, int icount, int size) { + this.pc = pc; + this.icount = icount; + this.size = size; + } +} diff --git a/bindings/java/unicorn/Unicorn.java b/bindings/java/unicorn/Unicorn.java index 9488da6a..d28f3999 100644 --- a/bindings/java/unicorn/Unicorn.java +++ b/bindings/java/unicorn/Unicorn.java @@ -2,7 +2,7 @@ Java bindings for the Unicorn Emulator Engine -Copyright(c) 2015 Chris Eagle +Copyright(c) 2015 Chris Eagle, 2023 Robert Xiao This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -21,324 +21,90 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. package unicorn; -import java.lang.ref.WeakReference; -import java.util.ArrayList; +import java.math.BigInteger; +import java.nio.Buffer; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.util.Arrays; import java.util.Hashtable; public class Unicorn - implements UnicornConst, ArmConst, Arm64Const, M68kConst, SparcConst, - MipsConst, X86Const { + implements UnicornConst, Arm64Const, ArmConst, M68kConst, MipsConst, + PpcConst, RiscvConst, S390xConst, SparcConst, TriCoreConst, X86Const { - private long eng; + private long nativePtr; private int arch; private int mode; + private Hashtable hooks = new Hashtable<>(); - private long blockHandle = 0; - private long interruptHandle = 0; - private long codeHandle = 0; + /** Wrapper around a registered hook */ + private static class HookWrapper { + private long nativePtr; - private Hashtable eventMemHandles = - new Hashtable(); - private long readInvalidHandle = 0; - private long writeInvalidHandle = 0; - private long fetchProtHandle = 0; - private long readProtHandle = 0; - private long writeProtHandle = 0; - - private long readHandle = 0; - private long writeHandle = 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; + @Override + protected void finalize() { + _hookwrapper_free(nativePtr); } } - private ArrayList blockList = new ArrayList(); - private ArrayList intrList = new ArrayList(); - private ArrayList codeList = new ArrayList(); - private ArrayList readList = new ArrayList(); - private ArrayList writeList = new ArrayList(); - private ArrayList inList = new ArrayList(); - private ArrayList outList = new ArrayList(); - private ArrayList syscallList = new ArrayList(); + public static class Context { + long nativePtr; + public int arch; + public int mode; - private Hashtable> eventMemLists = - new Hashtable<>(); + @Override + protected void finalize() { + _context_free(nativePtr); + } - private ArrayList> allLists = new ArrayList<>(); + /** + * Read register value. See {@link Unicorn#reg_read(int)}. + * + * @param regid Register ID that is to be retrieved. This function only supports + * integer registers at most 64 bits long. + * @return value of the register. + */ + public long reg_read(int regid) throws UnicornException { + return do_reg_read_long(nativePtr, 1, arch, regid); + } - private static Hashtable eventMemMap = new Hashtable<>(); - private static Hashtable> unicorns = - new Hashtable<>(); + /** + * Read register value. See {@link Unicorn#reg_read(int, Object)}. + * + * @param regid Register ID that is to be retrieved. + * @param opt Options for this register, or null if no options are required. + * @return value of the register - Long, BigInteger, or structure. + */ + public Object reg_read(int regid, Object opt) throws UnicornException { + return do_reg_read_obj(nativePtr, 1, arch, regid, opt); + } + + /** + * Write to register. See {@link Unicorn#reg_write(int, long)}. + * + * @param regid Register ID that is to be modified. + * @param value Object containing the new register value. + */ + public void reg_write(int regid, long value) throws UnicornException { + do_reg_write_long(nativePtr, 1, arch, regid, value); + } + + /** + * Write to register. See {@link Unicorn#reg_write(int, Object)}. + * + * @param regid Register ID that is to be modified. + * @param value Object containing the new register value. + */ + public void reg_write(int regid, Object value) throws UnicornException { + do_reg_write_obj(nativePtr, 1, arch, regid, value); + } + } - // required to load native method implementations static { // load libunicorn_java.{so,dylib} or unicorn_java.dll System.loadLibrary("unicorn_java"); - 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_FETCH_UNMAPPED, UC_MEM_FETCH_UNMAPPED); - 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_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. - * This function gets invoked from the native C callback registered for - * for UC_HOOK_BLOCK - * - * @param eng A Unicorn uc_engine* eng 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 eng, long address, int size) { - Unicorn u = unicorns.get(eng).get(); - 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 eng A Unicorn uc_engine* eng returned by uc_open - * @param intno The interrupt number - * @see hook_add, unicorn.InterruptHook - */ - private static void invokeInterruptCallbacks(long eng, int intno) { - Unicorn u = unicorns.get(eng).get(); - 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 eng A Unicorn uc_engine* eng 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 eng, long address, int size) { - Unicorn u = unicorns.get(eng).get(); - 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_XXX_UNMAPPED and/or UC_HOOK_MEM_XXX_PROT callbacks - * registered - * for a specific Unicorn. - * This function gets invoked from the native C callback registered for - * for UC_HOOK_MEM_XXX_UNMAPPED or UC_HOOK_MEM_XXX_PROT - * - * @param eng A Unicorn uc_engine* eng returned by uc_open - * @param type The type of event that is taking place - * @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.EventMemHook - */ - private static boolean invokeEventMemCallbacks(long eng, int type, - long address, int size, - long value) { - Unicorn u = unicorns.get(eng).get(); - boolean result = true; - if (u != null) { - ArrayList funcList = u.eventMemLists.get(type); - if (funcList != null) { - for (Tuple p : funcList) { - EventMemHook emh = (EventMemHook) p.function; - result &= emh.hook(u, 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 eng A Unicorn uc_engine* eng 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 eng, long address, int size) { - Unicorn u = unicorns.get(eng).get(); - 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 eng A Unicorn uc_engine* eng 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 eng, long address, int size, - long value) { - Unicorn u = unicorns.get(eng).get(); - 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_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 eng A Unicorn uc_engine* eng 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 eng, int port, int size) { - Unicorn u = unicorns.get(eng).get(); - 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 eng A Unicorn uc_engine* eng 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 eng, int port, int size, - int value) { - Unicorn u = unicorns.get(eng).get(); - 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 eng A Unicorn uc_engine* eng returned by uc_open - * @see hook_add, unicorn.SyscallHook - */ - private static void invokeSyscallCallbacks(long eng) { - Unicorn u = unicorns.get(eng).get(); - int result = 0; - if (u != null) { - for (Tuple p : u.syscallList) { - SyscallHook sh = (SyscallHook) p.function; - sh.hook(u, p.data); - } - } - } - - /** - * Write to register. - * - * @param regid Register ID that is to be modified. - * @param value Number containing the new register value - */ - private native void reg_write_num(int regid, Number value) - throws UnicornException; - - /** - * Write to register. - * - * @param regid Register ID that is to be modified. - * @param value X86 specific memory management register containing the new - * register value - */ - private native void reg_write_mmr(int regid, X86_MMR value) - throws UnicornException; - - /** - * Read register value. - * - * @param regid Register ID that is to be retrieved. - * @return Number containing the requested register value. - */ - private native Number reg_read_num(int regid) throws UnicornException; - - /** - * Read register value. - * - * @param regid Register ID that is to be retrieved. - * @return X86_MMR containing the requested register value. - */ - private native Number reg_read_mmr(int regid) throws UnicornException; - - /** - * 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; - /** * Create a new Unicorn object * @@ -351,22 +117,26 @@ public class Unicorn // remember these in case we need arch specific code this.arch = arch; this.mode = mode; - eng = open(arch, mode); - unicorns.put(eng, new WeakReference<>(this)); - allLists.add(blockList); - allLists.add(intrList); - allLists.add(codeList); - allLists.add(readList); - allLists.add(writeList); - allLists.add(inList); - allLists.add(outList); - allLists.add(syscallList); + nativePtr = _open(arch, mode); + } + + /** + * Close the underlying uc_engine* eng associated with this Unicorn object + * + */ + + public void close() throws UnicornException { + if (nativePtr != 0) { + _close(nativePtr); + nativePtr = 0; + } } /** * Perform native cleanup tasks associated with a Unicorn object * */ + @Override protected void finalize() { close(); } @@ -379,7 +149,9 @@ public class Unicorn * * For example Unicorn version 1.2 would yield 0x0102 */ - public native static int version(); + public static int version() { + return _version(); + } /** * Determine if the given architecture is supported by this library. @@ -388,158 +160,10 @@ public class Unicorn * @return true if this library supports the given arch. * @see unicorn.UnicornConst */ - public native static boolean arch_supported(int arch); - - /** - * Close the underlying uc_engine* eng associated with this Unicorn object - * - */ - private native void _close() throws UnicornException; - - public void close() throws UnicornException { - if (eng != 0) { - _close(); - unicorns.remove(eng); - eng = 0; - } + public static boolean arch_supported(int arch) { + return _arch_supported(arch); } - /** - * Query internal status of engine. - * - * @param type query type. See UC_QUERY_* - * @param result save the internal status queried - * - * @return: error code. see UC_ERR_* - * @see unicorn.UnicornConst - */ - public native int query(int type) 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.UnicornConst - */ - 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.UnicornConst - */ - public native static String strerror(int code); - - /** - * Write to register. - * - * @deprecated use reg_write(int regid, Object value) instead - * @param regid Register ID that is to be modified. - * @param value Array containing value that will be written into register @regid - */ - @Deprecated - public native void reg_write(int regid, byte[] value) - throws UnicornException; - - /** - * Write to register. - * - * @param regid Register ID that is to be modified. - * @param value Object containing the new register value. Long, BigInteger, or - * other custom class used to represent register values - */ - public void reg_write(int regid, Object value) throws UnicornException { - if (value instanceof Number) { - reg_write_num(regid, (Number) value); - } else if (arch == UC_ARCH_X86 && value instanceof X86_MMR) { - if (regid >= UC_X86_REG_IDTR && regid <= UC_X86_REG_TR) { - reg_write_mmr(regid, (X86_MMR) value); - } - } else { - throw new ClassCastException("Invalid value type"); - } - } - - /** - * Read register value. - * - * @deprecated use Object reg_read(int regid) instead - * @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. - */ - @Deprecated - public native byte[] reg_read(int regid, int regsz) throws UnicornException; - - /** - * Read register value. - * - * @param regid Register ID that is to be retrieved. - * @return Object containing the requested register value. Long, BigInteger, or - * other custom class used to represent register values - */ - public Object reg_read(int regid) throws UnicornException { - if (arch == UC_ARCH_X86 && regid >= UC_X86_REG_IDTR && - regid <= UC_X86_REG_TR) { - return reg_read_mmr(regid); - } else { - return reg_read_num(regid); - } - } - - /** - * 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. - * - * @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. * @@ -552,100 +176,452 @@ public class Unicorn * 0, we will emulate all the code available, until the code is * finished. */ - public native void emu_start(long begin, long until, long timeout, + public void emu_start(long begin, long until, long timeout, long count) - throws UnicornException; + throws UnicornException { + _emu_start(nativePtr, begin, until, timeout, count); + } /** * 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; + public void emu_stop() throws UnicornException { + _emu_stop(nativePtr); + } - /** - * Hook registration helper for hook types that require no additional arguments. - * - * @param eng Internal unicorn uc_engine* eng 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 eng, int type); - - /** - * Hook registration helper for hook types that require one additional argument. - * - * @param eng Internal unicorn uc_engine* eng 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 eng, int type, int arg1); - - /** - * Hook registration helper for hook types that require two additional - * arguments. - * - * @param eng Internal unicorn uc_engine* eng 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 eng, 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(eng, UC_HOOK_BLOCK, begin, end); + private static boolean is_long_register(int arch, int regid) { + switch (arch) { + case UC_ARCH_X86: + return !(regid == UC_X86_REG_IDTR || regid == UC_X86_REG_GDTR || + regid == UC_X86_REG_LDTR || regid == UC_X86_REG_TR || + (regid >= UC_X86_REG_FP0 && regid <= UC_X86_REG_FP7) || + (regid >= UC_X86_REG_ST0 && regid <= UC_X86_REG_ST7) || + (regid >= UC_X86_REG_XMM0 && regid <= UC_X86_REG_XMM31) || + (regid >= UC_X86_REG_YMM0 && regid <= UC_X86_REG_YMM31) || + (regid >= UC_X86_REG_ZMM0 && regid <= UC_X86_REG_ZMM31) || + regid == UC_X86_REG_MSR); + case UC_ARCH_ARM: + return !(regid == UC_ARM_REG_CP_REG); + case UC_ARCH_ARM64: + return !(regid == UC_ARM64_REG_CP_REG || + (regid >= UC_ARM64_REG_Q0 && regid <= UC_ARM64_REG_Q31) || + (regid >= UC_ARM64_REG_V0 && regid <= UC_ARM64_REG_V31)); } - blockList.add(new Tuple(callback, user_data)); + return true; + } + + private static long do_reg_read_long(long ptr, int isContext, int arch, + int regid) throws UnicornException { + if (is_long_register(arch, regid)) { + return _reg_read_long(ptr, isContext, regid); + } else { + throw new UnicornException("Invalid register for reg_read_long"); + } + } + + private static Object do_reg_read_obj(long ptr, int isContext, int arch, + int regid, + Object opt) throws UnicornException { + switch (arch) { + case UC_ARCH_X86: + if (regid == UC_X86_REG_IDTR || regid == UC_X86_REG_GDTR || + regid == UC_X86_REG_LDTR || regid == UC_X86_REG_TR) { + return _reg_read_x86_mmr(ptr, isContext, regid); + } else if ((regid >= UC_X86_REG_FP0 && regid <= UC_X86_REG_FP7) || + (regid >= UC_X86_REG_ST0 && regid <= UC_X86_REG_ST7)) { + ByteBuffer b = + ByteBuffer.allocate(16).order(ByteOrder.LITTLE_ENDIAN); + _reg_read_bytes(ptr, isContext, regid, b.array()); + return new X86_Float80(b.getLong(0), b.getShort(8)); + } else if (regid >= UC_X86_REG_XMM0 && regid <= UC_X86_REG_XMM31) { + return do_reg_read_bigint(ptr, isContext, regid, 128); + } else if (regid >= UC_X86_REG_YMM0 && regid <= UC_X86_REG_YMM31) { + return do_reg_read_bigint(ptr, isContext, regid, 256); + } else if (regid >= UC_X86_REG_ZMM0 && regid <= UC_X86_REG_ZMM31) { + return do_reg_read_bigint(ptr, isContext, regid, 512); + } else if (regid == UC_X86_REG_MSR) { + X86_MSR reg = (X86_MSR) opt; + return (Long) _reg_read_x86_msr(ptr, isContext, reg.rid); + } + case UC_ARCH_ARM: + if (regid == UC_ARM_REG_CP_REG) { + Arm_CP reg = (Arm_CP) opt; + return (Long) _reg_read_arm_cp(ptr, isContext, reg.cp, reg.is64, + reg.sec, reg.crn, reg.crm, reg.opc1, reg.opc2); + } + case UC_ARCH_ARM64: + if (regid == UC_ARM64_REG_CP_REG) { + Arm64_CP reg = (Arm64_CP) opt; + return (Long) _reg_read_arm64_cp(ptr, isContext, reg.crn, + reg.crm, reg.op0, reg.op1, reg.op2); + } else if ((regid >= UC_ARM64_REG_Q0 && + regid <= UC_ARM64_REG_Q31) || + (regid >= UC_ARM64_REG_V0 && regid <= UC_ARM64_REG_V31)) { + return do_reg_read_bigint(ptr, isContext, regid, 128); + } + } + return _reg_read_long(ptr, isContext, regid); + } + + private static void do_reg_write_long(long ptr, int isContext, int arch, + int regid, long value) throws UnicornException { + if (is_long_register(arch, regid)) { + _reg_write_long(ptr, isContext, regid, value); + } else { + throw new UnicornException("Invalid register for reg_read_long"); + } + } + + private static void do_reg_write_obj(long ptr, int isContext, int arch, + int regid, + Object value) throws UnicornException { + switch (arch) { + case UC_ARCH_X86: + if (regid == UC_X86_REG_IDTR || regid == UC_X86_REG_GDTR || + regid == UC_X86_REG_LDTR || regid == UC_X86_REG_TR) { + X86_MMR reg = (X86_MMR) value; + _reg_write_x86_mmr(ptr, isContext, regid, reg.selector, + reg.base, reg.limit, reg.flags); + return; + } else if ((regid >= UC_X86_REG_FP0 && regid <= UC_X86_REG_FP7) || + (regid >= UC_X86_REG_ST0 && regid <= UC_X86_REG_ST7)) { + X86_Float80 reg = (X86_Float80) value; + ByteBuffer b = + ByteBuffer.allocate(16).order(ByteOrder.LITTLE_ENDIAN); + b.putLong(0, reg.mantissa); + b.putShort(8, reg.exponent); + _reg_write_bytes(ptr, isContext, regid, b.array()); + return; + } else if (regid >= UC_X86_REG_XMM0 && regid <= UC_X86_REG_XMM31) { + do_reg_write_bigint(ptr, isContext, regid, (BigInteger) value, + 128); + return; + } else if (regid >= UC_X86_REG_YMM0 && regid <= UC_X86_REG_YMM31) { + do_reg_write_bigint(ptr, isContext, regid, (BigInteger) value, + 256); + return; + } else if (regid >= UC_X86_REG_ZMM0 && regid <= UC_X86_REG_ZMM31) { + do_reg_write_bigint(ptr, isContext, regid, (BigInteger) value, + 512); + return; + } else if (regid == UC_X86_REG_MSR) { + X86_MSR reg = (X86_MSR) value; + _reg_write_x86_msr(ptr, isContext, reg.rid, reg.value); + return; + } + case UC_ARCH_ARM: + if (regid == UC_ARM_REG_CP_REG) { + Arm_CP reg = (Arm_CP) value; + _reg_write_arm_cp(ptr, isContext, reg.cp, reg.is64, reg.sec, + reg.crn, reg.crm, reg.opc1, reg.opc2, reg.val); + return; + } + case UC_ARCH_ARM64: + if (regid == UC_ARM64_REG_CP_REG) { + Arm64_CP reg = (Arm64_CP) value; + _reg_write_arm64_cp(ptr, isContext, reg.crn, reg.crm, reg.op0, + reg.op1, reg.op2, reg.val); + return; + } else if ((regid >= UC_ARM64_REG_Q0 && + regid <= UC_ARM64_REG_Q31) || + (regid >= UC_ARM64_REG_V0 && regid <= UC_ARM64_REG_V31)) { + do_reg_write_bigint(ptr, isContext, regid, (BigInteger) value, + 128); + return; + } + } + _reg_write_long(ptr, isContext, regid, (Long) value); + } + + private static BigInteger do_reg_read_bigint(long ptr, int isContext, + int regid, + int nbits) { + + byte[] buf = new byte[nbits >> 3]; + _reg_read_bytes(ptr, isContext, regid, buf); + if (ByteOrder.nativeOrder().equals(ByteOrder.LITTLE_ENDIAN)) { + // reverse native buffer to big-endian on little-endian hosts + int i = buf.length - 1; + int j = 0; + while (i > j) { + byte temp = buf[i]; + buf[i] = buf[j]; + buf[j] = temp; + i--; + j++; + } + } + return new BigInteger(buf); + } + + private static void do_reg_write_bigint(long ptr, int isContext, int regid, + BigInteger value, int nbits) { + byte[] val = value.toByteArray(); + if (val.length > (nbits >> 3)) { + throw new IllegalArgumentException( + "input integer is too large for a " + nbits + + "-bit register (got " + (val.length * 8) + " bits)"); + } + byte[] buf = new byte[nbits >> 3]; + if (val[0] < 0) { + Arrays.fill(buf, (byte) 0xff); + } + + if (ByteOrder.nativeOrder().equals(ByteOrder.LITTLE_ENDIAN)) { + for (int i = 0; i < val.length; i++) { + buf[i] = val[val.length - i - 1]; + } + } else { + System.arraycopy(val, 0, buf, buf.length - val.length, val.length); + } + _reg_write_bytes(ptr, isContext, regid, buf); } /** - * Hook registration for UC_HOOK_INTR hooks. The registered callback function - * will be + * Read register value. This reads any register that would return a Long + * from {@link #reg_read(int, Object)}. + * + * @param regid Register ID that is to be retrieved. This function only supports + * integer registers at most 64 bits long. + * @return value of the register. + */ + public long reg_read(int regid) throws UnicornException { + return do_reg_read_long(nativePtr, 0, arch, regid); + } + + /** + * Read register value. The return type depends on regid as follows. + * opt should be null unless otherwise specified. + *

    + *
  • {@code UC_X86_REG_*TR} => {@link X86_MMR} + *
  • {@code UC_X86_REG_FP*} => {@link X86_Float80} + *
  • {@code UC_X86_REG_ST*} => {@link X86_Float80} + *
  • {@code UC_X86_REG_XMM*} => {@link BigInteger} (128 bits) + *
  • {@code UC_X86_REG_YMM*} => {@link BigInteger} (256 bits) + *
  • {@code UC_X86_REG_MSR} (opt: {@link X86_MSR}) => {@link Long} + *
  • {@code UC_ARM_REG_CP} (opt: {@link Arm_CP}) => {@link Long} + *
  • {@code UC_ARM64_REG_CP} (opt: {@link Arm64_CP}) => {@link Long} + *
  • {@code UC_ARM64_REG_Q*} => {@link BigInteger} (128 bits) + *
  • {@code UC_ARM64_REG_V*} => {@link BigInteger} (128 bits) + *
+ * + * @param regid Register ID that is to be retrieved. + * @param opt Options for this register, or null if no options are required. + * @return value of the register - Long, BigInteger, or structure. + */ + public Object reg_read(int regid, Object opt) throws UnicornException { + return do_reg_read_obj(nativePtr, 0, arch, regid, opt); + } + + /** + * Write to register. This sets any register that doesn't require special + * options and which is at most 64 bits long. + * + * @param regid Register ID that is to be modified. + * @param value Object containing the new register value. + */ + public void reg_write(int regid, long value) throws UnicornException { + do_reg_write_long(nativePtr, 0, arch, regid, value); + } + + /** + * Write to register. The type of {@code value} depends on regid: + *
    + *
  • {@code UC_X86_REG_*TR} => {@link X86_MMR} + *
  • {@code UC_X86_REG_FP*} => {@link X86_Float80} + *
  • {@code UC_X86_REG_ST*} => {@link X86_Float80} + *
  • {@code UC_X86_REG_XMM*} => {@link BigInteger} (128 bits) + *
  • {@code UC_X86_REG_YMM*} => {@link BigInteger} (256 bits) + *
  • {@code UC_X86_REG_MSR} => {@link X86_MSR} + *
  • {@code UC_ARM_REG_CP} => {@link Arm_CP} + *
  • {@code UC_ARM64_REG_CP} => {@link Arm64_CP} + *
  • {@code UC_ARM64_REG_Q*} => {@link BigInteger} (128 bits) + *
  • {@code UC_ARM64_REG_V*} => {@link BigInteger} (128 bits) + *
+ * + * @param regid Register ID that is to be modified. + * @param value Object containing the new register value. + */ + public void reg_write(int regid, Object value) throws UnicornException { + do_reg_write_obj(nativePtr, 0, arch, regid, value); + } + + /** + * Read from memory. + * + * @param address Start address 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 byte[] mem_read(long address, int size) throws UnicornException { + byte[] result = new byte[size]; + _mem_read(nativePtr, address, result); + return result; + } + + /** + * 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 void mem_write(long address, byte[] bytes) throws UnicornException { + _mem_write(nativePtr, address, bytes); + } + + /** + * Query internal status of engine. + * + * @param type query type. See UC_QUERY_* + * @param result save the internal status queried + * + * @return: error code. see UC_ERR_* + * @see unicorn.UnicornConst + */ + public long query(int type) throws UnicornException { + return _query(nativePtr, type); + } + + /** + * 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.UnicornConst + */ + public int errno() { + return _errno(nativePtr); + } + + /** + * 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.UnicornConst + */ + public static String strerror(int code) { + return _strerror(code); + } + + public int ctl_get_mode() { + return _ctl_get_mode(nativePtr); + } + + public int ctl_get_arch() { + return _ctl_get_arch(nativePtr); + } + + public long ctl_get_timeout() { + return _ctl_get_timeout(nativePtr); + } + + public int ctl_get_page_size() { + return _ctl_get_page_size(nativePtr); + } + + public void ctl_set_page_size(int page_size) { + _ctl_set_page_size(nativePtr, page_size); + } + + public void ctl_exits_enabled(boolean value) { + _ctl_set_use_exits(nativePtr, value); + } + + public long ctl_get_exits_cnt() { + return _ctl_get_exits_cnt(nativePtr); + } + + public long[] ctl_get_exits() { + return _ctl_get_exits(nativePtr); + } + + public void ctl_set_exits(long[] exits) { + _ctl_set_exits(nativePtr, exits); + } + + public int ctl_get_cpu_model() { + return _ctl_get_cpu_model(nativePtr); + } + + /** + * Set the emulated cpu model. + * + * @param cpu_model CPU model type (see UC_CPU_*). + */ + public void ctl_set_cpu_model(int cpu_model) { + _ctl_set_cpu_model(nativePtr, cpu_model); + } + + public TranslationBlock ctl_request_cache(long address) { + return _ctl_request_cache(nativePtr, address); + } + + public void ctl_remove_cache(long address, long end) { + _ctl_remove_cache(nativePtr, address, end); + } + + public void ctl_flush_tb() { + _ctl_flush_tb(nativePtr); + } + + public void ctl_flush_tlb() { + _ctl_flush_tlb(nativePtr); + } + + public void ctl_tlb_mode(int mode) { + _ctl_tlb_mode(nativePtr, mode); + } + + private long registerHook(long val) { + HookWrapper wrapper = new HookWrapper(); + wrapper.nativePtr = val; + hooks.put(val, wrapper); + return val; + } + + /** + * Register a UC_HOOK_INTR hook. 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) + public long hook_add(InterruptHook callback, Object user_data) throws UnicornException { - if (interruptHandle == 0) { - interruptHandle = registerHook(eng, UC_HOOK_INTR); - } - intrList.add(new Tuple(callback, user_data)); + return registerHook( + _hook_add(nativePtr, UC_HOOK_INTR, callback, user_data, 1, 0)); } /** - * 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. + * Register a UC_HOOK_INSN hook. The registered callback function will be + * invoked whenever the matching special instruction is executed. + * The exact interface called will depend on the instruction being hooked. + * + * @param callback Implementation of an InstructionHook sub-interface + * @param insn UC__INS_ constant, e.g. UC_X86_INS_IN or UC_ARM64_INS_MRS + * @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 long hook_add(InstructionHook callback, int insn, long begin, + long end, + Object user_data) + throws UnicornException { + return registerHook(_hook_add(nativePtr, UC_HOOK_INSN, callback, + user_data, begin, end, insn)); + } + + /** + * Register a UC_HOOK_CODE hook. 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 @@ -653,176 +629,130 @@ public class Unicorn * @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, + public long hook_add(CodeHook callback, long begin, long end, Object user_data) throws UnicornException { - if (codeHandle == 0) { - codeHandle = registerHook(eng, UC_HOOK_CODE, begin, end); - } - codeList.add(new Tuple(callback, user_data)); + return registerHook(_hook_add(nativePtr, UC_HOOK_CODE, callback, + user_data, begin, end)); } /** - * 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. + * Register a UC_HOOK_BLOCK hook. 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 ReadHook interface - * @param begin Start address of memory read range - * @param end End address of memory read range + * @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(ReadHook callback, long begin, long end, + public long hook_add(BlockHook callback, long begin, long end, Object user_data) throws UnicornException { - if (readHandle == 0) { - readHandle = registerHook(eng, UC_HOOK_MEM_READ, begin, end); - } - readList.add(new Tuple(callback, user_data)); + return registerHook(_hook_add(nativePtr, UC_HOOK_BLOCK, callback, + user_data, begin, end)); } /** - * 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(eng, UC_HOOK_MEM_WRITE, begin, end); - } - 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 - * invoked whenever a memory write or read is performed within the address range - * begin <= addr <= end. For - * the special case in which begin > end, the callback will be invoked for ALL - * memory writes. + * Register a UC_HOOK_MEM_VALID hook (UC_HOOK_MEM_{READ,WRITE_FETCH} and/or + * UC_HOOK_MEM_READ_AFTER. The registered callback function will be + * invoked whenever a corresponding memory operation is performed within the + * address range begin <= addr <= end. For the special case in which + * begin > end, the callback will be invoked for ALL memory operations. * * @param callback Implementation of a MemHook interface + * @param type UC_HOOK_MEM_* constant for a valid memory event * @param begin Start address of memory range * @param end End address of memory range * @param user_data User data to be passed to the callback function each time * the event is triggered */ - public void hook_add(MemHook callback, long begin, long end, + public long hook_add(MemHook callback, int type, long begin, long end, Object user_data) throws UnicornException { - hook_add((ReadHook) callback, begin, end, user_data); - hook_add((WriteHook) callback, begin, end, user_data); + return registerHook( + _hook_add(nativePtr, type, callback, user_data, begin, end)); } /** - * 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 - * attempted from an invalid or protected memory address. + * Register a UC_HOOK_MEM_XXX_UNMAPPED and/or UC_HOOK_MEM_XXX_PROT hook. + * The registered callback function will be invoked whenever a memory + * operation is attempted from an invalid or protected memory address. + * The registered callback function will be invoked whenever a + * corresponding memory operation is performed within the address range + * begin <= addr <= end. For the special case in which begin > end, the + * callback will be invoked for ALL memory operations. * * @param callback Implementation of a EventMemHook interface * @param type Type of memory event being hooked such as * UC_HOOK_MEM_READ_UNMAPPED or UC_HOOK_MEM_WRITE_PROT + * @param begin Start address of memory range + * @param end End address of memory range * @param user_data User data to be passed to the callback function each time * the event is triggered */ - public void hook_add(EventMemHook callback, int type, Object user_data) + public long hook_add(EventMemHook callback, int type, long begin, long end, + Object user_data) throws UnicornException { - // test all of the EventMem related bits in type - for (Integer htype : eventMemMap.keySet()) { - if ((type & htype) != 0) { // the 'htype' bit is set in type - Long handle = eventMemHandles.get(htype); - if (handle == null) { - eventMemHandles.put(htype, registerHook(eng, htype)); - } - int cbType = eventMemMap.get(htype); - ArrayList flist = eventMemLists.get(cbType); - if (flist == null) { - flist = new ArrayList(); - allLists.add(flist); - eventMemLists.put(cbType, flist); - } - flist.add(new Tuple(callback, user_data)); - } + return registerHook( + _hook_add(nativePtr, type, callback, user_data, begin, end)); + } + + public long hook_add(InvalidInstructionHook callback, + Object user_data) { + return registerHook(_hook_add(nativePtr, UC_HOOK_INSN_INVALID, callback, + user_data, 1, 0)); + } + + public long hook_add(EdgeGeneratedHook callback, long begin, long end, + Object user_data) + throws UnicornException { + return registerHook(_hook_add(nativePtr, UC_HOOK_EDGE_GENERATED, + callback, user_data, begin, end)); + } + + public long hook_add(TcgOpcodeHook callback, long begin, long end, + int opcode, int flags, + Object user_data) + throws UnicornException { + return registerHook(_hook_add(nativePtr, UC_HOOK_TCG_OPCODE, callback, + user_data, begin, end, opcode, flags)); + } + + public long hook_add(TlbFillHook callback, long begin, long end, + Object user_data) throws UnicornException { + return registerHook(_hook_add(nativePtr, UC_HOOK_TLB_FILL, callback, + user_data, begin, end)); + } + + /** Remove a hook that was previously registered. + * + * @param hook The return value from any hook_add function. + */ + public void hook_del(long hook) throws UnicornException { + if (hooks.contains(hook)) { + hooks.remove(hooks, hook); + _hook_del(nativePtr, hook); + } else { + throw new UnicornException("Hook is not registered!"); } } /** - * 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) + * Create a memory-mapped I/O range. + */ + public void mmio_map(long address, long size, MmioReadHandler read_cb, + Object user_data_read, MmioWriteHandler write_cb, + Object user_data_write) throws UnicornException { - if (inHandle == 0) { - inHandle = registerHook(eng, 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(eng, 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(eng, 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 l : allLists) { - for (Tuple t : l) { - if (t.function.equals(hook)) { - allLists.remove(t); - return; - } - } + /* TODO: Watch mem_unmap to know when it's safe to release the hook. */ + long[] hooks = _mmio_map(nativePtr, address, size, read_cb, + user_data_read, write_cb, user_data_write); + for (long hook : hooks) { + registerHook(hook); } } @@ -834,27 +764,27 @@ public class Unicorn * @param perms Permissions on the memory block. A combination of * UC_PROT_READ, UC_PROT_WRITE, UC_PROT_EXEC */ - public native void mem_map(long address, long size, int perms) - throws UnicornException; + public void mem_map(long address, long size, int perms) + throws UnicornException { + _mem_map(nativePtr, address, size, perms); + } /** * Map existing host memory in for emulation. * This API adds a memory region that can be used by emulation. * * @param address Base address of the memory range - * @param size Size of the memory block. + * @param buf Direct-mapped Buffer referencing the memory to + * map into the emulator. IMPORTANT: You are responsible + * for ensuring that this Buffer remains alive as long + * as the emulator is running! * @param perms Permissions on the memory block. A combination of * UC_PROT_READ, UC_PROT_WRITE, UC_PROT_EXEC - * @param ptr Block of host memory backing the newly mapped memory. This - * block is - * expected to be an equal or larger size than provided, and be - * mapped with at - * least PROT_READ | PROT_WRITE. If it is not, the resulting - * behavior is undefined. */ - public native void mem_map_ptr(long address, long size, int perms, - byte[] block) - throws UnicornException; + public void mem_map_ptr(long address, Buffer buf, int perms) + throws UnicornException { + _mem_map_ptr(nativePtr, address, buf, perms); + } /** * Unmap a range of memory. @@ -862,8 +792,9 @@ public class Unicorn * @param address Base address of the memory range * @param size Size of the memory block. */ - public native void mem_unmap(long address, long size) - throws UnicornException; + public void mem_unmap(long address, long size) throws UnicornException { + _mem_unmap(nativePtr, address, size); + } /** * Change permissions on a range of memory. @@ -873,8 +804,10 @@ public class Unicorn * @param perms New permissions on the memory block. A combination of * UC_PROT_READ, UC_PROT_WRITE, UC_PROT_EXEC */ - public native void mem_protect(long address, long size, int perms) - throws UnicornException; + public void mem_protect(long address, long size, int perms) + throws UnicornException { + _mem_protect(nativePtr, address, size, perms); + } /** * Retrieve all memory regions mapped by mem_map() and mem_map_ptr() @@ -882,48 +815,196 @@ public class Unicorn * * @return list of mapped regions. */ - public native MemRegion[] mem_regions() throws UnicornException; + public MemRegion[] mem_regions() throws UnicornException { + return _mem_regions(nativePtr); + } - /** - * 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(); + public Context context_save() throws UnicornException { + long ptr = _context_alloc(nativePtr); + Context context = new Context(); + context.nativePtr = ptr; + context.arch = arch; + context.mode = mode; + _context_save(nativePtr, ptr); + return context; + } - /** - * Free a resource allocated within Unicorn. Use for handles - * allocated by context_alloc. - * - * @param Previously allocated Unicorn object handle. - */ - public native void free(long handle); + public void context_update(Context context) throws UnicornException { + if (context.arch != arch || context.mode != mode) { + throw new UnicornException( + "Context is not compatible with this Unicorn"); + } + _context_save(nativePtr, context.nativePtr); + } - /** - * 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); + public void context_restore(Context context) throws UnicornException { + if (context.arch != arch || context.mode != mode) { + throw new UnicornException( + "Context is not compatible with this Unicorn"); + } + _context_restore(nativePtr, context.nativePtr); + } - /** - * 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); + /* Native implementation */ + private static native long _open(int arch, int mode) + throws UnicornException; + + private static native void _close(long uc) throws UnicornException; + + private static native void _emu_start(long uc, long begin, long until, + long timeout, + long count) throws UnicornException; + + private static native void _emu_stop(long uc) throws UnicornException; + + private static native long _reg_read_long(long ptr, int isContext, + int regid) throws UnicornException; + + private static native void _reg_read_bytes(long ptr, int isContext, + int regid, byte[] data) throws UnicornException; + + private static native void _reg_write_long(long ptr, int isContext, + int regid, long val) + throws UnicornException; + + private static native void _reg_write_bytes(long ptr, int isContext, + int regid, byte[] data) throws UnicornException; + + private static native X86_MMR _reg_read_x86_mmr(long ptr, int isContext, + int regid) throws UnicornException; + + private static native void _reg_write_x86_mmr(long ptr, int isContext, + int regid, short selector, long base, int limit, int flags) + throws UnicornException; + + private static native long _reg_read_x86_msr(long ptr, int isContext, + int rid) throws UnicornException; + + private static native void _reg_write_x86_msr(long ptr, int isContext, + int rid, long value) throws UnicornException; + + private static native long _reg_read_arm_cp(long ptr, int isContext, int cp, + int is64, int sec, int crn, int crm, int opc1, int opc2) + throws UnicornException; + + private static native void _reg_write_arm_cp(long ptr, int isContext, + int cp, int is64, int sec, int crn, int crm, int opc1, int opc2, + long value) throws UnicornException; + + private static native long _reg_read_arm64_cp(long ptr, int isContext, + int crn, int crm, int op0, int op1, int op2) + throws UnicornException; + + private static native void _reg_write_arm64_cp(long ptr, int isContext, + int crn, int crm, int op0, int op1, int op2, long value) + throws UnicornException; + + private static native void _mem_read(long uc, long address, + byte[] dest) throws UnicornException; + + private static native void _mem_write(long uc, long address, + byte[] src) throws UnicornException; + + private static native int _version(); + + private static native boolean _arch_supported(int arch); + + private static native long _query(long uc, int type) + throws UnicornException; + + private static native int _errno(long uc); + + private static native String _strerror(int code); + + private native long _hook_add(long uc, int type, Hook callback, + Object user_data, long begin, long end) throws UnicornException; + + private native long _hook_add(long uc, int type, Hook callback, + Object user_data, long begin, long end, int arg) + throws UnicornException; + + private native long _hook_add(long uc, int type, Hook callback, + Object user_data, long begin, long end, int arg1, int arg2) + throws UnicornException; + + private static native void _hook_del(long uc, long hh) + throws UnicornException; + + private static native void _hookwrapper_free(long hh) + throws UnicornException; + + private native long[] _mmio_map(long uc, long address, long size, + MmioReadHandler read_cb, Object user_data_read, + MmioWriteHandler write_cb, Object user_data_write) + throws UnicornException; + + private static native void _mem_map(long uc, long address, long size, + int perms) throws UnicornException; + + private static native void _mem_map_ptr(long uc, long address, Buffer buf, + int perms) throws UnicornException; + + private static native void _mem_unmap(long uc, long address, long size) + throws UnicornException; + + private static native void _mem_protect(long uc, long address, long size, + int perms) throws UnicornException; + + private static native MemRegion[] _mem_regions(long uc) + throws UnicornException; + + private static native long _context_alloc(long uc) throws UnicornException; + + private static native void _context_free(long ctx) throws UnicornException; + + private static native void _context_save(long uc, long ctx) + throws UnicornException; + + private static native void _context_restore(long uc, long ctx) + throws UnicornException; + + private static native int _ctl_get_mode(long uc) throws UnicornException; + + private static native int _ctl_get_arch(long uc) throws UnicornException; + + private static native long _ctl_get_timeout(long uc) + throws UnicornException; + + private static native int _ctl_get_page_size(long uc) + throws UnicornException; + + private static native void _ctl_set_page_size(long uc, int page_size) + throws UnicornException; + + private static native void _ctl_set_use_exits(long uc, boolean value) + throws UnicornException; + + private static native long _ctl_get_exits_cnt(long uc) + throws UnicornException; + + private static native long[] _ctl_get_exits(long uc) + throws UnicornException; + + private static native void _ctl_set_exits(long uc, long[] exits) + throws UnicornException; + + private static native int _ctl_get_cpu_model(long uc) + throws UnicornException; + + private static native void _ctl_set_cpu_model(long uc, int cpu_model) + throws UnicornException; + + private static native TranslationBlock _ctl_request_cache(long uc, + long address) throws UnicornException; + + private static native void _ctl_remove_cache(long uc, long address, + long end) throws UnicornException; + + private static native void _ctl_flush_tb(long uc) throws UnicornException; + + private static native void _ctl_flush_tlb(long uc) throws UnicornException; + + private static native void _ctl_tlb_mode(long uc, int mode) + throws UnicornException; - /** - * Set the emulated cpu model. - * - * @param cpu_model CPU model type (see UC_CPU_*). - */ - public native void ctl_set_cpu_model(int cpu_model); } diff --git a/bindings/java/unicorn/X86_Float80.java b/bindings/java/unicorn/X86_Float80.java new file mode 100644 index 00000000..df76dc7b --- /dev/null +++ b/bindings/java/unicorn/X86_Float80.java @@ -0,0 +1,72 @@ +/* + +Java bindings for the Unicorn Emulator Engine + +Copyright(c) 2023 Robert Xiao + +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 X86_Float80 { + public long mantissa; + public short exponent; + + public X86_Float80(long mantissa, short exponent) { + this.mantissa = mantissa; + this.exponent = exponent; + } + + public double toDouble() { + boolean sign = (exponent & 0x8000) != 0; + int exp = exponent & 0x7fff; + if (exp == 0) { + return sign ? -0.0 : 0.0; + } else if (exp == 0x7fff) { + if (((mantissa >> 62) & 1) == 0) { + return sign ? Double.NEGATIVE_INFINITY + : Double.POSITIVE_INFINITY; + } else { + return Double.NaN; + } + } else { + exp -= 16383; + double f = mantissa >>> 1; + return Math.scalb(sign ? -f : f, exp - 62); + } + } + + public static X86_Float80 fromDouble(double val) { + if (Double.isNaN(val)) { + return new X86_Float80(-1L, (short) -1); + } else if (Double.isInfinite(val)) { + return new X86_Float80(1L << 63, + (short) (val < 0 ? 0xffff : 0x7fff)); + } else { + int exp = Math.getExponent(val); + long mantissa = ((long) Math.scalb(Math.abs(val), 62 - exp)) << 1; + exp += 16383; + return new X86_Float80(mantissa, + (short) (val < 0 ? (exp | 0x8000) : exp)); + } + } + + @Override + public String toString() { + return "X86_Float80 [mantissa=" + mantissa + ", exponent=" + exponent + + "]"; + } +} diff --git a/bindings/java/unicorn/X86_MMR.java b/bindings/java/unicorn/X86_MMR.java index 17f3fe33..5f8e8b63 100644 --- a/bindings/java/unicorn/X86_MMR.java +++ b/bindings/java/unicorn/X86_MMR.java @@ -21,6 +21,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. package unicorn; +/** Memory-Management Register for instructions IDTR, GDTR, LDTR, TR. */ public class X86_MMR { public long base; public int limit; @@ -40,4 +41,10 @@ public class X86_MMR { selector = 0; flags = 0; } + + @Override + public String toString() { + return "X86_MMR [base=" + base + ", limit=" + limit + ", flags=" + + flags + ", selector=" + selector + "]"; + } } diff --git a/bindings/java/unicorn/X86_MSR.java b/bindings/java/unicorn/X86_MSR.java new file mode 100644 index 00000000..1bf9138c --- /dev/null +++ b/bindings/java/unicorn/X86_MSR.java @@ -0,0 +1,38 @@ +/* + +Java bindings for the Unicorn Emulator Engine + +Copyright(c) 2023 Robert Xiao + +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; + +/** Model-specific register */ +public class X86_MSR { + public int rid; + public long value; + + public X86_MSR(int rid, long value) { + this.rid = rid; + this.value = value; + } + + @Override + public String toString() { + return "X86_MSR [rid=" + rid + ", value=" + value + "]"; + } +} diff --git a/bindings/java/unicorn_Unicorn.c b/bindings/java/unicorn_Unicorn.c index de45f8ff..58ce3825 100644 --- a/bindings/java/unicorn_Unicorn.c +++ b/bindings/java/unicorn_Unicorn.c @@ -2,7 +2,7 @@ Java bindings for the Unicorn Emulator Engine -Copyright(c) 2015 Chris Eagle +Copyright(c) 2023 Robert Xiao This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -28,18 +28,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include #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 invokeEventMemCallbacks = 0; -static jmethodID invokeReadCallbacks = 0; -static jmethodID invokeWriteCallbacks = 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) @@ -48,772 +36,1223 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved) 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(uc_engine *eng, uint64_t address, uint32_t size, - void *user_data) +static void throwUnicornException(JNIEnv *env, uc_err err) +{ + jclass clazz = (*env)->FindClass(env, "unicorn/UnicornException"); + const char *msg = uc_strerror(err); + (*env)->ThrowNew(env, clazz, msg); +} + +static void throwCustomUnicornException(JNIEnv *env, const char *msg) +{ + jclass clazz = (*env)->FindClass(env, "unicorn/UnicornException"); + (*env)->ThrowNew(env, clazz, msg); +} + +static void throwOutOfMemoryError(JNIEnv *env, char *message) +{ + jclass clazz = (*env)->FindClass(env, "java/lang/OutOfMemoryError"); + (*env)->ThrowNew(env, clazz, message); +} + +static jobject makeX86_MMR(JNIEnv *env, const uc_x86_mmr *mmr) +{ + if (mmr == NULL) { + return NULL; + } + + static jclass clazz; + if (!clazz) { + clazz = (*env)->FindClass(env, "unicorn/X86_MMR"); + if (!clazz) + return NULL; + clazz = (*env)->NewGlobalRef(env, clazz); + if (!clazz) + return NULL; + } + + static jmethodID clazzInit; + if (!clazzInit) { + clazzInit = (*env)->GetMethodID(env, clazz, "", "(JIIS)V"); + if (!clazzInit) + return NULL; + } + + return (*env)->NewObject(env, clazz, clazzInit, (jlong)mmr->base, + (jint)mmr->limit, (jint)mmr->flags, + (jshort)mmr->selector); +} + +static jobject makeArm64_CP(JNIEnv *env, const uc_arm64_cp_reg *cp_reg) +{ + if (cp_reg == NULL) { + return NULL; + } + + static jclass clazz; + if (!clazz) { + clazz = (*env)->FindClass(env, "unicorn/Arm64_CP"); + if (!clazz) + return NULL; + clazz = (*env)->NewGlobalRef(env, clazz); + if (!clazz) + return NULL; + } + + static jmethodID clazzInit; + if (!clazzInit) { + clazzInit = (*env)->GetMethodID(env, clazz, "", "(IIIIIJ)V"); + if (!clazzInit) + return NULL; + } + + return (*env)->NewObject(env, clazz, clazzInit, (jint)cp_reg->crn, + (jint)cp_reg->crm, (jint)cp_reg->op0, + (jint)cp_reg->op1, (jint)cp_reg->op2, + (jlong)cp_reg->val); +} + +static jobject makeTranslationBlock(JNIEnv *env, const uc_tb *tb) +{ + if (tb == NULL) { + return NULL; + } + + static jclass clazz; + if (!clazz) { + clazz = (*env)->FindClass(env, "unicorn/TranslationBlock"); + if (!clazz) + return NULL; + clazz = (*env)->NewGlobalRef(env, clazz); + if (!clazz) + return NULL; + } + + static jmethodID clazzInit; + if (!clazzInit) { + clazzInit = (*env)->GetMethodID(env, clazz, "", "(JII)V"); + if (!clazzInit) + return NULL; + } + + return (*env)->NewObject(env, clazz, clazzInit, (jlong)tb->pc, + (jint)tb->icount, (jint)tb->size); +} + +struct hook_wrapper { + uc_hook uc_hh; + jobject unicorn; + jobject hook_obj; + jmethodID hook_meth; + jobject user_data; +}; + +static bool hookErrorCheck(uc_engine *uc, JNIEnv *env) +{ + /* If a hook throws an exception, we want to report it as soon as possible. + Additionally, once an exception is set, calling further hooks is + inadvisable. Therefore, try and stop the emulator as soon as an exception + is detected. + */ + if ((*env)->ExceptionCheck(env)) { + uc_emu_stop(uc); + return true; + } + return false; +} + +static const char *const sig_InterruptHook = + "(Lunicorn/Unicorn;ILjava/lang/Object;)V"; +static void cb_hookintr(uc_engine *uc, 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, invokeCodeCallbacks, (jlong)eng, - (jlong)address, (int)size); - (*cachedJVM)->DetachCurrentThread(cachedJVM); + struct hook_wrapper *hh = user_data; + (*env)->CallVoidMethod(env, hh->hook_obj, hh->hook_meth, hh->unicorn, + (jint)intno, hh->user_data); + hookErrorCheck(uc, env); } -// 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(uc_engine *eng, 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)eng, - (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(uc_engine *eng, 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)eng, - (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(uc_engine *eng, uint32_t port, int size, +static const char *const sig_InHook = + "(Lunicorn/Unicorn;IILjava/lang/Object;)I"; +static uint32_t cb_insn_in(uc_engine *uc, 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)) { + struct hook_wrapper *hh = user_data; + jint result = + (*env)->CallIntMethod(env, hh->hook_obj, hh->hook_meth, hh->unicorn, + (jint)port, (jint)size, hh->user_data); + if (hookErrorCheck(uc, env)) { return 0; } - res = (uint32_t)(*env)->CallStaticIntMethod( - env, clz, invokeInCallbacks, (jlong)eng, (jint)port, (jint)size); - (*cachedJVM)->DetachCurrentThread(cachedJVM); - return res; + return (uint32_t)result; } -// 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(uc_engine *eng, uint32_t port, int size, uint32_t value, +static const char *const sig_OutHook = + "(Lunicorn/Unicorn;IIILjava/lang/Object;)V"; +static void cb_insn_out(uc_engine *uc, 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)eng, - (jint)port, (jint)size, (jint)value); - (*cachedJVM)->DetachCurrentThread(cachedJVM); + struct hook_wrapper *hh = user_data; + (*env)->CallVoidMethod(env, hh->hook_obj, hh->hook_meth, hh->unicorn, + (jint)port, (jint)size, (jint)value, hh->user_data); + hookErrorCheck(uc, env); } -// x86's handler for SYSCALL/SYSENTER -static void cb_insn_syscall(uc_engine *eng, void *user_data) +static const char *const sig_SyscallHook = + "(Lunicorn/Unicorn;Ljava/lang/Object;)V"; +static void cb_insn_syscall(struct uc_struct *uc, 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)eng); - (*cachedJVM)->DetachCurrentThread(cachedJVM); + struct hook_wrapper *hh = user_data; + (*env)->CallVoidMethod(env, hh->hook_obj, hh->hook_meth, hh->unicorn, + hh->user_data); + hookErrorCheck(uc, env); } -// 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(uc_engine *eng, uc_mem_type type, uint64_t address, - int size, int64_t value, void *user_data) +static const char *const sig_CpuidHook = + "(Lunicorn/Unicorn;Ljava/lang/Object;)I"; +static int cb_insn_cpuid(struct uc_struct *uc, void *user_data) { JNIEnv *env; (*cachedJVM)->AttachCurrentThread(cachedJVM, (void **)&env, NULL); - jclass clz = (*env)->FindClass(env, "unicorn/Unicorn"); - if ((*env)->ExceptionCheck(env)) { - return; + struct hook_wrapper *hh = user_data; + jint result = (*env)->CallIntMethod(env, hh->hook_obj, hh->hook_meth, + hh->unicorn, hh->user_data); + if (hookErrorCheck(uc, env)) { + return 0; } - switch (type) { - case UC_MEM_READ: - (*env)->CallStaticVoidMethod(env, clz, invokeReadCallbacks, (jlong)eng, - (jlong)address, (int)size); - break; - case UC_MEM_WRITE: - (*env)->CallStaticVoidMethod(env, clz, invokeWriteCallbacks, (jlong)eng, - (jlong)address, (int)size, (jlong)value); - break; - } - (*cachedJVM)->DetachCurrentThread(cachedJVM); + return (int)result; } -// Callback function for handling memory events (for UC_HOOK_MEM_UNMAPPED) -// @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(uc_engine *eng, uc_mem_type type, uint64_t address, +static const char *const sig_Arm64SysHook = + "(Lunicorn/Unicorn;ILunicorn/Arm64_CP;Ljava/lang/Object;)I"; +static uint32_t cb_insn_sys(uc_engine *uc, uc_arm64_reg reg, + const uc_arm64_cp_reg *cp_reg, void *user_data) +{ + JNIEnv *env; + (*cachedJVM)->AttachCurrentThread(cachedJVM, (void **)&env, NULL); + struct hook_wrapper *hh = user_data; + jobject jcp_reg = makeArm64_CP(env, cp_reg); + if (!jcp_reg) { + hookErrorCheck(uc, env); + return 0; + } + jint result = + (*env)->CallIntMethod(env, hh->hook_obj, hh->hook_meth, hh->unicorn, + (jint)reg, jcp_reg, hh->user_data); + if (hookErrorCheck(uc, env)) { + return 0; + } + return (uint32_t)result; +} + +static const char *const sig_CodeHook = + "(Lunicorn/Unicorn;JILjava/lang/Object;)V"; +static void cb_hookcode(uc_engine *uc, uint64_t address, uint32_t size, + void *user_data) +{ + JNIEnv *env; + (*cachedJVM)->AttachCurrentThread(cachedJVM, (void **)&env, NULL); + struct hook_wrapper *hh = user_data; + (*env)->CallVoidMethod(env, hh->hook_obj, hh->hook_meth, hh->unicorn, + (jlong)address, (jint)size, hh->user_data); + hookErrorCheck(uc, env); +} + +static const char *const sig_EventMemHook = + "(Lunicorn/Unicorn;IJIJLjava/lang/Object;)Z"; +static bool cb_eventmem(uc_engine *uc, 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)) { + struct hook_wrapper *hh = user_data; + jboolean result = (*env)->CallBooleanMethod( + env, hh->hook_obj, hh->hook_meth, hh->unicorn, (jint)type, + (jlong)address, (jint)size, (jlong)value, hh->user_data); + if (hookErrorCheck(uc, env)) { return false; } - jboolean res = (*env)->CallStaticBooleanMethod( - env, clz, invokeEventMemCallbacks, (jlong)eng, (int)type, - (jlong)address, (int)size, (jlong)value); - (*cachedJVM)->DetachCurrentThread(cachedJVM); - return res; + return result != JNI_FALSE; } -static void throwException(JNIEnv *env, uc_err err) +static const char *const sig_MemHook = + "(Lunicorn/Unicorn;IJIJLjava/lang/Object;)V"; +static void cb_hookmem(uc_engine *uc, uc_mem_type type, uint64_t address, + int size, int64_t value, void *user_data) { - // 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); + JNIEnv *env; + (*cachedJVM)->AttachCurrentThread(cachedJVM, (void **)&env, NULL); + struct hook_wrapper *hh = user_data; + (*env)->CallVoidMethod(env, hh->hook_obj, hh->hook_meth, hh->unicorn, + (jint)type, (jlong)address, (jint)size, (jlong)value, + hh->user_data); + hookErrorCheck(uc, env); +} + +static const char *const sig_InvalidInstructionHook = + "(Lunicorn/Unicorn;Ljava/lang/Object;)Z"; +static bool cb_hookinsn_invalid(uc_engine *uc, void *user_data) +{ + JNIEnv *env; + (*cachedJVM)->AttachCurrentThread(cachedJVM, (void **)&env, NULL); + struct hook_wrapper *hh = user_data; + jboolean result = (*env)->CallBooleanMethod( + env, hh->hook_obj, hh->hook_meth, hh->unicorn, hh->user_data); + if (hookErrorCheck(uc, env)) { + return false; } + return result != JNI_FALSE; } -static uc_engine *getEngine(JNIEnv *env, jobject self) +static const char *const sig_EdgeGeneratedHook = + "(Lunicorn/Unicorn;Lunicorn/TranslationBlock;" + "Lunicorn/TranslationBlock;Ljava/lang/Object;)V"; +static void cb_edge_gen(uc_engine *uc, uc_tb *cur_tb, uc_tb *prev_tb, + void *user_data) { - 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, "eng", "J"); - haveFid = 1; - } - return (uc_engine *)(*env)->GetLongField(env, self, fid); -} - -/* - * Class: unicorn_Unicorn - * Method: reg_write_num - * Signature: (ILjava/lang/Number;)V - */ -JNIEXPORT void JNICALL Java_unicorn_Unicorn_reg_1write_1num(JNIEnv *env, - jobject self, - jint regid, - jobject value) -{ - uc_engine *eng = getEngine(env, self); - - jclass clz = (*env)->FindClass(env, "java/lang/Number"); - if ((*env)->ExceptionCheck(env)) { + JNIEnv *env; + (*cachedJVM)->AttachCurrentThread(cachedJVM, (void **)&env, NULL); + struct hook_wrapper *hh = user_data; + jobject jcur_tb = makeTranslationBlock(env, cur_tb); + if (!jcur_tb) { + hookErrorCheck(uc, env); return; } - jmethodID longValue = (*env)->GetMethodID(env, clz, "longValue", "()J"); - jlong longVal = (*env)->CallLongMethod(env, value, longValue); - uc_err err = uc_reg_write(eng, regid, &longVal); - if (err != UC_ERR_OK) { - throwException(env, err); - } -} - -/* - * Class: unicorn_Unicorn - * Method: reg_write_mmr - * Signature: (ILunicorn/X86_MMR;)V - */ -JNIEXPORT void JNICALL Java_unicorn_Unicorn_reg_1write_1mmr(JNIEnv *env, - jobject self, - jint regid, - jobject value) -{ - uc_engine *eng = getEngine(env, self); - uc_x86_mmr mmr; - - jclass clz = (*env)->FindClass(env, "unicorn/X86_MMR"); - if ((*env)->ExceptionCheck(env)) { + jobject jprev_tb = makeTranslationBlock(env, prev_tb); + if (!jprev_tb) { + hookErrorCheck(uc, env); return; } - jfieldID fid = (*env)->GetFieldID(env, clz, "base", "J"); - mmr.base = (uint64_t)(*env)->GetLongField(env, value, fid); - - fid = (*env)->GetFieldID(env, clz, "limit", "I"); - mmr.limit = (uint32_t)(*env)->GetLongField(env, value, fid); - - fid = (*env)->GetFieldID(env, clz, "flags", "I"); - mmr.flags = (uint32_t)(*env)->GetLongField(env, value, fid); - - fid = (*env)->GetFieldID(env, clz, "selector", "S"); - mmr.selector = (uint16_t)(*env)->GetLongField(env, value, fid); - - uc_err err = uc_reg_write(eng, regid, &mmr); - if (err != UC_ERR_OK) { - throwException(env, err); - } + (*env)->CallVoidMethod(env, hh->hook_obj, hh->hook_meth, hh->unicorn, + jcur_tb, jprev_tb, hh->user_data); + hookErrorCheck(uc, env); } -/* - * Class: unicorn_Unicorn - * Method: reg_read_num - * Signature: (I)Ljava/lang/Number; - */ -JNIEXPORT jobject JNICALL Java_unicorn_Unicorn_reg_1read_1num(JNIEnv *env, - jobject self, - jint regid) +static const char *const sig_TcgOpcodeHook = + "(Lunicorn/Unicorn;JJJILjava/lang/Object;)V"; +static void cb_tcg_op_2(uc_engine *uc, uint64_t address, uint64_t arg1, + uint64_t arg2, uint32_t size, void *user_data) { - uc_engine *eng = getEngine(env, self); - - jclass clz = (*env)->FindClass(env, "java/lang/Long"); - if ((*env)->ExceptionCheck(env)) { - return NULL; - } - - jlong longVal; - uc_err err = uc_reg_read(eng, regid, &longVal); - if (err != UC_ERR_OK) { - throwException(env, err); - } - - jmethodID cons = (*env)->GetMethodID(env, clz, "", "(J)V"); - jobject result = (*env)->NewObject(env, clz, cons, longVal); - if ((*env)->ExceptionCheck(env)) { - return NULL; - } - return result; + JNIEnv *env; + (*cachedJVM)->AttachCurrentThread(cachedJVM, (void **)&env, NULL); + struct hook_wrapper *hh = user_data; + (*env)->CallVoidMethod(env, hh->hook_obj, hh->hook_meth, hh->unicorn, + (jlong)address, (jlong)arg1, (jlong)arg2, (jint)size, + hh->user_data); + hookErrorCheck(uc, env); } -/* - * Class: unicorn_Unicorn - * Method: reg_read_mmr - * Signature: (I)Ljava/lang/Number; - */ -JNIEXPORT jobject JNICALL Java_unicorn_Unicorn_reg_1read_1mmr(JNIEnv *env, - jobject self, - jint regid) +static const char *const sig_TlbFillHook = + "(Lunicorn/Unicorn;JILjava/lang/Object;)J"; +static bool cb_tlbevent(uc_engine *uc, uint64_t vaddr, uc_mem_type type, + uc_tlb_entry *entry, void *user_data) { - uc_engine *eng = getEngine(env, self); - - jclass clz = (*env)->FindClass(env, "unicorn/X86_MMR"); - if ((*env)->ExceptionCheck(env)) { - return NULL; + JNIEnv *env; + (*cachedJVM)->AttachCurrentThread(cachedJVM, (void **)&env, NULL); + struct hook_wrapper *hh = user_data; + jlong result = + (*env)->CallLongMethod(env, hh->hook_obj, hh->hook_meth, hh->unicorn, + (jlong)vaddr, (jint)type, hh->user_data); + if (hookErrorCheck(uc, env)) { + return false; } - - uc_x86_mmr mmr; - uc_err err = uc_reg_read(eng, regid, &mmr); - if (err != UC_ERR_OK) { - throwException(env, err); + if (result == -1L) { + return false; + } else { + entry->paddr = result & ~UC_PROT_ALL; + entry->perms = result & UC_PROT_ALL; + return true; } +} - jmethodID cons = (*env)->GetMethodID(env, clz, "", "(JIIS)V"); - jobject result = (*env)->NewObject(env, clz, cons, mmr.base, mmr.limit, - mmr.flags, mmr.selector); - if ((*env)->ExceptionCheck(env)) { - return NULL; +static const char *const sig_MmioReadHandler = + "(Lunicorn/Unicorn;JILjava/lang/Object;)J"; +static uint64_t cb_mmio_read(uc_engine *uc, uint64_t offset, unsigned size, + void *user_data) +{ + JNIEnv *env; + (*cachedJVM)->AttachCurrentThread(cachedJVM, (void **)&env, NULL); + struct hook_wrapper *hh = user_data; + jlong result = + (*env)->CallLongMethod(env, hh->hook_obj, hh->hook_meth, hh->unicorn, + (jlong)offset, (jint)size, hh->user_data); + if (hookErrorCheck(uc, env)) { + return 0; } - return result; + return (uint64_t)result; +} + +static const char *const sig_MmioWriteHandler = + "(Lunicorn/Unicorn;JIJLjava/lang/Object;)V"; +static void cb_mmio_write(uc_engine *uc, uint64_t offset, unsigned size, + uint64_t value, void *user_data) +{ + JNIEnv *env; + (*cachedJVM)->AttachCurrentThread(cachedJVM, (void **)&env, NULL); + struct hook_wrapper *hh = user_data; + (*env)->CallVoidMethod(env, hh->hook_obj, hh->hook_meth, hh->unicorn, + (jlong)offset, (jint)size, (jlong)value, + hh->user_data); + hookErrorCheck(uc, env); } /* * Class: unicorn_Unicorn - * Method: open + * Method: _open * Signature: (II)J */ -JNIEXPORT jlong JNICALL Java_unicorn_Unicorn_open(JNIEnv *env, jobject self, - jint arch, jint mode) +JNIEXPORT jlong JNICALL Java_unicorn_Unicorn__1open(JNIEnv *env, jclass clazz, + jint arch, jint mode) { uc_engine *eng = NULL; - uc_err err = uc_open((uc_arch)arch, (uc_mode)mode, &eng); + uc_err err = uc_open(arch, mode, &eng); if (err != UC_ERR_OK) { - throwException(env, err); + throwUnicornException(env, err); + return 0; } return (jlong)eng; } /* * Class: unicorn_Unicorn - * Method: version + * Method: _close + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_unicorn_Unicorn__1close(JNIEnv *env, jclass clazz, + jlong uc) +{ + uc_err err = uc_close((uc_engine *)uc); + if (err != UC_ERR_OK) { + throwUnicornException(env, err); + return; + } +} + +/* + * Class: unicorn_Unicorn + * Method: _emu_start + * Signature: (JJJJJ)V + */ +JNIEXPORT void JNICALL Java_unicorn_Unicorn__1emu_1start( + JNIEnv *env, jclass clazz, jlong uc, jlong begin, jlong until, + jlong timeout, jlong count) +{ + uc_err err = + uc_emu_start((uc_engine *)uc, begin, until, timeout, (size_t)count); + if (err != UC_ERR_OK) { + throwUnicornException(env, err); + return; + } +} + +/* + * Class: unicorn_Unicorn + * Method: _emu_stop + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_unicorn_Unicorn__1emu_1stop(JNIEnv *env, + jclass clazz, jlong uc) +{ + uc_err err = uc_emu_stop((uc_engine *)uc); + if (err != UC_ERR_OK) { + throwUnicornException(env, err); + return; + } +} + +static uc_err generic_reg_read(jlong ptr, jint isContext, jint regid, + void *result) +{ + if (isContext) { + return uc_context_reg_read((uc_context *)ptr, regid, result); + } else { + return uc_reg_read((uc_engine *)ptr, regid, result); + } +} + +static uc_err generic_reg_write(jlong ptr, jint isContext, jint regid, + const void *value) +{ + if (isContext) { + return uc_context_reg_write((uc_context *)ptr, regid, value); + } else { + return uc_reg_write((uc_engine *)ptr, regid, value); + } +} + +/* + * Class: unicorn_Unicorn + * Method: _reg_read_long + * Signature: (JII)J + */ +JNIEXPORT jlong JNICALL Java_unicorn_Unicorn__1reg_1read_1long( + JNIEnv *env, jclass clazz, jlong ptr, jint isContext, jint regid) +{ + /* XXX: This is just *wrong* on big-endian hosts, since a register + smaller than 8 bytes will be written into the MSBs. */ + uint64_t result = 0; + uc_err err = generic_reg_read(ptr, isContext, regid, &result); + if (err != UC_ERR_OK) { + throwUnicornException(env, err); + return 0; + } + return result; +} + +/* + * Class: unicorn_Unicorn + * Method: _reg_read_bytes + * Signature: (JII[B)V + */ +JNIEXPORT void JNICALL Java_unicorn_Unicorn__1reg_1read_1bytes( + JNIEnv *env, jclass clazz, jlong ptr, jint isContext, jint regid, + jbyteArray data) +{ + jbyte *arr = (*env)->GetByteArrayElements(env, data, NULL); + uc_err err = generic_reg_read(ptr, isContext, regid, arr); + (*env)->ReleaseByteArrayElements(env, data, arr, 0); + if (err != UC_ERR_OK) { + throwUnicornException(env, err); + return; + } +} + +/* + * Class: unicorn_Unicorn + * Method: _reg_write_long + * Signature: (JIIJ)V + */ +JNIEXPORT void JNICALL +Java_unicorn_Unicorn__1reg_1write_1long(JNIEnv *env, jclass clazz, jlong ptr, + jint isContext, jint regid, jlong value) +{ + uint64_t cvalue = value; + uc_err err = generic_reg_write(ptr, isContext, regid, &cvalue); + if (err != UC_ERR_OK) { + throwUnicornException(env, err); + return; + } +} + +/* + * Class: unicorn_Unicorn + * Method: _reg_write_bytes + * Signature: (JII[B)V + */ +JNIEXPORT void JNICALL Java_unicorn_Unicorn__1reg_1write_1bytes( + JNIEnv *env, jclass clazz, jlong ptr, jint isContext, jint regid, + jbyteArray data) +{ + jbyte *arr = (*env)->GetByteArrayElements(env, data, NULL); + uc_err err = generic_reg_write(ptr, isContext, regid, arr); + (*env)->ReleaseByteArrayElements(env, data, arr, JNI_ABORT); + if (err != UC_ERR_OK) { + throwUnicornException(env, err); + return; + } +} + +/* + * Class: unicorn_Unicorn + * Method: _reg_read_x86_mmr + * Signature: (JII)Lunicorn/X86_MMR; + */ +JNIEXPORT jobject JNICALL Java_unicorn_Unicorn__1reg_1read_1x86_1mmr( + JNIEnv *env, jclass clazz, jlong ptr, jint isContext, jint regid) +{ + uc_x86_mmr reg = {0}; + uc_err err = generic_reg_read(ptr, isContext, regid, ®); + if (err != UC_ERR_OK) { + throwUnicornException(env, err); + return 0; + } + return makeX86_MMR(env, ®); +} + +/* + * Class: unicorn_Unicorn + * Method: _reg_write_x86_mmr + * Signature: (JIISJII)V + */ +JNIEXPORT void JNICALL Java_unicorn_Unicorn__1reg_1write_1x86_1mmr( + JNIEnv *env, jclass clazz, jlong ptr, jint isContext, jint regid, + jshort selector, jlong base, jint limit, jint flags) +{ + uc_x86_mmr reg = {0}; + reg.selector = selector; + reg.base = base; + reg.limit = limit; + reg.flags = flags; + uc_err err = generic_reg_write(ptr, isContext, regid, ®); + if (err != UC_ERR_OK) { + throwUnicornException(env, err); + return; + } +} + +/* + * Class: unicorn_Unicorn + * Method: _reg_read_x86_msr + * Signature: (JII)J + */ +JNIEXPORT jlong JNICALL Java_unicorn_Unicorn__1reg_1read_1x86_1msr( + JNIEnv *env, jclass clazz, jlong ptr, jint isContext, jint rid) +{ + uc_x86_msr reg = {0}; + reg.rid = rid; + uc_err err = generic_reg_read(ptr, isContext, UC_X86_REG_MSR, ®); + if (err != UC_ERR_OK) { + throwUnicornException(env, err); + return 0; + } + return reg.value; +} + +/* + * Class: unicorn_Unicorn + * Method: _reg_write_x86_msr + * Signature: (JIIJ)V + */ +JNIEXPORT void JNICALL Java_unicorn_Unicorn__1reg_1write_1x86_1msr( + JNIEnv *env, jclass clazz, jlong ptr, jint isContext, jint rid, jlong value) +{ + uc_x86_msr reg = {0}; + reg.rid = rid; + reg.value = value; + uc_err err = generic_reg_write(ptr, isContext, UC_X86_REG_MSR, ®); + if (err != UC_ERR_OK) { + throwUnicornException(env, err); + return; + } +} + +/* + * Class: unicorn_Unicorn + * Method: _reg_read_arm_cp + * Signature: (JIIIIIIII)J + */ +JNIEXPORT jlong JNICALL Java_unicorn_Unicorn__1reg_1read_1arm_1cp( + JNIEnv *env, jclass clazz, jlong ptr, jint isContext, jint cp, jint is64, + jint sec, jint crn, jint crm, jint opc1, jint opc2) +{ + uc_arm_cp_reg reg = {0}; + reg.cp = cp; + reg.is64 = is64; + reg.sec = sec; + reg.crn = crn; + reg.crm = crm; + reg.opc1 = opc1; + reg.opc2 = opc2; + uc_err err = generic_reg_read(ptr, isContext, UC_ARM_REG_CP_REG, ®); + if (err != UC_ERR_OK) { + throwUnicornException(env, err); + return 0; + } + return reg.val; +} + +/* + * Class: unicorn_Unicorn + * Method: _reg_write_arm_cp + * Signature: (JIIIIIIIIJ)V + */ +JNIEXPORT void JNICALL Java_unicorn_Unicorn__1reg_1write_1arm_1cp( + JNIEnv *env, jclass clazz, jlong ptr, jint isContext, jint cp, jint is64, + jint sec, jint crn, jint crm, jint opc1, jint opc2, jlong value) +{ + uc_arm_cp_reg reg = {0}; + reg.cp = cp; + reg.is64 = is64; + reg.sec = sec; + reg.crn = crn; + reg.crm = crm; + reg.opc1 = opc1; + reg.opc2 = opc2; + reg.val = value; + uc_err err = generic_reg_write(ptr, isContext, UC_ARM_REG_CP_REG, ®); + if (err != UC_ERR_OK) { + throwUnicornException(env, err); + return; + } +} + +/* + * Class: unicorn_Unicorn + * Method: _reg_read_arm64_cp + * Signature: (JIIIIII)J + */ +JNIEXPORT jlong JNICALL Java_unicorn_Unicorn__1reg_1read_1arm64_1cp( + JNIEnv *env, jclass clazz, jlong ptr, jint isContext, jint crn, jint crm, + jint op0, jint op1, jint op2) +{ + uc_arm64_cp_reg reg = {0}; + reg.crn = crn; + reg.crm = crm; + reg.op0 = op0; + reg.op1 = op1; + reg.op2 = op2; + uc_err err = generic_reg_read(ptr, isContext, UC_ARM64_REG_CP_REG, ®); + if (err != UC_ERR_OK) { + throwUnicornException(env, err); + return 0; + } + return reg.val; +} + +/* + * Class: unicorn_Unicorn + * Method: _reg_write_arm64_cp + * Signature: (JIIIIIIJ)V + */ +JNIEXPORT void JNICALL Java_unicorn_Unicorn__1reg_1write_1arm64_1cp( + JNIEnv *env, jclass clazz, jlong ptr, jint isContext, jint crn, jint crm, + jint op0, jint op1, jint op2, jlong value) +{ + uc_arm64_cp_reg reg = {0}; + reg.crn = crn; + reg.crm = crm; + reg.op0 = op0; + reg.op1 = op1; + reg.op2 = op2; + reg.val = value; + uc_err err = generic_reg_write(ptr, isContext, UC_ARM64_REG_CP_REG, ®); + if (err != UC_ERR_OK) { + throwUnicornException(env, err); + return; + } +} + +/* + * Class: unicorn_Unicorn + * Method: _mem_read + * Signature: (JJ[B)V + */ +JNIEXPORT void JNICALL Java_unicorn_Unicorn__1mem_1read(JNIEnv *env, + jclass clazz, jlong uc, + jlong address, + jbyteArray dest) +{ + jsize size = (*env)->GetArrayLength(env, dest); + jbyte *arr = (*env)->GetByteArrayElements(env, dest, NULL); + uc_err err = uc_mem_read((uc_engine *)uc, address, arr, size); + (*env)->ReleaseByteArrayElements(env, dest, arr, 0); + if (err != UC_ERR_OK) { + throwUnicornException(env, err); + return; + } +} + +/* + * Class: unicorn_Unicorn + * Method: _mem_write + * Signature: (JJ[B)V + */ +JNIEXPORT void JNICALL Java_unicorn_Unicorn__1mem_1write(JNIEnv *env, + jclass clazz, jlong uc, + jlong address, + jbyteArray src) +{ + jsize size = (*env)->GetArrayLength(env, src); + jbyte *arr = (*env)->GetByteArrayElements(env, src, NULL); + uc_err err = uc_mem_write((uc_engine *)uc, address, arr, size); + (*env)->ReleaseByteArrayElements(env, src, arr, JNI_ABORT); + if (err != UC_ERR_OK) { + throwUnicornException(env, err); + return; + } +} + +/* + * Class: unicorn_Unicorn + * Method: _version * Signature: ()I */ -JNIEXPORT jint JNICALL Java_unicorn_Unicorn_version(JNIEnv *env, jclass clz) +JNIEXPORT jint JNICALL Java_unicorn_Unicorn__1version(JNIEnv *env, jclass clazz) { return (jint)uc_version(NULL, NULL); } /* * Class: unicorn_Unicorn - * Method: arch_supported + * Method: _arch_supported * Signature: (I)Z */ -JNIEXPORT jboolean JNICALL Java_unicorn_Unicorn_arch_1supported(JNIEnv *env, - jclass clz, - jint arch) +JNIEXPORT jboolean JNICALL Java_unicorn_Unicorn__1arch_1supported(JNIEnv *env, + jclass clazz, + jint arch) { return (jboolean)(uc_arch_supported((uc_arch)arch) != 0); } /* * Class: unicorn_Unicorn - * Method: _close - * Signature: ()V - */ -JNIEXPORT void JNICALL Java_unicorn_Unicorn__1close(JNIEnv *env, jobject self) -{ - uc_engine *eng = getEngine(env, self); - uc_err err = uc_close(eng); - if (err != UC_ERR_OK) { - throwException(env, err); - } - // We also need to ReleaseByteArrayElements for any regions that - // were mapped with uc_mem_map_ptr -} - -/* - * Class: unicorn_Unicorn - * Method: query - * Signature: (I)I - */ -JNIEXPORT jint JNICALL Java_unicorn_Unicorn_query(JNIEnv *env, jobject self, - jint type) -{ - uc_engine *eng = getEngine(env, self); - size_t result; - uc_err err = uc_query(eng, type, &result); - if (err != UC_ERR_OK) { - throwException(env, err); - } - return (jint)result; -} - -/* - * Class: unicorn_Unicorn - * Method: errno - * Signature: ()I - */ -JNIEXPORT jint JNICALL Java_unicorn_Unicorn_errno(JNIEnv *env, jobject self) -{ - uc_engine *eng = getEngine(env, self); - return (jint)uc_errno(eng); -} - -/* - * 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) -{ - uc_engine *eng = getEngine(env, self); - jbyte *array = (*env)->GetByteArrayElements(env, value, NULL); - uc_err err = uc_reg_write(eng, (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) -{ - uc_engine *eng = getEngine(env, self); - jbyteArray regval = (*env)->NewByteArray(env, (jsize)regsz); - jbyte *array = (*env)->GetByteArrayElements(env, regval, NULL); - uc_err err = uc_reg_read(eng, (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) -{ - - uc_engine *eng = getEngine(env, self); - jbyte *array = (*env)->GetByteArrayElements(env, bytes, NULL); - jsize size = (*env)->GetArrayLength(env, bytes); - uc_err err = uc_mem_write(eng, (uint64_t)address, array, (size_t)size); - - 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) -{ - uc_engine *eng = getEngine(env, self); - - jbyteArray bytes = (*env)->NewByteArray(env, (jsize)size); - jbyte *array = (*env)->GetByteArrayElements(env, bytes, NULL); - uc_err err = uc_mem_read(eng, (uint64_t)address, array, (size_t)size); - 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) -{ - uc_engine *eng = getEngine(env, self); - - uc_err err = uc_emu_start(eng, (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) -{ - uc_engine *eng = getEngine(env, self); - - uc_err err = uc_emu_stop(eng); - if (err != UC_ERR_OK) { - throwException(env, err); - } -} - -/* - * Class: unicorn_Unicorn - * Method: registerHook + * Method: _query * Signature: (JI)J */ -JNIEXPORT jlong JNICALL Java_unicorn_Unicorn_registerHook__JI(JNIEnv *env, - jclass clz, - jlong eng, - jint type) +JNIEXPORT jlong JNICALL Java_unicorn_Unicorn__1query(JNIEnv *env, jclass clazz, + jlong uc, jint type) { - uc_hook hh = 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"); + size_t result; + uc_err err = uc_query((uc_engine *)uc, type, &result); + if (err != UC_ERR_OK) { + throwUnicornException(env, err); + return 0; + } + return result; +} + +/* + * Class: unicorn_Unicorn + * Method: _errno + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_unicorn_Unicorn__1errno(JNIEnv *env, jclass clazz, + jlong uc) +{ + return uc_errno((uc_engine *)uc); +} + +/* + * Class: unicorn_Unicorn + * Method: _strerror + * Signature: (I)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_unicorn_Unicorn__1strerror(JNIEnv *env, + jclass clazz, + jint code) +{ + const char *err = uc_strerror((int)code); + return (*env)->NewStringUTF(env, err); +} + +static void deleteHookWrapper(JNIEnv *env, struct hook_wrapper *hh) +{ + if (hh) { + if (hh->unicorn) + (*env)->DeleteGlobalRef(env, hh->unicorn); + if (hh->hook_obj) + (*env)->DeleteGlobalRef(env, hh->hook_obj); + if (hh->user_data) + (*env)->DeleteGlobalRef(env, hh->user_data); + free(hh); + } +} + +static struct hook_wrapper *makeHookWrapper(JNIEnv *env, jobject self, + jobject callback, jobject user_data, + const char *hook_name, + const char *hook_sig) +{ + struct hook_wrapper *hh = calloc(1, sizeof(struct hook_wrapper)); + if (!hh) { + throwOutOfMemoryError(env, "Unable to allocate hook_wrapper"); + return NULL; + } + + hh->unicorn = (*env)->NewGlobalRef(env, self); + if (!hh->unicorn) { + deleteHookWrapper(env, hh); + return NULL; + } + + hh->hook_obj = (*env)->NewGlobalRef(env, callback); + if (!hh->hook_obj) { + deleteHookWrapper(env, hh); + return NULL; + } + + jclass clazz = (*env)->GetObjectClass(env, callback); + if (!clazz) { + deleteHookWrapper(env, hh); + return NULL; + } + + hh->hook_meth = (*env)->GetMethodID(env, clazz, hook_name, hook_sig); + if (!hh->hook_meth) { + deleteHookWrapper(env, hh); + return NULL; + } + + if (user_data) { + hh->user_data = (*env)->NewGlobalRef(env, user_data); + if (!hh->user_data) { + deleteHookWrapper(env, hh); + return NULL; } - err = uc_hook_add((uc_engine *)eng, &hh, (uc_hook_type)type, - cb_hookintr, env, 1, 0); - break; - case UC_HOOK_MEM_FETCH_UNMAPPED: // Hook for all invalid memory access - // events - case UC_HOOK_MEM_READ_UNMAPPED: // Hook for all invalid memory access events - case UC_HOOK_MEM_WRITE_UNMAPPED: // Hook for all invalid memory access - // events - case UC_HOOK_MEM_FETCH_PROT: // Hook for all invalid memory access events - case UC_HOOK_MEM_READ_PROT: // Hook for all invalid memory access events - case UC_HOOK_MEM_WRITE_PROT: // Hook for all invalid memory access events - if (invokeEventMemCallbacks == 0) { - invokeEventMemCallbacks = (*env)->GetStaticMethodID( - env, clz, "invokeEventMemCallbacks", "(JIJIJ)Z"); - } - err = uc_hook_add((uc_engine *)eng, &hh, (uc_hook_type)type, - cb_eventmem, env, 1, 0); - break; + } + + return hh; +} + +/* + * Class: unicorn_Unicorn + * Method: _hook_add + * Signature: (JILunicorn/Hook;Ljava/lang/Object;JJ)J + */ +JNIEXPORT jlong JNICALL +Java_unicorn_Unicorn__1hook_1add__JILunicorn_Hook_2Ljava_lang_Object_2JJ( + JNIEnv *env, jobject self, jlong uc, jint type, jobject callback, + jobject user_data, jlong begin, jlong end) +{ + const char *hook_sig; + void *hook_callback; + + if (type == UC_HOOK_INTR) { + hook_sig = sig_InterruptHook; + hook_callback = cb_hookintr; + } else if (type == UC_HOOK_CODE || type == UC_HOOK_BLOCK) { + hook_sig = sig_CodeHook; // also BlockHook + hook_callback = cb_hookcode; + } else if ((type & UC_HOOK_MEM_INVALID) && !(type & ~UC_HOOK_MEM_INVALID)) { + hook_sig = sig_EventMemHook; + hook_callback = cb_eventmem; + } else if ((type & UC_HOOK_MEM_VALID) && !(type & ~UC_HOOK_MEM_VALID)) { + hook_sig = sig_MemHook; + hook_callback = cb_hookmem; + } else if (type == UC_HOOK_INSN_INVALID) { + hook_sig = sig_InvalidInstructionHook; + hook_callback = cb_hookinsn_invalid; + } else if (type == UC_HOOK_EDGE_GENERATED) { + hook_sig = sig_EdgeGeneratedHook; + hook_callback = cb_edge_gen; + } else if (type == UC_HOOK_TLB_FILL) { + hook_sig = sig_TlbFillHook; + hook_callback = cb_tlbevent; + } else { + throwUnicornException(env, UC_ERR_HOOK); + return 0; + } + + struct hook_wrapper *hh = + makeHookWrapper(env, self, callback, user_data, "hook", hook_sig); + uc_err err = uc_hook_add((uc_engine *)uc, &hh->uc_hh, type, hook_callback, + hh, begin, end); + if (err != UC_ERR_OK) { + throwUnicornException(env, err); + deleteHookWrapper(env, hh); + return 0; } return (jlong)hh; } /* * Class: unicorn_Unicorn - * Method: registerHook - * Signature: (JII)J + * Method: _hook_add + * Signature: (JILunicorn/Hook;Ljava/lang/Object;JJI)J */ -JNIEXPORT jlong JNICALL Java_unicorn_Unicorn_registerHook__JII( - JNIEnv *env, jclass clz, jlong eng, jint type, jint arg1) +JNIEXPORT jlong JNICALL +Java_unicorn_Unicorn__1hook_1add__JILunicorn_Hook_2Ljava_lang_Object_2JJI( + JNIEnv *env, jobject self, jlong uc, jint type, jobject callback, + jobject user_data, jlong begin, jlong end, jint arg) { - uc_hook hh = 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((uc_engine *)eng, &hh, (uc_hook_type)type, - cb_insn_out, env, 1, 0, arg1); + const char *hook_sig; + void *hook_callback; + + if (type == UC_HOOK_INSN) { + switch (arg) { case UC_X86_INS_IN: - if (invokeInCallbacks == 0) { - invokeInCallbacks = (*env)->GetStaticMethodID( - env, clz, "invokeInCallbacks", "(JII)I"); - } - err = uc_hook_add((uc_engine *)eng, &hh, (uc_hook_type)type, - cb_insn_in, env, 1, 0, arg1); - case UC_X86_INS_SYSENTER: + hook_sig = sig_InHook; + hook_callback = cb_insn_in; + break; + case UC_X86_INS_OUT: + hook_sig = sig_OutHook; + hook_callback = cb_insn_out; + break; case UC_X86_INS_SYSCALL: - if (invokeSyscallCallbacks == 0) { - invokeSyscallCallbacks = (*env)->GetStaticMethodID( - env, clz, "invokeSyscallCallbacks", "(J)V"); - } - err = uc_hook_add((uc_engine *)eng, &hh, (uc_hook_type)type, - cb_insn_syscall, env, 1, 0, arg1); + case UC_X86_INS_SYSENTER: + hook_sig = sig_SyscallHook; + hook_callback = cb_insn_syscall; + break; + case UC_X86_INS_CPUID: + hook_sig = sig_CpuidHook; + hook_callback = cb_insn_cpuid; + break; + case UC_ARM64_INS_MRS: + case UC_ARM64_INS_MSR: + case UC_ARM64_INS_SYS: + case UC_ARM64_INS_SYSL: + hook_sig = sig_Arm64SysHook; + hook_callback = cb_insn_sys; + break; + default: + throwUnicornException(env, UC_ERR_INSN_INVALID); + return 0; } - break; + } else { + throwUnicornException(env, UC_ERR_HOOK); + return 0; + } + + struct hook_wrapper *hh = + makeHookWrapper(env, self, callback, user_data, "hook", hook_sig); + uc_err err = uc_hook_add((uc_engine *)uc, &hh->uc_hh, type, hook_callback, + hh, begin, end, arg); + if (err != UC_ERR_OK) { + throwUnicornException(env, err); + deleteHookWrapper(env, hh); + return 0; } return (jlong)hh; } /* * Class: unicorn_Unicorn - * Method: registerHook - * Signature: (JIJJ)J + * Method: _hook_add + * Signature: (JILunicorn/Hook;Ljava/lang/Object;JJII)J */ -JNIEXPORT jlong JNICALL Java_unicorn_Unicorn_registerHook__JIJJ( - JNIEnv *env, jclass clz, jlong eng, jint type, jlong arg1, jlong arg2) +JNIEXPORT jlong JNICALL +Java_unicorn_Unicorn__1hook_1add__JILunicorn_Hook_2Ljava_lang_Object_2JJII( + JNIEnv *env, jobject self, jlong uc, jint type, jobject callback, + jobject user_data, jlong begin, jlong end, jint arg1, jint arg2) { - uc_hook hh = 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((uc_engine *)eng, &hh, (uc_hook_type)type, - cb_hookcode, env, 1, 0, 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((uc_engine *)eng, &hh, (uc_hook_type)type, - cb_hookblock, env, 1, 0, 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((uc_engine *)eng, &hh, (uc_hook_type)type, cb_hookmem, - env, 1, 0, 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((uc_engine *)eng, &hh, (uc_hook_type)type, cb_hookmem, - env, 1, 0, arg1, arg2); - break; + const char *hook_sig; + void *hook_callback; + + if (type == UC_HOOK_TCG_OPCODE) { + hook_sig = sig_TcgOpcodeHook; + hook_callback = cb_tcg_op_2; + } else { + throwUnicornException(env, UC_ERR_HOOK); + return 0; + } + + struct hook_wrapper *hh = + makeHookWrapper(env, self, callback, user_data, "hook", hook_sig); + uc_err err = uc_hook_add((uc_engine *)uc, &hh->uc_hh, type, hook_callback, + hh, begin, end, arg1, arg2); + if (err != UC_ERR_OK) { + throwUnicornException(env, err); + deleteHookWrapper(env, hh); + return 0; } return (jlong)hh; } /* * Class: unicorn_Unicorn - * Method: hook_del - * Signature: (J)V - */ -JNIEXPORT void JNICALL Java_unicorn_Unicorn_hook_1del(JNIEnv *env, jobject self, - jlong hh) -{ - uc_engine *eng = getEngine(env, self); - - //**** TODO remove hook from any internal hook tables as well - - uc_err err = uc_hook_del(eng, (uc_hook)hh); - if (err != UC_ERR_OK) { - throwException(env, err); - } -} - -/* - * Class: unicorn_Unicorn - * Method: mem_map - * Signature: (JJI)V - */ -JNIEXPORT void JNICALL Java_unicorn_Unicorn_mem_1map(JNIEnv *env, jobject self, - jlong address, jlong size, - jint perms) -{ - uc_engine *eng = getEngine(env, self); - - uc_err err = - uc_mem_map(eng, (uint64_t)address, (size_t)size, (uint32_t)perms); - if (err != UC_ERR_OK) { - throwException(env, err); - } -} - -/* - * Class: unicorn_Unicorn - * Method: mem_map_ptr - * Signature: (JJI[B)V - */ -JNIEXPORT void JNICALL -Java_unicorn_Unicorn_mem_1map_1ptr(JNIEnv *env, jobject self, jlong address, - jlong size, jint perms, jbyteArray block) -{ - uc_engine *eng = getEngine(env, self); - jbyte *array = (*env)->GetByteArrayElements(env, block, NULL); - uc_err err = uc_mem_map_ptr(eng, (uint64_t)address, (size_t)size, - (uint32_t)perms, (void *)array); - if (err != UC_ERR_OK) { - throwException(env, err); - } - // Need to track address/block/array so that we can ReleaseByteArrayElements - // when the block gets unmapped or when uc_close gets called - //(*env)->ReleaseByteArrayElements(env, block, array, JNI_ABORT); -} - -/* - * Class: unicorn_Unicorn - * Method: mem_unmap + * Method: _hook_del * Signature: (JJ)V */ -JNIEXPORT void JNICALL Java_unicorn_Unicorn_mem_1unmap(JNIEnv *env, - jobject self, - jlong address, - jlong size) +JNIEXPORT void JNICALL Java_unicorn_Unicorn__1hook_1del(JNIEnv *env, + jclass clazz, jlong uc, + jlong hh) { - uc_engine *eng = getEngine(env, self); - - uc_err err = uc_mem_unmap(eng, (uint64_t)address, (size_t)size); - if (err != UC_ERR_OK) { - throwException(env, err); + struct hook_wrapper *h = (struct hook_wrapper *)hh; + uc_hook_del((uc_engine *)uc, h->uc_hh); + if (h->unicorn) { + (*env)->DeleteGlobalRef(env, h->unicorn); + h->unicorn = NULL; + } + if (h->hook_obj) { + (*env)->DeleteGlobalRef(env, h->hook_obj); + h->hook_obj = NULL; + } + if (h->user_data) { + (*env)->DeleteGlobalRef(env, h->user_data); + h->user_data = NULL; } - - // If a region was mapped using uc_mem_map_ptr, we also need to - // ReleaseByteArrayElements for that region } /* * Class: unicorn_Unicorn - * Method: mem_protect - * Signature: (JJI)V + * Method: _hookwrapper_free + * Signature: (J)V */ -JNIEXPORT void JNICALL Java_unicorn_Unicorn_mem_1protect(JNIEnv *env, - jobject self, - jlong address, - jlong size, jint perms) +JNIEXPORT void JNICALL Java_unicorn_Unicorn__1hookwrapper_1free(JNIEnv *env, + jclass clazz, + jlong hh) { - uc_engine *eng = getEngine(env, self); + deleteHookWrapper(env, (struct hook_wrapper *)hh); +} + +/* + * Class: unicorn_Unicorn + * Method: _mmio_map + * Signature: + * (JJJLunicorn/MmioReadHandler;Ljava/lang/Object;Lunicorn/MmioWriteHandler;Ljava/lang/Object;)[J + */ +JNIEXPORT jlongArray JNICALL Java_unicorn_Unicorn__1mmio_1map( + JNIEnv *env, jobject self, jlong uc, jlong address, jlong size, + jobject read_cb, jobject user_data_read, jobject write_cb, + jobject user_data_write) +{ + struct hook_wrapper *hooks[2] = {0}; + + if (read_cb) { + hooks[0] = makeHookWrapper(env, self, read_cb, user_data_read, "read", + sig_MmioReadHandler); + if (!hooks[0]) { + goto fail; + } + } + + if (write_cb) { + hooks[1] = makeHookWrapper(env, self, write_cb, user_data_write, + "write", sig_MmioWriteHandler); + if (!hooks[1]) { + goto fail; + } + } + + jlong hooksLong[2]; + size_t hooksCount = 0; + if (hooks[0]) + hooksLong[hooksCount++] = (jlong)hooks[0]; + if (hooks[1]) + hooksLong[hooksCount++] = (jlong)hooks[1]; + + jlongArray result = (*env)->NewLongArray(env, hooksCount); + if (result == NULL) { + goto fail; + } + (*env)->SetLongArrayRegion(env, result, 0, hooksCount, hooksLong); + + uc_err err = uc_mmio_map((uc_engine *)uc, address, size, + (hooks[0] ? cb_mmio_read : NULL), hooks[0], + (hooks[1] ? cb_mmio_write : NULL), hooks[1]); + if (err != UC_ERR_OK) { + throwUnicornException(env, err); + goto fail; + } + return result; +fail: + deleteHookWrapper(env, hooks[0]); + deleteHookWrapper(env, hooks[1]); + return NULL; +} + +/* + * Class: unicorn_Unicorn + * Method: _mem_map + * Signature: (JJJI)V + */ +JNIEXPORT void JNICALL Java_unicorn_Unicorn__1mem_1map(JNIEnv *env, + jclass clazz, jlong uc, + jlong address, + jlong size, jint perms) +{ + uc_err err = uc_mem_map((uc_engine *)uc, address, size, perms); + if (err != UC_ERR_OK) { + throwUnicornException(env, err); + return; + } +} + +/* + * Class: unicorn_Unicorn + * Method: _mem_map_ptr + * Signature: (JJLjava/nio/Buffer;I)V + */ +JNIEXPORT void JNICALL Java_unicorn_Unicorn__1mem_1map_1ptr( + JNIEnv *env, jclass clazz, jlong uc, jlong address, jobject buf, jint perms) +{ + jlong size = (*env)->GetDirectBufferCapacity(env, buf); + void *host_address = (*env)->GetDirectBufferAddress(env, buf); + if (size < 0 || host_address == NULL) { + throwCustomUnicornException(env, + "mem_map_ptr requires a direct buffer"); + return; + } uc_err err = - uc_mem_protect(eng, (uint64_t)address, (size_t)size, (uint32_t)perms); + uc_mem_map_ptr((uc_engine *)uc, address, size, perms, host_address); if (err != UC_ERR_OK) { - throwException(env, err); + throwUnicornException(env, err); + return; } } /* * Class: unicorn_Unicorn - * Method: mem_regions - * Signature: ()[Lunicorn/MemRegion; + * Method: _mem_unmap + * Signature: (JJJ)V */ -JNIEXPORT jobjectArray JNICALL Java_unicorn_Unicorn_mem_1regions(JNIEnv *env, - jobject self) +JNIEXPORT void JNICALL Java_unicorn_Unicorn__1mem_1unmap(JNIEnv *env, + jclass clazz, jlong uc, + jlong address, + jlong size) { - uc_engine *eng = getEngine(env, self); + uc_err err = uc_mem_unmap((uc_engine *)uc, address, size); + if (err != UC_ERR_OK) { + throwUnicornException(env, err); + return; + } +} + +/* + * Class: unicorn_Unicorn + * Method: _mem_protect + * Signature: (JJJI)V + */ +JNIEXPORT void JNICALL Java_unicorn_Unicorn__1mem_1protect( + JNIEnv *env, jclass clazz, jlong uc, jlong address, jlong size, jint perms) +{ + uc_err err = uc_mem_protect((uc_engine *)uc, address, size, perms); + if (err != UC_ERR_OK) { + throwUnicornException(env, err); + return; + } +} + +/* + * Class: unicorn_Unicorn + * Method: _mem_regions + * Signature: (J)[Lunicorn/MemRegion; + */ +JNIEXPORT jobjectArray JNICALL +Java_unicorn_Unicorn__1mem_1regions(JNIEnv *env, jclass uc_clazz, jlong uc) +{ + static jclass clazz; + if (!clazz) { + clazz = (*env)->FindClass(env, "unicorn/MemRegion"); + if (!clazz) + return NULL; + clazz = (*env)->NewGlobalRef(env, clazz); + if (!clazz) + return NULL; + } + + static jmethodID clazzInit; + if (!clazzInit) { + clazzInit = (*env)->GetMethodID(env, clazz, "", "(JJI)V"); + if (!clazzInit) + return NULL; + } uc_mem_region *regions = NULL; uint32_t count = 0; uint32_t i; - uc_err err = uc_mem_regions(eng, ®ions, &count); + uc_err err = uc_mem_regions((uc_engine *)uc, ®ions, &count); if (err != UC_ERR_OK) { - throwException(env, err); - } - jclass clz = (*env)->FindClass(env, "unicorn/MemRegion"); - if ((*env)->ExceptionCheck(env)) { + throwUnicornException(env, err); return NULL; } - jobjectArray result = (*env)->NewObjectArray(env, (jsize)count, clz, NULL); - jmethodID cons = (*env)->GetMethodID(env, clz, "", "(JJI)V"); + + jobjectArray result = + (*env)->NewObjectArray(env, (jsize)count, clazz, NULL); + if (!result) { + uc_free(regions); + return NULL; + } + for (i = 0; i < count; i++) { - jobject mr = (*env)->NewObject(env, clz, cons, regions[i].begin, - regions[i].end, regions[i].perms); + jobject mr = + (*env)->NewObject(env, clazz, clazzInit, (jlong)regions[i].begin, + (jlong)regions[i].end, (jint)regions[i].perms); + if (!mr) { + uc_free(regions); + return NULL; + } (*env)->SetObjectArrayElement(env, result, (jsize)i, mr); } uc_free(regions); @@ -823,79 +1262,362 @@ JNIEXPORT jobjectArray JNICALL Java_unicorn_Unicorn_mem_1regions(JNIEnv *env, /* * Class: unicorn_Unicorn - * Method: context_alloc - * Signature: ()J + * Method: _context_alloc + * Signature: (J)J */ -JNIEXPORT jlong JNICALL Java_unicorn_Unicorn_context_1alloc(JNIEnv *env, - jobject self) +JNIEXPORT jlong JNICALL Java_unicorn_Unicorn__1context_1alloc(JNIEnv *env, + jclass clazz, + jlong uc) { - uc_engine *eng = getEngine(env, self); uc_context *ctx; - uc_err err = uc_context_alloc(eng, &ctx); + uc_err err = uc_context_alloc((uc_engine *)uc, &ctx); if (err != UC_ERR_OK) { - throwException(env, err); + throwUnicornException(env, err); + return 0; } - return (jlong)(uint64_t)ctx; + return (jlong)ctx; } /* * Class: unicorn_Unicorn - * Method: free + * Method: _context_free * Signature: (J)V */ -JNIEXPORT void JNICALL Java_unicorn_Unicorn_free(JNIEnv *env, jobject self, - jlong ctx) +JNIEXPORT void JNICALL Java_unicorn_Unicorn__1context_1free(JNIEnv *env, + jclass clazz, + jlong ctx) { - uc_err err = uc_free((void *)ctx); + uc_err err = uc_context_free((uc_context *)ctx); if (err != UC_ERR_OK) { - throwException(env, err); + throwUnicornException(env, err); + return; } } /* * Class: unicorn_Unicorn - * Method: context_save + * Method: _context_save + * Signature: (JJ)V + */ +JNIEXPORT void JNICALL Java_unicorn_Unicorn__1context_1save(JNIEnv *env, + jclass clazz, + jlong uc, jlong ctx) +{ + uc_err err = uc_context_save((uc_engine *)uc, (uc_context *)ctx); + if (err != UC_ERR_OK) { + throwUnicornException(env, err); + return; + } +} + +/* + * Class: unicorn_Unicorn + * Method: _context_restore + * Signature: (JJ)V + */ +JNIEXPORT void JNICALL Java_unicorn_Unicorn__1context_1restore(JNIEnv *env, + jclass clazz, + jlong uc, + jlong ctx) +{ + uc_err err = uc_context_restore((uc_engine *)uc, (uc_context *)ctx); + if (err != UC_ERR_OK) { + throwUnicornException(env, err); + return; + } +} + +/* + * Class: unicorn_Unicorn + * Method: _ctl_get_mode + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_unicorn_Unicorn__1ctl_1get_1mode(JNIEnv *env, + jclass clazz, + jlong uc) +{ + int mode; + uc_err err = uc_ctl_get_mode((uc_engine *)uc, &mode); + if (err != UC_ERR_OK) { + throwUnicornException(env, err); + return 0; + } + return mode; +} + +/* + * Class: unicorn_Unicorn + * Method: _ctl_get_arch + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_unicorn_Unicorn__1ctl_1get_1arch(JNIEnv *env, + jclass clazz, + jlong uc) +{ + int arch; + uc_err err = uc_ctl_get_arch((uc_engine *)uc, &arch); + if (err != UC_ERR_OK) { + throwUnicornException(env, err); + return 0; + } + return arch; +} + +/* + * Class: unicorn_Unicorn + * Method: _ctl_get_timeout + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL Java_unicorn_Unicorn__1ctl_1get_1timeout(JNIEnv *env, + jclass clazz, + jlong uc) +{ + uint64_t timeout; + uc_err err = uc_ctl_get_timeout((uc_engine *)uc, &timeout); + if (err != UC_ERR_OK) { + throwUnicornException(env, err); + return 0; + } + return timeout; +} + +/* + * Class: unicorn_Unicorn + * Method: _ctl_get_page_size + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_unicorn_Unicorn__1ctl_1get_1page_1size(JNIEnv *env, + jclass clazz, + jlong uc) +{ + uint32_t page_size; + uc_err err = uc_ctl_get_page_size((uc_engine *)uc, &page_size); + if (err != UC_ERR_OK) { + throwUnicornException(env, err); + return 0; + } + return page_size; +} + +/* + * Class: unicorn_Unicorn + * Method: _ctl_set_page_size + * Signature: (JI)V + */ +JNIEXPORT void JNICALL Java_unicorn_Unicorn__1ctl_1set_1page_1size( + JNIEnv *env, jclass clazz, jlong uc, jint page_size) +{ + uc_err err = uc_ctl_set_page_size((uc_engine *)uc, (uint32_t)page_size); + if (err != UC_ERR_OK) { + throwUnicornException(env, err); + return; + } +} + +/* + * Class: unicorn_Unicorn + * Method: _ctl_set_use_exits + * Signature: (JZ)V + */ +JNIEXPORT void JNICALL Java_unicorn_Unicorn__1ctl_1set_1use_1exits( + JNIEnv *env, jclass clazz, jlong uc, jboolean value) +{ + uc_err err; + if (value) { + err = uc_ctl_exits_enable((uc_engine *)uc); + } else { + err = uc_ctl_exits_disable((uc_engine *)uc); + } + if (err != UC_ERR_OK) { + throwUnicornException(env, err); + return; + } +} + +/* + * Class: unicorn_Unicorn + * Method: _ctl_get_exits_cnt + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL +Java_unicorn_Unicorn__1ctl_1get_1exits_1cnt(JNIEnv *env, jclass clazz, jlong uc) +{ + size_t exits_cnt; + uc_err err = uc_ctl_get_exits_cnt((uc_engine *)uc, &exits_cnt); + if (err != UC_ERR_OK) { + throwUnicornException(env, err); + return 0; + } + return exits_cnt; +} + +/* + * Class: unicorn_Unicorn + * Method: _ctl_get_exits + * Signature: (J)[J + */ +JNIEXPORT jlongArray JNICALL +Java_unicorn_Unicorn__1ctl_1get_1exits(JNIEnv *env, jclass clazz, jlong uc) +{ + size_t exits_cnt; + uc_err err = uc_ctl_get_exits_cnt((uc_engine *)uc, &exits_cnt); + if (err != UC_ERR_OK) { + throwUnicornException(env, err); + return 0; + } + + jlongArray result = (*env)->NewLongArray(env, (jsize)exits_cnt); + if (!result) + return NULL; + + jlong *resultArr = (*env)->GetLongArrayElements(env, result, NULL); + if (!resultArr) + return NULL; + + err = uc_ctl_get_exits((uc_engine *)uc, (uint64_t *)resultArr, exits_cnt); + (*env)->ReleaseLongArrayElements(env, result, resultArr, 0); + if (err != UC_ERR_OK) { + throwUnicornException(env, err); + return 0; + } + return result; +} + +/* + * Class: unicorn_Unicorn + * Method: _ctl_set_exits + * Signature: (J[J)V + */ +JNIEXPORT void JNICALL Java_unicorn_Unicorn__1ctl_1set_1exits(JNIEnv *env, + jclass clazz, + jlong uc, + jlongArray exits) +{ + jsize count = (*env)->GetArrayLength(env, exits); + jlong *arr = (*env)->GetLongArrayElements(env, exits, NULL); + if (!arr) + return; + + uc_err err = + uc_ctl_set_exits((uc_engine *)uc, (uint64_t *)arr, (size_t)count); + (*env)->ReleaseLongArrayElements(env, exits, arr, JNI_ABORT); + if (err != UC_ERR_OK) { + throwUnicornException(env, err); + return; + } +} + +/* + * Class: unicorn_Unicorn + * Method: _ctl_get_cpu_model + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_unicorn_Unicorn__1ctl_1get_1cpu_1model(JNIEnv *env, + jclass clazz, + jlong uc) +{ + int cpu_model; + uc_err err = uc_ctl_get_cpu_model((uc_engine *)uc, &cpu_model); + if (err != UC_ERR_OK) { + throwUnicornException(env, err); + return 0; + } + return cpu_model; +} + +/* + * Class: unicorn_Unicorn + * Method: _ctl_set_cpu_model + * Signature: (JI)V + */ +JNIEXPORT void JNICALL Java_unicorn_Unicorn__1ctl_1set_1cpu_1model( + JNIEnv *env, jclass clazz, jlong uc, jint cpu_model) +{ + uc_err err = uc_ctl_set_cpu_model((uc_engine *)uc, (int)cpu_model); + if (err != UC_ERR_OK) { + throwUnicornException(env, err); + return; + } +} + +/* + * Class: unicorn_Unicorn + * Method: _ctl_request_cache + * Signature: (JJ)Lunicorn/TranslationBlock; + */ +JNIEXPORT jobject JNICALL Java_unicorn_Unicorn__1ctl_1request_1cache( + JNIEnv *env, jclass clazz, jlong uc, jlong address) +{ + uc_tb tb; + uc_err err = uc_ctl_request_cache((uc_engine *)uc, (uint64_t)address, &tb); + if (err != UC_ERR_OK) { + throwUnicornException(env, err); + return NULL; + } + return makeTranslationBlock(env, &tb); +} + +/* + * Class: unicorn_Unicorn + * Method: _ctl_remove_cache + * Signature: (JJJ)V + */ +JNIEXPORT void JNICALL Java_unicorn_Unicorn__1ctl_1remove_1cache( + JNIEnv *env, jclass clazz, jlong uc, jlong address, jlong end) +{ + uc_err err = + uc_ctl_remove_cache((uc_engine *)uc, (uint64_t)address, (uint64_t)end); + if (err != UC_ERR_OK) { + throwUnicornException(env, err); + return; + } +} + +/* + * Class: unicorn_Unicorn + * Method: _ctl_flush_tb * Signature: (J)V */ -JNIEXPORT void JNICALL Java_unicorn_Unicorn_context_1save(JNIEnv *env, - jobject self, - jlong ctx) +JNIEXPORT void JNICALL Java_unicorn_Unicorn__1ctl_1flush_1tb(JNIEnv *env, + jclass clazz, + jlong uc) { - uc_engine *eng = getEngine(env, self); - uc_err err = uc_context_save(eng, (uc_context *)ctx); + uc_err err = uc_ctl_flush_tb((uc_engine *)uc); if (err != UC_ERR_OK) { - throwException(env, err); + throwUnicornException(env, err); + return; } } /* * Class: unicorn_Unicorn - * Method: context_restore + * Method: _ctl_flush_tlb * Signature: (J)V */ -JNIEXPORT void JNICALL Java_unicorn_Unicorn_context_1restore(JNIEnv *env, - jobject self, - jlong ctx) +JNIEXPORT void JNICALL Java_unicorn_Unicorn__1ctl_1flush_1tlb(JNIEnv *env, + jclass clazz, + jlong uc) { - uc_engine *eng = getEngine(env, self); - uc_err err = uc_context_restore(eng, (uc_context *)ctx); + uc_err err = uc_ctl_flush_tlb((uc_engine *)uc); if (err != UC_ERR_OK) { - throwException(env, err); + throwUnicornException(env, err); + return; } } /* * Class: unicorn_Unicorn - * Method: ctl_set_cpu_model - * Signature: (I)V + * Method: _ctl_tlb_mode + * Signature: (JI)V */ -JNIEXPORT void JNICALL Java_unicorn_Unicorn_ctl_1set_1cpu_1model(JNIEnv *env, - jobject self, - jint cpu_model) +JNIEXPORT void JNICALL Java_unicorn_Unicorn__1ctl_1tlb_1mode(JNIEnv *env, + jclass clazz, + jlong uc, + jint mode) { - uc_engine *eng = getEngine(env, self); - uc_err err = uc_ctl_set_cpu_model(eng, cpu_model); + uc_err err = uc_ctl_tlb_mode((uc_engine *)uc, (int)mode); if (err != UC_ERR_OK) { - throwException(env, err); + throwUnicornException(env, err); + return; } } From 78de5844096694b0215c1b71ed6595e24ca97d0b Mon Sep 17 00:00:00 2001 From: Robert Xiao Date: Sun, 7 May 2023 01:01:58 -0700 Subject: [PATCH 06/25] Switch samples to use long instead of Long for registers --- .../java/samples/SampleNetworkAuditing.java | 18 +- bindings/java/samples/Sample_arm.java | 22 +-- bindings/java/samples/Sample_arm64.java | 10 +- bindings/java/samples/Sample_m68k.java | 92 +++++----- bindings/java/samples/Sample_mips.java | 12 +- bindings/java/samples/Sample_sparc.java | 10 +- bindings/java/samples/Sample_x86.java | 160 +++++++++--------- bindings/java/samples/Sample_x86_mmr.java | 4 +- bindings/java/samples/Shellcode.java | 28 +-- 9 files changed, 178 insertions(+), 178 deletions(-) diff --git a/bindings/java/samples/SampleNetworkAuditing.java b/bindings/java/samples/SampleNetworkAuditing.java index d41d4061..95e567fd 100644 --- a/bindings/java/samples/SampleNetworkAuditing.java +++ b/bindings/java/samples/SampleNetworkAuditing.java @@ -67,11 +67,11 @@ public class SampleNetworkAuditing { if (intno != 0x80) { return; } - Long eax = (Long) uc.reg_read(Unicorn.UC_X86_REG_EAX); - Long ebx = (Long) uc.reg_read(Unicorn.UC_X86_REG_EBX); - Long ecx = (Long) uc.reg_read(Unicorn.UC_X86_REG_ECX); - Long edx = (Long) uc.reg_read(Unicorn.UC_X86_REG_EDX); - Long eip = (Long) uc.reg_read(Unicorn.UC_X86_REG_EIP); + long eax = uc.reg_read(Unicorn.UC_X86_REG_EAX); + long ebx = uc.reg_read(Unicorn.UC_X86_REG_EBX); + long ecx = uc.reg_read(Unicorn.UC_X86_REG_ECX); + long edx = uc.reg_read(Unicorn.UC_X86_REG_EDX); + long eip = uc.reg_read(Unicorn.UC_X86_REG_EIP); // System.out.printf(">>> INTERRUPT %d\n", toInt(eax)); @@ -113,7 +113,7 @@ public class SampleNetworkAuditing { long mode = edx; String filename = read_string(uc, filename_addr); - Long dummy_fd = get_id(); + long dummy_fd = get_id(); uc.reg_write(Unicorn.UC_X86_REG_EAX, dummy_fd); String msg = String.format( @@ -133,8 +133,8 @@ public class SampleNetworkAuditing { System.out.printf(">>> SYS_DUP2 oldfd=%d newfd=%d\n", ebx, ecx); } else if (eax == 102) { // sys_socketcall // ref: http://www.skyfree.org/linux/kernel_network/socket.html - Long call = (Long) uc.reg_read(Unicorn.UC_X86_REG_EBX); - Long args = (Long) uc.reg_read(Unicorn.UC_X86_REG_ECX); + long call = uc.reg_read(Unicorn.UC_X86_REG_EBX); + long args = uc.reg_read(Unicorn.UC_X86_REG_ECX); // int sys_socketcall(int call, unsigned long *args) if (call == 1) { // sys_socket @@ -146,7 +146,7 @@ public class SampleNetworkAuditing { long protocol = toInt(uc.mem_read(args + SIZE_REG * 2, SIZE_REG)); - Long dummy_fd = get_id(); + long dummy_fd = get_id(); uc.reg_write(Unicorn.UC_X86_REG_EAX, dummy_fd); if (family == 2) { // AF_INET diff --git a/bindings/java/samples/Sample_arm.java b/bindings/java/samples/Sample_arm.java index a6f8e184..fc5b7dd1 100644 --- a/bindings/java/samples/Sample_arm.java +++ b/bindings/java/samples/Sample_arm.java @@ -45,10 +45,10 @@ public class Sample_arm { public static void test_arm() { - Long r0 = 0x1234L; // R0 register - Long r2 = 0x6789L; // R1 register - Long r3 = 0x3333L; // R2 register - Long r1; // R1 register + long r0 = 0x1234L; // R0 register + long r2 = 0x6789L; // R1 register + long r3 = 0x3333L; // R2 register + long r1; // R1 register System.out.print("Emulate ARM code\n"); @@ -79,17 +79,17 @@ public class Sample_arm { // now print out some registers System.out.print(">>> Emulation done. Below is the CPU context\n"); - r0 = (Long) u.reg_read(Unicorn.UC_ARM_REG_R0); - r1 = (Long) u.reg_read(Unicorn.UC_ARM_REG_R1); - System.out.print(String.format(">>> R0 = 0x%x\n", r0.intValue())); - System.out.print(String.format(">>> R1 = 0x%x\n", r1.intValue())); + r0 = u.reg_read(Unicorn.UC_ARM_REG_R0); + r1 = u.reg_read(Unicorn.UC_ARM_REG_R1); + System.out.print(String.format(">>> R0 = 0x%x\n", r0)); + System.out.print(String.format(">>> R1 = 0x%x\n", r1)); u.close(); } public static void test_thumb() { - Long sp = 0x1234L; // R0 register + long sp = 0x1234L; // R0 register System.out.print("Emulate THUMB code\n"); @@ -118,8 +118,8 @@ public class Sample_arm { // now print out some registers System.out.print(">>> Emulation done. Below is the CPU context\n"); - sp = (Long) u.reg_read(Unicorn.UC_ARM_REG_SP); - System.out.print(String.format(">>> SP = 0x%x\n", sp.intValue())); + sp = u.reg_read(Unicorn.UC_ARM_REG_SP); + System.out.print(String.format(">>> SP = 0x%x\n", sp)); u.close(); } diff --git a/bindings/java/samples/Sample_arm64.java b/bindings/java/samples/Sample_arm64.java index 5c137d6b..151bf58b 100644 --- a/bindings/java/samples/Sample_arm64.java +++ b/bindings/java/samples/Sample_arm64.java @@ -74,9 +74,9 @@ public class Sample_arm64 { public static void test_arm64() { - Long x11 = 0x1234L; // X11 register - Long x13 = 0x6789L; // X13 register - Long x15 = 0x3333L; // X15 register + long x11 = 0x1234L; // X11 register + long x13 = 0x6789L; // X13 register + long x15 = 0x3333L; // X15 register System.out.print("Emulate ARM64 code\n"); @@ -107,8 +107,8 @@ public class Sample_arm64 { // now print out some registers System.out.print(">>> Emulation done. Below is the CPU context\n"); - x11 = (Long) u.reg_read(Unicorn.UC_ARM64_REG_X11); - System.out.print(String.format(">>> X11 = 0x%x\n", x11.longValue())); + x11 = u.reg_read(Unicorn.UC_ARM64_REG_X11); + System.out.print(String.format(">>> X11 = 0x%x\n", x11)); u.close(); } diff --git a/bindings/java/samples/Sample_m68k.java b/bindings/java/samples/Sample_m68k.java index f9ffb19e..772b5fcd 100644 --- a/bindings/java/samples/Sample_m68k.java +++ b/bindings/java/samples/Sample_m68k.java @@ -73,26 +73,26 @@ public class Sample_m68k { } public static void test_m68k() { - Long d0 = 0x0000L; // d0 data register - Long d1 = 0x0000L; // d1 data register - Long d2 = 0x0000L; // d2 data register - Long d3 = 0x0000L; // d3 data register - Long d4 = 0x0000L; // d4 data register - Long d5 = 0x0000L; // d5 data register - Long d6 = 0x0000L; // d6 data register - Long d7 = 0x0000L; // d7 data register + long d0 = 0x0000L; // d0 data register + long d1 = 0x0000L; // d1 data register + long d2 = 0x0000L; // d2 data register + long d3 = 0x0000L; // d3 data register + long d4 = 0x0000L; // d4 data register + long d5 = 0x0000L; // d5 data register + long d6 = 0x0000L; // d6 data register + long d7 = 0x0000L; // d7 data register - Long a0 = 0x0000L; // a0 address register - Long a1 = 0x0000L; // a1 address register - Long a2 = 0x0000L; // a2 address register - Long a3 = 0x0000L; // a3 address register - Long a4 = 0x0000L; // a4 address register - Long a5 = 0x0000L; // a5 address register - Long a6 = 0x0000L; // a6 address register - Long a7 = 0x0000L; // a6 address register + long a0 = 0x0000L; // a0 address register + long a1 = 0x0000L; // a1 address register + long a2 = 0x0000L; // a2 address register + long a3 = 0x0000L; // a3 address register + long a4 = 0x0000L; // a4 address register + long a5 = 0x0000L; // a5 address register + long a6 = 0x0000L; // a6 address register + long a7 = 0x0000L; // a6 address register - Long pc = 0x0000L; // program counter - Long sr = 0x0000L; // status register + long pc = 0x0000L; // program counter + long sr = 0x0000L; // status register System.out.print("Emulate M68K code\n"); @@ -141,45 +141,45 @@ public class Sample_m68k { // now print out some registers System.out.print(">>> Emulation done. Below is the CPU context\n"); - d0 = (Long) u.reg_read(Unicorn.UC_M68K_REG_D0); - d1 = (Long) u.reg_read(Unicorn.UC_M68K_REG_D1); - d2 = (Long) u.reg_read(Unicorn.UC_M68K_REG_D2); - d3 = (Long) u.reg_read(Unicorn.UC_M68K_REG_D3); - d4 = (Long) u.reg_read(Unicorn.UC_M68K_REG_D4); - d5 = (Long) u.reg_read(Unicorn.UC_M68K_REG_D5); - d6 = (Long) u.reg_read(Unicorn.UC_M68K_REG_D6); - d7 = (Long) u.reg_read(Unicorn.UC_M68K_REG_D7); + d0 = u.reg_read(Unicorn.UC_M68K_REG_D0); + d1 = u.reg_read(Unicorn.UC_M68K_REG_D1); + d2 = u.reg_read(Unicorn.UC_M68K_REG_D2); + d3 = u.reg_read(Unicorn.UC_M68K_REG_D3); + d4 = u.reg_read(Unicorn.UC_M68K_REG_D4); + d5 = u.reg_read(Unicorn.UC_M68K_REG_D5); + d6 = u.reg_read(Unicorn.UC_M68K_REG_D6); + d7 = u.reg_read(Unicorn.UC_M68K_REG_D7); - a0 = (Long) u.reg_read(Unicorn.UC_M68K_REG_A0); - a1 = (Long) u.reg_read(Unicorn.UC_M68K_REG_A1); - a2 = (Long) u.reg_read(Unicorn.UC_M68K_REG_A2); - a3 = (Long) u.reg_read(Unicorn.UC_M68K_REG_A3); - a4 = (Long) u.reg_read(Unicorn.UC_M68K_REG_A4); - a5 = (Long) u.reg_read(Unicorn.UC_M68K_REG_A5); - a6 = (Long) u.reg_read(Unicorn.UC_M68K_REG_A6); - a7 = (Long) u.reg_read(Unicorn.UC_M68K_REG_A7); + a0 = u.reg_read(Unicorn.UC_M68K_REG_A0); + a1 = u.reg_read(Unicorn.UC_M68K_REG_A1); + a2 = u.reg_read(Unicorn.UC_M68K_REG_A2); + a3 = u.reg_read(Unicorn.UC_M68K_REG_A3); + a4 = u.reg_read(Unicorn.UC_M68K_REG_A4); + a5 = u.reg_read(Unicorn.UC_M68K_REG_A5); + a6 = u.reg_read(Unicorn.UC_M68K_REG_A6); + a7 = u.reg_read(Unicorn.UC_M68K_REG_A7); - pc = (Long) u.reg_read(Unicorn.UC_M68K_REG_PC); - sr = (Long) u.reg_read(Unicorn.UC_M68K_REG_SR); + pc = u.reg_read(Unicorn.UC_M68K_REG_PC); + sr = u.reg_read(Unicorn.UC_M68K_REG_SR); System.out.print(String.format(">>> A0 = 0x%x\t\t>>> D0 = 0x%x\n", - a0.intValue(), d0.intValue())); + a0, d0)); System.out.print(String.format(">>> A1 = 0x%x\t\t>>> D1 = 0x%x\n", - a1.intValue(), d1.intValue())); + a1, d1)); System.out.print(String.format(">>> A2 = 0x%x\t\t>>> D2 = 0x%x\n", - a2.intValue(), d2.intValue())); + a2, d2)); System.out.print(String.format(">>> A3 = 0x%x\t\t>>> D3 = 0x%x\n", - a3.intValue(), d3.intValue())); + a3, d3)); System.out.print(String.format(">>> A4 = 0x%x\t\t>>> D4 = 0x%x\n", - a4.intValue(), d4.intValue())); + a4, d4)); System.out.print(String.format(">>> A5 = 0x%x\t\t>>> D5 = 0x%x\n", - a5.intValue(), d5.intValue())); + a5, d5)); System.out.print(String.format(">>> A6 = 0x%x\t\t>>> D6 = 0x%x\n", - a6.intValue(), d6.intValue())); + a6, d6)); 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", pc.intValue())); - System.out.print(String.format(">>> SR = 0x%x\n", sr.intValue())); + a7, d7)); + System.out.print(String.format(">>> PC = 0x%x\n", pc)); + System.out.print(String.format(">>> SR = 0x%x\n", sr)); u.close(); } diff --git a/bindings/java/samples/Sample_mips.java b/bindings/java/samples/Sample_mips.java index 60f5abcd..03697f3e 100644 --- a/bindings/java/samples/Sample_mips.java +++ b/bindings/java/samples/Sample_mips.java @@ -75,7 +75,7 @@ public class Sample_mips { public static void test_mips_eb() { - Long r1 = 0x6789L; // R1 register + long r1 = 0x6789L; // R1 register System.out.print("Emulate MIPS code (big-endian)\n"); @@ -105,14 +105,14 @@ public class Sample_mips { // now print out some registers System.out.print(">>> Emulation done. Below is the CPU context\n"); - r1 = (Long) u.reg_read(Unicorn.UC_MIPS_REG_1); - System.out.print(String.format(">>> R1 = 0x%x\n", r1.intValue())); + r1 = u.reg_read(Unicorn.UC_MIPS_REG_1); + System.out.print(String.format(">>> R1 = 0x%x\n", r1)); u.close(); } public static void test_mips_el() { - Long r1 = 0x6789L; // R1 register + long r1 = 0x6789L; // R1 register System.out.print("===========================\n"); System.out.print("Emulate MIPS code (little-endian)\n"); @@ -143,8 +143,8 @@ public class Sample_mips { // now print out some registers System.out.print(">>> Emulation done. Below is the CPU context\n"); - r1 = (Long) u.reg_read(Unicorn.UC_MIPS_REG_1); - System.out.print(String.format(">>> R1 = 0x%x\n", r1.intValue())); + r1 = u.reg_read(Unicorn.UC_MIPS_REG_1); + System.out.print(String.format(">>> R1 = 0x%x\n", r1)); u.close(); } diff --git a/bindings/java/samples/Sample_sparc.java b/bindings/java/samples/Sample_sparc.java index 1ecbbd32..90058d2e 100644 --- a/bindings/java/samples/Sample_sparc.java +++ b/bindings/java/samples/Sample_sparc.java @@ -74,9 +74,9 @@ public class Sample_sparc { } public static void test_sparc() { - Long g1 = 0x1230L; // G1 register - Long g2 = 0x6789L; // G2 register - Long g3 = 0x5555L; // G3 register + long g1 = 0x1230L; // G1 register + long g2 = 0x6789L; // G2 register + long g3 = 0x5555L; // G3 register System.out.print("Emulate SPARC code\n"); @@ -108,8 +108,8 @@ public class Sample_sparc { // now print out some registers System.out.print(">>> Emulation done. Below is the CPU context\n"); - g3 = (Long) u.reg_read(Unicorn.UC_SPARC_REG_G3); - System.out.print(String.format(">>> G3 = 0x%x\n", g3.intValue())); + g3 = u.reg_read(Unicorn.UC_SPARC_REG_G3); + System.out.print(String.format(">>> G3 = 0x%x\n", g3)); u.close(); } diff --git a/bindings/java/samples/Sample_x86.java b/bindings/java/samples/Sample_x86.java index 6dea2849..75e6a3fc 100644 --- a/bindings/java/samples/Sample_x86.java +++ b/bindings/java/samples/Sample_x86.java @@ -94,8 +94,8 @@ public class Sample_x86 { ">>> Tracing instruction at 0x%x, instruction size = 0x%x\n", address, size); - Long eflags = (Long) u.reg_read(Unicorn.UC_X86_REG_EFLAGS); - System.out.printf(">>> --- EFLAGS is 0x%x\n", eflags.intValue()); + long eflags = u.reg_read(Unicorn.UC_X86_REG_EFLAGS); + System.out.printf(">>> --- EFLAGS is 0x%x\n", eflags); // Uncomment below code to stop the emulation using uc_emu_stop() // if (address == 0x1000009) @@ -120,11 +120,11 @@ public class Sample_x86 { // callback for tracing instruction private static class MyCode64Hook implements CodeHook { public void hook(Unicorn u, long address, int size, Object user_data) { - Long r_rip = (Long) u.reg_read(Unicorn.UC_X86_REG_RIP); + long r_rip = 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(">>> RIP is 0x%x\n", r_rip.longValue()); + System.out.printf(">>> RIP is 0x%x\n", r_rip); // Uncomment below code to stop the emulation using uc_emu_stop() // if (address == 0x1000009) @@ -155,11 +155,11 @@ public class Sample_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) { - Long r_eip = (Long) u.reg_read(Unicorn.UC_X86_REG_EIP); + long r_eip = u.reg_read(Unicorn.UC_X86_REG_EIP); System.out.printf( "--- reading from port 0x%x, size: %d, address: 0x%x\n", port, - size, r_eip.intValue()); + size, r_eip); switch (size) { case 1: @@ -180,34 +180,34 @@ public class Sample_x86 { private static class MyOutHook implements OutHook { public void hook(Unicorn u, int port, int size, int value, Object user) { - Long eip = (Long) u.reg_read(Unicorn.UC_X86_REG_EIP); - Long tmp = null; + long eip = u.reg_read(Unicorn.UC_X86_REG_EIP); + long tmp = 0; System.out.printf( "--- writing to port 0x%x, size: %d, value: 0x%x, address: 0x%x\n", - port, size, value, eip.intValue()); + port, size, value, eip); // confirm that value is indeed the value of AL/AX/EAX switch (size) { default: return; // should never reach this case 1: - tmp = (Long) u.reg_read(Unicorn.UC_X86_REG_AL); + tmp = u.reg_read(Unicorn.UC_X86_REG_AL); break; case 2: - tmp = (Long) u.reg_read(Unicorn.UC_X86_REG_AX); + tmp = u.reg_read(Unicorn.UC_X86_REG_AX); break; case 4: - tmp = (Long) u.reg_read(Unicorn.UC_X86_REG_EAX); + tmp = u.reg_read(Unicorn.UC_X86_REG_EAX); break; } - System.out.printf("--- register value = 0x%x\n", tmp.intValue()); + System.out.printf("--- register value = 0x%x\n", tmp); } } public static void test_i386() { - Long r_ecx = 0x1234L; // ECX register - Long r_edx = 0x7890L; // EDX register + long r_ecx = 0x1234L; // ECX register + long r_edx = 0x7890L; // EDX register System.out.print("Emulate i386 code\n"); @@ -254,10 +254,10 @@ public class Sample_x86 { // now print out some registers System.out.print(">>> Emulation done. Below is the CPU context\n"); - r_ecx = (Long) uc.reg_read(Unicorn.UC_X86_REG_ECX); - r_edx = (Long) uc.reg_read(Unicorn.UC_X86_REG_EDX); - System.out.printf(">>> ECX = 0x%x\n", r_ecx.intValue()); - System.out.printf(">>> EDX = 0x%x\n", r_edx.intValue()); + r_ecx = uc.reg_read(Unicorn.UC_X86_REG_ECX); + r_edx = uc.reg_read(Unicorn.UC_X86_REG_EDX); + System.out.printf(">>> ECX = 0x%x\n", r_ecx); + System.out.printf(">>> EDX = 0x%x\n", r_edx); // read from memory try { @@ -272,8 +272,8 @@ public class Sample_x86 { } public static void test_i386_inout() { - Long r_eax = 0x1234L; // ECX register - Long r_ecx = 0x6789L; // EDX register + long r_eax = 0x1234L; // ECX register + long r_ecx = 0x6789L; // EDX register System.out.print("===================================\n"); System.out.print("Emulate i386 code with IN/OUT instructions\n"); @@ -308,10 +308,10 @@ public class Sample_x86 { // now print out some registers System.out.print(">>> Emulation done. Below is the CPU context\n"); - r_eax = (Long) u.reg_read(Unicorn.UC_X86_REG_EAX); - r_ecx = (Long) u.reg_read(Unicorn.UC_X86_REG_ECX); - System.out.printf(">>> EAX = 0x%x\n", r_eax.intValue()); - System.out.printf(">>> ECX = 0x%x\n", r_ecx.intValue()); + r_eax = u.reg_read(Unicorn.UC_X86_REG_EAX); + r_ecx = u.reg_read(Unicorn.UC_X86_REG_ECX); + System.out.printf(">>> EAX = 0x%x\n", r_eax); + System.out.printf(">>> ECX = 0x%x\n", r_ecx); u.close(); } @@ -345,8 +345,8 @@ public class Sample_x86 { // emulate code that loop forever public static void test_i386_loop() { - Long r_ecx = 0x1234L; // ECX register - Long r_edx = 0x7890L; // EDX register + long r_ecx = 0x1234L; // ECX register + long r_edx = 0x7890L; // EDX register System.out.print("===================================\n"); System.out.print("Emulate i386 code that loop forever\n"); @@ -372,18 +372,18 @@ public class Sample_x86 { // now print out some registers System.out.print(">>> Emulation done. Below is the CPU context\n"); - r_ecx = (Long) u.reg_read(Unicorn.UC_X86_REG_ECX); - r_edx = (Long) u.reg_read(Unicorn.UC_X86_REG_EDX); - System.out.printf(">>> ECX = 0x%x\n", r_ecx.intValue()); - System.out.printf(">>> EDX = 0x%x\n", r_edx.intValue()); + r_ecx = u.reg_read(Unicorn.UC_X86_REG_ECX); + r_edx = u.reg_read(Unicorn.UC_X86_REG_EDX); + System.out.printf(">>> ECX = 0x%x\n", r_ecx); + System.out.printf(">>> EDX = 0x%x\n", r_edx); u.close(); } // emulate code that read invalid memory public static void test_i386_invalid_mem_read() { - Long r_ecx = 0x1234L; // ECX register - Long r_edx = 0x7890L; // EDX register + long r_ecx = 0x1234L; // ECX register + long r_edx = 0x7890L; // EDX register System.out.print("===================================\n"); System.out.print("Emulate i386 code that read from invalid memory\n"); @@ -420,18 +420,18 @@ public class Sample_x86 { // now print out some registers System.out.print(">>> Emulation done. Below is the CPU context\n"); - r_ecx = (Long) u.reg_read(Unicorn.UC_X86_REG_ECX); - r_edx = (Long) u.reg_read(Unicorn.UC_X86_REG_EDX); - System.out.printf(">>> ECX = 0x%x\n", r_ecx.intValue()); - System.out.printf(">>> EDX = 0x%x\n", r_edx.intValue()); + r_ecx = u.reg_read(Unicorn.UC_X86_REG_ECX); + r_edx = u.reg_read(Unicorn.UC_X86_REG_EDX); + System.out.printf(">>> ECX = 0x%x\n", r_ecx); + System.out.printf(">>> EDX = 0x%x\n", r_edx); u.close(); } // emulate code that read invalid memory public static void test_i386_invalid_mem_write() { - Long r_ecx = 0x1234L; // ECX register - Long r_edx = 0x7890L; // EDX register + long r_ecx = 0x1234L; // ECX register + long r_edx = 0x7890L; // EDX register System.out.print("===================================\n"); System.out.print("Emulate i386 code that write to invalid memory\n"); @@ -472,10 +472,10 @@ public class Sample_x86 { // now print out some registers System.out.print(">>> Emulation done. Below is the CPU context\n"); - r_ecx = (Long) u.reg_read(Unicorn.UC_X86_REG_ECX); - r_edx = (Long) u.reg_read(Unicorn.UC_X86_REG_EDX); - System.out.printf(">>> ECX = 0x%x\n", r_ecx.intValue()); - System.out.printf(">>> EDX = 0x%x\n", r_edx.intValue()); + r_ecx = u.reg_read(Unicorn.UC_X86_REG_ECX); + r_edx = u.reg_read(Unicorn.UC_X86_REG_EDX); + System.out.printf(">>> ECX = 0x%x\n", r_ecx); + System.out.printf(">>> EDX = 0x%x\n", r_edx); // read from memory byte tmp[] = u.mem_read(0xaaaaaaaa, 4); @@ -496,8 +496,8 @@ public class Sample_x86 { // emulate code that jump to invalid memory public static void test_i386_jump_invalid() { - Long r_ecx = 0x1234L; // ECX register - Long r_edx = 0x7890L; // EDX register + long r_ecx = 0x1234L; // ECX register + long r_edx = 0x7890L; // EDX register System.out.print("===================================\n"); System.out.print("Emulate i386 code that jumps to invalid memory\n"); @@ -533,10 +533,10 @@ public class Sample_x86 { // now print out some registers System.out.print(">>> Emulation done. Below is the CPU context\n"); - r_ecx = (Long) u.reg_read(Unicorn.UC_X86_REG_ECX); - r_edx = (Long) u.reg_read(Unicorn.UC_X86_REG_EDX); - System.out.printf(">>> ECX = 0x%x\n", r_ecx.intValue()); - System.out.printf(">>> EDX = 0x%x\n", r_edx.intValue()); + r_ecx = u.reg_read(Unicorn.UC_X86_REG_ECX); + r_edx = u.reg_read(Unicorn.UC_X86_REG_EDX); + System.out.printf(">>> ECX = 0x%x\n", r_ecx); + System.out.printf(">>> EDX = 0x%x\n", r_edx); u.close(); } @@ -607,43 +607,43 @@ public class Sample_x86 { // now print out some registers System.out.print(">>> Emulation done. Below is the CPU context\n"); - Long r_rax = (Long) u.reg_read(Unicorn.UC_X86_REG_RAX); - Long r_rbx = (Long) u.reg_read(Unicorn.UC_X86_REG_RBX); - Long r_rcx = (Long) u.reg_read(Unicorn.UC_X86_REG_RCX); - Long r_rdx = (Long) u.reg_read(Unicorn.UC_X86_REG_RDX); - Long r_rsi = (Long) u.reg_read(Unicorn.UC_X86_REG_RSI); - Long r_rdi = (Long) u.reg_read(Unicorn.UC_X86_REG_RDI); - Long r_r8 = (Long) u.reg_read(Unicorn.UC_X86_REG_R8); - Long r_r9 = (Long) u.reg_read(Unicorn.UC_X86_REG_R9); - Long r_r10 = (Long) u.reg_read(Unicorn.UC_X86_REG_R10); - Long r_r11 = (Long) u.reg_read(Unicorn.UC_X86_REG_R11); - Long r_r12 = (Long) u.reg_read(Unicorn.UC_X86_REG_R12); - Long r_r13 = (Long) u.reg_read(Unicorn.UC_X86_REG_R13); - Long r_r14 = (Long) u.reg_read(Unicorn.UC_X86_REG_R14); - Long r_r15 = (Long) u.reg_read(Unicorn.UC_X86_REG_R15); + long r_rax = u.reg_read(Unicorn.UC_X86_REG_RAX); + long r_rbx = u.reg_read(Unicorn.UC_X86_REG_RBX); + long r_rcx = u.reg_read(Unicorn.UC_X86_REG_RCX); + long r_rdx = u.reg_read(Unicorn.UC_X86_REG_RDX); + long r_rsi = u.reg_read(Unicorn.UC_X86_REG_RSI); + long r_rdi = u.reg_read(Unicorn.UC_X86_REG_RDI); + long r_r8 = u.reg_read(Unicorn.UC_X86_REG_R8); + long r_r9 = u.reg_read(Unicorn.UC_X86_REG_R9); + long r_r10 = u.reg_read(Unicorn.UC_X86_REG_R10); + long r_r11 = u.reg_read(Unicorn.UC_X86_REG_R11); + long r_r12 = u.reg_read(Unicorn.UC_X86_REG_R12); + long r_r13 = u.reg_read(Unicorn.UC_X86_REG_R13); + long r_r14 = u.reg_read(Unicorn.UC_X86_REG_R14); + long r_r15 = u.reg_read(Unicorn.UC_X86_REG_R15); - System.out.printf(">>> RAX = 0x%x\n", r_rax.longValue()); - System.out.printf(">>> RBX = 0x%x\n", r_rbx.longValue()); - System.out.printf(">>> RCX = 0x%x\n", r_rcx.longValue()); - System.out.printf(">>> RDX = 0x%x\n", r_rdx.longValue()); - System.out.printf(">>> RSI = 0x%x\n", r_rsi.longValue()); - System.out.printf(">>> RDI = 0x%x\n", r_rdi.longValue()); - System.out.printf(">>> R8 = 0x%x\n", r_r8.longValue()); - System.out.printf(">>> R9 = 0x%x\n", r_r9.longValue()); - System.out.printf(">>> R10 = 0x%x\n", r_r10.longValue()); - System.out.printf(">>> R11 = 0x%x\n", r_r11.longValue()); - System.out.printf(">>> R12 = 0x%x\n", r_r12.longValue()); - System.out.printf(">>> R13 = 0x%x\n", r_r13.longValue()); - System.out.printf(">>> R14 = 0x%x\n", r_r14.longValue()); - System.out.printf(">>> R15 = 0x%x\n", r_r15.longValue()); + System.out.printf(">>> RAX = 0x%x\n", r_rax); + System.out.printf(">>> RBX = 0x%x\n", r_rbx); + System.out.printf(">>> RCX = 0x%x\n", r_rcx); + System.out.printf(">>> RDX = 0x%x\n", r_rdx); + System.out.printf(">>> RSI = 0x%x\n", r_rsi); + System.out.printf(">>> RDI = 0x%x\n", r_rdi); + System.out.printf(">>> R8 = 0x%x\n", r_r8); + System.out.printf(">>> R9 = 0x%x\n", r_r9); + System.out.printf(">>> R10 = 0x%x\n", r_r10); + System.out.printf(">>> R11 = 0x%x\n", r_r11); + System.out.printf(">>> R12 = 0x%x\n", r_r12); + System.out.printf(">>> R13 = 0x%x\n", r_r13); + System.out.printf(">>> R14 = 0x%x\n", r_r14); + System.out.printf(">>> R15 = 0x%x\n", r_r15); u.close(); } public static void test_x86_16() { - Long eax = 7L; - Long ebx = 5L; - Long esi = 6L; + long eax = 7L; + long ebx = 5L; + long esi = 6L; System.out.print("Emulate x86 16-bit code\n"); diff --git a/bindings/java/samples/Sample_x86_mmr.java b/bindings/java/samples/Sample_x86_mmr.java index 41378d74..65cd4b76 100644 --- a/bindings/java/samples/Sample_x86_mmr.java +++ b/bindings/java/samples/Sample_x86_mmr.java @@ -46,7 +46,7 @@ public class Sample_x86_mmr { X86_MMR ldtr2; X86_MMR gdtr1 = new X86_MMR(0x6666666677777777L, 0x88888888, 0x99999999, (short) 0xaaaa); - X86_MMR gdtr2, gdtr3, gdtr4; + X86_MMR gdtr2; int eax; @@ -57,7 +57,7 @@ public class Sample_x86_mmr { uc.reg_write(Unicorn.UC_X86_REG_EAX, 0xddddddddL); // read the registers back out - eax = (int) ((Long) uc.reg_read(Unicorn.UC_X86_REG_EAX)).longValue(); + eax = (int) uc.reg_read(Unicorn.UC_X86_REG_EAX); ldtr2 = (X86_MMR) uc.reg_read(Unicorn.UC_X86_REG_LDTR, null); gdtr2 = (X86_MMR) uc.reg_read(Unicorn.UC_X86_REG_GDTR, null); diff --git a/bindings/java/samples/Shellcode.java b/bindings/java/samples/Shellcode.java index d0199052..e31dc3a2 100644 --- a/bindings/java/samples/Shellcode.java +++ b/bindings/java/samples/Shellcode.java @@ -67,9 +67,9 @@ public class Shellcode { "Tracing instruction at 0x%x, instruction size = 0x%x\n", address, size)); - Long r_eip = (Long) u.reg_read(Unicorn.UC_X86_REG_EIP); + long r_eip = u.reg_read(Unicorn.UC_X86_REG_EIP); System.out.print( - String.format("*** EIP = %x ***: ", r_eip.intValue())); + String.format("*** EIP = %x ***: ", r_eip)); size = Math.min(16, size); @@ -83,8 +83,8 @@ public class Shellcode { public static class MyInterruptHook implements InterruptHook { public void hook(Unicorn u, int intno, Object user) { - Long r_ecx; - Long r_edx; + long r_ecx; + long r_edx; int size; // only handle Linux syscall @@ -92,27 +92,27 @@ public class Shellcode { return; } - Long r_eax = (Long) u.reg_read(Unicorn.UC_X86_REG_EAX); - Long r_eip = (Long) u.reg_read(Unicorn.UC_X86_REG_EIP); + long r_eax = u.reg_read(Unicorn.UC_X86_REG_EAX); + long r_eip = u.reg_read(Unicorn.UC_X86_REG_EIP); - switch (r_eax.intValue()) { + switch ((int) r_eax) { default: System.out.print( String.format(">>> 0x%x: interrupt 0x%x, EAX = 0x%x\n", - r_eip.intValue(), intno, r_eax.intValue())); + 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.intValue(), intno)); + r_eip, intno)); u.emu_stop(); break; case 4: // sys_write // ECX = buffer address - r_ecx = (Long) u.reg_read(Unicorn.UC_X86_REG_ECX); + r_ecx = u.reg_read(Unicorn.UC_X86_REG_ECX); // EDX = buffer size - r_edx = (Long) u.reg_read(Unicorn.UC_X86_REG_EDX); + r_edx = u.reg_read(Unicorn.UC_X86_REG_EDX); // read the buffer in size = (int) Math.min(256, r_edx); @@ -120,15 +120,15 @@ public class Shellcode { 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.intValue(), intno, r_ecx.intValue(), - r_edx.intValue(), new String(buffer))); + r_eip, intno, r_ecx, + r_edx, new String(buffer))); break; } } } public static void test_i386() { - Long r_esp = ADDRESS + 0x200000L; // ESP register + long r_esp = ADDRESS + 0x200000L; // ESP register System.out.print("Emulate i386 code\n"); From b8bd25030e457a1d75196b7e50b552eaec7055e9 Mon Sep 17 00:00:00 2001 From: Robert Xiao Date: Tue, 9 May 2023 02:42:14 -0700 Subject: [PATCH 07/25] Javadoc updates --- bindings/java/unicorn/EdgeGeneratedHook.java | 9 +- .../java/unicorn/InvalidInstructionHook.java | 2 +- bindings/java/unicorn/Unicorn.java | 374 ++++++++++++------ 3 files changed, 266 insertions(+), 119 deletions(-) diff --git a/bindings/java/unicorn/EdgeGeneratedHook.java b/bindings/java/unicorn/EdgeGeneratedHook.java index 1564d752..9e2c5b3e 100644 --- a/bindings/java/unicorn/EdgeGeneratedHook.java +++ b/bindings/java/unicorn/EdgeGeneratedHook.java @@ -21,8 +21,15 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. package unicorn; -/** Callback for UC_HOOK_EDGE_GENERATED */ +/** Callback for {@code UC_HOOK_EDGE_GENERATED} */ public interface EdgeGeneratedHook extends Hook { + /** Called whenever a jump is made to a new (untranslated) basic block. + * + * @param u {@link Unicorn} instance firing this hook + * @param cur_tb newly translated block being entered + * @param prev_tb previous block being exited + * @param user user data provided when registering this hook + */ public void hook(Unicorn u, TranslationBlock cur_tb, TranslationBlock prev_tb, Object user); } diff --git a/bindings/java/unicorn/InvalidInstructionHook.java b/bindings/java/unicorn/InvalidInstructionHook.java index 1edb509a..8d54abce 100644 --- a/bindings/java/unicorn/InvalidInstructionHook.java +++ b/bindings/java/unicorn/InvalidInstructionHook.java @@ -21,7 +21,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. package unicorn; -/* Callback for {@code UC_HOOK_INSN_INVALID} */ +/** Callback for {@code UC_HOOK_INSN_INVALID} */ public interface InvalidInstructionHook extends Hook { /** Called when an invalid instruction is encountered. * diff --git a/bindings/java/unicorn/Unicorn.java b/bindings/java/unicorn/Unicorn.java index d28f3999..884a9190 100644 --- a/bindings/java/unicorn/Unicorn.java +++ b/bindings/java/unicorn/Unicorn.java @@ -28,6 +28,7 @@ import java.nio.ByteOrder; import java.util.Arrays; import java.util.Hashtable; +/** Unicorn is a lightweight multi-platform, multi-architecture CPU emulator framework. */ public class Unicorn implements UnicornConst, Arm64Const, ArmConst, M68kConst, MipsConst, PpcConst, RiscvConst, S390xConst, SparcConst, TriCoreConst, X86Const { @@ -58,42 +59,46 @@ public class Unicorn } /** - * Read register value. See {@link Unicorn#reg_read(int)}. + * Read register value from saved context. * * @param regid Register ID that is to be retrieved. This function only supports * integer registers at most 64 bits long. * @return value of the register. + * @see Unicorn#reg_read(int) */ public long reg_read(int regid) throws UnicornException { return do_reg_read_long(nativePtr, 1, arch, regid); } /** - * Read register value. See {@link Unicorn#reg_read(int, Object)}. + * Read register value from saved context. * * @param regid Register ID that is to be retrieved. * @param opt Options for this register, or null if no options are required. * @return value of the register - Long, BigInteger, or structure. + * @see Unicorn#reg_read(int, Object) */ public Object reg_read(int regid, Object opt) throws UnicornException { return do_reg_read_obj(nativePtr, 1, arch, regid, opt); } /** - * Write to register. See {@link Unicorn#reg_write(int, long)}. + * Write to register in saved context. * * @param regid Register ID that is to be modified. * @param value Object containing the new register value. + * @see Unicorn#reg_write(int, long) */ public void reg_write(int regid, long value) throws UnicornException { do_reg_write_long(nativePtr, 1, arch, regid, value); } /** - * Write to register. See {@link Unicorn#reg_write(int, Object)}. + * Write to register in saved context. * * @param regid Register ID that is to be modified. * @param value Object containing the new register value. + * @see Unicorn#reg_write(int, Object) */ public void reg_write(int regid, Object value) throws UnicornException { do_reg_write_obj(nativePtr, 1, arch, regid, value); @@ -108,9 +113,9 @@ public class Unicorn /** * Create a new Unicorn object * - * @param arch Architecture type (UC_ARCH_*) - * @param mode Hardware mode. This is combined of UC_MODE_* - * @see unicorn.UnicornConst + * @param arch Architecture type. One of the {@code UC_ARCH_*} constants. + * @param mode Hardware mode. Bitwise combination of {@code UC_MODE_*} constants. + * @see UnicornConst * */ public Unicorn(int arch, int mode) throws UnicornException { @@ -121,10 +126,10 @@ public class Unicorn } /** - * Close the underlying uc_engine* eng associated with this Unicorn object - * + * Close the C {@code uc_engine} associated with this Unicorn object, + * freeing all associated resources. After calling this method, the + * API will no longer be usable. */ - public void close() throws UnicornException { if (nativePtr != 0) { _close(nativePtr); @@ -133,8 +138,7 @@ public class Unicorn } /** - * Perform native cleanup tasks associated with a Unicorn object - * + * Automatically close the {@code uc_engine} upon GC finalization. */ @Override protected void finalize() { @@ -144,10 +148,9 @@ public class Unicorn /** * 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 would yield 0x0102 + * @return version number as {@code (major << 8 | minor)}, which encodes + * both major & minor versions. + * For example, Unicorn version 1.2 would yield 0x0102. */ public static int version() { return _version(); @@ -156,25 +159,26 @@ public class Unicorn /** * 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.UnicornConst + * @param arch Architecture type ({@code UC_ARCH_*} constant) + * @return {@code true} if this library supports the given arch. + * @see UnicornConst */ public static boolean arch_supported(int arch) { return _arch_supported(arch); } /** - * Emulate machine code in a specific duration of time. + * Emulate machine code for a specific length of time or number of + * instructions. * * @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. + * @param until Address where emulation stops (i.e. when this address is hit) + * @param timeout Duration to emulate the code for, in microseconds, or 0 to + * run indefinitely. + * @param count The maximum number of instructions to execute, or 0 to + * execute indefinitely. + * @throws UnicornException if an unhandled CPU exception or other error + * occurs during emulation. */ public void emu_start(long begin, long until, long timeout, long count) @@ -183,9 +187,11 @@ public class Unicorn } /** - * 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. + * Stop emulation (which was started by {@link #emu_start()}). + * + * This can be called from hook callbacks or from a separate thread. + * NOTE: for now, this will stop the execution only after the current + * basic block. */ public void emu_stop() throws UnicornException { _emu_stop(nativePtr); @@ -380,20 +386,21 @@ public class Unicorn } /** - * Read register value. This reads any register that would return a Long - * from {@link #reg_read(int, Object)}. + * Read register value of at most 64 bits in size. * * @param regid Register ID that is to be retrieved. This function only supports * integer registers at most 64 bits long. * @return value of the register. + * @see {@link #reg_read(int, Object)} to read larger registers or + * registers requiring configuration. */ public long reg_read(int regid) throws UnicornException { return do_reg_read_long(nativePtr, 0, arch, regid); } /** - * Read register value. The return type depends on regid as follows. - * opt should be null unless otherwise specified. + * Read register value. The return type depends on {@code regid} as + * follows. {@code opt} should be {@code null} unless otherwise specified. *
    *
  • {@code UC_X86_REG_*TR} => {@link X86_MMR} *
  • {@code UC_X86_REG_FP*} => {@link X86_Float80} @@ -408,8 +415,10 @@ public class Unicorn *
* * @param regid Register ID that is to be retrieved. - * @param opt Options for this register, or null if no options are required. - * @return value of the register - Long, BigInteger, or structure. + * @param opt Options for this register, or {@code null} if no options + * are required. + * @return value of the register - {@link Long}, {@link BigInteger}, + * or other class. */ public Object reg_read(int regid, Object opt) throws UnicornException { return do_reg_read_obj(nativePtr, 0, arch, regid, opt); @@ -421,13 +430,15 @@ public class Unicorn * * @param regid Register ID that is to be modified. * @param value Object containing the new register value. + * @see {@link #reg_read(int, Object)} to write larger registers or + * registers requiring configuration. */ public void reg_write(int regid, long value) throws UnicornException { do_reg_write_long(nativePtr, 0, arch, regid, value); } /** - * Write to register. The type of {@code value} depends on regid: + * Write to register. The type of {@code value} depends on {@code regid}: *
    *
  • {@code UC_X86_REG_*TR} => {@link X86_MMR} *
  • {@code UC_X86_REG_FP*} => {@link X86_Float80} @@ -464,115 +475,172 @@ public class Unicorn /** * 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. + * @param address Start address of the memory region to be written. + * @param bytes The values to be written into memory. {@code bytes.length} + * bytes will be written. */ public void mem_write(long address, byte[] bytes) throws UnicornException { _mem_write(nativePtr, address, bytes); } /** - * Query internal status of engine. + * Query the internal status of the engine. * - * @param type query type. See UC_QUERY_* - * @param result save the internal status queried - * - * @return: error code. see UC_ERR_* - * @see unicorn.UnicornConst + * @param type query type, one of the {@code UC_QUERY_*} constants. + * @return result of the query + * @see UnicornConst */ public long query(int type) throws UnicornException { return _query(nativePtr, type); } /** - * Report the last error number when some API function fail. - * Like glibc's errno, uc_errno might not retain its old value once accessed. + * Report the last error number when some API functions fail. + * {@code errno} may not retain its old value once accessed. * - * @return Error code of uc_err enum type (UC_ERR_*, see above) - * @see unicorn.UnicornConst + * @return Error code, one of the {@code UC_ERR_*} constants. + * @see UnicornConst */ public int errno() { return _errno(nativePtr); } /** - * Return a string describing given error code. + * Return a string describing the given error code. * - * @param code Error code (see UC_ERR_* above) - * @return Returns a String that describes the error code - * @see unicorn.UnicornConst + * @param code Error code, one of the {@code UC_ERR_*} constants. + * @return a String that describes the error code + * @see UnicornConst */ public static String strerror(int code) { return _strerror(code); } - public int ctl_get_mode() { + /** + * Get the current emulation mode. + * + * @return a bitwise OR of {@code UC_MODE_*} constants. + */ + public int ctl_get_mode() throws UnicornException { return _ctl_get_mode(nativePtr); } - public int ctl_get_arch() { + /** + * Get the current emulation architecture. + * + * @return a {@code UC_ARCH_*} constant. + */ + public int ctl_get_arch() throws UnicornException { return _ctl_get_arch(nativePtr); } - public long ctl_get_timeout() { + /** Get the current execution timeout, in nanoseconds. */ + public long ctl_get_timeout() throws UnicornException { return _ctl_get_timeout(nativePtr); } - public int ctl_get_page_size() { + /** Get the current page size, in bytes. */ + public int ctl_get_page_size() throws UnicornException { return _ctl_get_page_size(nativePtr); } - public void ctl_set_page_size(int page_size) { + /** Set the current page size, in bytes. + * + * @param page_size Requested page type. Must be a power of two. + * @throws UnicornException if the architecture does not support setting + * the page size. + */ + public void ctl_set_page_size(int page_size) throws UnicornException { _ctl_set_page_size(nativePtr, page_size); } - public void ctl_exits_enabled(boolean value) { + /** Enable or disable multiple exit support. + * + * Exits provide a more flexible way to terminate execution, versus using + * the {@code until} parameter to {@link #emu_start}. When exits are + * enabled, execution will stop at any of the configured exit addresses, + * and the {@code until} parameter will be ignored. + */ + public void ctl_exits_enabled(boolean value) throws UnicornException { _ctl_set_use_exits(nativePtr, value); } - public long ctl_get_exits_cnt() { + /** Get the current number of active exits. + * + * @return The number of exit addresses currently configured + * @throws UnicornException if exits are not enabled + */ + public long ctl_get_exits_cnt() throws UnicornException { return _ctl_get_exits_cnt(nativePtr); } - public long[] ctl_get_exits() { + /** Get the current active exits. + * + * @return An array of active exit addresses. + * @throws UnicornException if exits are not enabled + */ + public long[] ctl_get_exits() throws UnicornException { return _ctl_get_exits(nativePtr); } - public void ctl_set_exits(long[] exits) { + /** Set the active exit addresses. + * + * @param exits An array of exit addresses to use. + * @throws UnicornException if exits are not enabled + */ + public void ctl_set_exits(long[] exits) throws UnicornException { _ctl_set_exits(nativePtr, exits); } - public int ctl_get_cpu_model() { + /** Get the emulated CPU model. + * + * @return One of the {@code UC_CPU__*} constants. See the + * appropriate Const class for a list of valid constants. + */ + public int ctl_get_cpu_model() throws UnicornException { return _ctl_get_cpu_model(nativePtr); } - /** - * Set the emulated cpu model. - * - * @param cpu_model CPU model type (see UC_CPU_*). - */ - public void ctl_set_cpu_model(int cpu_model) { + /** Set the emulated CPU model. Note that this option can only be called + * immediately after constructing the Unicorn object, before any other APIs + * are called. + * + * @param cpu_model One of the {@code UC_CPU__*} constants. See the + * appropriate Const class for a list of valid constants. + */ + public void ctl_set_cpu_model(int cpu_model) throws UnicornException { _ctl_set_cpu_model(nativePtr, cpu_model); } - public TranslationBlock ctl_request_cache(long address) { + /** Request the TB cache at a specific address. */ + public TranslationBlock ctl_request_cache(long address) + throws UnicornException { return _ctl_request_cache(nativePtr, address); } - public void ctl_remove_cache(long address, long end) { + /** Invalidate the TB cache at a specific range of addresses. */ + public void ctl_remove_cache(long address, long end) + throws UnicornException { _ctl_remove_cache(nativePtr, address, end); } - public void ctl_flush_tb() { + /** Flush the entire TB cache, invalidating all translation blocks. */ + public void ctl_flush_tb() throws UnicornException { _ctl_flush_tb(nativePtr); } - public void ctl_flush_tlb() { + /** Flush the TLB cache, invalidating all TLB cache entries and + * translation blocks. */ + public void ctl_flush_tlb() throws UnicornException { _ctl_flush_tlb(nativePtr); } - public void ctl_tlb_mode(int mode) { + /** Change the TLB implementation. + * + * @param mode One of the {@code UC_TLB_*} constants. + * @see UnicornConst + */ + public void ctl_tlb_mode(int mode) throws UnicornException { _ctl_tlb_mode(nativePtr, mode); } @@ -584,10 +652,10 @@ public class Unicorn } /** - * Register a UC_HOOK_INTR hook. The registered callback function will be - * invoked whenever an interrupt instruction is executed. + * Register a {@code UC_HOOK_INTR} hook. The hook function will be invoked + * whenever a CPU interrupt occurs. * - * @param callback Implementation of a InterruptHook interface + * @param callback Implementation of a {@link InterruptHook} interface * @param user_data User data to be passed to the callback function each time * the event is triggered */ @@ -598,12 +666,13 @@ public class Unicorn } /** - * Register a UC_HOOK_INSN hook. The registered callback function will be + * Register a {@code UC_HOOK_INSN} hook. The hook function will be * invoked whenever the matching special instruction is executed. * The exact interface called will depend on the instruction being hooked. * - * @param callback Implementation of an InstructionHook sub-interface - * @param insn UC__INS_ constant, e.g. UC_X86_INS_IN or UC_ARM64_INS_MRS + * @param callback Implementation of an {@link InstructionHook} sub-interface + * @param insn {@code UC__INS_} constant, e.g. + * {@code UC_X86_INS_IN} or {@code UC_ARM64_INS_MRS} * @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 @@ -618,12 +687,12 @@ public class Unicorn } /** - * Register a UC_HOOK_CODE hook. The registered callback function will be + * Register a {@code UC_HOOK_CODE} hook. The hook 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 callback Implementation of a {@link 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 @@ -637,13 +706,13 @@ public class Unicorn } /** - * Register a UC_HOOK_BLOCK hook. The registered callback function will be + * Register a {@code UC_HOOK_BLOCK} hook. The hook 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 callback Implementation of a {@link 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 @@ -657,14 +726,16 @@ public class Unicorn } /** - * Register a UC_HOOK_MEM_VALID hook (UC_HOOK_MEM_{READ,WRITE_FETCH} and/or - * UC_HOOK_MEM_READ_AFTER. The registered callback function will be + * Register a {@code UC_HOOK_MEM_VALID} hook + * ({@code UC_HOOK_MEM_[READ,WRITE,FETCH]} and/or + * {@code UC_HOOK_MEM_READ_AFTER}. The registered callback function will be * invoked whenever a corresponding memory operation is performed within the * address range begin <= addr <= end. For the special case in which * begin > end, the callback will be invoked for ALL memory operations. * - * @param callback Implementation of a MemHook interface - * @param type UC_HOOK_MEM_* constant for a valid memory event + * @param callback Implementation of a {@link MemHook} interface + * @param type Bitwise OR of {@code UC_HOOK_MEM_*} constants for valid + * memory events * @param begin Start address of memory range * @param end End address of memory range * @param user_data User data to be passed to the callback function each time @@ -678,17 +749,16 @@ public class Unicorn } /** - * Register a UC_HOOK_MEM_XXX_UNMAPPED and/or UC_HOOK_MEM_XXX_PROT hook. - * The registered callback function will be invoked whenever a memory - * operation is attempted from an invalid or protected memory address. - * The registered callback function will be invoked whenever a - * corresponding memory operation is performed within the address range - * begin <= addr <= end. For the special case in which begin > end, the - * callback will be invoked for ALL memory operations. + * Register a {@code UC_HOOK_MEM_*_UNMAPPED} and/or + * {@code UC_HOOK_MEM_*_PROT} hook. + * The hook function will be invoked whenever a memory operation is + * attempted from an invalid or protected memory address within the address + * range begin <= addr <= end. For the special case in which begin > end, + * the callback will be invoked for ALL invalid memory operations. * - * @param callback Implementation of a EventMemHook interface - * @param type Type of memory event being hooked such as - * UC_HOOK_MEM_READ_UNMAPPED or UC_HOOK_MEM_WRITE_PROT + * @param callback Implementation of a {@link EventMemHook} interface + * @param type Bitwise OR of {@code UC_HOOK_MEM_*} constants for + * invalid memory events. * @param begin Start address of memory range * @param end End address of memory range * @param user_data User data to be passed to the callback function each time @@ -701,12 +771,33 @@ public class Unicorn _hook_add(nativePtr, type, callback, user_data, begin, end)); } + /** + * Register a {@code UC_HOOK_INSN_INVALID} hook. The hook function will be + * invoked whenever an invalid instruction is encountered. + * + * @param callback Implementation of a {@link InvalidInstructionHook} + * interface + * @param user_data User data to be passed to the callback function each time + * the event is triggered + */ public long hook_add(InvalidInstructionHook callback, Object user_data) { return registerHook(_hook_add(nativePtr, UC_HOOK_INSN_INVALID, callback, user_data, 1, 0)); } + /** + * Register a {@code UC_HOOK_EDGE_GENERATED} hook. The hook function will be + * invoked whenever a jump is made to a new (untranslated) basic block with + * a start address in the range of begin <= pc <= end. For the special case + * in which begin > end, the callback will be invoked for ALL new edges. + * + * @param callback Implementation of a {@link EdgeGeneratedHook} interface + * @param begin Start address + * @param end End address + * @param user_data User data to be passed to the callback function each time + * the event is triggered + */ public long hook_add(EdgeGeneratedHook callback, long begin, long end, Object user_data) throws UnicornException { @@ -714,6 +805,20 @@ public class Unicorn callback, user_data, begin, end)); } + /** + * Register a {@code UC_HOOK_TCG_OPCODE} hook. The hook function will be + * invoked whenever a matching instruction is executed within the + * registered range. + * + * @param callback Implementation of a {@link TcgOpcodeHook} interface + * @param begin Start address + * @param end End address + * @param opcode Opcode to hook. One of the {@code UC_TCG_OP_*} constants. + * @param flags Flags to filter opcode matches. A bitwise-OR of + * {@code UC_TCG_OP_FLAG_*} constants. + * @param user_data User data to be passed to the callback function each time + * the event is triggered + */ public long hook_add(TcgOpcodeHook callback, long begin, long end, int opcode, int flags, Object user_data) @@ -722,6 +827,18 @@ public class Unicorn user_data, begin, end, opcode, flags)); } + /** + * Register a {@code UC_HOOK_TLB_FILL} hook. The hook function will be + * invoked to map a virtual address within the registered range to a + * physical address. These hooks will only be called if the TLB mode (set + * via {@link #ctl_tlb_mode}) is set to {@code UC_TLB_VIRTUAL}. + * + * @param callback Implementation of a {@link TlbFillHook} interface + * @param begin Start address + * @param end End address + * @param user_data User data to be passed to the callback function each time + * the event is triggered + */ public long hook_add(TlbFillHook callback, long begin, long end, Object user_data) throws UnicornException { return registerHook(_hook_add(nativePtr, UC_HOOK_TLB_FILL, callback, @@ -730,7 +847,7 @@ public class Unicorn /** Remove a hook that was previously registered. * - * @param hook The return value from any hook_add function. + * @param hook The return value from any {@code hook_add} function. */ public void hook_del(long hook) throws UnicornException { if (hooks.contains(hook)) { @@ -743,6 +860,16 @@ public class Unicorn /** * Create a memory-mapped I/O range. + * + * @param address Starting memory address of the MMIO area + * @param size Size of the MMIO area + * @param read_cb Implementation of {@link MmioReadHandler} to handle read + * operations, or {@code null} for non-readable memory + * @param user_data_read User data to be passed to the read callback + * @param write_cb Implementation of {@link MmioWriteHandler} to handle + * write operations, or {@code null} for non-writable memory + * @param user_data_write User data to be passed to the write callback + * @throws UnicornException */ public void mmio_map(long address, long size, MmioReadHandler read_cb, Object user_data_read, MmioWriteHandler write_cb, @@ -757,12 +884,12 @@ public class Unicorn } /** - * Map a range of memory. + * Map a range of memory, automatically allocating backing host memory. * * @param address Base address of the memory range - * @param size Size of the memory block. - * @param perms Permissions on the memory block. A combination of - * UC_PROT_READ, UC_PROT_WRITE, UC_PROT_EXEC + * @param size Size of the memory block + * @param perms Permissions on the memory block. A bitwise combination + * of {@code UC_PROT_*} constants. */ public void mem_map(long address, long size, int perms) throws UnicornException { @@ -770,16 +897,17 @@ public class Unicorn } /** - * Map existing host memory in for emulation. - * This API adds a memory region that can be used by emulation. + * Map a range of memory, backed by an existing region of host memory. + * This API enables direct access to emulator memory without going through + * {@link #mem_read} and {@link #mem_write}. * * @param address Base address of the memory range - * @param buf Direct-mapped Buffer referencing the memory to - * map into the emulator. IMPORTANT: You are responsible - * for ensuring that this Buffer remains alive as long - * as the emulator is running! - * @param perms Permissions on the memory block. A combination of - * UC_PROT_READ, UC_PROT_WRITE, UC_PROT_EXEC + * @param buf Direct Buffer referencing the memory to map into the + * emulator. IMPORTANT: You are responsible for ensuring + * that this Buffer remains alive as long as the memory + * remains mapped! + * @param perms Permissions on the memory block. A bitwise combination + * of {@code UC_PROT_*} constants. */ public void mem_map_ptr(long address, Buffer buf, int perms) throws UnicornException { @@ -801,8 +929,8 @@ public class Unicorn * * @param address Base address of the memory range * @param size Size of the memory block. - * @param perms New permissions on the memory block. A combination of - * UC_PROT_READ, UC_PROT_WRITE, UC_PROT_EXEC + * @param perms Permissions on the memory block. A bitwise combination + * of {@code UC_PROT_*} constants. */ public void mem_protect(long address, long size, int perms) throws UnicornException { @@ -810,15 +938,20 @@ public class Unicorn } /** - * Retrieve all memory regions mapped by mem_map() and mem_map_ptr() - * NOTE: memory regions may be split by mem_unmap() + * Retrieve all memory regions mapped by {@link #mem_map}, + * {@link #mmio_map} and {@link #mem_map_ptr}. + * NOTE: memory regions may be split by {@link #mem_unmap}. * - * @return list of mapped regions. + * @return array of mapped regions. */ public MemRegion[] mem_regions() throws UnicornException { return _mem_regions(nativePtr); } + /** + * Save the current CPU state of the emulator. The resulting context can be + * restored on any emulator with the same {@code arch} and {@code mode}. + */ public Context context_save() throws UnicornException { long ptr = _context_alloc(nativePtr); Context context = new Context(); @@ -829,6 +962,10 @@ public class Unicorn return context; } + /** + * Update a {@link Context} object with the current CPU state of the + * emulator. + */ public void context_update(Context context) throws UnicornException { if (context.arch != arch || context.mode != mode) { throw new UnicornException( @@ -837,6 +974,9 @@ public class Unicorn _context_save(nativePtr, context.nativePtr); } + /** + * Restore the current CPU context from a saved copy. + */ public void context_restore(Context context) throws UnicornException { if (context.arch != arch || context.mode != mode) { throw new UnicornException( From 3fab8abca77a535f0bda69900991f7f67b7a43e2 Mon Sep 17 00:00:00 2001 From: Robert Xiao Date: Fri, 12 May 2023 21:25:34 -0700 Subject: [PATCH 08/25] Restore some of the less problematic old APIs for backwards compatibility. --- bindings/java/Makefile | 20 +- bindings/java/unicorn/Unicorn.java | 679 +++++++++++++++++------------ 2 files changed, 408 insertions(+), 291 deletions(-) diff --git a/bindings/java/Makefile b/bindings/java/Makefile index 65712f44..7fb72495 100644 --- a/bindings/java/Makefile +++ b/bindings/java/Makefile @@ -35,10 +35,10 @@ CLASSPATH=./ .SUFFIXES: .java .class tests/%.class: tests/%.java - $(JC) -classpath .:unicorn.jar:testdep/junit-4.13.2.jar $(JFLAGS) $< + $(JC) -Xlint:deprecation -classpath .:unicorn.jar:testdep/junit-4.13.2.jar $(JFLAGS) $< %.class: %.java - $(JC) -classpath .:unicorn.jar $(JFLAGS) $< + $(JC) -Xlint:deprecation -classpath .:unicorn.jar $(JFLAGS) $< OBJS=unicorn_Unicorn.o @@ -48,7 +48,7 @@ JARFILE=unicorn.jar $(CC) -c $(CFLAGS) $(INCS) $< -o $@ unicorn_Unicorn.h: unicorn/Unicorn.java - javac -h . $< + $(JC) -h . $< unicorn_Unicorn.o: unicorn_Unicorn.c unicorn_Unicorn.h $(CC) -O2 -Wall -Wextra -Wno-unused-parameter -c $(CFLAGS) $(INCS) $< -o $@ @@ -73,17 +73,17 @@ install: lib jar cp $(JARFILE) /usr/share/java uninstall: - rm /usr/lib/libunicorn_java$(LIB_EXT) - rm /usr/share/java/$(JARFILE) + rm -f /usr/lib/libunicorn_java$(LIB_EXT) + rm -f /usr/share/java/$(JARFILE) gen_const: cd .. && python3 const_generator.py java clean: - rm unicorn/*.class - rm samples/*.class - rm *.so - rm *.dylib - rm *.dll + rm -f unicorn/*.class + rm -f samples/*.class + rm -f *.so + rm -f *.dylib + rm -f *.dll .PHONY: all lib samples jar install uninstall gen_const clean diff --git a/bindings/java/unicorn/Unicorn.java b/bindings/java/unicorn/Unicorn.java index 884a9190..bcdad6ca 100644 --- a/bindings/java/unicorn/Unicorn.java +++ b/bindings/java/unicorn/Unicorn.java @@ -59,13 +59,13 @@ public class Unicorn } /** - * Read register value from saved context. - * - * @param regid Register ID that is to be retrieved. This function only supports - * integer registers at most 64 bits long. - * @return value of the register. - * @see Unicorn#reg_read(int) - */ + * Read register value from saved context. + * + * @param regid Register ID that is to be retrieved. This function only supports + * integer registers at most 64 bits long. + * @return value of the register. + * @see Unicorn#reg_read(int) + */ public long reg_read(int regid) throws UnicornException { return do_reg_read_long(nativePtr, 1, arch, regid); } @@ -83,23 +83,23 @@ public class Unicorn } /** - * Write to register in saved context. - * - * @param regid Register ID that is to be modified. - * @param value Object containing the new register value. - * @see Unicorn#reg_write(int, long) - */ + * Write to register in saved context. + * + * @param regid Register ID that is to be modified. + * @param value Object containing the new register value. + * @see Unicorn#reg_write(int, long) + */ public void reg_write(int regid, long value) throws UnicornException { do_reg_write_long(nativePtr, 1, arch, regid, value); } /** - * Write to register in saved context. - * - * @param regid Register ID that is to be modified. - * @param value Object containing the new register value. - * @see Unicorn#reg_write(int, Object) - */ + * Write to register in saved context. + * + * @param regid Register ID that is to be modified. + * @param value Object containing the new register value. + * @see Unicorn#reg_write(int, Object) + */ public void reg_write(int regid, Object value) throws UnicornException { do_reg_write_obj(nativePtr, 1, arch, regid, value); } @@ -111,13 +111,13 @@ public class Unicorn } /** - * Create a new Unicorn object - * - * @param arch Architecture type. One of the {@code UC_ARCH_*} constants. - * @param mode Hardware mode. Bitwise combination of {@code UC_MODE_*} constants. - * @see UnicornConst - * - */ + * Create a new Unicorn object + * + * @param arch Architecture type. One of the {@code UC_ARCH_*} constants. + * @param mode Hardware mode. Bitwise combination of {@code UC_MODE_*} constants. + * @see UnicornConst + * + */ public Unicorn(int arch, int mode) throws UnicornException { // remember these in case we need arch specific code this.arch = arch; @@ -126,10 +126,10 @@ public class Unicorn } /** - * Close the C {@code uc_engine} associated with this Unicorn object, - * freeing all associated resources. After calling this method, the - * API will no longer be usable. - */ + * Close the C {@code uc_engine} associated with this Unicorn object, + * freeing all associated resources. After calling this method, the + * API will no longer be usable. + */ public void close() throws UnicornException { if (nativePtr != 0) { _close(nativePtr); @@ -138,48 +138,48 @@ public class Unicorn } /** - * Automatically close the {@code uc_engine} upon GC finalization. - */ + * Automatically close the {@code uc_engine} upon GC finalization. + */ @Override protected void finalize() { close(); } /** - * Return combined API version & major and minor version numbers. - * - * @return version number as {@code (major << 8 | minor)}, which encodes - * both major & minor versions. - * For example, Unicorn version 1.2 would yield 0x0102. - */ + * Return combined API version & major and minor version numbers. + * + * @return version number as {@code (major << 8 | minor)}, which encodes + * both major & minor versions. + * For example, Unicorn version 1.2 would yield 0x0102. + */ public static int version() { return _version(); } /** - * Determine if the given architecture is supported by this library. - * - * @param arch Architecture type ({@code UC_ARCH_*} constant) - * @return {@code true} if this library supports the given arch. - * @see UnicornConst - */ + * Determine if the given architecture is supported by this library. + * + * @param arch Architecture type ({@code UC_ARCH_*} constant) + * @return {@code true} if this library supports the given arch. + * @see UnicornConst + */ public static boolean arch_supported(int arch) { return _arch_supported(arch); } /** - * Emulate machine code for a specific length of time or number of - * instructions. - * - * @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 for, in microseconds, or 0 to - * run indefinitely. - * @param count The maximum number of instructions to execute, or 0 to - * execute indefinitely. - * @throws UnicornException if an unhandled CPU exception or other error - * occurs during emulation. - */ + * Emulate machine code for a specific length of time or number of + * instructions. + * + * @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 for, in microseconds, or 0 to + * run indefinitely. + * @param count The maximum number of instructions to execute, or 0 to + * execute indefinitely. + * @throws UnicornException if an unhandled CPU exception or other error + * occurs during emulation. + */ public void emu_start(long begin, long until, long timeout, long count) throws UnicornException { @@ -187,12 +187,12 @@ public class Unicorn } /** - * Stop emulation (which was started by {@link #emu_start()}). - * - * This can be called from hook callbacks or from a separate thread. - * NOTE: for now, this will stop the execution only after the current - * basic block. - */ + * Stop emulation (which was started by {@link #emu_start()}). + * + * This can be called from hook callbacks or from a separate thread. + * NOTE: for now, this will stop the execution only after the current + * basic block. + */ public void emu_stop() throws UnicornException { _emu_stop(nativePtr); } @@ -386,14 +386,14 @@ public class Unicorn } /** - * Read register value of at most 64 bits in size. - * - * @param regid Register ID that is to be retrieved. This function only supports - * integer registers at most 64 bits long. - * @return value of the register. - * @see {@link #reg_read(int, Object)} to read larger registers or - * registers requiring configuration. - */ + * Read register value of at most 64 bits in size. + * + * @param regid Register ID that is to be retrieved. This function only supports + * integer registers at most 64 bits long. + * @return value of the register. + * @see {@link #reg_read(int, Object)} to read larger registers or + * registers requiring configuration. + */ public long reg_read(int regid) throws UnicornException { return do_reg_read_long(nativePtr, 0, arch, regid); } @@ -425,93 +425,106 @@ public class Unicorn } /** - * Write to register. This sets any register that doesn't require special - * options and which is at most 64 bits long. - * - * @param regid Register ID that is to be modified. - * @param value Object containing the new register value. - * @see {@link #reg_read(int, Object)} to write larger registers or - * registers requiring configuration. - */ + * Write to register. This sets any register that doesn't require special + * options and which is at most 64 bits long. + * + * @param regid Register ID that is to be modified. + * @param value Object containing the new register value. + * @see {@link #reg_read(int, Object)} to write larger registers or + * registers requiring configuration. + */ public void reg_write(int regid, long value) throws UnicornException { do_reg_write_long(nativePtr, 0, arch, regid, value); } /** - * Write to register. The type of {@code value} depends on {@code regid}: - *
      - *
    • {@code UC_X86_REG_*TR} => {@link X86_MMR} - *
    • {@code UC_X86_REG_FP*} => {@link X86_Float80} - *
    • {@code UC_X86_REG_ST*} => {@link X86_Float80} - *
    • {@code UC_X86_REG_XMM*} => {@link BigInteger} (128 bits) - *
    • {@code UC_X86_REG_YMM*} => {@link BigInteger} (256 bits) - *
    • {@code UC_X86_REG_MSR} => {@link X86_MSR} - *
    • {@code UC_ARM_REG_CP} => {@link Arm_CP} - *
    • {@code UC_ARM64_REG_CP} => {@link Arm64_CP} - *
    • {@code UC_ARM64_REG_Q*} => {@link BigInteger} (128 bits) - *
    • {@code UC_ARM64_REG_V*} => {@link BigInteger} (128 bits) - *
    - * - * @param regid Register ID that is to be modified. - * @param value Object containing the new register value. - */ + * Write to register. The type of {@code value} depends on {@code regid}: + *
      + *
    • {@code UC_X86_REG_*TR} => {@link X86_MMR} + *
    • {@code UC_X86_REG_FP*} => {@link X86_Float80} + *
    • {@code UC_X86_REG_ST*} => {@link X86_Float80} + *
    • {@code UC_X86_REG_XMM*} => {@link BigInteger} (128 bits) + *
    • {@code UC_X86_REG_YMM*} => {@link BigInteger} (256 bits) + *
    • {@code UC_X86_REG_MSR} => {@link X86_MSR} + *
    • {@code UC_ARM_REG_CP} => {@link Arm_CP} + *
    • {@code UC_ARM64_REG_CP} => {@link Arm64_CP} + *
    • {@code UC_ARM64_REG_Q*} => {@link BigInteger} (128 bits) + *
    • {@code UC_ARM64_REG_V*} => {@link BigInteger} (128 bits) + *
    + * + * @param regid Register ID that is to be modified. + * @param value Object containing the new register value. + */ public void reg_write(int regid, Object value) throws UnicornException { do_reg_write_obj(nativePtr, 0, arch, regid, value); } /** - * Read from memory. - * - * @param address Start address 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. - */ + * Read from memory. + * + * @param address Start address 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 byte[] mem_read(long address, int size) throws UnicornException { byte[] result = new byte[size]; _mem_read(nativePtr, address, result); return result; } + /** @deprecated Use {@link #mem_read(long, int)} instead. */ + @Deprecated + public byte[] mem_read(long address, long size) throws UnicornException { + if (size < 0) { + throw new NegativeArraySizeException("size cannot be negative"); + } else if (size > Integer.MAX_VALUE) { + throw new IllegalArgumentException("size must fit in an int"); + } + byte[] result = new byte[(int) size]; + _mem_read(nativePtr, address, result); + return result; + } + /** - * Write to memory. - * - * @param address Start address of the memory region to be written. - * @param bytes The values to be written into memory. {@code bytes.length} - * bytes will be written. - */ + * Write to memory. + * + * @param address Start address of the memory region to be written. + * @param bytes The values to be written into memory. {@code bytes.length} + * bytes will be written. + */ public void mem_write(long address, byte[] bytes) throws UnicornException { _mem_write(nativePtr, address, bytes); } /** - * Query the internal status of the engine. - * - * @param type query type, one of the {@code UC_QUERY_*} constants. - * @return result of the query - * @see UnicornConst - */ + * Query the internal status of the engine. + * + * @param type query type, one of the {@code UC_QUERY_*} constants. + * @return result of the query + * @see UnicornConst + */ public long query(int type) throws UnicornException { return _query(nativePtr, type); } /** - * Report the last error number when some API functions fail. - * {@code errno} may not retain its old value once accessed. - * - * @return Error code, one of the {@code UC_ERR_*} constants. - * @see UnicornConst - */ + * Report the last error number when some API functions fail. + * {@code errno} may not retain its old value once accessed. + * + * @return Error code, one of the {@code UC_ERR_*} constants. + * @see UnicornConst + */ public int errno() { return _errno(nativePtr); } /** - * Return a string describing the given error code. - * - * @param code Error code, one of the {@code UC_ERR_*} constants. - * @return a String that describes the error code - * @see UnicornConst - */ + * Return a string describing the given error code. + * + * @param code Error code, one of the {@code UC_ERR_*} constants. + * @return a String that describes the error code + * @see UnicornConst + */ public static String strerror(int code) { return _strerror(code); } @@ -652,13 +665,15 @@ public class Unicorn } /** - * Register a {@code UC_HOOK_INTR} hook. The hook function will be invoked - * whenever a CPU interrupt occurs. - * - * @param callback Implementation of a {@link InterruptHook} interface - * @param user_data User data to be passed to the callback function each time - * the event is triggered - */ + * Register a {@code UC_HOOK_INTR} hook. The hook function will be invoked + * whenever a CPU interrupt occurs. + * + * @param callback Implementation of a {@link InterruptHook} interface + * @param user_data User data to be passed to the callback function each + * time the event is triggered + * @return A value that can be passed to {@link #hook_del} to unregister + * this hook + */ public long hook_add(InterruptHook callback, Object user_data) throws UnicornException { return registerHook( @@ -666,18 +681,20 @@ public class Unicorn } /** - * Register a {@code UC_HOOK_INSN} hook. The hook function will be - * invoked whenever the matching special instruction is executed. - * The exact interface called will depend on the instruction being hooked. - * - * @param callback Implementation of an {@link InstructionHook} sub-interface - * @param insn {@code UC__INS_} constant, e.g. - * {@code UC_X86_INS_IN} or {@code UC_ARM64_INS_MRS} - * @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 - */ + * Register a {@code UC_HOOK_INSN} hook. The hook function will be + * invoked whenever the matching special instruction is executed. + * The exact interface called will depend on the instruction being hooked. + * + * @param callback Implementation of an {@link InstructionHook} sub-interface + * @param insn {@code UC__INS_} constant, e.g. + * {@code UC_X86_INS_IN} or {@code UC_ARM64_INS_MRS} + * @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 + * @return A value that can be passed to {@link #hook_del} to unregister + * this hook + */ public long hook_add(InstructionHook callback, int insn, long begin, long end, Object user_data) @@ -687,17 +704,81 @@ public class Unicorn } /** - * Register a {@code UC_HOOK_CODE} hook. The hook 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 {@link 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 - */ + * Register a {@code UC_HOOK_INSN} hook for all program addresses. + * The exact interface called will depend on the instruction being hooked. + * + * @param callback Implementation of an {@link InstructionHook} + * sub-interface + * @param insn {@code UC__INS_} constant, e.g. + * {@code UC_X86_INS_IN} or {@code UC_ARM64_INS_MRS} + * @param user_data User data to be passed to the callback function each + * time the event is triggered + * @return A value that can be passed to {@link #hook_del} to unregister + * this hook + */ + public long hook_add(InstructionHook callback, int insn, Object user_data) + throws UnicornException { + return hook_add(callback, insn, 1, 0, user_data); + } + + /** + * Register a hook for the X86 IN instruction. + * The registered callback will be called whenever an IN instruction + * is executed. + * + * @param callback Object implementing the {@link InHook} interface + * @param user_data User data to be passed to the callback function each + * time the event is triggered + * @return A value that can be passed to {@link #hook_del} to unregister + * this hook + */ + public long hook_add(InHook callback, Object user_data) + throws UnicornException { + return hook_add(callback, UC_X86_INS_IN, user_data); + } + + /** + * Register a hook for the X86 OUT instruction. + * The registered callback will be called whenever an OUT instruction + * is executed. + * + * @param callback Object implementing the {@link InHook} interface + * @param user_data User data to be passed to the callback function each + * time the event is triggered + * @return A value that can be passed to {@link #hook_del} to unregister + * this hook + */ + public long hook_add(OutHook callback, Object user_data) + throws UnicornException { + return hook_add(callback, UC_X86_INS_OUT, user_data); + } + + /** @deprecated Use {@code hook_add(callback, UC_X86_INS_SYSCALL, begin, + * end, user_data)} or {@code hook_add(callback, + * UC_X86_INS_SYSENTER, begin, end, user_data)} instead. + */ + @Deprecated + public long hook_add(SyscallHook callback, Object user_data) + throws UnicornException { + // Old implementation only registered SYSCALL, not SYSENTER. + // Since this is deprecated anyway, we retain the old behaviour. + return hook_add(callback, UC_X86_INS_SYSCALL, user_data); + } + + /** + * Register a {@code UC_HOOK_CODE} hook. The hook 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 {@link 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 + * @return A value that can be passed to {@link #hook_del} to unregister + * this hook + */ public long hook_add(CodeHook callback, long begin, long end, Object user_data) throws UnicornException { @@ -706,18 +787,20 @@ public class Unicorn } /** - * Register a {@code UC_HOOK_BLOCK} hook. The hook 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 {@link 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 - */ + * Register a {@code UC_HOOK_BLOCK} hook. The hook 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 {@link 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 + * @return A value that can be passed to {@link #hook_del} to unregister + * this hook + */ public long hook_add(BlockHook callback, long begin, long end, Object user_data) throws UnicornException { @@ -726,21 +809,24 @@ public class Unicorn } /** - * Register a {@code UC_HOOK_MEM_VALID} hook - * ({@code UC_HOOK_MEM_[READ,WRITE,FETCH]} and/or - * {@code UC_HOOK_MEM_READ_AFTER}. The registered callback function will be - * invoked whenever a corresponding memory operation is performed within the - * address range begin <= addr <= end. For the special case in which - * begin > end, the callback will be invoked for ALL memory operations. - * - * @param callback Implementation of a {@link MemHook} interface - * @param type Bitwise OR of {@code UC_HOOK_MEM_*} constants for valid - * memory events - * @param begin Start address of memory range - * @param end End address of memory range - * @param user_data User data to be passed to the callback function each time - * the event is triggered - */ + * Register a {@code UC_HOOK_MEM_VALID} hook + * ({@code UC_HOOK_MEM_[READ,WRITE,FETCH]} and/or + * {@code UC_HOOK_MEM_READ_AFTER}. The registered callback function will + * be invoked whenever a corresponding memory operation is performed + * within the address range begin <= addr <= end. For the special case in + * which begin > end, the callback will be invoked for ALL memory + * operations. + * + * @param callback Implementation of a {@link MemHook} interface + * @param type Bitwise OR of {@code UC_HOOK_MEM_*} constants for + * valid memory events + * @param begin Start address of memory range + * @param end End address of memory range + * @param user_data User data to be passed to the callback function each + * time the event is triggered + * @return A value that can be passed to {@link #hook_del} to unregister + * this hook + */ public long hook_add(MemHook callback, int type, long begin, long end, Object user_data) throws UnicornException { @@ -749,21 +835,23 @@ public class Unicorn } /** - * Register a {@code UC_HOOK_MEM_*_UNMAPPED} and/or - * {@code UC_HOOK_MEM_*_PROT} hook. - * The hook function will be invoked whenever a memory operation is - * attempted from an invalid or protected memory address within the address - * range begin <= addr <= end. For the special case in which begin > end, - * the callback will be invoked for ALL invalid memory operations. - * - * @param callback Implementation of a {@link EventMemHook} interface - * @param type Bitwise OR of {@code UC_HOOK_MEM_*} constants for - * invalid memory events. - * @param begin Start address of memory range - * @param end End address of memory range - * @param user_data User data to be passed to the callback function each time - * the event is triggered - */ + * Register a {@code UC_HOOK_MEM_*_UNMAPPED} and/or + * {@code UC_HOOK_MEM_*_PROT} hook. + * The hook function will be invoked whenever a memory operation is + * attempted from an invalid or protected memory address within the address + * range begin <= addr <= end. For the special case in which begin > end, + * the callback will be invoked for ALL invalid memory operations. + * + * @param callback Implementation of a {@link EventMemHook} interface + * @param type Bitwise OR of {@code UC_HOOK_MEM_*} constants for + * invalid memory events. + * @param begin Start address of memory range + * @param end End address of memory range + * @param user_data User data to be passed to the callback function each + * time the event is triggered + * @return A value that can be passed to {@link #hook_del} to unregister + * this hook + */ public long hook_add(EventMemHook callback, int type, long begin, long end, Object user_data) throws UnicornException { @@ -772,14 +860,34 @@ public class Unicorn } /** - * Register a {@code UC_HOOK_INSN_INVALID} hook. The hook function will be - * invoked whenever an invalid instruction is encountered. - * - * @param callback Implementation of a {@link InvalidInstructionHook} - * interface - * @param user_data User data to be passed to the callback function each time - * the event is triggered - */ + * Register a {@code UC_HOOK_MEM_*_UNMAPPED} and/or + * {@code UC_HOOK_MEM_*_PROT} hook for all memory addresses. + * + * @param callback Implementation of a {@link EventMemHook} interface + * @param type Bitwise OR of {@code UC_HOOK_MEM_*} constants for + * invalid memory events. + * @param user_data User data to be passed to the callback function each + * time the event is triggered + * @return A value that can be passed to {@link #hook_del} to unregister + * this hook + */ + public long hook_add(EventMemHook callback, int type, Object user_data) + throws UnicornException { + return registerHook( + _hook_add(nativePtr, type, callback, user_data, 1, 0)); + } + + /** + * Register a {@code UC_HOOK_INSN_INVALID} hook. The hook function will be + * invoked whenever an invalid instruction is encountered. + * + * @param callback Implementation of a {@link InvalidInstructionHook} + * interface + * @param user_data User data to be passed to the callback function each + * time the event is triggered + * @return A value that can be passed to {@link #hook_del} to unregister + * this hook + */ public long hook_add(InvalidInstructionHook callback, Object user_data) { return registerHook(_hook_add(nativePtr, UC_HOOK_INSN_INVALID, callback, @@ -787,17 +895,20 @@ public class Unicorn } /** - * Register a {@code UC_HOOK_EDGE_GENERATED} hook. The hook function will be - * invoked whenever a jump is made to a new (untranslated) basic block with - * a start address in the range of begin <= pc <= end. For the special case - * in which begin > end, the callback will be invoked for ALL new edges. - * - * @param callback Implementation of a {@link EdgeGeneratedHook} interface - * @param begin Start address - * @param end End address - * @param user_data User data to be passed to the callback function each time - * the event is triggered - */ + * Register a {@code UC_HOOK_EDGE_GENERATED} hook. The hook function will + * be invoked whenever a jump is made to a new (untranslated) basic block + * with a start address in the range of begin <= pc <= end. For the + * special case in which begin > end, the callback will be invoked for ALL + * new edges. + * + * @param callback Implementation of a {@link EdgeGeneratedHook} interface + * @param begin Start address + * @param end End address + * @param user_data User data to be passed to the callback function each + * time the event is triggered + * @return A value that can be passed to {@link #hook_del} to unregister + * this hook + */ public long hook_add(EdgeGeneratedHook callback, long begin, long end, Object user_data) throws UnicornException { @@ -806,19 +917,22 @@ public class Unicorn } /** - * Register a {@code UC_HOOK_TCG_OPCODE} hook. The hook function will be - * invoked whenever a matching instruction is executed within the - * registered range. - * - * @param callback Implementation of a {@link TcgOpcodeHook} interface - * @param begin Start address - * @param end End address - * @param opcode Opcode to hook. One of the {@code UC_TCG_OP_*} constants. - * @param flags Flags to filter opcode matches. A bitwise-OR of - * {@code UC_TCG_OP_FLAG_*} constants. - * @param user_data User data to be passed to the callback function each time - * the event is triggered - */ + * Register a {@code UC_HOOK_TCG_OPCODE} hook. The hook function will be + * invoked whenever a matching instruction is executed within the + * registered range. + * + * @param callback Implementation of a {@link TcgOpcodeHook} interface + * @param begin Start address + * @param end End address + * @param opcode Opcode to hook. One of the {@code UC_TCG_OP_*} + * constants. + * @param flags Flags to filter opcode matches. A bitwise-OR of + * {@code UC_TCG_OP_FLAG_*} constants. + * @param user_data User data to be passed to the callback function each + * time the event is triggered + * @return A value that can be passed to {@link #hook_del} to unregister + * this hook + */ public long hook_add(TcgOpcodeHook callback, long begin, long end, int opcode, int flags, Object user_data) @@ -828,17 +942,19 @@ public class Unicorn } /** - * Register a {@code UC_HOOK_TLB_FILL} hook. The hook function will be - * invoked to map a virtual address within the registered range to a - * physical address. These hooks will only be called if the TLB mode (set - * via {@link #ctl_tlb_mode}) is set to {@code UC_TLB_VIRTUAL}. - * - * @param callback Implementation of a {@link TlbFillHook} interface - * @param begin Start address - * @param end End address - * @param user_data User data to be passed to the callback function each time - * the event is triggered - */ + * Register a {@code UC_HOOK_TLB_FILL} hook. The hook function will be + * invoked to map a virtual address within the registered range to a + * physical address. These hooks will only be called if the TLB mode (set + * via {@link #ctl_tlb_mode}) is set to {@code UC_TLB_VIRTUAL}. + * + * @param callback Implementation of a {@link TlbFillHook} interface + * @param begin Start address + * @param end End address + * @param user_data User data to be passed to the callback function each + * time the event is triggered + * @return A value that can be passed to {@link #hook_del} to unregister + * this hook + */ public long hook_add(TlbFillHook callback, long begin, long end, Object user_data) throws UnicornException { return registerHook(_hook_add(nativePtr, UC_HOOK_TLB_FILL, callback, @@ -863,11 +979,13 @@ public class Unicorn * * @param address Starting memory address of the MMIO area * @param size Size of the MMIO area - * @param read_cb Implementation of {@link MmioReadHandler} to handle read - * operations, or {@code null} for non-readable memory + * @param read_cb Implementation of {@link MmioReadHandler} to handle + * read operations, or {@code null} for non-readable + * memory * @param user_data_read User data to be passed to the read callback * @param write_cb Implementation of {@link MmioWriteHandler} to handle - * write operations, or {@code null} for non-writable memory + * write operations, or {@code null} for non-writable + * memory * @param user_data_write User data to be passed to the write callback * @throws UnicornException */ @@ -884,66 +1002,66 @@ public class Unicorn } /** - * Map a range of memory, automatically allocating backing host memory. - * - * @param address Base address of the memory range - * @param size Size of the memory block - * @param perms Permissions on the memory block. A bitwise combination - * of {@code UC_PROT_*} constants. - */ + * Map a range of memory, automatically allocating backing host memory. + * + * @param address Base address of the memory range + * @param size Size of the memory block + * @param perms Permissions on the memory block. A bitwise combination + * of {@code UC_PROT_*} constants. + */ public void mem_map(long address, long size, int perms) throws UnicornException { _mem_map(nativePtr, address, size, perms); } /** - * Map a range of memory, backed by an existing region of host memory. - * This API enables direct access to emulator memory without going through - * {@link #mem_read} and {@link #mem_write}. - * - * @param address Base address of the memory range - * @param buf Direct Buffer referencing the memory to map into the - * emulator. IMPORTANT: You are responsible for ensuring - * that this Buffer remains alive as long as the memory - * remains mapped! - * @param perms Permissions on the memory block. A bitwise combination - * of {@code UC_PROT_*} constants. - */ + * Map a range of memory, backed by an existing region of host memory. + * This API enables direct access to emulator memory without going through + * {@link #mem_read} and {@link #mem_write}. + * + * @param address Base address of the memory range + * @param buf Direct Buffer referencing the memory to map into the + * emulator. IMPORTANT: You are responsible for ensuring + * that this Buffer remains alive as long as the memory + * remains mapped! + * @param perms Permissions on the memory block. A bitwise combination + * of {@code UC_PROT_*} constants. + */ public void mem_map_ptr(long address, Buffer buf, int perms) throws UnicornException { _mem_map_ptr(nativePtr, address, buf, perms); } /** - * Unmap a range of memory. - * - * @param address Base address of the memory range - * @param size Size of the memory block. - */ + * Unmap a range of memory. + * + * @param address Base address of the memory range + * @param size Size of the memory block. + */ public void mem_unmap(long address, long size) throws UnicornException { _mem_unmap(nativePtr, address, size); } /** - * Change permissions on a range of memory. - * - * @param address Base address of the memory range - * @param size Size of the memory block. - * @param perms Permissions on the memory block. A bitwise combination - * of {@code UC_PROT_*} constants. - */ + * Change permissions on a range of memory. + * + * @param address Base address of the memory range + * @param size Size of the memory block. + * @param perms Permissions on the memory block. A bitwise combination + * of {@code UC_PROT_*} constants. + */ public void mem_protect(long address, long size, int perms) throws UnicornException { _mem_protect(nativePtr, address, size, perms); } /** - * Retrieve all memory regions mapped by {@link #mem_map}, - * {@link #mmio_map} and {@link #mem_map_ptr}. - * NOTE: memory regions may be split by {@link #mem_unmap}. - * - * @return array of mapped regions. - */ + * Retrieve all memory regions mapped by {@link #mem_map}, + * {@link #mmio_map} and {@link #mem_map_ptr}. + * NOTE: memory regions may be split by {@link #mem_unmap}. + * + * @return array of mapped regions. + */ public MemRegion[] mem_regions() throws UnicornException { return _mem_regions(nativePtr); } @@ -1146,5 +1264,4 @@ public class Unicorn private static native void _ctl_tlb_mode(long uc, int mode) throws UnicornException; - } From 4764d54250d5397cca88fad4371b5a95bfab8e00 Mon Sep 17 00:00:00 2001 From: Robert Xiao Date: Fri, 12 May 2023 22:05:13 -0700 Subject: [PATCH 09/25] Javadoc updates --- bindings/java/unicorn/Unicorn.java | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/bindings/java/unicorn/Unicorn.java b/bindings/java/unicorn/Unicorn.java index bcdad6ca..6ca880e1 100644 --- a/bindings/java/unicorn/Unicorn.java +++ b/bindings/java/unicorn/Unicorn.java @@ -393,6 +393,8 @@ public class Unicorn * @return value of the register. * @see {@link #reg_read(int, Object)} to read larger registers or * registers requiring configuration. + * @throws UnicornException if the register is not valid for the current + * architecture or mode. */ public long reg_read(int regid) throws UnicornException { return do_reg_read_long(nativePtr, 0, arch, regid); @@ -407,6 +409,7 @@ public class Unicorn *
  • {@code UC_X86_REG_ST*} => {@link X86_Float80} *
  • {@code UC_X86_REG_XMM*} => {@link BigInteger} (128 bits) *
  • {@code UC_X86_REG_YMM*} => {@link BigInteger} (256 bits) + *
  • {@code UC_X86_REG_ZMM*} => {@link BigInteger} (512 bits) *
  • {@code UC_X86_REG_MSR} (opt: {@link X86_MSR}) => {@link Long} *
  • {@code UC_ARM_REG_CP} (opt: {@link Arm_CP}) => {@link Long} *
  • {@code UC_ARM64_REG_CP} (opt: {@link Arm64_CP}) => {@link Long} @@ -419,6 +422,8 @@ public class Unicorn * are required. * @return value of the register - {@link Long}, {@link BigInteger}, * or other class. + * @throws UnicornException if the register is not valid for the current + * architecture or mode. */ public Object reg_read(int regid, Object opt) throws UnicornException { return do_reg_read_obj(nativePtr, 0, arch, regid, opt); @@ -432,6 +437,8 @@ public class Unicorn * @param value Object containing the new register value. * @see {@link #reg_read(int, Object)} to write larger registers or * registers requiring configuration. + * @throws UnicornException if the register is not valid for the current + * architecture or mode. */ public void reg_write(int regid, long value) throws UnicornException { do_reg_write_long(nativePtr, 0, arch, regid, value); @@ -445,6 +452,7 @@ public class Unicorn *
  • {@code UC_X86_REG_ST*} => {@link X86_Float80} *
  • {@code UC_X86_REG_XMM*} => {@link BigInteger} (128 bits) *
  • {@code UC_X86_REG_YMM*} => {@link BigInteger} (256 bits) + *
  • {@code UC_X86_REG_ZMM*} => {@link BigInteger} (512 bits) *
  • {@code UC_X86_REG_MSR} => {@link X86_MSR} *
  • {@code UC_ARM_REG_CP} => {@link Arm_CP} *
  • {@code UC_ARM64_REG_CP} => {@link Arm64_CP} @@ -454,6 +462,8 @@ public class Unicorn * * @param regid Register ID that is to be modified. * @param value Object containing the new register value. + * @throws UnicornException if the register is not valid for the current + * architecture or mode. */ public void reg_write(int regid, Object value) throws UnicornException { do_reg_write_obj(nativePtr, 0, arch, regid, value); @@ -631,7 +641,13 @@ public class Unicorn return _ctl_request_cache(nativePtr, address); } - /** Invalidate the TB cache at a specific range of addresses. */ + /** Invalidate the TB cache for a specific range of addresses + * {@code [address, end)}. Note that invalidation will not include address + * {@code end} itself. + * + * @param address The first address in the region to invalidate + * @param end The last address in the region to invalidate, plus one + */ public void ctl_remove_cache(long address, long end) throws UnicornException { _ctl_remove_cache(nativePtr, address, end); @@ -1018,6 +1034,14 @@ public class Unicorn * Map a range of memory, backed by an existing region of host memory. * This API enables direct access to emulator memory without going through * {@link #mem_read} and {@link #mem_write}. + *

    + * Usage note: The mapped memory region will correspond to the entire + * passed-in Buffer from position 0 (the origin) up to its capacity. The + * capacity MUST be a multiple of the page size. The current position and + * limit will be ignored. + * You can use {@link Buffer#slice()} to get a new Buffer sharing the same + * memory region, with the origin set to the current {@code position} and + * the capacity set to {@code limit - position}. * * @param address Base address of the memory range * @param buf Direct Buffer referencing the memory to map into the From e787f49d21f1ef7d8a614249bebda5b479845273 Mon Sep 17 00:00:00 2001 From: Robert Xiao Date: Fri, 12 May 2023 23:17:08 -0700 Subject: [PATCH 10/25] Use an incrementing handle instead of returning a raw pointer to the user. --- bindings/java/unicorn/Unicorn.java | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/bindings/java/unicorn/Unicorn.java b/bindings/java/unicorn/Unicorn.java index 6ca880e1..bc19b57e 100644 --- a/bindings/java/unicorn/Unicorn.java +++ b/bindings/java/unicorn/Unicorn.java @@ -27,6 +27,9 @@ import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.Arrays; import java.util.Hashtable; +import java.util.Iterator; +import java.util.Map; +import java.util.concurrent.atomic.AtomicLong; /** Unicorn is a lightweight multi-platform, multi-architecture CPU emulator framework. */ public class Unicorn @@ -38,6 +41,15 @@ public class Unicorn private int mode; private Hashtable hooks = new Hashtable<>(); + /** Instead of handing out native pointers, we'll hand out a handle + * ID for safety. This prevents things like "double frees" - + * accidentally releasing an unrelated object via handle reuse. */ + private static AtomicLong allocCounter = new AtomicLong(0x1000); + + private static long nextAllocCounter() { + return allocCounter.addAndGet(8); + } + /** Wrapper around a registered hook */ private static class HookWrapper { private long nativePtr; @@ -676,8 +688,9 @@ public class Unicorn private long registerHook(long val) { HookWrapper wrapper = new HookWrapper(); wrapper.nativePtr = val; - hooks.put(val, wrapper); - return val; + long index = nextAllocCounter(); + hooks.put(index, wrapper); + return index; } /** @@ -982,9 +995,9 @@ public class Unicorn * @param hook The return value from any {@code hook_add} function. */ public void hook_del(long hook) throws UnicornException { - if (hooks.contains(hook)) { - hooks.remove(hooks, hook); - _hook_del(nativePtr, hook); + if (hooks.containsKey(hook)) { + HookWrapper wrapper = hooks.remove(hook); + _hook_del(nativePtr, wrapper.nativePtr); } else { throw new UnicornException("Hook is not registered!"); } From 48870c4cc3554552061c152495d4aa0ef066ac64 Mon Sep 17 00:00:00 2001 From: Robert Xiao Date: Fri, 12 May 2023 22:43:46 -0700 Subject: [PATCH 11/25] Reintroduce hook_del(Hook), since it seems useful. This also improves backwards compatibility a bit. --- bindings/java/tests/FunctionalityTests.java | 43 ++++++++++++++ bindings/java/unicorn/Unicorn.java | 63 ++++++++++++++------- 2 files changed, 85 insertions(+), 21 deletions(-) diff --git a/bindings/java/tests/FunctionalityTests.java b/bindings/java/tests/FunctionalityTests.java index ad3d6393..2c8bd79c 100644 --- a/bindings/java/tests/FunctionalityTests.java +++ b/bindings/java/tests/FunctionalityTests.java @@ -1,15 +1,18 @@ package tests; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThrows; import java.nio.ByteBuffer; import java.nio.ByteOrder; import org.junit.Test; +import unicorn.CodeHook; import unicorn.MemRegion; import unicorn.TlbFillHook; import unicorn.Unicorn; +import unicorn.UnicornException; import unicorn.X86_Float80; public class FunctionalityTests { @@ -181,4 +184,44 @@ public class FunctionalityTests { assertEquals(Math.sin(-1.1), reg.toDouble(), 1e-12); u.close(); } + + @Test + public void testRemoveHook() { + byte[] X86_CODE = { 0x40, 0x40, 0x40, 0x40 }; // (inc eax) x 4 + int ADDRESS = 0x10000; + final int[] hook_accum = { 0 }; + + Unicorn u = new Unicorn(Unicorn.UC_ARCH_X86, Unicorn.UC_MODE_32); + u.mem_map(ADDRESS, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL); + u.mem_write(ADDRESS, X86_CODE); + + CodeHook hook = + (uc, address, size, user) -> hook_accum[0] += (int) user; + long h1 = u.hook_add(hook, ADDRESS, ADDRESS, 1); + long h2 = u.hook_add(hook, ADDRESS + 1, ADDRESS + 1, 2); + long h3 = u.hook_add(hook, ADDRESS + 2, ADDRESS + 2, 4); + long h4 = u.hook_add(hook, ADDRESS + 3, ADDRESS + 3, 8); + + hook_accum[0] = 0; + u.emu_start(ADDRESS, ADDRESS + X86_CODE.length, 0, 0); + assertEquals(15, hook_accum[0]); + + u.hook_del(h2); + + hook_accum[0] = 0; + u.emu_start(ADDRESS, ADDRESS + X86_CODE.length, 0, 0); + assertEquals(13, hook_accum[0]); + + u.hook_del(hook); + + hook_accum[0] = 0; + u.emu_start(ADDRESS, ADDRESS + X86_CODE.length, 0, 0); + assertEquals(0, hook_accum[0]); + + assertThrows(UnicornException.class, () -> u.hook_del(h1)); + assertThrows(UnicornException.class, () -> u.hook_del(h3)); + assertThrows(UnicornException.class, () -> u.hook_del(h4)); + + u.close(); + } } diff --git a/bindings/java/unicorn/Unicorn.java b/bindings/java/unicorn/Unicorn.java index bc19b57e..7b7fe321 100644 --- a/bindings/java/unicorn/Unicorn.java +++ b/bindings/java/unicorn/Unicorn.java @@ -52,7 +52,8 @@ public class Unicorn /** Wrapper around a registered hook */ private static class HookWrapper { - private long nativePtr; + Hook hook; + long nativePtr; @Override protected void finalize() { @@ -685,8 +686,9 @@ public class Unicorn _ctl_tlb_mode(nativePtr, mode); } - private long registerHook(long val) { + private long registerHook(Hook hook, long val) { HookWrapper wrapper = new HookWrapper(); + wrapper.hook = hook; wrapper.nativePtr = val; long index = nextAllocCounter(); hooks.put(index, wrapper); @@ -705,7 +707,7 @@ public class Unicorn */ public long hook_add(InterruptHook callback, Object user_data) throws UnicornException { - return registerHook( + return registerHook(callback, _hook_add(nativePtr, UC_HOOK_INTR, callback, user_data, 1, 0)); } @@ -728,8 +730,8 @@ public class Unicorn long end, Object user_data) throws UnicornException { - return registerHook(_hook_add(nativePtr, UC_HOOK_INSN, callback, - user_data, begin, end, insn)); + return registerHook(callback, _hook_add(nativePtr, UC_HOOK_INSN, + callback, user_data, begin, end, insn)); } /** @@ -811,8 +813,8 @@ public class Unicorn public long hook_add(CodeHook callback, long begin, long end, Object user_data) throws UnicornException { - return registerHook(_hook_add(nativePtr, UC_HOOK_CODE, callback, - user_data, begin, end)); + return registerHook(callback, _hook_add(nativePtr, UC_HOOK_CODE, + callback, user_data, begin, end)); } /** @@ -833,8 +835,8 @@ public class Unicorn public long hook_add(BlockHook callback, long begin, long end, Object user_data) throws UnicornException { - return registerHook(_hook_add(nativePtr, UC_HOOK_BLOCK, callback, - user_data, begin, end)); + return registerHook(callback, _hook_add(nativePtr, UC_HOOK_BLOCK, + callback, user_data, begin, end)); } /** @@ -859,7 +861,7 @@ public class Unicorn public long hook_add(MemHook callback, int type, long begin, long end, Object user_data) throws UnicornException { - return registerHook( + return registerHook(callback, _hook_add(nativePtr, type, callback, user_data, begin, end)); } @@ -884,7 +886,7 @@ public class Unicorn public long hook_add(EventMemHook callback, int type, long begin, long end, Object user_data) throws UnicornException { - return registerHook( + return registerHook(callback, _hook_add(nativePtr, type, callback, user_data, begin, end)); } @@ -902,7 +904,7 @@ public class Unicorn */ public long hook_add(EventMemHook callback, int type, Object user_data) throws UnicornException { - return registerHook( + return registerHook(callback, _hook_add(nativePtr, type, callback, user_data, 1, 0)); } @@ -919,8 +921,8 @@ public class Unicorn */ public long hook_add(InvalidInstructionHook callback, Object user_data) { - return registerHook(_hook_add(nativePtr, UC_HOOK_INSN_INVALID, callback, - user_data, 1, 0)); + return registerHook(callback, _hook_add(nativePtr, UC_HOOK_INSN_INVALID, + callback, user_data, 1, 0)); } /** @@ -941,8 +943,8 @@ public class Unicorn public long hook_add(EdgeGeneratedHook callback, long begin, long end, Object user_data) throws UnicornException { - return registerHook(_hook_add(nativePtr, UC_HOOK_EDGE_GENERATED, - callback, user_data, begin, end)); + return registerHook(callback, _hook_add(nativePtr, + UC_HOOK_EDGE_GENERATED, callback, user_data, begin, end)); } /** @@ -966,8 +968,8 @@ public class Unicorn int opcode, int flags, Object user_data) throws UnicornException { - return registerHook(_hook_add(nativePtr, UC_HOOK_TCG_OPCODE, callback, - user_data, begin, end, opcode, flags)); + return registerHook(callback, _hook_add(nativePtr, UC_HOOK_TCG_OPCODE, + callback, user_data, begin, end, opcode, flags)); } /** @@ -986,8 +988,8 @@ public class Unicorn */ public long hook_add(TlbFillHook callback, long begin, long end, Object user_data) throws UnicornException { - return registerHook(_hook_add(nativePtr, UC_HOOK_TLB_FILL, callback, - user_data, begin, end)); + return registerHook(callback, _hook_add(nativePtr, UC_HOOK_TLB_FILL, + callback, user_data, begin, end)); } /** Remove a hook that was previously registered. @@ -1003,6 +1005,25 @@ public class Unicorn } } + /** Remove all registrations for a given {@link Hook} object. + * + * @param hook A {@link Hook} object to unregister. + */ + public void hook_del(Hook hook) throws UnicornException { + if (hook == null) { + // we use null for "special" hooks that can't be _hook_del'd + throw new NullPointerException("hook must not be null"); + } + Iterator> it = hooks.entrySet().iterator(); + while (it.hasNext()) { + HookWrapper wrapper = it.next().getValue(); + if (wrapper.hook == hook) { + it.remove(); + _hook_del(nativePtr, wrapper.nativePtr); + } + } + } + /** * Create a memory-mapped I/O range. * @@ -1026,7 +1047,7 @@ public class Unicorn long[] hooks = _mmio_map(nativePtr, address, size, read_cb, user_data_read, write_cb, user_data_write); for (long hook : hooks) { - registerHook(hook); + registerHook(null, hook); } } From 32e638dcf48a90bfa98ead806c5b44cc38560ca2 Mon Sep 17 00:00:00 2001 From: Robert Xiao Date: Fri, 12 May 2023 23:05:35 -0700 Subject: [PATCH 12/25] Add more deprecated APIs for backwards compat --- bindings/java/unicorn/Unicorn.java | 70 ++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/bindings/java/unicorn/Unicorn.java b/bindings/java/unicorn/Unicorn.java index 7b7fe321..f1f1cb8f 100644 --- a/bindings/java/unicorn/Unicorn.java +++ b/bindings/java/unicorn/Unicorn.java @@ -482,6 +482,34 @@ public class Unicorn do_reg_write_obj(nativePtr, 0, arch, regid, value); } + /** @deprecated Use individual calls to {@code reg_read} instead. + * This method is deprecated as it is much slower than + * {@link #reg_read(int)} for reading 64-bit-or-smaller registers. + */ + @Deprecated + public Object[] reg_read_batch(int regids[]) throws UnicornException { + Object[] res = new Object[regids.length]; + for (int i = 0; i < regids.length; i++) { + res[i] = reg_read(regids[i], null); + } + return res; + } + + /** @deprecated Use individual calls to {@code reg_write} instead. + * This method is deprecated as it is much slower than + * {@link #reg_write(int, long)} for writing 64-bit-or-smaller registers. + */ + @Deprecated + 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]); + } + } + /** * Read from memory. * @@ -1161,6 +1189,48 @@ public class Unicorn _context_restore(nativePtr, context.nativePtr); } + /* Obsolete context implementation, for backwards compatibility only */ + /** Structure to track contexts allocated using context_alloc, for + * memory safety. Not used for contexts created using + * {@link #context_save()}. + */ + private static Hashtable allocedContexts = new Hashtable<>(); + + /** @deprecated Use {@link #context_save()} instead. */ + @Deprecated + public long context_alloc() { + long ptr = _context_alloc(nativePtr); + Context context = new Context(); + context.nativePtr = ptr; + context.arch = arch; + context.mode = mode; + long index = nextAllocCounter(); + allocedContexts.put(index, context); + return index; + } + + /** @deprecated Do not use this method. + * + * @param handle Value previously returned by {@link #context_alloc} + */ + @Deprecated + public void free(long handle) { + allocedContexts.remove(handle); + } + + /** @deprecated Use {@link #context_save()} or {@link #context_update} + * instead */ + @Deprecated + public void context_save(long context) { + context_update(allocedContexts.get(context)); + } + + /** @deprecated Use {@link #context_restore(Context)} instead */ + @Deprecated + public void context_restore(long context) { + context_restore(allocedContexts.get(context)); + } + /* Native implementation */ private static native long _open(int arch, int mode) throws UnicornException; From 77d4a1d8b11b17d580e489cd6136c0fa44f0995f Mon Sep 17 00:00:00 2001 From: Robert Xiao Date: Sat, 13 May 2023 00:56:07 -0700 Subject: [PATCH 13/25] Fix definition of uc_version --- bindings/java/unicorn/Unicorn.java | 6 +++--- include/unicorn/unicorn.h | 8 +++----- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/bindings/java/unicorn/Unicorn.java b/bindings/java/unicorn/Unicorn.java index f1f1cb8f..f2840cce 100644 --- a/bindings/java/unicorn/Unicorn.java +++ b/bindings/java/unicorn/Unicorn.java @@ -161,9 +161,9 @@ public class Unicorn /** * Return combined API version & major and minor version numbers. * - * @return version number as {@code (major << 8 | minor)}, which encodes - * both major & minor versions. - * For example, Unicorn version 1.2 would yield 0x0102. + * @return version number as {@code (major << 24 | minor << 16 | + * patch << 8 | extra)}. + * For example, Unicorn version 2.0.1 final would be 0x020001ff. */ public static int version() { return _version(); diff --git a/include/unicorn/unicorn.h b/include/unicorn/unicorn.h index 3814b8e0..c170029b 100644 --- a/include/unicorn/unicorn.h +++ b/include/unicorn/unicorn.h @@ -86,7 +86,7 @@ typedef size_t uc_hook; Macro to create combined version which can be compared to result of uc_version() API. */ -#define UC_MAKE_VERSION(major, minor) ((major << 8) + minor) +#define UC_MAKE_VERSION(major, minor) (((major) << 24) + ((minor) << 16)) // Scales to calculate timeout on microsecond unit // 1 second = 1000,000 microseconds @@ -673,13 +673,11 @@ typedef struct uc_context uc_context; @major: major number of API version @minor: minor number of API version - @return hexical number as (major << 8 | minor), which encodes both - major & minor versions. + @return hexadecimal number as (major << 24 | minor << 16 | patch << 8 | extra). NOTE: This returned value can be compared with version number made with macro UC_MAKE_VERSION - For example, second API version would return 1 in @major, and 1 in @minor - The return value would be 0x0101 + For example, Unicorn version 2.0.1 final would be 0x020001ff. NOTE: if you only care about returned value, but not major and minor values, set both @major & @minor arguments to NULL. From d4df61b4c5a2227213c09c28020aedd10f842a67 Mon Sep 17 00:00:00 2001 From: Robert Xiao Date: Sat, 13 May 2023 10:55:13 -0700 Subject: [PATCH 14/25] Refactor tests and add a few more --- bindings/java/tests/FunctionalityTests.java | 352 +++++++++----------- bindings/java/tests/HookTests.java | 130 ++++++++ bindings/java/tests/MemTests.java | 138 ++++++++ bindings/java/tests/RegTests.java | 50 +++ bindings/java/unicorn/MemRegion.java | 4 +- bindings/java/unicorn/TranslationBlock.java | 6 + bindings/java/unicorn/Unicorn.java | 3 + 7 files changed, 488 insertions(+), 195 deletions(-) create mode 100644 bindings/java/tests/HookTests.java create mode 100644 bindings/java/tests/MemTests.java create mode 100644 bindings/java/tests/RegTests.java diff --git a/bindings/java/tests/FunctionalityTests.java b/bindings/java/tests/FunctionalityTests.java index 2c8bd79c..38e7908d 100644 --- a/bindings/java/tests/FunctionalityTests.java +++ b/bindings/java/tests/FunctionalityTests.java @@ -2,226 +2,192 @@ package tests; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThrows; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; +import static org.junit.Assert.assertTrue; import org.junit.Test; -import unicorn.CodeHook; -import unicorn.MemRegion; -import unicorn.TlbFillHook; import unicorn.Unicorn; import unicorn.UnicornException; -import unicorn.X86_Float80; +/** Test miscellaneous features that don't fall into the register, memory + * or hook API */ public class FunctionalityTests { + @Test - public void testMemRegions() { - Unicorn uc = new Unicorn(Unicorn.UC_ARCH_ARM64, Unicorn.UC_MODE_ARM); - long ADDR1 = 0x10000; - long ADDR2 = 0xdeadbeeffeed1000L; - uc.mem_map(ADDR1, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL); - uc.mem_map(ADDR2, 4096, Unicorn.UC_PROT_READ); - MemRegion[] arr = uc.mem_regions(); - assertEquals("two memory regions", 2, arr.length); - assertEquals("begin", ADDR1, arr[0].begin); - assertEquals("end", ADDR1 + 2 * 1024 * 1024 - 1, arr[0].end); - assertEquals("perms", Unicorn.UC_PROT_ALL, arr[0].perms); - assertEquals("begin", ADDR2, arr[1].begin); - assertEquals("end", ADDR2 + 4096 - 1, arr[1].end); - assertEquals("perms", Unicorn.UC_PROT_READ, arr[1].perms); - uc.close(); + public void testStatics() { + assertEquals(true, Unicorn.arch_supported(Unicorn.UC_ARCH_X86)); + assertEquals(false, Unicorn.arch_supported(Unicorn.UC_ARCH_MAX + 1)); + assertTrue("version check", Unicorn.version() >= 0x02000100); + assertEquals("OK (UC_ERR_OK)", Unicorn.strerror(Unicorn.UC_ERR_OK)); + assertEquals("Invalid handle (UC_ERR_HANDLE)", + Unicorn.strerror(Unicorn.UC_ERR_HANDLE)); + } + + @Test + public void testCreation() { + assertThrows(UnicornException.class, + () -> new Unicorn(Unicorn.UC_ARCH_MAX + 1, 0)); + + if (Unicorn.arch_supported(Unicorn.UC_ARCH_X86)) { + new Unicorn(Unicorn.UC_ARCH_X86, Unicorn.UC_MODE_16); + new Unicorn(Unicorn.UC_ARCH_X86, Unicorn.UC_MODE_32); + new Unicorn(Unicorn.UC_ARCH_X86, Unicorn.UC_MODE_64); + assertThrows(UnicornException.class, + () -> new Unicorn(Unicorn.UC_ARCH_X86, + Unicorn.UC_MODE_BIG_ENDIAN)); + } + + if (Unicorn.arch_supported(Unicorn.UC_ARCH_M68K)) { + new Unicorn(Unicorn.UC_ARCH_M68K, Unicorn.UC_MODE_BIG_ENDIAN); + assertThrows(UnicornException.class, + () -> new Unicorn(Unicorn.UC_ARCH_M68K, + Unicorn.UC_MODE_LITTLE_ENDIAN)); + } + + if (Unicorn.arch_supported(Unicorn.UC_ARCH_ARM)) { + new Unicorn(Unicorn.UC_ARCH_ARM, 0); + new Unicorn(Unicorn.UC_ARCH_ARM, Unicorn.UC_MODE_BIG_ENDIAN); + new Unicorn(Unicorn.UC_ARCH_ARM, Unicorn.UC_MODE_THUMB); + } + + if (Unicorn.arch_supported(Unicorn.UC_ARCH_ARM64)) { + new Unicorn(Unicorn.UC_ARCH_ARM64, 0); + new Unicorn(Unicorn.UC_ARCH_ARM64, Unicorn.UC_MODE_BIG_ENDIAN); + } + + if (Unicorn.arch_supported(Unicorn.UC_ARCH_MIPS)) { + new Unicorn(Unicorn.UC_ARCH_MIPS, + Unicorn.UC_MODE_BIG_ENDIAN | Unicorn.UC_MODE_32); + new Unicorn(Unicorn.UC_ARCH_MIPS, + Unicorn.UC_MODE_LITTLE_ENDIAN | Unicorn.UC_MODE_32); + new Unicorn(Unicorn.UC_ARCH_MIPS, + Unicorn.UC_MODE_BIG_ENDIAN | Unicorn.UC_MODE_64); + new Unicorn(Unicorn.UC_ARCH_MIPS, + Unicorn.UC_MODE_LITTLE_ENDIAN | Unicorn.UC_MODE_64); + assertThrows(UnicornException.class, + () -> new Unicorn(Unicorn.UC_ARCH_MIPS, Unicorn.UC_MODE_16)); + } + + if (Unicorn.arch_supported(Unicorn.UC_ARCH_SPARC)) { + new Unicorn(Unicorn.UC_ARCH_SPARC, + Unicorn.UC_MODE_BIG_ENDIAN | Unicorn.UC_MODE_32); + new Unicorn(Unicorn.UC_ARCH_SPARC, + Unicorn.UC_MODE_BIG_ENDIAN | Unicorn.UC_MODE_64); + assertThrows(UnicornException.class, + () -> new Unicorn(Unicorn.UC_ARCH_SPARC, + Unicorn.UC_MODE_LITTLE_ENDIAN | Unicorn.UC_MODE_32)); + } + + if (Unicorn.arch_supported(Unicorn.UC_ARCH_PPC)) { + new Unicorn(Unicorn.UC_ARCH_PPC, + Unicorn.UC_MODE_BIG_ENDIAN | Unicorn.UC_MODE_32); + new Unicorn(Unicorn.UC_ARCH_PPC, + Unicorn.UC_MODE_BIG_ENDIAN | Unicorn.UC_MODE_64); + assertThrows(UnicornException.class, + () -> new Unicorn(Unicorn.UC_ARCH_PPC, + Unicorn.UC_MODE_LITTLE_ENDIAN | Unicorn.UC_MODE_32)); + } + + if (Unicorn.arch_supported(Unicorn.UC_ARCH_RISCV)) { + new Unicorn(Unicorn.UC_ARCH_RISCV, Unicorn.UC_MODE_32); + new Unicorn(Unicorn.UC_ARCH_RISCV, Unicorn.UC_MODE_64); + } + + if (Unicorn.arch_supported(Unicorn.UC_ARCH_S390X)) { + new Unicorn(Unicorn.UC_ARCH_S390X, Unicorn.UC_MODE_BIG_ENDIAN); + assertThrows(UnicornException.class, + () -> new Unicorn(Unicorn.UC_ARCH_S390X, + Unicorn.UC_MODE_LITTLE_ENDIAN)); + + new Unicorn(Unicorn.UC_ARCH_TRICORE, 0); + } + } + + @Test + public void testThreading() { + // EB FE - label: jmp label + final byte[] X86_CODE = { -21, -2 }; + + long ADDRESS = 0x100000; + + Unicorn u = new Unicorn(Unicorn.UC_ARCH_X86, Unicorn.UC_MODE_32); + u.mem_map(ADDRESS, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL); + u.mem_write(ADDRESS, X86_CODE); + new Thread(() -> { + try { + Thread.sleep(500); + } catch (InterruptedException e) { + e.printStackTrace(); + } + u.emu_stop(); + }).start(); + u.emu_start(ADDRESS, ADDRESS + X86_CODE.length, 0, 0); + + u.close(); } @Test public void testContext() { Unicorn uc = new Unicorn(Unicorn.UC_ARCH_ARM64, Unicorn.UC_MODE_ARM); - uc.reg_write(Unicorn.UC_ARM64_REG_X0, 0xdeadbeef); + uc.reg_write(Unicorn.UC_ARM64_REG_X0, 0xdeadbeefL); Unicorn.Context ctx = uc.context_save(); - uc.reg_write(Unicorn.UC_ARM64_REG_X0, 0xfeedface); - assertEquals("X0 changed", 0xfeedface, - uc.reg_read(Unicorn.UC_ARM64_REG_X0)); + assertEquals(0xdeadbeefL, uc.reg_read(Unicorn.UC_ARM64_REG_X0)); + assertEquals(0xdeadbeefL, ctx.reg_read(Unicorn.UC_ARM64_REG_X0)); + + uc.reg_write(Unicorn.UC_ARM64_REG_X0, 0xfeedfaceL); + assertEquals(0xfeedfaceL, uc.reg_read(Unicorn.UC_ARM64_REG_X0)); + assertEquals(0xdeadbeefL, ctx.reg_read(Unicorn.UC_ARM64_REG_X0)); + uc.context_restore(ctx); - assertEquals("X0 restored", 0xdeadbeef, - uc.reg_read(Unicorn.UC_ARM64_REG_X0)); - uc.reg_write(Unicorn.UC_ARM64_REG_X0, 0xfee1dead); + assertEquals(0xdeadbeefL, uc.reg_read(Unicorn.UC_ARM64_REG_X0)); + assertEquals(0xdeadbeefL, ctx.reg_read(Unicorn.UC_ARM64_REG_X0)); + + uc.reg_write(Unicorn.UC_ARM64_REG_X0, 0xfee1deadL); + assertEquals(0xfee1deadL, uc.reg_read(Unicorn.UC_ARM64_REG_X0)); + assertEquals(0xdeadbeefL, ctx.reg_read(Unicorn.UC_ARM64_REG_X0)); + uc.context_update(ctx); - assertEquals("X0 changed", 0xfee1dead, - uc.reg_read(Unicorn.UC_ARM64_REG_X0)); - uc.reg_write(Unicorn.UC_ARM64_REG_X0, 0xdeadbeef); - assertEquals("X0 changed", 0xdeadbeef, - uc.reg_read(Unicorn.UC_ARM64_REG_X0)); + assertEquals(0xfee1deadL, uc.reg_read(Unicorn.UC_ARM64_REG_X0)); + assertEquals(0xfee1deadL, ctx.reg_read(Unicorn.UC_ARM64_REG_X0)); + + uc.reg_write(Unicorn.UC_ARM64_REG_X0, 0xdeadbeefL); + assertEquals(0xdeadbeefL, uc.reg_read(Unicorn.UC_ARM64_REG_X0)); + assertEquals(0xfee1deadL, ctx.reg_read(Unicorn.UC_ARM64_REG_X0)); + uc.context_restore(ctx); - assertEquals("X0 restored", 0xfee1dead, - uc.reg_read(Unicorn.UC_ARM64_REG_X0)); + assertEquals(0xfee1deadL, uc.reg_read(Unicorn.UC_ARM64_REG_X0)); + assertEquals(0xfee1deadL, ctx.reg_read(Unicorn.UC_ARM64_REG_X0)); + uc.close(); } @Test - public void testMmio() { - // mov ecx, [0xaaaaaaa8]; inc ecx; dec edx; mov [0xaaaaaaa8], ecx; inc ecx; dec edx - final byte[] X86_CODE32_MEM_READ_WRITE = - { -117, 13, -88, -86, -86, -86, 65, 74, -119, 13, -88, -86, -86, - -86, 65, 74 }; + public void testOldContext() { + Unicorn uc = new Unicorn(Unicorn.UC_ARCH_ARM64, Unicorn.UC_MODE_ARM); + uc.reg_write(Unicorn.UC_ARM64_REG_X0, 0xdeadbeefL); + long ctx = uc.context_alloc(); + uc.context_save(ctx); + assertEquals(0xdeadbeefL, uc.reg_read(Unicorn.UC_ARM64_REG_X0)); - long ADDRESS = 0x100000; + uc.reg_write(Unicorn.UC_ARM64_REG_X0, 0xfeedfaceL); + assertEquals(0xfeedfaceL, uc.reg_read(Unicorn.UC_ARM64_REG_X0)); - 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, Unicorn.UC_PROT_ALL); + uc.context_restore(ctx); + assertEquals(0xdeadbeefL, uc.reg_read(Unicorn.UC_ARM64_REG_X0)); - // write machine code to be emulated to memory - u.mem_write(ADDRESS, X86_CODE32_MEM_READ_WRITE); + uc.reg_write(Unicorn.UC_ARM64_REG_X0, 0xfee1deadL); + assertEquals(0xfee1deadL, uc.reg_read(Unicorn.UC_ARM64_REG_X0)); - // initialize machine registers - u.reg_write(Unicorn.UC_X86_REG_ECX, 0x12345678); - u.reg_write(Unicorn.UC_X86_REG_EDX, 0x22334455); + uc.context_save(ctx); + assertEquals(0xfee1deadL, uc.reg_read(Unicorn.UC_ARM64_REG_X0)); - u.mmio_map(0xaaaaa000L, 0x1000, (uc, offset, size, user_data) -> { - assertEquals("read offset", 0xaa8, offset); - assertEquals("read size", 4, size); - assertEquals("read user_data", "read_data", user_data); - return 0x44556677; - }, "read_data", (uc, offset, size, value, user_data) -> { - assertEquals("write offset", 0xaa8, offset); - assertEquals("write size", 4, size); - assertEquals("write value", 0x44556678, value); - assertEquals("write user_data", "write_data", user_data); - }, "write_data"); + uc.reg_write(Unicorn.UC_ARM64_REG_X0, 0xdeadbeefL); + assertEquals(0xdeadbeefL, uc.reg_read(Unicorn.UC_ARM64_REG_X0)); - u.emu_start(ADDRESS, ADDRESS + X86_CODE32_MEM_READ_WRITE.length, 0, 0); + uc.context_restore(ctx); + assertEquals(0xfee1deadL, uc.reg_read(Unicorn.UC_ARM64_REG_X0)); - assertEquals("ecx", 0x44556679, u.reg_read(Unicorn.UC_X86_REG_ECX)); - assertEquals("edx", 0x22334453, u.reg_read(Unicorn.UC_X86_REG_EDX)); - - u.close(); - } - - @Test - public void testMemMapPtr() { - ByteBuffer buffer = - ByteBuffer.allocateDirect(0x1000).order(ByteOrder.LITTLE_ENDIAN); - final byte[] X86_CODE32_MEM_WRITE = - { -119, 13, -86, -86, -86, -86, 65, 74 }; - - long ADDRESS = 0x100000; - - Unicorn u = new Unicorn(Unicorn.UC_ARCH_X86, Unicorn.UC_MODE_32); - u.mem_map(ADDRESS, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL); - u.mem_map_ptr(0xaaaaa000L, buffer, Unicorn.UC_PROT_ALL); - u.mem_write(ADDRESS, X86_CODE32_MEM_WRITE); - u.reg_write(Unicorn.UC_X86_REG_ECX, 0x12345678); - u.emu_start(ADDRESS, ADDRESS + X86_CODE32_MEM_WRITE.length, 0, 0); - - assertEquals("buffer contents", 0x12345678, buffer.getInt(0xaaa)); - - u.close(); - } - - @Test - public void testTlbHook() { - // mov ecx, [0xaaaaaaa8] - final byte[] X86_CODE32_MEM_READ = { -117, 13, -88, -86, -86, -86 }; - - long ADDRESS = 0x100000; - - Unicorn u = new Unicorn(Unicorn.UC_ARCH_X86, Unicorn.UC_MODE_32); - u.mem_map(ADDRESS, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL); - u.mem_map(0xbbbbb000L, 0x1000, Unicorn.UC_PROT_READ); - u.hook_add((TlbFillHook) (uc, address, type, user_data) -> { - assertEquals("fill hook address", 0xaaaaa000L, address); - assertEquals("fill hook type", Unicorn.UC_MEM_READ, type); - assertEquals("fill hook user", "fill_hook", user_data); - return 0xbbbbb000L | Unicorn.UC_PROT_READ; - }, 0xaaaaa000L, 0xaaaab000L, "fill_hook"); - u.mem_write(ADDRESS, X86_CODE32_MEM_READ); - u.mem_write(0xbbbbbaa8L, new byte[] { 1, 2, 3, 4 }); - u.reg_write(Unicorn.UC_X86_REG_ECX, 0x12345678); - u.ctl_tlb_mode(Unicorn.UC_TLB_VIRTUAL); - u.emu_start(ADDRESS, ADDRESS + X86_CODE32_MEM_READ.length, 0, 0); - assertEquals("ecx", u.reg_read(Unicorn.UC_X86_REG_ECX), 0x04030201); - - u.close(); - } - - @Test - public void testX86ReadFloat80() { - // fldl2e; fsin - final byte[] X86_CODE = { -39, -22, -39, -2 }; - - long ADDRESS = 0x100000; - - Unicorn u = new Unicorn(Unicorn.UC_ARCH_X86, Unicorn.UC_MODE_32); - u.mem_map(ADDRESS, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL); - u.mem_write(ADDRESS, X86_CODE); - u.emu_start(ADDRESS, ADDRESS + X86_CODE.length, 0, 0); - X86_Float80 reg1 = - (X86_Float80) u.reg_read(Unicorn.UC_X86_REG_ST0, null); - X86_Float80 reg2 = - (X86_Float80) u.reg_read(Unicorn.UC_X86_REG_FP7, null); - assertEquals(null, ADDRESS, ADDRESS, ADDRESS); - assertEquals(Math.sin(Math.log(Math.E) / Math.log(2)), reg1.toDouble(), - 1e-12); - assertEquals(reg1.toDouble(), reg2.toDouble(), 1e-12); - u.close(); - } - - @Test - public void testX86WriteFloat80() { - // fsin - final byte[] X86_CODE = { -39, -2 }; - - long ADDRESS = 0x100000; - - Unicorn u = new Unicorn(Unicorn.UC_ARCH_X86, Unicorn.UC_MODE_32); - u.mem_map(ADDRESS, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL); - u.mem_write(ADDRESS, X86_CODE); - X86_Float80 reg = X86_Float80.fromDouble(-1.1); - u.reg_write(Unicorn.UC_X86_REG_ST0, reg); - u.emu_start(ADDRESS, ADDRESS + X86_CODE.length, 0, 0); - reg = (X86_Float80) u.reg_read(Unicorn.UC_X86_REG_ST0, null); - assertEquals(Math.sin(-1.1), reg.toDouble(), 1e-12); - u.close(); - } - - @Test - public void testRemoveHook() { - byte[] X86_CODE = { 0x40, 0x40, 0x40, 0x40 }; // (inc eax) x 4 - int ADDRESS = 0x10000; - final int[] hook_accum = { 0 }; - - Unicorn u = new Unicorn(Unicorn.UC_ARCH_X86, Unicorn.UC_MODE_32); - u.mem_map(ADDRESS, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL); - u.mem_write(ADDRESS, X86_CODE); - - CodeHook hook = - (uc, address, size, user) -> hook_accum[0] += (int) user; - long h1 = u.hook_add(hook, ADDRESS, ADDRESS, 1); - long h2 = u.hook_add(hook, ADDRESS + 1, ADDRESS + 1, 2); - long h3 = u.hook_add(hook, ADDRESS + 2, ADDRESS + 2, 4); - long h4 = u.hook_add(hook, ADDRESS + 3, ADDRESS + 3, 8); - - hook_accum[0] = 0; - u.emu_start(ADDRESS, ADDRESS + X86_CODE.length, 0, 0); - assertEquals(15, hook_accum[0]); - - u.hook_del(h2); - - hook_accum[0] = 0; - u.emu_start(ADDRESS, ADDRESS + X86_CODE.length, 0, 0); - assertEquals(13, hook_accum[0]); - - u.hook_del(hook); - - hook_accum[0] = 0; - u.emu_start(ADDRESS, ADDRESS + X86_CODE.length, 0, 0); - assertEquals(0, hook_accum[0]); - - assertThrows(UnicornException.class, () -> u.hook_del(h1)); - assertThrows(UnicornException.class, () -> u.hook_del(h3)); - assertThrows(UnicornException.class, () -> u.hook_del(h4)); - - u.close(); + uc.free(ctx); + uc.close(); } } diff --git a/bindings/java/tests/HookTests.java b/bindings/java/tests/HookTests.java new file mode 100644 index 00000000..7b0500fc --- /dev/null +++ b/bindings/java/tests/HookTests.java @@ -0,0 +1,130 @@ +package tests; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThrows; + +import org.junit.Test; + +import unicorn.CodeHook; +import unicorn.EdgeGeneratedHook; +import unicorn.TlbFillHook; +import unicorn.TranslationBlock; +import unicorn.Unicorn; +import unicorn.UnicornException; + +public class HookTests { + private static void assertTranslationBlock(TranslationBlock expected, + TranslationBlock actual) { + assertEquals(expected.pc, actual.pc); + assertEquals(expected.icount, actual.icount); + assertEquals(expected.size, actual.size); + } + + @Test + public void testEdgeHook() { + /* + 00000000 83FB01 cmp ebx,byte +0x1 + 00000003 7405 jz 0xa + 00000005 B802000000 mov eax,0x2 + 0000000A 40 inc eax + 0000000B EBFE jmp short 0xb + */ + final byte[] X86_CODE = + { -125, -5, 1, 116, 5, -72, 2, 0, 0, 0, 64, -21, -2 }; + final TranslationBlock[] expectedTb = { null, null }; + + long ADDRESS = 0x100000; + + Unicorn u = new Unicorn(Unicorn.UC_ARCH_X86, Unicorn.UC_MODE_32); + u.mem_map(ADDRESS, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL); + u.mem_write(ADDRESS, X86_CODE); + expectedTb[1] = new TranslationBlock(ADDRESS, 2, 5); + u.hook_add((EdgeGeneratedHook) (uc, cur_tb, prev_tb, user) -> { + assertTranslationBlock(expectedTb[0], cur_tb); + assertTranslationBlock(expectedTb[1], prev_tb); + assertEquals("user data", user); + }, ADDRESS, ADDRESS + 10, "user data"); + + // TODO(nneonneo): why is icount 2/3 in the subsequent blocks? + expectedTb[0] = new TranslationBlock(ADDRESS + 10, 2, 1); + u.reg_write(Unicorn.UC_X86_REG_EBX, 1); + u.emu_start(ADDRESS, ADDRESS + 11, 0, 0); + + expectedTb[0] = new TranslationBlock(ADDRESS + 5, 3, 6); + u.reg_write(Unicorn.UC_X86_REG_EBX, 0); + u.emu_start(ADDRESS, ADDRESS + 11, 0, 0); + + assertTranslationBlock(new TranslationBlock(ADDRESS, 2, 5), + u.ctl_request_cache(ADDRESS)); + // TODO(nneonneo): I don't totally understand this output! Why 8 bytes at address 5? + assertTranslationBlock(new TranslationBlock(ADDRESS + 5, 3, 8), + u.ctl_request_cache(ADDRESS + 5)); + u.close(); + } + + @Test + public void testTlbHook() { + // mov ecx, [0xaaaaaaa8] + final byte[] X86_CODE32_MEM_READ = { -117, 13, -88, -86, -86, -86 }; + + long ADDRESS = 0x100000; + + Unicorn u = new Unicorn(Unicorn.UC_ARCH_X86, Unicorn.UC_MODE_32); + u.mem_map(ADDRESS, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL); + u.mem_map(0xbbbbb000L, 0x1000, Unicorn.UC_PROT_READ); + u.hook_add((TlbFillHook) (uc, address, type, user_data) -> { + assertEquals("fill hook address", 0xaaaaa000L, address); + assertEquals("fill hook type", Unicorn.UC_MEM_READ, type); + assertEquals("fill hook user", "fill_hook", user_data); + return 0xbbbbb000L | Unicorn.UC_PROT_READ; + }, 0xaaaaa000L, 0xaaaab000L, "fill_hook"); + u.mem_write(ADDRESS, X86_CODE32_MEM_READ); + u.mem_write(0xbbbbbaa8L, new byte[] { 1, 2, 3, 4 }); + u.reg_write(Unicorn.UC_X86_REG_ECX, 0x12345678); + u.ctl_tlb_mode(Unicorn.UC_TLB_VIRTUAL); + u.emu_start(ADDRESS, ADDRESS + X86_CODE32_MEM_READ.length, 0, 0); + assertEquals("ecx", u.reg_read(Unicorn.UC_X86_REG_ECX), 0x04030201); + + u.close(); + } + + @Test + public void testRemoveHook() { + byte[] X86_CODE = { 0x40, 0x40, 0x40, 0x40 }; // (inc eax) x 4 + int ADDRESS = 0x10000; + final int[] hook_accum = { 0 }; + + Unicorn u = new Unicorn(Unicorn.UC_ARCH_X86, Unicorn.UC_MODE_32); + u.mem_map(ADDRESS, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL); + u.mem_write(ADDRESS, X86_CODE); + + CodeHook hook = + (uc, address, size, user) -> hook_accum[0] += (int) user; + long h1 = u.hook_add(hook, ADDRESS, ADDRESS, 1); + long h2 = u.hook_add(hook, ADDRESS + 1, ADDRESS + 1, 2); + long h3 = u.hook_add(hook, ADDRESS + 2, ADDRESS + 2, 4); + long h4 = u.hook_add(hook, ADDRESS + 3, ADDRESS + 3, 8); + + hook_accum[0] = 0; + u.emu_start(ADDRESS, ADDRESS + X86_CODE.length, 0, 0); + assertEquals(15, hook_accum[0]); + + u.hook_del(h2); + + hook_accum[0] = 0; + u.emu_start(ADDRESS, ADDRESS + X86_CODE.length, 0, 0); + assertEquals(13, hook_accum[0]); + + u.hook_del(hook); + + hook_accum[0] = 0; + u.emu_start(ADDRESS, ADDRESS + X86_CODE.length, 0, 0); + assertEquals(0, hook_accum[0]); + + assertThrows(UnicornException.class, () -> u.hook_del(h1)); + assertThrows(UnicornException.class, () -> u.hook_del(h3)); + assertThrows(UnicornException.class, () -> u.hook_del(h4)); + + u.close(); + } +} diff --git a/bindings/java/tests/MemTests.java b/bindings/java/tests/MemTests.java new file mode 100644 index 00000000..976f5d7f --- /dev/null +++ b/bindings/java/tests/MemTests.java @@ -0,0 +1,138 @@ +package tests; + +import static org.junit.Assert.assertEquals; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + +import org.junit.Test; + +import unicorn.MemRegion; +import unicorn.Unicorn; + +public class MemTests { + private static void assertMemRegion(long address, long size, + int perms, MemRegion actual) { + assertEquals(address, actual.begin); + assertEquals(address + size - 1, actual.end); + assertEquals(perms, actual.perms); + } + + @Test + public void testMemRegions() { + Unicorn uc = new Unicorn(Unicorn.UC_ARCH_ARM64, Unicorn.UC_MODE_ARM); + long ADDR1 = 0x10000; + long ADDR2 = 0xdeadbeeffeed1000L; + uc.mem_map(ADDR1, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL); + uc.mem_map(ADDR2, 4096, Unicorn.UC_PROT_READ); + MemRegion[] arr = uc.mem_regions(); + assertEquals("two memory regions", 2, arr.length); + assertMemRegion(ADDR1, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL, arr[0]); + assertMemRegion(ADDR2, 4096, Unicorn.UC_PROT_READ, arr[1]); + uc.close(); + } + + @Test + public void testMemRegions2() { + Unicorn u = new Unicorn(Unicorn.UC_ARCH_TRICORE, 0); + u.mem_map(0x10000, 0x10000, Unicorn.UC_PROT_ALL); + u.mem_map(0x30000, 0x10000, Unicorn.UC_PROT_READ); + u.mem_map(0x50000, 0x10000, + Unicorn.UC_PROT_READ | Unicorn.UC_PROT_WRITE); + u.mem_map(0x70000, 0x20000, 0); + u.mem_protect(0x80000, 0x10000, Unicorn.UC_PROT_EXEC); + + ByteBuffer buf = ByteBuffer.allocateDirect(0x10000); + u.mem_map_ptr(0x110000, buf, Unicorn.UC_PROT_ALL); + + u.mmio_map(0x210000, 0x10000, + (uc, offset, size, user_data) -> 0x41414141, + null, (uc, offset, size, value, user_data) -> { + }, null); + u.mmio_map(0x230000, 0x10000, + (uc, offset, size, user_data) -> 0x41414141, + null, null, null); + u.mmio_map(0x250000, 0x10000, null, null, + (uc, offset, size, value, user_data) -> { + }, null); + u.mmio_map(0x270000, 0x10000, null, null, null, null); + + MemRegion[] mrs = u.mem_regions(); + assertEquals(10, mrs.length); + assertMemRegion(0x10000, 0x10000, Unicorn.UC_PROT_ALL, mrs[0]); + assertMemRegion(0x30000, 0x10000, Unicorn.UC_PROT_READ, mrs[1]); + assertMemRegion(0x50000, 0x10000, + Unicorn.UC_PROT_READ | Unicorn.UC_PROT_WRITE, mrs[2]); + assertMemRegion(0x70000, 0x10000, Unicorn.UC_PROT_NONE, mrs[3]); + assertMemRegion(0x80000, 0x10000, Unicorn.UC_PROT_EXEC, mrs[4]); + assertMemRegion(0x110000, 0x10000, Unicorn.UC_PROT_ALL, mrs[5]); + assertMemRegion(0x210000, 0x10000, + Unicorn.UC_PROT_READ | Unicorn.UC_PROT_WRITE, mrs[6]); + assertMemRegion(0x230000, 0x10000, Unicorn.UC_PROT_READ, mrs[7]); + assertMemRegion(0x250000, 0x10000, Unicorn.UC_PROT_WRITE, mrs[8]); + assertMemRegion(0x270000, 0x10000, Unicorn.UC_PROT_NONE, mrs[9]); + + u.close(); + } + + @Test + public void testMmio() { + // mov ecx, [0xaaaaaaa8]; inc ecx; dec edx; mov [0xaaaaaaa8], ecx; inc ecx; dec edx + final byte[] X86_CODE32_MEM_READ_WRITE = + { -117, 13, -88, -86, -86, -86, 65, 74, -119, 13, -88, -86, -86, + -86, 65, 74 }; + + long ADDRESS = 0x100000; + + 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, Unicorn.UC_PROT_ALL); + + // write machine code to be emulated to memory + u.mem_write(ADDRESS, X86_CODE32_MEM_READ_WRITE); + + // initialize machine registers + u.reg_write(Unicorn.UC_X86_REG_ECX, 0x12345678); + u.reg_write(Unicorn.UC_X86_REG_EDX, 0x22334455); + + u.mmio_map(0xaaaaa000L, 0x1000, (uc, offset, size, user_data) -> { + assertEquals("read offset", 0xaa8, offset); + assertEquals("read size", 4, size); + assertEquals("read user_data", "read_data", user_data); + return 0x44556677; + }, "read_data", (uc, offset, size, value, user_data) -> { + assertEquals("write offset", 0xaa8, offset); + assertEquals("write size", 4, size); + assertEquals("write value", 0x44556678, value); + assertEquals("write user_data", "write_data", user_data); + }, "write_data"); + + u.emu_start(ADDRESS, ADDRESS + X86_CODE32_MEM_READ_WRITE.length, 0, 0); + + assertEquals("ecx", 0x44556679, u.reg_read(Unicorn.UC_X86_REG_ECX)); + assertEquals("edx", 0x22334453, u.reg_read(Unicorn.UC_X86_REG_EDX)); + + u.close(); + } + + @Test + public void testMemMapPtr() { + ByteBuffer buffer = + ByteBuffer.allocateDirect(0x1000).order(ByteOrder.LITTLE_ENDIAN); + final byte[] X86_CODE32_MEM_WRITE = + { -119, 13, -86, -86, -86, -86, 65, 74 }; + + long ADDRESS = 0x100000; + + Unicorn u = new Unicorn(Unicorn.UC_ARCH_X86, Unicorn.UC_MODE_32); + u.mem_map(ADDRESS, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL); + u.mem_map_ptr(0xaaaaa000L, buffer, Unicorn.UC_PROT_ALL); + u.mem_write(ADDRESS, X86_CODE32_MEM_WRITE); + u.reg_write(Unicorn.UC_X86_REG_ECX, 0x12345678); + u.emu_start(ADDRESS, ADDRESS + X86_CODE32_MEM_WRITE.length, 0, 0); + + assertEquals("buffer contents", 0x12345678, buffer.getInt(0xaaa)); + + u.close(); + } +} diff --git a/bindings/java/tests/RegTests.java b/bindings/java/tests/RegTests.java new file mode 100644 index 00000000..9eb653f3 --- /dev/null +++ b/bindings/java/tests/RegTests.java @@ -0,0 +1,50 @@ +package tests; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import unicorn.Unicorn; +import unicorn.X86_Float80; + +public class RegTests { + @Test + public void testX86ReadFloat80() { + // fldl2e; fsin + final byte[] X86_CODE = { -39, -22, -39, -2 }; + + long ADDRESS = 0x100000; + + Unicorn u = new Unicorn(Unicorn.UC_ARCH_X86, Unicorn.UC_MODE_32); + u.mem_map(ADDRESS, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL); + u.mem_write(ADDRESS, X86_CODE); + u.emu_start(ADDRESS, ADDRESS + X86_CODE.length, 0, 0); + X86_Float80 reg1 = + (X86_Float80) u.reg_read(Unicorn.UC_X86_REG_ST0, null); + X86_Float80 reg2 = + (X86_Float80) u.reg_read(Unicorn.UC_X86_REG_FP7, null); + assertEquals(null, ADDRESS, ADDRESS, ADDRESS); + assertEquals(Math.sin(Math.log(Math.E) / Math.log(2)), reg1.toDouble(), + 1e-12); + assertEquals(reg1.toDouble(), reg2.toDouble(), 1e-12); + u.close(); + } + + @Test + public void testX86WriteFloat80() { + // fsin + final byte[] X86_CODE = { -39, -2 }; + + long ADDRESS = 0x100000; + + Unicorn u = new Unicorn(Unicorn.UC_ARCH_X86, Unicorn.UC_MODE_32); + u.mem_map(ADDRESS, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL); + u.mem_write(ADDRESS, X86_CODE); + X86_Float80 reg = X86_Float80.fromDouble(-1.1); + u.reg_write(Unicorn.UC_X86_REG_ST0, reg); + u.emu_start(ADDRESS, ADDRESS + X86_CODE.length, 0, 0); + reg = (X86_Float80) u.reg_read(Unicorn.UC_X86_REG_ST0, null); + assertEquals(Math.sin(-1.1), reg.toDouble(), 1e-12); + u.close(); + } +} diff --git a/bindings/java/unicorn/MemRegion.java b/bindings/java/unicorn/MemRegion.java index 20fa9200..033651f9 100644 --- a/bindings/java/unicorn/MemRegion.java +++ b/bindings/java/unicorn/MemRegion.java @@ -34,7 +34,7 @@ public class MemRegion { @Override public String toString() { - return "MemRegion [begin=" + begin + ", end=" + end + ", perms=" + - perms + "]"; + return String.format("MemRegion [begin=0x%x, end=0x%x, perms=%d]", + begin, end, perms); } } diff --git a/bindings/java/unicorn/TranslationBlock.java b/bindings/java/unicorn/TranslationBlock.java index 755534c1..721d192d 100644 --- a/bindings/java/unicorn/TranslationBlock.java +++ b/bindings/java/unicorn/TranslationBlock.java @@ -32,4 +32,10 @@ public class TranslationBlock { this.icount = icount; this.size = size; } + + @Override + public String toString() { + return String.format("TranslationBlock [pc=0x%x, icount=%d, size=%d]", + pc, icount, size); + } } diff --git a/bindings/java/unicorn/Unicorn.java b/bindings/java/unicorn/Unicorn.java index f2840cce..fb23320b 100644 --- a/bindings/java/unicorn/Unicorn.java +++ b/bindings/java/unicorn/Unicorn.java @@ -563,8 +563,11 @@ public class Unicorn * {@code errno} may not retain its old value once accessed. * * @return Error code, one of the {@code UC_ERR_*} constants. + * @deprecated Not actually useful in Java; error numbers are always + * converted into {@link UnicornException} exceptions. * @see UnicornConst */ + @Deprecated public int errno() { return _errno(nativePtr); } From 910bb572d375c4e82f65497acc58713cdcf6dac3 Mon Sep 17 00:00:00 2001 From: Robert Xiao Date: Sat, 13 May 2023 19:43:39 -0700 Subject: [PATCH 15/25] Accept unsigned BigIntegers, and produce unsigned BigIntegers by default. Unsigned BigIntegers are a bit more ergonomic, particularly for bitwise operations. reg_write still accepts negative BigIntegers (and will automatically sign extend them), but reg_read will produce unsigned BigIntegers by default. --- bindings/java/tests/RegTests.java | 98 ++++++++++++++++++++++++++++++ bindings/java/unicorn/Unicorn.java | 23 +++++-- 2 files changed, 115 insertions(+), 6 deletions(-) diff --git a/bindings/java/tests/RegTests.java b/bindings/java/tests/RegTests.java index 9eb653f3..206604f5 100644 --- a/bindings/java/tests/RegTests.java +++ b/bindings/java/tests/RegTests.java @@ -1,10 +1,14 @@ package tests; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThrows; + +import java.math.BigInteger; import org.junit.Test; import unicorn.Unicorn; +import unicorn.UnicornException; import unicorn.X86_Float80; public class RegTests { @@ -47,4 +51,98 @@ public class RegTests { assertEquals(Math.sin(-1.1), reg.toDouble(), 1e-12); u.close(); } + + @Test + public void testBigIntegerRegister() { + Unicorn uc = + new Unicorn(Unicorn.UC_ARCH_ARM64, Unicorn.UC_MODE_ARM); + int reg = Unicorn.UC_ARM64_REG_V0; + + assertThrows(UnicornException.class, () -> uc.reg_read(reg)); + assertThrows(UnicornException.class, () -> uc.reg_write(reg, 1L)); + assertThrows(ClassCastException.class, + () -> uc.reg_write(reg, (Long) 1L)); + + BigInteger b127 = BigInteger.valueOf(2).pow(127); + BigInteger bmax = + BigInteger.valueOf(2).pow(128).subtract(BigInteger.ONE); + + uc.reg_write(reg, BigInteger.ZERO); + assertEquals("write 0, get 0", BigInteger.ZERO, uc.reg_read(reg, null)); + + uc.reg_write(reg, BigInteger.ONE); + assertEquals("write 1, get 1", BigInteger.ONE, uc.reg_read(reg, null)); + assertEquals("get 1 from alias", BigInteger.ONE, + uc.reg_read(Unicorn.UC_ARM64_REG_Q0, null)); + + uc.reg_write(reg, BigInteger.ONE.negate()); + assertEquals("write -1, get 2^128 - 1", bmax, uc.reg_read(reg, null)); + + uc.reg_write(reg, b127); + assertEquals("write 2^127, get 2^127", b127, uc.reg_read(reg, null)); + + uc.reg_write(reg, b127.negate()); + assertEquals("write -2^127, get 2^127", b127, uc.reg_read(reg, null)); + + uc.reg_write(reg, bmax); + assertEquals("write 2^128 - 1, get 2^128 - 1", bmax, + uc.reg_read(reg, null)); + + assertThrows("reject 2^128", IllegalArgumentException.class, + () -> uc.reg_write(reg, bmax.add(BigInteger.ONE))); + assertEquals("reg unchanged", bmax, + uc.reg_read(reg, null)); + + assertThrows("reject -2^127 - 1", IllegalArgumentException.class, + () -> uc.reg_write(reg, b127.negate().subtract(BigInteger.ONE))); + assertEquals("reg unchanged", bmax, + uc.reg_read(reg, null)); + + byte[] b = new byte[0x80]; + b[0x70] = -0x80; + uc.reg_write(reg, new BigInteger(b)); + assertEquals("write untrimmed value", b127, uc.reg_read(reg, null)); + + uc.close(); + } + + @Test + public void testArm64Vector() { + // add v0.8h, v1.8h, v2.8h + final byte[] ARM64_CODE = { 0x20, (byte) 0x84, 0x62, 0x4e }; + + long ADDRESS = 0x100000; + + Unicorn uc = new Unicorn(Unicorn.UC_ARCH_ARM64, Unicorn.UC_MODE_ARM); + uc.mem_map(ADDRESS, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL); + uc.mem_write(ADDRESS, ARM64_CODE); + + uc.reg_write(Unicorn.UC_ARM64_REG_V0, + new BigInteger("0cc175b9c0f1b6a831c399e269772661", 16)); // MD5("a") + uc.reg_write(Unicorn.UC_ARM64_REG_V1, + new BigInteger("92eb5ffee6ae2fec3ad71c777531578f", 16)); // MD5("b") + uc.reg_write(Unicorn.UC_ARM64_REG_V2, + new BigInteger("-4a8a08f09d37b73795649038408b5f33", 16)); // -MD5("c") + assertThrows("rejects overly large values", + IllegalArgumentException.class, + () -> uc.reg_write(Unicorn.UC_ARM64_REG_V2, + new BigInteger("1111222233334444aaaabbbbccccdddde", 16))); + + assertEquals("v0 value", + new BigInteger("0cc175b9c0f1b6a831c399e269772661", 16), + uc.reg_read(Unicorn.UC_ARM64_REG_V0, null)); + assertEquals("v1 value", + new BigInteger("92eb5ffee6ae2fec3ad71c777531578f", 16), + uc.reg_read(Unicorn.UC_ARM64_REG_V1, null)); + assertEquals("v2 value", + new BigInteger("b575f70f62c848c86a9b6fc7bf74a0cd", 16), + uc.reg_read(Unicorn.UC_ARM64_REG_V2, null)); + + uc.emu_start(ADDRESS, ADDRESS + ARM64_CODE.length, 0, 0); + assertEquals("v0.8h = v1.8h + v2.8h", + new BigInteger("4860570d497678b4a5728c3e34a5f85c", 16), + uc.reg_read(Unicorn.UC_ARM64_REG_V0, null)); + + uc.close(); + } } diff --git a/bindings/java/unicorn/Unicorn.java b/bindings/java/unicorn/Unicorn.java index fb23320b..e89bd1df 100644 --- a/bindings/java/unicorn/Unicorn.java +++ b/bindings/java/unicorn/Unicorn.java @@ -372,20 +372,24 @@ public class Unicorn j++; } } - return new BigInteger(buf); + return new BigInteger(1, buf); } private static void do_reg_write_bigint(long ptr, int isContext, int regid, BigInteger value, int nbits) { byte[] val = value.toByteArray(); + byte[] buf = new byte[nbits >> 3]; + if (val.length == ((nbits >> 3) + 1) && val[0] == 0x00) { + // unsigned value >= 2^(nbits - 1): has a zero sign bit + val = Arrays.copyOfRange(val, 1, val.length); + } else if (val[0] < 0) { + Arrays.fill(buf, (byte) 0xff); + } + if (val.length > (nbits >> 3)) { throw new IllegalArgumentException( "input integer is too large for a " + nbits + - "-bit register (got " + (val.length * 8) + " bits)"); - } - byte[] buf = new byte[nbits >> 3]; - if (val[0] < 0) { - Arrays.fill(buf, (byte) 0xff); + "-bit register (got " + (value.bitLength() + 1) + " bits)"); } if (ByteOrder.nativeOrder().equals(ByteOrder.LITTLE_ENDIAN)) { @@ -430,6 +434,9 @@ public class Unicorn *

  • {@code UC_ARM64_REG_V*} => {@link BigInteger} (128 bits) *
* + * {@link BigInteger} registers always produce non-negative results (i.e. + * they read as unsigned integers). + * * @param regid Register ID that is to be retrieved. * @param opt Options for this register, or {@code null} if no options * are required. @@ -472,6 +479,10 @@ public class Unicorn *
  • {@code UC_ARM64_REG_Q*} => {@link BigInteger} (128 bits) *
  • {@code UC_ARM64_REG_V*} => {@link BigInteger} (128 bits) * + * + * {@link BigInteger} values can be signed or unsigned, as long as the + * value fits in the target register size. Values that are too large will + * be rejected. * * @param regid Register ID that is to be modified. * @param value Object containing the new register value. From 3739c7e3e0ddfea0392386f4ed74e8ef3ef3191a Mon Sep 17 00:00:00 2001 From: Robert Xiao Date: Sat, 13 May 2023 21:59:05 -0700 Subject: [PATCH 16/25] Write some code to test out ARM64 CP register handling. --- bindings/java/tests/RegTests.java | 58 +++++++++++++++++++++++++++++ bindings/java/unicorn/Arm64_CP.java | 4 ++ bindings/java/unicorn/Arm_CP.java | 5 +++ bindings/java/unicorn/X86_MSR.java | 4 ++ 4 files changed, 71 insertions(+) diff --git a/bindings/java/tests/RegTests.java b/bindings/java/tests/RegTests.java index 206604f5..f9f0183c 100644 --- a/bindings/java/tests/RegTests.java +++ b/bindings/java/tests/RegTests.java @@ -1,12 +1,14 @@ package tests; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertThrows; import java.math.BigInteger; import org.junit.Test; +import unicorn.Arm64_CP; import unicorn.Unicorn; import unicorn.UnicornException; import unicorn.X86_Float80; @@ -145,4 +147,60 @@ public class RegTests { uc.close(); } + + @Test + public void testArm64EnablePAC() { + // paciza x1 + final byte[] ARM64_CODE = + { (byte) 0xe1, 0x23, (byte) 0xc1, (byte) 0xda }; + + long ADDRESS = 0x100000; + + Unicorn uc = new Unicorn(Unicorn.UC_ARCH_ARM64, Unicorn.UC_MODE_ARM); + uc.ctl_set_cpu_model(Unicorn.UC_CPU_ARM64_MAX); + uc.mem_map(ADDRESS, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL); + uc.mem_write(ADDRESS, ARM64_CODE); + + Arm64_CP sctlr_el3 = new Arm64_CP(1, 1, 3, 6, 0); + sctlr_el3.val = + (Long) uc.reg_read(Unicorn.UC_ARM64_REG_CP_REG, sctlr_el3); + // NS | RW | API + sctlr_el3.val |= 1L | (1L << 10) | (1L << 17); + uc.reg_write(Unicorn.UC_ARM64_REG_CP_REG, sctlr_el3); + sctlr_el3.val = + (Long) uc.reg_read(Unicorn.UC_ARM64_REG_CP_REG, sctlr_el3); + + Arm64_CP sctlr_el1 = new Arm64_CP(1, 0, 3, 0, 0); + sctlr_el1.val = + (Long) uc.reg_read(Unicorn.UC_ARM64_REG_CP_REG, sctlr_el1); + // EnIA | EnIB + sctlr_el1.val |= (1L << 31) | (1L << 30) | (1L << 27) | (1L << 13); + uc.reg_write(Unicorn.UC_ARM64_REG_CP_REG, sctlr_el1); + sctlr_el1.val = + (Long) uc.reg_read(Unicorn.UC_ARM64_REG_CP_REG, sctlr_el1); + + Arm64_CP hcr_el2 = new Arm64_CP(1, 1, 3, 4, 0); + hcr_el2.val = + (Long) uc.reg_read(Unicorn.UC_ARM64_REG_CP_REG, hcr_el2); + // API + hcr_el2.val |= (1L << 41); + uc.reg_write(Unicorn.UC_ARM64_REG_CP_REG, hcr_el2); + + Arm64_CP apiakeylo_el1 = new Arm64_CP(2, 1, 3, 0, 0); + apiakeylo_el1.val = 0x4141424243434444L; + uc.reg_write(Unicorn.UC_ARM64_REG_CP_REG, apiakeylo_el1); + + Arm64_CP apiakeyhi_el1 = new Arm64_CP(2, 1, 3, 0, 1); + apiakeyhi_el1.val = 0x1234abcd4444aaaaL; + uc.reg_write(Unicorn.UC_ARM64_REG_CP_REG, apiakeyhi_el1); + + uc.reg_write(Unicorn.UC_ARM64_REG_X1, 0x0000bbbbccccddddL); + uc.emu_start(ADDRESS, ADDRESS + ARM64_CODE.length, 0, 0); + assertNotEquals("X1 should be signed", 0x0000bbbbccccddddL, + uc.reg_read(Unicorn.UC_ARM64_REG_X1)); + assertEquals("X1 low bits should be unchanged", 0x0000bbbbccccddddL, + uc.reg_read(Unicorn.UC_ARM64_REG_X1) & 0xffffffffffffL); + + uc.close(); + } } diff --git a/bindings/java/unicorn/Arm64_CP.java b/bindings/java/unicorn/Arm64_CP.java index 6c0e9528..7b0b0e23 100644 --- a/bindings/java/unicorn/Arm64_CP.java +++ b/bindings/java/unicorn/Arm64_CP.java @@ -26,6 +26,10 @@ public class Arm64_CP { public int crn, crm, op0, op1, op2; public long val; + public Arm64_CP(int crn, int crm, int op0, int op1, int op2) { + this(crn, crm, op0, op1, op2, 0); + } + public Arm64_CP(int crn, int crm, int op0, int op1, int op2, long val) { this.crn = crn; this.crm = crm; diff --git a/bindings/java/unicorn/Arm_CP.java b/bindings/java/unicorn/Arm_CP.java index 278cc272..fe3f6c5b 100644 --- a/bindings/java/unicorn/Arm_CP.java +++ b/bindings/java/unicorn/Arm_CP.java @@ -5,6 +5,11 @@ public class Arm_CP { public int cp, is64, sec, crn, crm, opc1, opc2; public long val; + public Arm_CP(int cp, int is64, int sec, int crn, int crm, int opc1, + int opc2) { + this(cp, is64, sec, crn, crm, opc1, opc2, 0); + } + public Arm_CP(int cp, int is64, int sec, int crn, int crm, int opc1, int opc2, long val) { this.cp = cp; diff --git a/bindings/java/unicorn/X86_MSR.java b/bindings/java/unicorn/X86_MSR.java index 1bf9138c..4da232f3 100644 --- a/bindings/java/unicorn/X86_MSR.java +++ b/bindings/java/unicorn/X86_MSR.java @@ -26,6 +26,10 @@ public class X86_MSR { public int rid; public long value; + public X86_MSR(int rid) { + this(rid, 0); + } + public X86_MSR(int rid, long value) { this.rid = rid; this.value = value; From 4f563490e2c26e49c0d5e98ebde8adebddc5d476 Mon Sep 17 00:00:00 2001 From: Robert Xiao Date: Sun, 14 May 2023 16:23:49 -0700 Subject: [PATCH 17/25] Update Java samples to match C samples. Also add all of the samples as Java tests, referencing the output of the C samples. --- .../java/samples/SampleNetworkAuditing.java | 26 +- bindings/java/samples/Sample_arm.java | 305 ++++- bindings/java/samples/Sample_arm64.java | 274 +++- bindings/java/samples/Sample_ctl.java | 159 +++ bindings/java/samples/Sample_m68k.java | 157 +-- bindings/java/samples/Sample_mips.java | 70 +- bindings/java/samples/Sample_mmu.java | 224 +++ bindings/java/samples/Sample_ppc.java | 91 ++ bindings/java/samples/Sample_riscv.java | 477 +++++++ bindings/java/samples/Sample_s390x.java | 88 ++ bindings/java/samples/Sample_sparc.java | 77 +- bindings/java/samples/Sample_tricore.java | 84 ++ bindings/java/samples/Sample_x86.java | 1212 +++++++++++------ bindings/java/samples/Sample_x86_mmr.java | 27 +- bindings/java/samples/Shellcode.java | 170 +-- bindings/java/samples/Utils.java | 49 + bindings/java/tests/FunctionalityTests.java | 5 - bindings/java/tests/HookTests.java | 5 - bindings/java/tests/MemTests.java | 7 - bindings/java/tests/RegTests.java | 8 - bindings/java/tests/RegressionTests.java | 1 - bindings/java/tests/TestSamples.java | 1140 +++++++++++++++- samples/sample_arm64.c | 88 ++ samples/sample_tricore.c | 6 +- samples/sample_x86.c | 40 +- 25 files changed, 3884 insertions(+), 906 deletions(-) create mode 100644 bindings/java/samples/Sample_ctl.java create mode 100644 bindings/java/samples/Sample_mmu.java create mode 100644 bindings/java/samples/Sample_ppc.java create mode 100644 bindings/java/samples/Sample_riscv.java create mode 100644 bindings/java/samples/Sample_s390x.java create mode 100644 bindings/java/samples/Sample_tricore.java create mode 100644 bindings/java/samples/Utils.java diff --git a/bindings/java/samples/SampleNetworkAuditing.java b/bindings/java/samples/SampleNetworkAuditing.java index 95e567fd..7b689a5d 100644 --- a/bindings/java/samples/SampleNetworkAuditing.java +++ b/bindings/java/samples/SampleNetworkAuditing.java @@ -29,7 +29,7 @@ package samples; import unicorn.*; import java.util.*; -public class SampleNetworkAuditing { +public class SampleNetworkAuditing implements UnicornConst, X86Const { public static long next_id = 3; public static final int SIZE_REG = 4; @@ -67,11 +67,11 @@ public class SampleNetworkAuditing { if (intno != 0x80) { return; } - long eax = uc.reg_read(Unicorn.UC_X86_REG_EAX); - long ebx = uc.reg_read(Unicorn.UC_X86_REG_EBX); - long ecx = uc.reg_read(Unicorn.UC_X86_REG_ECX); - long edx = uc.reg_read(Unicorn.UC_X86_REG_EDX); - long eip = uc.reg_read(Unicorn.UC_X86_REG_EIP); + long eax = uc.reg_read(UC_X86_REG_EAX); + long ebx = uc.reg_read(UC_X86_REG_EBX); + long ecx = uc.reg_read(UC_X86_REG_ECX); + long edx = uc.reg_read(UC_X86_REG_EDX); + long eip = uc.reg_read(UC_X86_REG_EIP); // System.out.printf(">>> INTERRUPT %d\n", toInt(eax)); @@ -114,7 +114,7 @@ public class SampleNetworkAuditing { String filename = read_string(uc, filename_addr); long dummy_fd = get_id(); - uc.reg_write(Unicorn.UC_X86_REG_EAX, dummy_fd); + uc.reg_write(UC_X86_REG_EAX, dummy_fd); String msg = String.format( "open file (filename=%s flags=%d mode=%d) with fd(%d)", @@ -133,8 +133,8 @@ public class SampleNetworkAuditing { System.out.printf(">>> SYS_DUP2 oldfd=%d newfd=%d\n", ebx, ecx); } else if (eax == 102) { // sys_socketcall // ref: http://www.skyfree.org/linux/kernel_network/socket.html - long call = uc.reg_read(Unicorn.UC_X86_REG_EBX); - long args = uc.reg_read(Unicorn.UC_X86_REG_ECX); + long call = uc.reg_read(UC_X86_REG_EBX); + long args = uc.reg_read(UC_X86_REG_ECX); // int sys_socketcall(int call, unsigned long *args) if (call == 1) { // sys_socket @@ -147,7 +147,7 @@ public class SampleNetworkAuditing { toInt(uc.mem_read(args + SIZE_REG * 2, SIZE_REG)); long dummy_fd = get_id(); - uc.reg_write(Unicorn.UC_X86_REG_EAX, dummy_fd); + uc.reg_write(UC_X86_REG_EAX, dummy_fd); if (family == 2) { // AF_INET String msg = @@ -437,16 +437,16 @@ public class SampleNetworkAuditing { System.out.printf("Emulate i386 code\n"); try { // Initialize emulator in X86-32bit mode - Unicorn mu = new Unicorn(Unicorn.UC_ARCH_X86, Unicorn.UC_MODE_32); + Unicorn mu = new Unicorn(UC_ARCH_X86, UC_MODE_32); // map 2MB memory for this emulation - mu.mem_map(ADDRESS, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL); + mu.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL); // write machine code to be emulated to memory mu.mem_write(ADDRESS, code); // initialize stack - mu.reg_write(Unicorn.UC_X86_REG_ESP, ADDRESS + 0x200000L); + mu.reg_write(UC_X86_REG_ESP, ADDRESS + 0x200000L); // handle interrupt ourself mu.hook_add(new MyInterruptHook(), null); diff --git a/bindings/java/samples/Sample_arm.java b/bindings/java/samples/Sample_arm.java index fc5b7dd1..77ba0d39 100644 --- a/bindings/java/samples/Sample_arm.java +++ b/bindings/java/samples/Sample_arm.java @@ -5,111 +5,117 @@ package samples; +import java.util.Arrays; + import unicorn.*; -public class Sample_arm { +public class Sample_arm implements UnicornConst, ArmConst { - // 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 + /** code to be emulated {@code mov r0, #0x37; sub r1, r2, r3} */ + // private static final byte[] ARM_CODE = Utils.hexToBytes("3700a0e3031042e0"); + /** code to be emulated {@code nop} */ + private static final byte[] ARM_CODE = Utils.hexToBytes("00f020e3"); - // memory address where emulation starts - public static final int ADDRESS = 0x10000; + /** code to be emulated {@code sub sp, #0xc} */ + private static final byte[] THUMB_CODE = Utils.hexToBytes("83b0"); - 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; - } + /** code to be emulated + *
    +     * cmp r2, r3
    +     * it ne
    +     * mov r2, #0x68
    +     * mov r2, #0x4d
    +     * 
    + */ + private static final byte[] ARM_THUMB_COND_CODE = + Utils.hexToBytes("9a4214bf68224d22"); - 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)); - } - } + /** code to be emulated {@code mov r0, #0x37; sub r1, r2, r3} */ + private static final byte[] ARM_CODE_EB = + Utils.hexToBytes("e3a00037e0421003"); + /** code to be emulated {@code sub sp, #0xc} */ + private static final byte[] THUMB_CODE_EB = Utils.hexToBytes("b083"); - // 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( + /** {@code 0xf3ef8014 - mrs r0, control} */ + private static final byte[] THUMB_CODE_MRS = Utils.hexToBytes("eff31480"); + + /** memory address where emulation starts */ + private static final long ADDRESS = 0x10000; + + private static final BlockHook hook_block = + (uc, address, size, user_data) -> { + System.out.format( + ">>> Tracing basic block at 0x%x, block size = 0x%x\n", + address, size); + }; + + private static final CodeHook hook_code = + (uc, address, size, user_data) -> { + System.out.format( ">>> Tracing instruction at 0x%x, instruction size = 0x%x\n", - address, size)); - } - } + address, size); + }; public static void test_arm() { - long r0 = 0x1234L; // R0 register long r2 = 0x6789L; // R1 register long r3 = 0x3333L; // R2 register - long r1; // R1 register - System.out.print("Emulate ARM code\n"); + System.out.println("Emulate ARM code"); // Initialize emulator in ARM mode - Unicorn u = new Unicorn(Unicorn.UC_ARCH_ARM, Unicorn.UC_MODE_ARM); + Unicorn u = new Unicorn(UC_ARCH_ARM, UC_MODE_ARM); // map 2MB memory for this emulation - u.mem_map(ADDRESS, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL); + u.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL); // 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); + u.reg_write(UC_ARM_REG_R0, r0); + u.reg_write(UC_ARM_REG_R2, r2); + u.reg_write(UC_ARM_REG_R3, r3); // tracing all basic blocks with customized callback - u.hook_add(new MyBlockHook(), 1, 0, null); + u.hook_add(hook_block, 1, 0, null); // tracing one instruction at ADDRESS with customized callback - u.hook_add(new MyCodeHook(), ADDRESS, ADDRESS, null); + u.hook_add(hook_code, 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"); + System.out.println(">>> Emulation done. Below is the CPU context"); - r0 = u.reg_read(Unicorn.UC_ARM_REG_R0); - r1 = u.reg_read(Unicorn.UC_ARM_REG_R1); - System.out.print(String.format(">>> R0 = 0x%x\n", r0)); - System.out.print(String.format(">>> R1 = 0x%x\n", r1)); - - u.close(); + System.out.format(">>> R0 = 0x%x\n", u.reg_read(UC_ARM_REG_R0)); + System.out.format(">>> R1 = 0x%x\n", u.reg_read(UC_ARM_REG_R1)); } public static void test_thumb() { - long sp = 0x1234L; // R0 register - System.out.print("Emulate THUMB code\n"); + System.out.println("Emulate THUMB code"); // Initialize emulator in ARM mode - Unicorn u = new Unicorn(Unicorn.UC_ARCH_ARM, Unicorn.UC_MODE_THUMB); + Unicorn u = new Unicorn(UC_ARCH_ARM, UC_MODE_THUMB); // map 2MB memory for this emulation - u.mem_map(ADDRESS, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL); + u.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL); // 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); + u.reg_write(UC_ARM_REG_SP, sp); // tracing all basic blocks with customized callback - u.hook_add(new MyBlockHook(), 1, 0, null); + u.hook_add(hook_block, 1, 0, null); // tracing one instruction at ADDRESS with customized callback - u.hook_add(new MyCodeHook(), ADDRESS, ADDRESS, null); + u.hook_add(hook_code, ADDRESS, ADDRESS, null); // emulate machine code in infinite time (last param = 0), or when // finishing all the code. @@ -117,17 +123,204 @@ public class Sample_arm { // now print out some registers System.out.print(">>> Emulation done. Below is the CPU context\n"); + System.out.format(">>> SP = 0x%x\n", u.reg_read(UC_ARM_REG_SP)); + } - sp = u.reg_read(Unicorn.UC_ARM_REG_SP); - System.out.print(String.format(">>> SP = 0x%x\n", sp)); + public static void test_armeb() { + long r0 = 0x1234L; // R0 register + long r2 = 0x6789L; // R1 register + long r3 = 0x3333L; // R2 register - u.close(); + System.out.println("Emulate ARM Big-Endian code"); + + // Initialize emulator in ARM mode + Unicorn uc = new Unicorn(UC_ARCH_ARM, UC_MODE_ARM | UC_MODE_BIG_ENDIAN); + + // map 2MB memory for this emulation + uc.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL); + + // write machine code to be emulated to memory + uc.mem_write(ADDRESS, ARM_CODE_EB); + + // initialize machine registers + uc.reg_write(UC_ARM_REG_R0, r0); + uc.reg_write(UC_ARM_REG_R2, r2); + uc.reg_write(UC_ARM_REG_R3, r3); + + // tracing all basic blocks with customized callback + uc.hook_add(hook_block, 1, 0, null); + + // tracing one instruction at ADDRESS with customized callback + uc.hook_add(hook_code, ADDRESS, ADDRESS, null); + + // emulate machine code in infinite time (last param = 0), or when + // finishing all the code. + uc.emu_start(ADDRESS, ADDRESS + ARM_CODE_EB.length, 0, 0); + + // now print out some registers + System.out.println(">>> Emulation done. Below is the CPU context"); + System.out.format(">>> R0 = 0x%x\n", uc.reg_read(UC_ARM_REG_R0)); + System.out.format(">>> R1 = 0x%x\n", uc.reg_read(UC_ARM_REG_R1)); + } + + public static void test_thumbeb() { + long sp = 0x1234L; + + System.out.println("Emulate THUMB Big-Endian code"); + + // Initialize emulator in ARM mode + Unicorn uc = + new Unicorn(UC_ARCH_ARM, UC_MODE_THUMB + UC_MODE_BIG_ENDIAN); + + // map 2MB memory for this emulation + uc.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL); + + // write machine code to be emulated to memory + uc.mem_write(ADDRESS, THUMB_CODE_EB); + + // initialize machine registers + uc.reg_write(UC_ARM_REG_SP, sp); + + // tracing all basic blocks with customized callback + uc.hook_add(hook_block, 1, 0, null); + + // tracing one instruction at ADDRESS with customized callback + uc.hook_add(hook_code, ADDRESS, ADDRESS, null); + + // emulate machine code in infinite time (last param = 0), or when + // finishing all the code. + // Note we start at ADDRESS | 1 to indicate THUMB mode. + uc.emu_start(ADDRESS | 1, ADDRESS + THUMB_CODE_EB.length, 0, 0); + + // now print out some registers + System.out.println(">>> Emulation done. Below is the CPU context"); + System.out.format(">>> SP = 0x%x\n", uc.reg_read(UC_ARM_REG_SP)); + } + + public static void test_thumb_mrs() { + System.out.println("Emulate THUMB MRS instruction"); + // 0xf3ef8014 - mrs r0, control + + // Initialize emulator in ARM mode + Unicorn uc = new Unicorn(UC_ARCH_ARM, UC_MODE_THUMB); + + // Setup the cpu model. + uc.ctl_set_cpu_model(UC_CPU_ARM_CORTEX_M33); + + // map 2MB memory for this emulation + uc.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL); + + // write machine code to be emulated to memory + uc.mem_write(ADDRESS, THUMB_CODE_MRS); + + // tracing all basic blocks with customized callback + uc.hook_add(hook_block, 1, 0, null); + + // tracing one instruction at ADDRESS with customized callback + uc.hook_add(hook_code, ADDRESS, ADDRESS, null); + + // emulate machine code in infinite time (last param = 0), or when + // finishing all the code. + + // Note we start at ADDRESS | 1 to indicate THUMB mode. + uc.emu_start(ADDRESS | 1, ADDRESS + THUMB_CODE_MRS.length, 0, 1); + + // now print out some registers + System.out.println(">>> Emulation done. Below is the CPU context"); + + long pc = uc.reg_read(UC_ARM_REG_PC); + System.out.format(">>> PC = 0x%x\n", pc); + if (pc != ADDRESS + 4) { + System.out.format("Error, PC was 0x%x, expected was 0x%x.\n", pc, + ADDRESS + 4); + } + } + + private static void test_thumb_ite_internal(boolean step, long[] r2r3) { + Unicorn uc = new Unicorn(UC_ARCH_ARM, UC_MODE_THUMB); + + uc.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL); + + uc.mem_write(ADDRESS, ARM_THUMB_COND_CODE); + + uc.reg_write(UC_ARM_REG_SP, 0x1234L); + + uc.reg_write(UC_ARM_REG_R2, 0); + uc.reg_write(UC_ARM_REG_R3, 1); + + if (!step) { + uc.emu_start(ADDRESS | 1, ADDRESS + ARM_THUMB_COND_CODE.length, 0, + 0); + } else { + long addr = ADDRESS; + for (int i = 0; i < ARM_THUMB_COND_CODE.length / 2; i++) { + uc.emu_start(addr | 1, ADDRESS + ARM_THUMB_COND_CODE.length, 0, + 1); + addr = uc.reg_read(UC_ARM_REG_PC); + } + } + + r2r3[0] = uc.reg_read(UC_ARM_REG_R2); + r2r3[1] = uc.reg_read(UC_ARM_REG_R3); + } + + public static void test_thumb_ite() { + long[] r2r3 = new long[2]; + long[] step_r2r3 = new long[2]; + + System.out.println( + "Emulate a THUMB ITE block as a whole or per instruction."); + + // Run once. + System.out.println("Running the entire binary."); + test_thumb_ite_internal(false, r2r3); + System.out.format(">>> R2: %d\n", r2r3[0]); + System.out.format(">>> R3: %d\n\n", r2r3[1]); + + // Step each instruction. + System.out.println("Running the binary one instruction at a time."); + test_thumb_ite_internal(true, step_r2r3); + System.out.format(">>> R2: %d\n", step_r2r3[0]); + System.out.format(">>> R3: %d\n\n", step_r2r3[1]); + + if (!Arrays.equals(r2r3, step_r2r3)) { + System.out.println("Failed with ARM ITE blocks stepping!"); + } + } + + public static void test_read_sctlr() { + System.out.println("Read the SCTLR register."); + + Unicorn uc = new Unicorn(UC_ARCH_ARM, UC_MODE_ARM); + + // SCTLR. See arm reference. + Arm_CP reg = new Arm_CP(15, 0, 0, 1, 0, 0, 0); + long val = (Long) uc.reg_read(UC_ARM_REG_CP_REG, reg); + + System.out.format(">>> SCTLR = 0x%x\n", val & 0xffffffffL); + System.out.format(">>> SCTLR.IE = %d\n", (val >> 31) & 1); + System.out.format(">>> SCTLR.B = %d\n", (val >> 7) & 1); } public static void main(String args[]) { test_arm(); System.out.print("==========================\n"); test_thumb(); + + System.out.print("==========================\n"); + test_armeb(); + + System.out.print("==========================\n"); + test_thumbeb(); + + System.out.print("==========================\n"); + test_thumb_mrs(); + + System.out.print("==========================\n"); + test_thumb_ite(); + + System.out.print("==========================\n"); + test_read_sctlr(); } } diff --git a/bindings/java/samples/Sample_arm64.java b/bindings/java/samples/Sample_arm64.java index 151bf58b..e8b4a4a7 100644 --- a/bindings/java/samples/Sample_arm64.java +++ b/bindings/java/samples/Sample_arm64.java @@ -26,94 +26,262 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. package samples; +import java.util.Arrays; + import unicorn.*; -public class Sample_arm64 { +public class Sample_arm64 implements UnicornConst, Arm64Const { - // code to be emulated - public static final byte[] ARM_CODE = { -85, 1, 15, -117 }; // add x11, x13, x15 + /** code to be emulated {@code str w11, [x13], #0; ldrb w15, [x13], #0} */ + private static final byte[] ARM64_CODE = + Utils.hexToBytes("ab0500b8af054038"); + + /** code to be emulated {@code str w11, [x13]; ldrb w15, [x13]} */ + //private static final byte[] ARM64_CODE_EB = Utils.hexToBytes("b80005ab384005af"); // str w11, [x13]; + + private static final byte[] ARM64_CODE_EB = ARM64_CODE; + + /** code to be emulated {@code mrs x2, tpidrro_el0} */ + private static final byte[] ARM64_MRS_CODE = Utils.hexToBytes("62d03bd5"); + + /** code to be emulated {@code paciza x1} */ + private static final byte[] ARM64_PAC_CODE = Utils.hexToBytes("e123c1da"); // 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 final BlockHook hook_block = + (uc, address, size, user_data) -> { + System.out.format( + ">>> Tracing basic block at 0x%x, block size = 0x%x\n", + address, size); + }; - 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( + private static final CodeHook hook_code = + (uc, address, size, user_data) -> { + System.out.format( ">>> Tracing instruction at 0x%x, instruction size = 0x%x\n", - address, size)); - } + address, size); + }; + + public static void test_arm64_mem_fetch() { + // msr x0, CurrentEL + byte[] shellcode0 = { 64, 66, 56, (byte) 213 }; + // .text:00000000004002C0 LDR X1, [SP,#arg_0] + byte[] shellcode = { (byte) 0xE1, 0x03, 0x40, (byte) 0xF9 }; + long shellcode_address = 0x4002C0L; + long data_address = 0x10000000000000L; + + System.out.format( + ">>> Emulate ARM64 fetching stack data from high address %x\n", + data_address); + + // Initialize emulator in ARM mode + Unicorn uc = new Unicorn(UC_ARCH_ARM64, UC_MODE_ARM); + + uc.mem_map(data_address, 0x30000, UC_PROT_ALL); + uc.mem_map(0x400000, 0x1000, UC_PROT_ALL); + + uc.reg_write(UC_ARM64_REG_SP, data_address); + byte[] data = new byte[8]; + Arrays.fill(data, (byte) 0xc8); + uc.mem_write(data_address, data); + uc.mem_write(shellcode_address, shellcode0); + uc.mem_write(shellcode_address + 4, shellcode); + + uc.emu_start(shellcode_address, shellcode_address + 4, 0, 0); + + long x0 = uc.reg_read(UC_ARM64_REG_X0); + System.out.format(">>> x0(Exception Level)=%x\n", x0 >> 2); + + uc.emu_start(shellcode_address + 4, shellcode_address + 8, 0, 0); + + long x1 = uc.reg_read(UC_ARM64_REG_X1); + + System.out.format(">>> X1 = 0x%x\n", x1); } public static void test_arm64() { + long x11 = 0x12345678; // X11 register + long x13 = 0x10000 + 0x8; // X13 register + long x15 = 0x33; // X15 register - long x11 = 0x1234L; // X11 register - long x13 = 0x6789L; // X13 register - long x15 = 0x3333L; // X15 register - - System.out.print("Emulate ARM64 code\n"); + System.out.println("Emulate ARM64 code"); // Initialize emulator in ARM mode - Unicorn u = new Unicorn(Unicorn.UC_ARCH_ARM64, Unicorn.UC_MODE_ARM); + Unicorn uc = new Unicorn(UC_ARCH_ARM64, UC_MODE_ARM); // map 2MB memory for this emulation - u.mem_map(ADDRESS, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL); + uc.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL); // write machine code to be emulated to memory - u.mem_write(ADDRESS, ARM_CODE); + uc.mem_write(ADDRESS, ARM64_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); + uc.reg_write(UC_ARM64_REG_X11, x11); + uc.reg_write(UC_ARM64_REG_X13, x13); + uc.reg_write(UC_ARM64_REG_X15, x15); // tracing all basic blocks with customized callback - u.hook_add(new MyBlockHook(), 1, 0, null); + uc.hook_add(hook_block, 1, 0, null); // tracing one instruction at ADDRESS with customized callback - u.hook_add(new MyCodeHook(), ADDRESS, ADDRESS, null); + uc.hook_add(hook_code, 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); + uc.emu_start(ADDRESS, ADDRESS + ARM64_CODE.length, 0, 0); // now print out some registers - System.out.print(">>> Emulation done. Below is the CPU context\n"); + System.out.println(">>> Emulation done. Below is the CPU context"); + System.out.println(">>> As little endian, X15 should be 0x78:"); + System.out.format(">>> X15 = 0x%x\n", uc.reg_read(UC_ARM64_REG_X15)); + } - x11 = u.reg_read(Unicorn.UC_ARM64_REG_X11); - System.out.print(String.format(">>> X11 = 0x%x\n", x11)); + public static void test_arm64eb() { + long x11 = 0x12345678; // X11 register + long x13 = 0x10000 + 0x8; // X13 register + long x15 = 0x33; // X15 register - u.close(); + System.out.println("Emulate ARM64 Big-Endian code"); + + // Initialize emulator in ARM mode + Unicorn uc = + new Unicorn(UC_ARCH_ARM64, UC_MODE_ARM + UC_MODE_BIG_ENDIAN); + + // map 2MB memory for this emulation + uc.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL); + + // write machine code to be emulated to memory + uc.mem_write(ADDRESS, ARM64_CODE_EB); + + // initialize machine registers + uc.reg_write(UC_ARM64_REG_X11, x11); + uc.reg_write(UC_ARM64_REG_X13, x13); + uc.reg_write(UC_ARM64_REG_X15, x15); + + // tracing all basic blocks with customized callback + uc.hook_add(hook_block, 1, 0, null); + + // tracing one instruction at ADDRESS with customized callback + uc.hook_add(hook_code, ADDRESS, ADDRESS, null); + + // emulate machine code in infinite time (last param = 0), or when + // finishing all the code. + uc.emu_start(ADDRESS, ADDRESS + ARM64_CODE_EB.length, 0, 0); + + // now print out some registers + System.out.println(">>> Emulation done. Below is the CPU context"); + System.out.println(">>> As big endian, X15 should be 0x78:"); + System.out.format(">>> X15 = 0x%x\n", uc.reg_read(UC_ARM64_REG_X15)); + } + + public static void test_arm64_sctlr() { + long val; + System.out.println("Read the SCTLR register."); + + Unicorn uc = + new Unicorn(UC_ARCH_ARM64, UC_MODE_LITTLE_ENDIAN | UC_MODE_ARM); + + // SCTLR_EL1. See arm reference. + Arm64_CP reg = new Arm64_CP(1, 0, 3, 0, 0); + + val = (long) uc.reg_read(UC_ARM64_REG_CP_REG, reg); + System.out.format(">>> SCTLR_EL1 = 0x%x\n", val); + + reg.op1 = 0b100; + val = (long) uc.reg_read(UC_ARM64_REG_CP_REG, reg); + System.out.format(">>> SCTLR_EL2 = 0x%x\n", val); + } + + private static final Arm64SysHook hook_mrs = + (uc, reg, cp_reg, user_data) -> { + System.out + .println(">>> Hook MSR instruction. Write 0x114514 to X2."); + + uc.reg_write(reg, 0x114514L); + + // Skip + return 1; + }; + + public static void test_arm64_hook_mrs() { + System.out.println("Hook MRS instruction."); + + Unicorn uc = + new Unicorn(UC_ARCH_ARM64, UC_MODE_LITTLE_ENDIAN | UC_MODE_ARM); + uc.mem_map(0x1000, 0x1000, UC_PROT_ALL); + uc.mem_write(0x1000, ARM64_MRS_CODE); + uc.hook_add(hook_mrs, UC_ARM64_INS_MRS, 1, 0, null); + uc.emu_start(0x1000, 0x1000 + ARM64_MRS_CODE.length, 0, 0); + System.out.format(">>> X2 = 0x%x\n", uc.reg_read(UC_ARM64_REG_X2)); + } + + public static void test_arm64_pac() { + long x1 = 0x0000aaaabbbbccccL; + + System.out.println("Try ARM64 PAC"); + + // Initialize emulator in ARM mode + Unicorn uc = new Unicorn(UC_ARCH_ARM64, UC_MODE_ARM); + uc.ctl_set_cpu_model(UC_CPU_ARM64_MAX); + uc.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL); + uc.mem_write(ADDRESS, ARM64_PAC_CODE); + uc.reg_write(UC_ARM64_REG_X1, x1); + + /** Initialize PAC support **/ + Arm64_CP reg; + + // SCR_EL3 + reg = new Arm64_CP(1, 1, 3, 6, 0); + reg.val = (Long) uc.reg_read(UC_ARM64_REG_CP_REG, reg); + // NS && RW && API + reg.val |= (1 | (1L << 10) | (1L << 17)); + uc.reg_write(UC_ARM64_REG_CP_REG, reg); + + // SCTLR_EL1 + reg = new Arm64_CP(1, 0, 3, 0, 0); + reg.val = (Long) uc.reg_read(UC_ARM64_REG_CP_REG, reg); + // EnIA && EnIB + reg.val |= (1L << 31) | (1L << 30); + uc.reg_write(UC_ARM64_REG_CP_REG, reg); + + // HCR_EL2 + reg = new Arm64_CP(1, 1, 3, 4, 0); + reg.val = (Long) uc.reg_read(UC_ARM64_REG_CP_REG, reg); + // HCR.API + reg.val |= (1L << 41); + uc.reg_write(UC_ARM64_REG_CP_REG, reg); + + /** Check that PAC worked **/ + uc.emu_start(ADDRESS, ADDRESS + ARM64_PAC_CODE.length, 0, 0); + long new_x1 = uc.reg_read(UC_ARM64_REG_X1); + + System.out.format("X1 = 0x%x\n", new_x1); + if (new_x1 == x1) { + System.out.println("FAIL: No PAC tag added!"); + } else { + // Expect 0x1401aaaabbbbccccULL with the default key + System.out.println("SUCCESS: PAC tag found."); + } } public static void main(String args[]) { + test_arm64_mem_fetch(); + + System.out.println("-------------------------"); test_arm64(); + + System.out.println("-------------------------"); + test_arm64eb(); + + System.out.println("-------------------------"); + test_arm64_sctlr(); + + System.out.println("-------------------------"); + test_arm64_hook_mrs(); + + System.out.println("-------------------------"); + test_arm64_pac(); } } diff --git a/bindings/java/samples/Sample_ctl.java b/bindings/java/samples/Sample_ctl.java new file mode 100644 index 00000000..29fddac0 --- /dev/null +++ b/bindings/java/samples/Sample_ctl.java @@ -0,0 +1,159 @@ +package samples; + +import java.util.Arrays; + +import unicorn.*; + +public class Sample_ctl implements UnicornConst, X86Const { + /** Code to be emulated + *
    +     *   cmp eax, 0;
    +     *   jg lb;
    +     *   inc eax;
    +     *   nop;
    +     * lb:
    +     *   inc ebx;
    +     *   nop;
    +     * 
    + */ + private static final byte[] X86_JUMP_CODE = + Utils.hexToBytes("83f8007f0240904390"); + + /** memory address where emulation starts */ + private static final long ADDRESS = 0x10000; + + public static void test_uc_ctl_read() { + System.out.println("Reading some properties by uc_ctl."); + + // Initialize emulator in X86-32bit mode + Unicorn uc = new Unicorn(UC_ARCH_X86, UC_MODE_32); + + // Let's query some properties by uc_ctl. + int mode = uc.ctl_get_mode(); + int arch = uc.ctl_get_arch(); + long timeout = uc.ctl_get_timeout(); + int pagesize = uc.ctl_get_page_size(); + + System.out.format(">>> mode = %d, arch = %d, timeout=%d, pagesize=%d\n", + mode, arch, timeout, pagesize); + } + + private static final EdgeGeneratedHook trace_new_edge = + (uc, cur, prev, data) -> { + System.out.format(">>> Getting a new edge from 0x%x to 0x%x.\n", + prev.pc + prev.size - 1, cur.pc); + }; + + public static void test_uc_ctl_exits() { + long r_eax, r_ebx; + long exits[] = { ADDRESS + 6, ADDRESS + 8 }; + + System.out.println("Using multiple exits by uc_ctl."); + + // Initialize emulator in X86-32bit mode + Unicorn uc = new Unicorn(UC_ARCH_X86, UC_MODE_32); + + uc.mem_map(ADDRESS, 0x1000, UC_PROT_ALL); + + // Write our code to the memory. + uc.mem_write(ADDRESS, X86_JUMP_CODE); + + // We trace if any new edge is generated. + uc.hook_add(trace_new_edge, 1, 0, null); + + // Enable multiple exits. + uc.ctl_exits_enabled(true); + uc.ctl_set_exits(exits); + + // This should stop at ADDRESS + 6 and increase eax, even thouhg we don't + // provide an exit. + uc.emu_start(ADDRESS, 0, 0, 0); + + r_eax = uc.reg_read(UC_X86_REG_EAX); + r_ebx = uc.reg_read(UC_X86_REG_EBX); + System.out.format( + ">>> eax = %d and ebx = %d after the first emulation\n", + r_eax, r_ebx); + + // This should stop at ADDRESS + 8, even though we don't provide an exit. + uc.emu_start(ADDRESS, 0, 0, 0); + + r_eax = uc.reg_read(UC_X86_REG_EAX); + r_ebx = uc.reg_read(UC_X86_REG_EBX); + System.out.format( + ">>> eax = %d and ebx = %d after the second emulation\n", + r_eax, r_ebx); + } + + private static final int TB_COUNT = 8; + private static final int TCG_MAX_INSNS = 512; // from tcg.h + private static final int CODE_LEN = TB_COUNT * TCG_MAX_INSNS; + + private static double time_emulation(Unicorn uc, long start, long end) { + long t1 = System.nanoTime(); + uc.emu_start(start, end, 0, 0); + long t2 = System.nanoTime(); + return (t2 - t1) / 1000000.0; + } + + public static void test_uc_ctl_tb_cache() { + byte[] code = new byte[CODE_LEN]; + double standard, cached, evicted; + + System.out.println( + "Controlling the TB cache in a finer granularity by uc_ctl."); + + // Fill the code buffer with NOP. + Arrays.fill(code, (byte) 0x90); + + // Initialize emulator in X86-32bit mode + Unicorn uc = new Unicorn(UC_ARCH_X86, UC_MODE_32); + + uc.mem_map(ADDRESS, 0x10000, UC_PROT_ALL); + + // Write our code to the memory. + uc.mem_write(ADDRESS, code); + + // We trace if any new edge is generated. + // Note: In this sample, there is only **one** basic block while muliple + // translation blocks is generated due to QEMU tcg buffer limit. In this + // case, we don't consider it as a new edge. + uc.hook_add(trace_new_edge, 1, 0, null); + + // Do emulation without any cache. + standard = time_emulation(uc, ADDRESS, ADDRESS + CODE_LEN); + + // Now we request cache for all TBs. + for (int i = 0; i < TB_COUNT; i++) { + TranslationBlock tb = + uc.ctl_request_cache(ADDRESS + i * TCG_MAX_INSNS); + System.out.format( + ">>> TB is cached at 0x%x which has %d instructions with %d bytes.\n", + tb.pc, tb.icount, tb.size); + } + + // Do emulation with all TB cached. + cached = time_emulation(uc, ADDRESS, ADDRESS + CODE_LEN); + + // Now we clear cache for all TBs. + for (int i = 0; i < TB_COUNT; i++) { + uc.ctl_remove_cache(ADDRESS + i * TCG_MAX_INSNS, + ADDRESS + i * TCG_MAX_INSNS + 1); + } + + // Do emulation with all TB cache evicted. + evicted = time_emulation(uc, ADDRESS, ADDRESS + CODE_LEN); + + System.out.format( + ">>> Run time: First time: %fms, Cached: %fms, Cache evicted: %fms\n", + standard, cached, evicted); + } + + public static final void main(String[] args) { + test_uc_ctl_read(); + System.out.println("===================="); + test_uc_ctl_exits(); + System.out.println("===================="); + test_uc_ctl_tb_cache(); + } +} diff --git a/bindings/java/samples/Sample_m68k.java b/bindings/java/samples/Sample_m68k.java index 772b5fcd..80ea4a6b 100644 --- a/bindings/java/samples/Sample_m68k.java +++ b/bindings/java/samples/Sample_m68k.java @@ -28,7 +28,7 @@ package samples; import unicorn.*; -public class Sample_m68k { +public class Sample_m68k implements UnicornConst, M68kConst { // code to be emulated public static final byte[] M68K_CODE = { 118, -19 }; // movq #-19, %d3 @@ -36,41 +36,21 @@ public class Sample_m68k { // 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)); - } - } + private static final BlockHook hook_block = + (uc, address, size, user_data) -> { + System.out.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( + // callback for tracing instructions + private static final CodeHook hook_code = + (uc, address, size, user_data) -> { + System.out.format( ">>> Tracing instruction at 0x%x, instruction size = 0x%x\n", - address, size)); - } - } + address, size); + }; public static void test_m68k() { long d0 = 0x0000L; // d0 data register @@ -97,42 +77,41 @@ public class Sample_m68k { 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); + Unicorn u = new Unicorn(UC_ARCH_M68K, UC_MODE_BIG_ENDIAN); // map 2MB memory for this emulation - u.mem_map(ADDRESS, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL); + u.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL); // 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(UC_M68K_REG_D0, d0); + u.reg_write(UC_M68K_REG_D1, d1); + u.reg_write(UC_M68K_REG_D2, d2); + u.reg_write(UC_M68K_REG_D3, d3); + u.reg_write(UC_M68K_REG_D4, d4); + u.reg_write(UC_M68K_REG_D5, d5); + u.reg_write(UC_M68K_REG_D6, d6); + u.reg_write(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(UC_M68K_REG_A0, a0); + u.reg_write(UC_M68K_REG_A1, a1); + u.reg_write(UC_M68K_REG_A2, a2); + u.reg_write(UC_M68K_REG_A3, a3); + u.reg_write(UC_M68K_REG_A4, a4); + u.reg_write(UC_M68K_REG_A5, a5); + u.reg_write(UC_M68K_REG_A6, a6); + u.reg_write(UC_M68K_REG_A7, a7); - u.reg_write(Unicorn.UC_M68K_REG_PC, pc); - u.reg_write(Unicorn.UC_M68K_REG_SR, sr); + u.reg_write(UC_M68K_REG_PC, pc); + u.reg_write(UC_M68K_REG_SR, sr); // tracing all basic blocks with customized callback - u.hook_add(new MyBlockHook(), 1, 0, null); + u.hook_add(hook_block, 1, 0, null); // tracing all instruction - u.hook_add(new MyCodeHook(), 1, 0, null); + u.hook_add(hook_code, 1, 0, null); // emulate machine code in infinite time (last param = 0), or when // finishing all the code. @@ -141,47 +120,37 @@ public class Sample_m68k { // 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); - d1 = u.reg_read(Unicorn.UC_M68K_REG_D1); - d2 = u.reg_read(Unicorn.UC_M68K_REG_D2); - d3 = u.reg_read(Unicorn.UC_M68K_REG_D3); - d4 = u.reg_read(Unicorn.UC_M68K_REG_D4); - d5 = u.reg_read(Unicorn.UC_M68K_REG_D5); - d6 = u.reg_read(Unicorn.UC_M68K_REG_D6); - d7 = u.reg_read(Unicorn.UC_M68K_REG_D7); + d0 = u.reg_read(UC_M68K_REG_D0); + d1 = u.reg_read(UC_M68K_REG_D1); + d2 = u.reg_read(UC_M68K_REG_D2); + d3 = u.reg_read(UC_M68K_REG_D3); + d4 = u.reg_read(UC_M68K_REG_D4); + d5 = u.reg_read(UC_M68K_REG_D5); + d6 = u.reg_read(UC_M68K_REG_D6); + d7 = u.reg_read(UC_M68K_REG_D7); - a0 = u.reg_read(Unicorn.UC_M68K_REG_A0); - a1 = u.reg_read(Unicorn.UC_M68K_REG_A1); - a2 = u.reg_read(Unicorn.UC_M68K_REG_A2); - a3 = u.reg_read(Unicorn.UC_M68K_REG_A3); - a4 = u.reg_read(Unicorn.UC_M68K_REG_A4); - a5 = u.reg_read(Unicorn.UC_M68K_REG_A5); - a6 = u.reg_read(Unicorn.UC_M68K_REG_A6); - a7 = u.reg_read(Unicorn.UC_M68K_REG_A7); + a0 = u.reg_read(UC_M68K_REG_A0); + a1 = u.reg_read(UC_M68K_REG_A1); + a2 = u.reg_read(UC_M68K_REG_A2); + a3 = u.reg_read(UC_M68K_REG_A3); + a4 = u.reg_read(UC_M68K_REG_A4); + a5 = u.reg_read(UC_M68K_REG_A5); + a6 = u.reg_read(UC_M68K_REG_A6); + a7 = u.reg_read(UC_M68K_REG_A7); - pc = u.reg_read(Unicorn.UC_M68K_REG_PC); - sr = u.reg_read(Unicorn.UC_M68K_REG_SR); + pc = u.reg_read(UC_M68K_REG_PC); + sr = u.reg_read(UC_M68K_REG_SR); - System.out.print(String.format(">>> A0 = 0x%x\t\t>>> D0 = 0x%x\n", - a0, d0)); - System.out.print(String.format(">>> A1 = 0x%x\t\t>>> D1 = 0x%x\n", - a1, d1)); - System.out.print(String.format(">>> A2 = 0x%x\t\t>>> D2 = 0x%x\n", - a2, d2)); - System.out.print(String.format(">>> A3 = 0x%x\t\t>>> D3 = 0x%x\n", - a3, d3)); - System.out.print(String.format(">>> A4 = 0x%x\t\t>>> D4 = 0x%x\n", - a4, d4)); - System.out.print(String.format(">>> A5 = 0x%x\t\t>>> D5 = 0x%x\n", - a5, d5)); - System.out.print(String.format(">>> A6 = 0x%x\t\t>>> D6 = 0x%x\n", - a6, d6)); - System.out.print(String.format(">>> A7 = 0x%x\t\t>>> D7 = 0x%x\n", - a7, d7)); - System.out.print(String.format(">>> PC = 0x%x\n", pc)); - System.out.print(String.format(">>> SR = 0x%x\n", sr)); - - u.close(); + System.out.format(">>> A0 = 0x%x\t\t>>> D0 = 0x%x\n", a0, d0); + System.out.format(">>> A1 = 0x%x\t\t>>> D1 = 0x%x\n", a1, d1); + System.out.format(">>> A2 = 0x%x\t\t>>> D2 = 0x%x\n", a2, d2); + System.out.format(">>> A3 = 0x%x\t\t>>> D3 = 0x%x\n", a3, d3); + System.out.format(">>> A4 = 0x%x\t\t>>> D4 = 0x%x\n", a4, d4); + System.out.format(">>> A5 = 0x%x\t\t>>> D5 = 0x%x\n", a5, d5); + System.out.format(">>> A6 = 0x%x\t\t>>> D6 = 0x%x\n", a6, d6); + System.out.format(">>> A7 = 0x%x\t\t>>> D7 = 0x%x\n", a7, d7); + System.out.format(">>> PC = 0x%x\n", pc); + System.out.format(">>> SR = 0x%x\n", sr); } public static void main(String args[]) { diff --git a/bindings/java/samples/Sample_mips.java b/bindings/java/samples/Sample_mips.java index 03697f3e..d238b604 100644 --- a/bindings/java/samples/Sample_mips.java +++ b/bindings/java/samples/Sample_mips.java @@ -28,48 +28,30 @@ package samples; import unicorn.*; -public class Sample_mips { +public class Sample_mips implements UnicornConst, MipsConst { // 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 }; + public static final byte[] MIPS_CODE_EB = { 52, 33, 52, 86 }; // ori $at, $at, 0x3456 + public static final byte[] MIPS_CODE_EL = { 86, 52, 33, 52 }; // ori $at, $at, 0x3456 // 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( + System.out.format( ">>> Tracing basic block at 0x%x, block size = 0x%x\n", address, - size)); + 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( + System.out.format( ">>> Tracing instruction at 0x%x, instruction size = 0x%x\n", - address, size)); + address, size); } } @@ -77,20 +59,20 @@ public class Sample_mips { long r1 = 0x6789L; // R1 register - System.out.print("Emulate MIPS code (big-endian)\n"); + System.out.println("Emulate MIPS code (big-endian)"); // Initialize emulator in MIPS mode - Unicorn u = new Unicorn(Unicorn.UC_ARCH_MIPS, - Unicorn.UC_MODE_MIPS32 + Unicorn.UC_MODE_BIG_ENDIAN); + Unicorn u = + new Unicorn(UC_ARCH_MIPS, UC_MODE_MIPS32 + UC_MODE_BIG_ENDIAN); // map 2MB memory for this emulation - u.mem_map(ADDRESS, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL); + u.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL); // 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); + u.reg_write(UC_MIPS_REG_1, r1); // tracing all basic blocks with customized callback u.hook_add(new MyBlockHook(), 1, 0, null); @@ -103,32 +85,29 @@ public class Sample_mips { 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"); + System.out.println(">>> Emulation done. Below is the CPU context"); - r1 = u.reg_read(Unicorn.UC_MIPS_REG_1); - System.out.print(String.format(">>> R1 = 0x%x\n", r1)); - - u.close(); + r1 = u.reg_read(UC_MIPS_REG_1); + System.out.format(">>> R1 = 0x%x\n", r1); } public static void test_mips_el() { long r1 = 0x6789L; // R1 register - System.out.print("===========================\n"); - System.out.print("Emulate MIPS code (little-endian)\n"); + System.out.println("Emulate MIPS code (little-endian)"); // Initialize emulator in MIPS mode - Unicorn u = new Unicorn(Unicorn.UC_ARCH_MIPS, - Unicorn.UC_MODE_MIPS32 + Unicorn.UC_MODE_LITTLE_ENDIAN); + Unicorn u = new Unicorn(UC_ARCH_MIPS, + UC_MODE_MIPS32 + UC_MODE_LITTLE_ENDIAN); // map 2MB memory for this emulation - u.mem_map(ADDRESS, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL); + u.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL); // 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); + u.reg_write(UC_MIPS_REG_1, r1); // tracing all basic blocks with customized callback u.hook_add(new MyBlockHook(), 1, 0, null); @@ -141,16 +120,15 @@ public class Sample_mips { 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"); + System.out.println(">>> Emulation done. Below is the CPU context"); - r1 = u.reg_read(Unicorn.UC_MIPS_REG_1); - System.out.print(String.format(">>> R1 = 0x%x\n", r1)); - - u.close(); + r1 = u.reg_read(UC_MIPS_REG_1); + System.out.format(">>> R1 = 0x%x\n", r1); } public static void main(String args[]) { test_mips_eb(); + System.out.println("==========================="); test_mips_el(); } } diff --git a/bindings/java/samples/Sample_mmu.java b/bindings/java/samples/Sample_mmu.java new file mode 100644 index 00000000..f5fe680f --- /dev/null +++ b/bindings/java/samples/Sample_mmu.java @@ -0,0 +1,224 @@ +package samples; + +import unicorn.*; + +public class Sample_mmu implements UnicornConst, X86Const { + /** Code: + *
    +     * mov rax, 57
    +     * syscall
    +     * test rax, rax
    +     * jz child
    +     * xor rax, rax
    +     * mov rax, 60
    +     * mov [0x4000], rax
    +     * syscall
    +     *
    +     * child:
    +     * xor rcx, rcx
    +     * mov rcx, 42
    +     * mov [0x4000], rcx
    +     * mov rax, 60
    +     * syscall
    +     * 
    + */ + private static final byte[] CODE = Utils.hexToBytes( + "B8390000000F054885C0740FB83C00000048890425004000000F05B92A00000048890C2500400000B83C0000000F05"); + + private static final MemHook mmu_write_callback = + (uc, type, address, size, value, user_data) -> { + System.out.format("write at 0x%x: 0x%x\n", address, value); + }; + + private static void x86_mmu_prepare_tlb(Unicorn uc, long vaddr, + long tlb_base) { + long cr0; + long cr4; + X86_MSR msr = new X86_MSR(0xC0000080); + long pml4o = ((vaddr & 0x00ff8000000000L) >> 39) * 8; + long pdpo = ((vaddr & 0x00007fc0000000L) >> 30) * 8; + long pdo = ((vaddr & 0x0000003fe00000L) >> 21) * 8; + long pml4e = (tlb_base + 0x1000L) | 1 | (1 << 2); + long pdpe = (tlb_base + 0x2000L) | 1 | (1 << 2); + long pde = (tlb_base + 0x3000L) | 1 | (1 << 2); + uc.mem_write(tlb_base + pml4o, Utils.toBytes(pml4e)); + uc.mem_write(tlb_base + 0x1000 + pdpo, Utils.toBytes(pdpe)); + uc.mem_write(tlb_base + 0x2000 + pdo, Utils.toBytes(pde)); + uc.reg_write(UC_X86_REG_CR3, tlb_base); + cr0 = uc.reg_read(UC_X86_REG_CR0); + cr4 = uc.reg_read(UC_X86_REG_CR4); + msr.value = (Long) uc.reg_read(UC_X86_REG_MSR, msr); + + cr0 |= 1; //enable protected mode + cr0 |= 1l << 31; //enable paging + cr4 |= 1l << 5; //enable physical address extension + msr.value |= 1l << 8; //enable long mode + + uc.reg_write(UC_X86_REG_CR0, cr0); + uc.reg_write(UC_X86_REG_CR4, cr4); + uc.reg_write(UC_X86_REG_MSR, msr); + } + + private static void x86_mmu_pt_set(Unicorn uc, long vaddr, long paddr, + long tlb_base) { + long pto = ((vaddr & 0x000000001ff000L) >> 12) * 8; + long pte = (paddr) | 1 | (1 << 2); + uc.mem_write(tlb_base + 0x3000 + pto, Utils.toBytes((int) pte)); + } + + private static SyscallHook x86_mmu_syscall_callback = (uc, userdata) -> { + boolean[] parent_done = (boolean[]) userdata; + long rax = uc.reg_read(UC_X86_REG_RAX); + switch ((int) rax) { + case 57: + /* fork */ + break; + case 60: + /* exit */ + parent_done[0] = true; + uc.emu_stop(); + return; + default: + System.out.println("unknown syscall"); + System.exit(1); + } + + if (!parent_done[0]) { + rax = 27; + uc.reg_write(UC_X86_REG_RAX, rax); + uc.emu_stop(); + } + }; + + public static void cpu_tlb() { + long tlb_base = 0x3000; + long rip; + boolean[] parent_done = { false }; + + System.out.println( + "Emulate x86 amd64 code with mmu enabled and switch mappings"); + + Unicorn uc = new Unicorn(UC_ARCH_X86, UC_MODE_64); + uc.ctl_tlb_mode(UC_TLB_CPU); + Unicorn.Context context = uc.context_save(); + + uc.hook_add(x86_mmu_syscall_callback, UC_X86_INS_SYSCALL, 1, 0, + parent_done); + + // Memory hooks are called after the mmu translation, so hook the physicall addresses + uc.hook_add(mmu_write_callback, UC_HOOK_MEM_WRITE, 0x1000, 0x3000, + null); + + System.out.println("map code"); + uc.mem_map(0x0, 0x1000, UC_PROT_ALL); // Code + uc.mem_write(0x0, CODE); + System.out.println("map parent memory"); + uc.mem_map(0x1000, 0x1000, UC_PROT_ALL); // Parrent + System.out.println("map child memory"); + uc.mem_map(0x2000, 0x1000, UC_PROT_ALL); // Child + System.out.println("map tlb memory"); + uc.mem_map(tlb_base, 0x4000, UC_PROT_ALL); // TLB + + System.out.println("set up the tlb"); + x86_mmu_prepare_tlb(uc, 0x0, tlb_base); + x86_mmu_pt_set(uc, 0x2000, 0x0, tlb_base); + x86_mmu_pt_set(uc, 0x4000, 0x1000, tlb_base); + + uc.ctl_flush_tlb(); + System.out.println("run the parent"); + uc.emu_start(0x2000, 0x0, 0, 0); + + System.out.println("save the context for the child"); + uc.context_update(context); + System.out.println("finish the parent"); + rip = uc.reg_read(UC_X86_REG_RIP); + + uc.emu_start(rip, 0x0, 0, 0); + + System.out.println("restore the context for the child"); + uc.context_restore(context); + x86_mmu_prepare_tlb(uc, 0x0, tlb_base); + x86_mmu_pt_set(uc, 0x4000, 0x2000, tlb_base); + uc.reg_write(UC_X86_REG_RAX, 0L); + uc.ctl_flush_tlb(); + + uc.emu_start(rip, 0x0, 0, 0); + long parent = Utils.toLong(uc.mem_read(0x1000, Long.BYTES)); + long child = Utils.toLong(uc.mem_read(0x2000, Long.BYTES)); + System.out.format("parent result == %d\n", parent); + System.out.format("child result == %d\n", child); + } + + private static final TlbFillHook virtual_tlb_callback = + (uc, addr, type, user_data) -> { + boolean[] parent_done = (boolean[]) user_data; + System.out.format("tlb lookup for address: 0x%X\n", addr); + switch ((int) (addr & ~(0xfffL))) { + case 0x2000: + return 0x0L | UC_PROT_EXEC; + case 0x4000: + if (parent_done[0]) { + return (0x2000L) | UC_PROT_READ | UC_PROT_WRITE; + } else { + return (0x1000L) | UC_PROT_READ | UC_PROT_WRITE; + } + default: + return -1L; + } + }; + + public static void virtual_tlb() { + long rip; + boolean[] parent_done = { false }; + + System.out.println("Emulate x86 amd64 code with virtual mmu"); + Unicorn uc = new Unicorn(UC_ARCH_X86, UC_MODE_64); + uc.ctl_tlb_mode(UC_TLB_VIRTUAL); + Unicorn.Context context = uc.context_save(); + + uc.hook_add(x86_mmu_syscall_callback, UC_X86_INS_SYSCALL, 1, 0, + parent_done); + + // Memory hooks are called after the mmu translation, so hook the physicall addresses + uc.hook_add(mmu_write_callback, UC_HOOK_MEM_WRITE, 0x1000, 0x3000, + null); + + System.out.println("map code"); + uc.mem_map(0x0, 0x1000, UC_PROT_ALL); // Code + uc.mem_write(0x0, CODE); + System.out.println("map parent memory"); + uc.mem_map(0x1000, 0x1000, UC_PROT_ALL); // Parrent + System.out.println("map child memory"); + uc.mem_map(0x2000, 0x1000, UC_PROT_ALL); // Child + + uc.hook_add(virtual_tlb_callback, 1, 0, parent_done); + + System.out.println("run the parent"); + uc.emu_start(0x2000, 0x0, 0, 0); + + System.out.println("save the context for the child"); + uc.context_update(context); + System.out.println("finish the parent"); + rip = uc.reg_read(UC_X86_REG_RIP); + + uc.emu_start(rip, 0x0, 0, 0); + + System.out.println("restore the context for the child"); + uc.context_restore(context); + parent_done[0] = true; + uc.reg_write(UC_X86_REG_RAX, 0); + uc.ctl_flush_tlb(); + + uc.emu_start(rip, 0x0, 0, 0); + long parent = Utils.toLong(uc.mem_read(0x1000, Long.BYTES)); + long child = Utils.toLong(uc.mem_read(0x2000, Long.BYTES)); + System.out.format("parent result == %d\n", parent); + System.out.format("child result == %d\n", child); + } + + public static final void main(String[] args) { + cpu_tlb(); + System.out.println("------------------"); + virtual_tlb(); + } +} diff --git a/bindings/java/samples/Sample_ppc.java b/bindings/java/samples/Sample_ppc.java new file mode 100644 index 00000000..ed7aea26 --- /dev/null +++ b/bindings/java/samples/Sample_ppc.java @@ -0,0 +1,91 @@ +/* + +Java bindings for the Unicorn Emulator Engine + +Copyright(c) 2023 Robert Xiao + +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. + +*/ + +/* Sample code to demonstrate how to emulate S390X code */ + +package samples; + +import unicorn.*; + +public class Sample_ppc implements UnicornConst, PpcConst { + /** code to be emulated: + * {@code add r26, r6, r3} + */ + private static final byte[] CODE = Utils.hexToBytes("7F461A14"); + + // memory address where emulation starts + private static final long ADDRESS = 0x10000; + + private static final BlockHook hook_block = + (uc, address, size, user_data) -> { + System.out.format( + ">>> Tracing basic block at 0x%x, block size = 0x%x\n", + address, size); + }; + + private static final CodeHook hook_code = + (uc, address, size, user_data) -> { + System.out.format( + ">>> Tracing instruction at 0x%x, instruction size = 0x%x\n", + address, size); + }; + + public static void test_ppc() { + long r3 = 0x1234; // R3 register + long r6 = 0x6789; // R6 register + long r26 = 0x8877; // R26 register (result) + + System.out.println("Emulate PPC code"); + + Unicorn uc = + new Unicorn(UC_ARCH_PPC, UC_MODE_PPC32 | UC_MODE_BIG_ENDIAN); + + // map 2MB memory for this emulation + uc.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL); + + // write machine code to be emulated to memory + uc.mem_write(ADDRESS, CODE); + + // initialize machine registers + uc.reg_write(UC_PPC_REG_3, r3); + uc.reg_write(UC_PPC_REG_6, r6); + uc.reg_write(UC_PPC_REG_26, r26); + + // tracing all basic blocks with customized callback + uc.hook_add(hook_block, 1, 0, null); + + // tracing one instruction at ADDRESS with customized callback + uc.hook_add(hook_code, ADDRESS, ADDRESS + CODE.length, null); + + // emulate machine code in infinite time (last param = 0), or when + // finishing all the code. + uc.emu_start(ADDRESS, ADDRESS + CODE.length, 0, 0); + + // now print out some registers + System.out.println(">>> Emulation done. Below is the CPU context"); + + System.out.format(">>> r26 = 0x%x\n", uc.reg_read(UC_PPC_REG_26)); + } + + public static final void main(String[] args) { + test_ppc(); + } +} diff --git a/bindings/java/samples/Sample_riscv.java b/bindings/java/samples/Sample_riscv.java new file mode 100644 index 00000000..97e3b486 --- /dev/null +++ b/bindings/java/samples/Sample_riscv.java @@ -0,0 +1,477 @@ +/* + +Java bindings for the Unicorn Emulator Engine + +Copyright(c) 2023 Robert Xiao + +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. + +*/ + +/* Sample code to demonstrate how to emulate S390X code */ + +package samples; + +import unicorn.*; + +public class Sample_riscv implements UnicornConst, RiscvConst { + /** code to be emulated: + *
    +     * $ cstool riscv64 1305100093850502
    +     *  0  13 05 10 00  addi   a0, zero, 1
    +     *  4  93 85 05 02  addi   a1, a1, 0x20
    +     * 
    + */ + private static final byte[] CODE = Utils.hexToBytes("1305100093850502"); + + // memory address where emulation starts + private static final long ADDRESS = 0x10000; + + private static final BlockHook hook_block = + (uc, address, size, user_data) -> { + System.out.format( + ">>> Tracing basic block at 0x%x, block size = 0x%x\n", + address, size); + }; + + private static final CodeHook hook_code = + (uc, address, size, user_data) -> { + System.out.format( + ">>> Tracing instruction at 0x%x, instruction size = 0x%x\n", + address, size); + }; + + private static final CodeHook hook_code3 = + (uc, address, size, user_data) -> { + System.out.format( + ">>> Tracing instruction at 0x%x, instruction size = 0x%x\n", + address, size); + if (address == ADDRESS) { + System.out.println("stop emulation"); + uc.emu_stop(); + } + }; + + /* + 00813823 sd s0,16(sp) + 00000013 nop + */ + private static final byte[] CODE64 = Utils.hexToBytes("2338810013000000"); + + // 10000: 00008067 ret + // 10004: 8082 c.ret + // 10006: 0001 nop + // 10008: 0001 nop + + private static final byte[] FUNC_CODE = + Utils.hexToBytes("67800000828001000100"); + + public static void test_riscv() { + long a0 = 0x1234L; + long a1 = 0x7890L; + + System.out.println("Emulate RISCV code"); + + // Initialize emulator in RISCV64 mode + Unicorn uc = new Unicorn(UC_ARCH_RISCV, UC_MODE_RISCV32); + + // map 2MB memory for this emulation + uc.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL); + + // write machine code to be emulated to memory + uc.mem_write(ADDRESS, CODE); + + // initialize machine registers + uc.reg_write(UC_RISCV_REG_A0, a0); + uc.reg_write(UC_RISCV_REG_A1, a1); + + // tracing all basic blocks with customized callback + uc.hook_add(hook_block, 1, 0, null); + + // tracing all instruction + uc.hook_add(hook_code, 1, 0, null); + + // emulate machine code in infinite time (last param = 0), or when + // finishing all the code. + uc.emu_start(ADDRESS, ADDRESS + CODE.length, 0, 0); + + // now print out some registers + System.out.println(">>> Emulation done. Below is the CPU context"); + + System.out.format(">>> A0 = 0x%x\n", uc.reg_read(UC_RISCV_REG_A0)); + System.out.format(">>> A1 = 0x%x\n", uc.reg_read(UC_RISCV_REG_A1)); + } + + public static void test_riscv2() { + long a0 = 0x1234L; + long a1 = 0x7890L; + + System.out.println("Emulate RISCV code: split emulation"); + + // Initialize emulator in RISCV64 mode + Unicorn uc = new Unicorn(UC_ARCH_RISCV, UC_MODE_RISCV32); + + // map 2MB memory for this emulation + uc.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL); + + // write machine code to be emulated to memory + uc.mem_write(ADDRESS, CODE); + + // initialize machine registers + uc.reg_write(UC_RISCV_REG_A0, a0); + uc.reg_write(UC_RISCV_REG_A1, a1); + + // tracing all basic blocks with customized callback + uc.hook_add(hook_block, 1, 0, null); + + // tracing all instruction + uc.hook_add(hook_code, 1, 0, null); + + // emulate 1 instruction + uc.emu_start(ADDRESS, ADDRESS + 4, 0, 0); + + System.out.format(">>> A0 = 0x%x\n", uc.reg_read(UC_RISCV_REG_A0)); + System.out.format(">>> A1 = 0x%x\n", uc.reg_read(UC_RISCV_REG_A1)); + + // emulate one more instruction + uc.emu_start(ADDRESS + 4, ADDRESS + 8, 0, 0); + + // now print out some registers + System.out.println(">>> Emulation done. Below is the CPU context"); + + System.out.format(">>> A0 = 0x%x\n", uc.reg_read(UC_RISCV_REG_A0)); + System.out.format(">>> A1 = 0x%x\n", uc.reg_read(UC_RISCV_REG_A1)); + } + + public static void test_riscv3() { + long a0 = 0x1234L; + long a1 = 0x7890L; + + System.out.println("Emulate RISCV code: early stop"); + + // Initialize emulator in RISCV64 mode + Unicorn uc = new Unicorn(UC_ARCH_RISCV, UC_MODE_RISCV32); + + // map 2MB memory for this emulation + uc.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL); + + // write machine code to be emulated to memory + uc.mem_write(ADDRESS, CODE); + + // initialize machine registers + uc.reg_write(UC_RISCV_REG_A0, a0); + uc.reg_write(UC_RISCV_REG_A1, a1); + + // tracing all basic blocks with customized callback + uc.hook_add(hook_block, 1, 0, null); + + // tracing all instruction + uc.hook_add(hook_code3, 1, 0, null); + + // emulate machine code in infinite time (last param = 0), or when + // finishing all the code. + uc.emu_start(ADDRESS, ADDRESS + CODE.length, 0, 0); + + // now print out some registers + System.out.println(">>> Emulation done. Below is the CPU context"); + + System.out.format(">>> A0 = 0x%x\n", uc.reg_read(UC_RISCV_REG_A0)); + System.out.format(">>> A1 = 0x%x\n", uc.reg_read(UC_RISCV_REG_A1)); + } + + public static void test_riscv_step() { + long a0 = 0x1234L; + long a1 = 0x7890L; + long pc = 0x0000L; + + System.out.println("Emulate RISCV code: step"); + + // Initialize emulator in RISCV64 mode + Unicorn uc = new Unicorn(UC_ARCH_RISCV, UC_MODE_RISCV32); + + // map 2MB memory for this emulation + uc.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL); + + // write machine code to be emulated to memory + uc.mem_write(ADDRESS, CODE); + + // initialize machine registers + uc.reg_write(UC_RISCV_REG_A0, a0); + uc.reg_write(UC_RISCV_REG_A1, a1); + + // tracing all basic blocks with customized callback + uc.hook_add(hook_block, 1, 0, null); + + // tracing all instruction + uc.hook_add(hook_code, 1, 0, null); + + // emulate 1 instruction + uc.emu_start(ADDRESS, ADDRESS + CODE.length, 0, 1); + + pc = uc.reg_read(UC_RISCV_REG_PC); + + System.out.format(">>> A0 = 0x%x\n", uc.reg_read(UC_RISCV_REG_A0)); + System.out.format(">>> A1 = 0x%x\n", uc.reg_read(UC_RISCV_REG_A1)); + + if (pc != 0x10004) { + System.out.format( + "Error after step: PC is: 0x%x, expected was 0x10004\n", pc); + } + + // emulate one more instruction + uc.emu_start(ADDRESS + 4, ADDRESS + 8, 0, 0); + + // now print out some registers + System.out.println(">>> Emulation done. Below is the CPU context"); + + System.out.format(">>> A0 = 0x%x\n", uc.reg_read(UC_RISCV_REG_A0)); + System.out.format(">>> A1 = 0x%x\n", uc.reg_read(UC_RISCV_REG_A1)); + } + + public static void test_riscv_timeout() { + long a0 = 0x1234L; + long a1 = 0x7890L; + long pc = 0x0000L; + + System.out.println("Emulate RISCV code: timeout"); + + // Initialize emulator in RISCV64 mode + Unicorn uc = new Unicorn(UC_ARCH_RISCV, UC_MODE_RISCV32); + + // map 2MB memory for this emulation + uc.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL); + + // write machine code to be emulated to memory + // TODO(nneonneo): what code was meant to go here? sample_riscv.c + // has all zeros, but that just crashes without running into the + // timeout... + uc.mem_write(ADDRESS, new byte[8]); + + // initialize machine registers + uc.reg_write(UC_RISCV_REG_A0, a0); + uc.reg_write(UC_RISCV_REG_A1, a1); + + // tracing all basic blocks with customized callback + uc.hook_add(hook_block, 1, 0, null); + + // tracing all instruction + uc.hook_add(hook_code, 1, 0, null); + + // emulate 1 instruction with timeout + uc.emu_start(ADDRESS, ADDRESS + 4, 1000, 1); + pc = uc.reg_read(UC_RISCV_REG_PC); + + if (pc != 0x10000) { + System.out.format( + "Error after step: PC is: 0x%x, expected was 0x10004\n", pc); + } + + // emulate 1 instruction with timeout + uc.emu_start(ADDRESS, ADDRESS + 4, 1000, 1); + pc = uc.reg_read(UC_RISCV_REG_PC); + + if (pc != 0x10000) { + System.out.format( + "Error after step: PC is: 0x%x, expected was 0x10004\n", pc); + } + + // now print out some registers + System.out.println(">>> Emulation done"); + } + + public static void test_riscv_sd64() { + long reg; + + System.out.println("Emulate RISCV code: sd64 instruction"); + + // Initialize emulator in RISCV64 mode + Unicorn uc = new Unicorn(UC_ARCH_RISCV, UC_MODE_RISCV64); + + // map 2MB memory for this emulation + uc.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL); + + // write machine code to be emulated to memory + uc.mem_write(ADDRESS, CODE64); + + // tracing all basic blocks with customized callback + uc.hook_add(hook_block, 1, 0, null); + + // tracing all instruction + uc.hook_add(hook_code, 1, 0, null); + + reg = ADDRESS + 0x100; + uc.reg_write(UC_RISCV_REG_SP, reg); + + reg = 0x11223344; + uc.reg_write(UC_RISCV_REG_S0, reg); + + // execute instruction + uc.emu_start(0x10000, -1, 0, 1); + + // now print out some registers + System.out.println(">>> Emulation done."); + } + + private static final EventMemHook hook_memalloc = + (uc, type, address, size, value, user_data) -> { + long aligned_address = address & ~0xFFFL; + int aligned_size = ((int) (size / 0x1000) + 1) * 0x1000; + + System.out.format( + ">>> Allocating block at 0x%x (0x%x), block size = 0x%x (0x%x)\n", + address, aligned_address, size, aligned_size); + + uc.mem_map(aligned_address, aligned_size, UC_PROT_ALL); + + // this recovers from missing memory, so we return true + return true; + }; + + public static void test_recover_from_illegal() { + long a0 = 0x1234L; + long a1 = 0x7890L; + + System.out.println("Emulate RISCV code: recover_from_illegal"); + + // Initialize emulator in RISCV64 mode + Unicorn uc = new Unicorn(UC_ARCH_RISCV, UC_MODE_RISCV64); + + uc.reg_write(UC_RISCV_REG_A0, a0); + uc.reg_write(UC_RISCV_REG_A1, a1); + + // map 2MB memory for this emulation + uc.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL); + + // auto-allocate memory on access + uc.hook_add(hook_memalloc, UC_HOOK_MEM_UNMAPPED, 1, 0, null); + + // tracing all basic blocks with customized callback + uc.hook_add(hook_block, 1, 0, null); + + // tracing all instruction + uc.hook_add(hook_code, 1, 0, null); + + // write machine code to be emulated to memory + uc.mem_write(ADDRESS, CODE); + + // emulate 1 instruction, wrong address, illegal code + try { + uc.emu_start(0x1000, -1, 0, 1); + throw new RuntimeException("emu_start should have failed!"); + } catch (UnicornException e) { + System.out.println("Expected Illegal Instruction error, got: " + e); + } + + // emulate 1 instruction, correct address, valid code + uc.emu_start(ADDRESS, -1, 0, 1); + + // now print out some registers + System.out.println(">>> Emulation done. Below is the CPU context"); + + System.out.format(">>> A0 = 0x%x\n", uc.reg_read(UC_RISCV_REG_A0)); + System.out.format(">>> A1 = 0x%x\n", uc.reg_read(UC_RISCV_REG_A1)); + } + + public static void test_riscv_func_return() { + long pc = 0, ra = 0; + + System.out.println("Emulate RISCV code: return from func"); + + // Initialize emulator in RISCV64 mode + Unicorn uc = new Unicorn(UC_ARCH_RISCV, UC_MODE_RISCV64); + + // map 2MB memory for this emulation + uc.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL); + + // write machine code to be emulated to memory + uc.mem_write(ADDRESS, FUNC_CODE); + + // tracing all basic blocks with customized callback + uc.hook_add(hook_block, 1, 0, null); + + // tracing all instruction + uc.hook_add(hook_code, 1, 0, null); + + // set return address register + // RET instruction will return to address in RA + // so after RET, PC == RA + ra = 0x10006; + uc.reg_write(UC_RISCV_REG_RA, ra); + + // execute ret instruction + uc.emu_start(0x10000, -1, 0, 1); + + pc = uc.reg_read(UC_RISCV_REG_PC); + if (pc != ra) { + System.out.format( + "Error after execution: PC is: 0x%x, expected was 0x%x\n", + pc, ra); + if (pc == 0x10000) { + System.out.println(" PC did not change during execution"); + } + } else { + System.out.println("Good, PC == RA"); + } + + // set return address register + // C.RET instruction will return to address in RA + // so after C.RET, PC == RA + ra = 0x10006; + uc.reg_write(UC_RISCV_REG_RA, ra); + + System.out.println("========"); + // execute c.ret instruction + uc.emu_start(0x10004, -1, 0, 1); + + pc = uc.reg_read(UC_RISCV_REG_PC); + if (pc != ra) { + System.out.format( + "Error after execution: PC is: 0x%x, expected was 0x%x\n", + pc, ra); + if (pc == 0x10004) { + System.out.println(" PC did not change during execution"); + } + } else { + System.out.println("Good, PC == RA"); + } + + // now print out some registers + System.out.println(">>> Emulation done."); + } + + public static final void main(String[] args) { + test_recover_from_illegal(); + + System.out.println("------------------"); + test_riscv(); + + System.out.println("------------------"); + test_riscv2(); + + System.out.println("------------------"); + test_riscv3(); + + System.out.println("------------------"); + test_riscv_step(); + + // System.out.println("------------------"); + // test_riscv_timeout(); + + System.out.println("------------------"); + test_riscv_sd64(); + + System.out.println("------------------"); + test_riscv_func_return(); + } +} diff --git a/bindings/java/samples/Sample_s390x.java b/bindings/java/samples/Sample_s390x.java new file mode 100644 index 00000000..66c9dd17 --- /dev/null +++ b/bindings/java/samples/Sample_s390x.java @@ -0,0 +1,88 @@ +/* + +Java bindings for the Unicorn Emulator Engine + +Copyright(c) 2023 Robert Xiao + +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. + +*/ + +/* Sample code to demonstrate how to emulate S390X code */ + +package samples; + +import unicorn.*; + +public class Sample_s390x implements UnicornConst, S390xConst { + /** code to be emulated: + * {@code lr %r2, %r3} + */ + private static final byte[] CODE = Utils.hexToBytes("1823"); + + // memory address where emulation starts + private static final long ADDRESS = 0x10000; + + private static final BlockHook hook_block = + (uc, address, size, user_data) -> { + System.out.format( + ">>> Tracing basic block at 0x%x, block size = 0x%x\n", + address, size); + }; + + private static final CodeHook hook_code = + (uc, address, size, user_data) -> { + System.out.format( + ">>> Tracing instruction at 0x%x, instruction size = 0x%x\n", + address, size); + }; + + public static void test_s390x() { + long r2 = 2, r3 = 3; + + System.out.println("Emulate S390X code"); + + Unicorn uc = new Unicorn(UC_ARCH_S390X, UC_MODE_BIG_ENDIAN); + + // map 2MB memory for this emulation + uc.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL); + + // write machine code to be emulated to memory + uc.mem_write(ADDRESS, CODE); + + // initialize machine registers + uc.reg_write(UC_S390X_REG_R2, r2); + uc.reg_write(UC_S390X_REG_R3, r3); + + // tracing all basic blocks with customized callback + uc.hook_add(hook_block, 1, 0, null); + + // tracing one instruction at ADDRESS with customized callback + uc.hook_add(hook_code, ADDRESS, ADDRESS + CODE.length, null); + + // emulate machine code in infinite time (last param = 0), or when + // finishing all the code. + uc.emu_start(ADDRESS, ADDRESS + CODE.length, 0, 0); + + // now print out some registers + System.out.println(">>> Emulation done. Below is the CPU context"); + + System.out.format(">>> R2 = 0x%x\t\t>>> R3 = 0x%x\n", + uc.reg_read(UC_S390X_REG_R2), uc.reg_read(UC_S390X_REG_R3)); + } + + public static final void main(String[] args) { + test_s390x(); + } +} diff --git a/bindings/java/samples/Sample_sparc.java b/bindings/java/samples/Sample_sparc.java index 90058d2e..43f01af7 100644 --- a/bindings/java/samples/Sample_sparc.java +++ b/bindings/java/samples/Sample_sparc.java @@ -28,50 +28,30 @@ package samples; import unicorn.*; -public class Sample_sparc { +public class Sample_sparc implements UnicornConst, SparcConst { - // 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 + /** code to be emulated: + * {@code add %g1, %g2, %g3} + */ + private static final byte[] SPARC_CODE = Utils.hexToBytes("86004002"); + //public static final byte[] SPARC_CODE = Utils.hexToBytes("bb700000"); //illegal code // memory address where emulation starts - public static final int ADDRESS = 0x10000; + private 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 final BlockHook hook_block = + (uc, address, size, user_data) -> { + System.out.format( + ">>> Tracing basic block at 0x%x, block size = 0x%x\n", + address, size); + }; - 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( + private static final CodeHook hook_code = + (uc, address, size, user_data) -> { + System.out.format( ">>> Tracing instruction at 0x%x, instruction size = 0x%x\n", - address, size)); - } - } + address, size); + }; public static void test_sparc() { long g1 = 0x1230L; // G1 register @@ -81,25 +61,24 @@ public class Sample_sparc { System.out.print("Emulate SPARC code\n"); // Initialize emulator in Sparc mode - Unicorn u = new Unicorn(Unicorn.UC_ARCH_SPARC, - Unicorn.UC_MODE_32 + Unicorn.UC_MODE_BIG_ENDIAN); + Unicorn u = new Unicorn(UC_ARCH_SPARC, UC_MODE_32 | UC_MODE_BIG_ENDIAN); // map 2MB memory for this emulation - u.mem_map(ADDRESS, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL); + u.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL); // 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); + u.reg_write(UC_SPARC_REG_G1, g1); + u.reg_write(UC_SPARC_REG_G2, g2); + u.reg_write(UC_SPARC_REG_G3, g3); // tracing all basic blocks with customized callback - u.hook_add(new MyBlockHook(), 1, 0, null); + u.hook_add(hook_block, 1, 0, null); // tracing one instruction at ADDRESS with customized callback - u.hook_add(new MyCodeHook(), ADDRESS, ADDRESS, null); + u.hook_add(hook_code, ADDRESS, ADDRESS, null); // emulate machine code in infinite time (last param = 0), or when // finishing all the code. @@ -107,11 +86,7 @@ public class Sample_sparc { // 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); - System.out.print(String.format(">>> G3 = 0x%x\n", g3)); - - u.close(); + System.out.format(">>> G3 = 0x%x\n", u.reg_read(UC_SPARC_REG_G3)); } public static void main(String args[]) { diff --git a/bindings/java/samples/Sample_tricore.java b/bindings/java/samples/Sample_tricore.java new file mode 100644 index 00000000..6a67a8da --- /dev/null +++ b/bindings/java/samples/Sample_tricore.java @@ -0,0 +1,84 @@ +/* + +Java bindings for the Unicorn Emulator Engine + +Copyright(c) 2023 Robert Xiao + +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. + +*/ + +/* Sample code to demonstrate how to emulate TriCore code + * Ported from the C version originally by Eric Poole , 2022 + */ + +package samples; + +import unicorn.*; + +public class Sample_tricore implements UnicornConst, TriCoreConst { + /** code to be emulated: + * {@code mov d1, #0x1; mov.u d0, #0x8000} + */ + private static final byte[] CODE = Utils.hexToBytes("8211bb000008"); + + // memory address where emulation starts + private static final long ADDRESS = 0x10000; + + private static final BlockHook hook_block = + (uc, address, size, user_data) -> { + System.out.format( + ">>> Tracing basic block at 0x%x, block size = 0x%x\n", + address, size); + }; + + private static final CodeHook hook_code = + (uc, address, size, user_data) -> { + System.out.format( + ">>> Tracing instruction at 0x%x, instruction size = 0x%x\n", + address, size); + }; + + public static void test_tricore() { + System.out.println("Emulate TriCore code"); + + Unicorn uc = new Unicorn(UC_ARCH_TRICORE, UC_MODE_LITTLE_ENDIAN); + + // map 2MB memory for this emulation + uc.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL); + + // write machine code to be emulated to memory + uc.mem_write(ADDRESS, CODE); + + // tracing all basic blocks with customized callback + uc.hook_add(hook_block, 1, 0, null); + + // tracing one instruction at ADDRESS with customized callback + uc.hook_add(hook_code, ADDRESS, ADDRESS + CODE.length, null); + + // emulate machine code in infinite time (last param = 0), or when + // finishing all the code. + uc.emu_start(ADDRESS, ADDRESS + CODE.length, 0, 0); + + // now print out some registers + System.out.println(">>> Emulation done. Below is the CPU context"); + + System.out.format(">>> d0 = 0x%x\n", uc.reg_read(UC_TRICORE_REG_D0)); + System.out.format(">>> d1 = 0x%x\n", uc.reg_read(UC_TRICORE_REG_D1)); + } + + public static final void main(String[] args) { + test_tricore(); + } +} diff --git a/bindings/java/samples/Sample_x86.java b/bindings/java/samples/Sample_x86.java index 75e6a3fc..5870a66d 100644 --- a/bindings/java/samples/Sample_x86.java +++ b/bindings/java/samples/Sample_x86.java @@ -26,519 +26,653 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. package samples; +import java.math.BigInteger; +import java.nio.ByteBuffer; + import unicorn.*; -public class Sample_x86 { +public class Sample_x86 implements UnicornConst, X86Const { - // 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 }; - public static final byte[] X86_CODE16 = { 0, 0 }; // add byte ptr [bx + si], al + /** code to be emulated + * {@code INC ecx; DEC edx; PXOR xmm0, xmm1} + */ + private static final byte[] X86_CODE32 = Utils.hexToBytes("414a660fefc1"); + /** code to be emulated + * {@code jmp 4; nop; nop; nop; nop; nop; nop} + */ + private static final byte[] X86_CODE32_JUMP = + Utils.hexToBytes("eb02909090909090"); + // private static final byte[] X86_CODE32_SELF = Utils.hexToBytes("eb1c5a89d68b02663dca7d7506660503038902fec23d4141414175e9ffe6e8dfffffff31d26a0b589952682f2f7368682f62696e89e3525389e1ca7d41414141"); - // memory address where emulation starts + /** code to be emulated + * {@code PUSH ecx; PUSH ecx; PUSH ecx; PUSH ecx} + */ + // private static final byte[] X86_CODE32 = Utils.hexToBytes("51515151"); + + /** code to be emulated + * {@code INC ecx; DEC edx; self_loop: JMP self_loop} + */ + private static final byte[] X86_CODE32_LOOP = Utils.hexToBytes("414aebfe"); + + /** code to be emulated + * {@code mov [0xaaaaaaaa], ecx; INC ecx; DEC edx} + */ + private static final byte[] X86_CODE32_MEM_WRITE = + Utils.hexToBytes("890DAAAAAAAA414a"); + + /** code to be emulated + * {@code mov ecx, [0xaaaaaaaa]; INC ecx; DEC edx} + */ + private static final byte[] X86_CODE32_MEM_READ = + Utils.hexToBytes("8B0DAAAAAAAA414a"); + + /** code to be emulated + * {@code inc eax; mov ebx, [0x100000]; inc edx} + */ + private static final byte[] X86_CODE32_MEM_READ_IN_TB = + Utils.hexToBytes("408b1d0000100042"); + + /** code to be emulated + * {@code JMP outside; INC ecx; DEC edx} + */ + private static final byte[] X86_CODE32_JMP_INVALID = + Utils.hexToBytes("e9e9eeeeee414a"); + + /** code to be emulated + * {@code INC ecx; IN AL, 0x3f; DEC edx; OUT 0x46, AL; INC ebx} + */ + private static final byte[] X86_CODE32_INOUT = + Utils.hexToBytes("41E43F4aE64643"); + + /** code to be emulated + * {@code INC eax} + */ + private static final byte[] X86_CODE32_INC = Utils.hexToBytes("40"); + + //private static final byte[] X86_CODE64 = Utils.hexToBytes("41BC3BB0282A490FC9904D0FADCF4987FD904881D28ACE773548F7D9"); // <== still crash + /** code to be emulated */ + private static final byte[] X86_CODE64 = + Utils.hexToBytes("41BC3BB0282A490FC9904D0FADCF4987FD90" + + "4881D28ACE773548F7D94D29F44981C9F68A" + + "C6534D87ED480FADD249F7D448F7E14D19C5" + + "4D89C548F7D641B84F8D6B594D87D0686A1E" + + "093C59"); + /** code to be emulated + * {@code add byte ptr [bx + si], al} + */ + private static final byte[] X86_CODE16 = Utils.hexToBytes("0000"); + /** code to be emulated + * {@code syscall} + */ + private static final byte[] X86_CODE64_SYSCALL = Utils.hexToBytes("0f05"); + /** code to be emulated + * {@code mov [0x20004], ecx; mov ecx, [0x20004]} + */ + private static final byte[] X86_MMIO_CODE = + Utils.hexToBytes("890d040002008b0d04000200"); + /** code to be emulated + *
    +     * 0x1000 xor dword ptr [edi+0x3], eax ; edi=0x1000, eax=0xbc4177e6
    +     * 0x1003 dw 0x3ea98b13
    +     * 
    + */ + private static final byte[] X86_CODE32_SMC = + Utils.hexToBytes("314703138ba93e"); + + /** 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; - } + private static final BlockHook hook_block = + (uc, address, size, user_data) -> { + System.out.format( + ">>> Tracing basic block at 0x%x, block size = 0x%x\n", + address, size); + }; - 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.printf( - ">>> 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.printf( + private static final CodeHook hook_code = + (uc, address, size, user_data) -> { + System.out.format( ">>> Tracing instruction at 0x%x, instruction size = 0x%x\n", address, size); - long eflags = u.reg_read(Unicorn.UC_X86_REG_EFLAGS); - System.out.printf(">>> --- EFLAGS is 0x%x\n", eflags); + long eflags = uc.reg_read(UC_X86_REG_EFLAGS); + System.out.format(">>> --- EFLAGS is 0x%x\n", eflags); // Uncomment below code to stop the emulation using uc_emu_stop() // if (address == 0x1000009) - // u.emu_stop(); - } - } + // uc.emu_stop(); + }; - private static class MyWriteInvalidHook implements EventMemHook { - public boolean hook(Unicorn u, int type, long address, int size, - long value, - Object user) { - System.out.printf( - ">>> 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, Unicorn.UC_PROT_ALL); - // return true to indicate we want to continue - return true; - } - } - - // callback for tracing instruction - private static class MyCode64Hook implements CodeHook { - public void hook(Unicorn u, long address, int size, Object user_data) { - long r_rip = u.reg_read(Unicorn.UC_X86_REG_RIP); - System.out.printf( + private static final CodeHook hook_code64 = + (uc, address, size, user_data) -> { + long rip = uc.reg_read(UC_X86_REG_RIP); + System.out.format( ">>> Tracing instruction at 0x%x, instruction size = 0x%x\n", address, size); - System.out.printf(">>> RIP is 0x%x\n", r_rip); + System.out.format(">>> RIP is 0x%x\n", rip); + }; - // Uncomment below code to stop the emulation using uc_emu_stop() - // if (address == 0x1000009) - // uc_emu_stop(handle); - } - } + private static final EventMemHook hook_mem_invalid = + (uc, type, address, size, value, user) -> { + switch (type) { + default: + // return false to indicate we want to stop emulation + return false; + case UC_MEM_WRITE_UNMAPPED: + System.out.printf( + ">>> 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 + uc.mem_map(0xaaaa0000L, 2 * 1024 * 1024, UC_PROT_ALL); + // return true to indicate we want to continue + return true; + } + }; - private static class MyRead64Hook implements MemHook { - public void hook(Unicorn u, int type, long address, int size, - long value, Object user) { - System.out.printf( - ">>> Memory is being READ at 0x%x, data size = %d\n", address, - size); - } - } - - private static class MyWrite64Hook implements MemHook { - public void hook(Unicorn u, int type, long address, int size, - long value, - Object user) { - System.out.printf( - ">>> Memory is being WRITE at 0x%x, data size = %d, data value = 0x%x\n", - address, size, value); - } - } + private static final MemHook hook_mem64 = + (uc, type, address, size, value, user_data) -> { + switch (type) { + default: + break; + case UC_MEM_READ: + System.out.format( + ">>> Memory is being READ at 0x%x, data size = %d\n", + address, size); + break; + case UC_MEM_WRITE: + System.out.format( + ">>> Memory is being WRITE at 0x%x, data size = %d, data value = 0x%x\n", + address, size, value); + break; + } + }; // 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) { - long r_eip = u.reg_read(Unicorn.UC_X86_REG_EIP); + private static final InHook hook_in = (uc, port, size, user) -> { + long r_eip = uc.reg_read(UC_X86_REG_EIP); - System.out.printf( - "--- reading from port 0x%x, size: %d, address: 0x%x\n", port, - size, r_eip); + System.out.printf( + "--- reading from port 0x%x, size: %d, address: 0x%x\n", port, + size, 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; + 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) { - long eip = u.reg_read(Unicorn.UC_X86_REG_EIP); - long tmp = 0; - System.out.printf( - "--- writing to port 0x%x, size: %d, value: 0x%x, address: 0x%x\n", - port, size, value, eip); + private static final OutHook hook_out = (uc, port, size, value, user) -> { + long eip = uc.reg_read(UC_X86_REG_EIP); + long tmp = 0; + System.out.printf( + "--- writing to port 0x%x, size: %d, value: 0x%x, address: 0x%x\n", + port, size, value, 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); - break; - case 2: - tmp = u.reg_read(Unicorn.UC_X86_REG_AX); - break; - case 4: - tmp = u.reg_read(Unicorn.UC_X86_REG_EAX); - break; - } - - System.out.printf("--- register value = 0x%x\n", tmp); + // confirm that value is indeed the value of AL/AX/EAX + switch (size) { + default: + return; // should never reach this + case 1: + tmp = uc.reg_read(UC_X86_REG_AL); + break; + case 2: + tmp = uc.reg_read(UC_X86_REG_AX); + break; + case 4: + tmp = uc.reg_read(UC_X86_REG_EAX); + break; } + + System.out.printf("--- register value = 0x%x\n", tmp); + }; + + // callback for SYSCALL instruction (X86). + private static final SyscallHook hook_syscall = (uc, user_data) -> { + long rax = uc.reg_read(UC_X86_REG_RAX); + if (rax == 0x100) { + rax = 0x200; + uc.reg_write(UC_X86_REG_RAX, rax); + } else { + System.out.format("ERROR: was not expecting rax=0x%x in syscall\n", + rax); + } + }; + + private static final EventMemHook hook_memalloc = + (uc, type, address, size, value, user_data) -> { + long aligned_address = address & ~(0xFFFL); + int aligned_size = ((int) (size / 0x1000) + 1) * 0x1000; + + System.out.format( + ">>> Allocating block at 0x%x (0x%x), block size = 0x%x (0x%x)\n", + address, aligned_address, size, aligned_size); + + uc.mem_map(aligned_address, aligned_size, UC_PROT_ALL); + + // write machine code to be emulated to memory + uc.mem_write(aligned_address, X86_CODE32); + + // this recovers from missing memory, so we return true + return true; + }; + + public static void test_miss_code() { + int r_ecx = 0x1234; // ECX register + int r_edx = 0x7890; // EDX register + + System.out.println("Emulate i386 code - missing code"); + + // Initialize emulator in X86-32bit mode + Unicorn uc = new Unicorn(UC_ARCH_X86, UC_MODE_32); + + // initialize machine registers + uc.reg_write(UC_X86_REG_ECX, r_ecx); + uc.reg_write(UC_X86_REG_EDX, r_edx); + + // tracing all instruction by having @begin > @end + uc.hook_add(hook_code, 1, 0, null); + + // auto-allocate memory on access + uc.hook_add(hook_memalloc, UC_HOOK_MEM_UNMAPPED, 1, 0, null); + + // emulate machine code, without having the code in yet + uc.emu_start(ADDRESS, ADDRESS + X86_CODE32.length, 0, 0); + + // now print out some registers + System.out.println(">>> Emulation done. Below is the CPU context"); + + System.out.format(">>> ECX = 0x%x\n", uc.reg_read(UC_X86_REG_ECX)); + System.out.format(">>> EDX = 0x%x\n", uc.reg_read(UC_X86_REG_EDX)); } public static void test_i386() { - long r_ecx = 0x1234L; // ECX register - long r_edx = 0x7890L; // EDX register + int tmp; + long r_ecx = 0x1234; // ECX register + long r_edx = 0x7890; // EDX register + // XMM0 and XMM1 registers, low qword then high qword + BigInteger r_xmm0 = + new BigInteger("000102030405060708090a0b0c0d0e0f", 16); + BigInteger r_xmm1 = + new BigInteger("00102030405060708090a0b0c0d0e0f0", 16); - System.out.print("Emulate i386 code\n"); + System.out.println("Emulate i386 code"); // 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; - } + Unicorn uc = new Unicorn(UC_ARCH_X86, UC_MODE_32); // map 2MB memory for this emulation - uc.mem_map(ADDRESS, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL); + uc.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL); // 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; - } + uc.mem_write(ADDRESS, X86_CODE32); // initialize machine registers - uc.reg_write(Unicorn.UC_X86_REG_ECX, r_ecx); - uc.reg_write(Unicorn.UC_X86_REG_EDX, r_edx); + uc.reg_write(UC_X86_REG_ECX, r_ecx); + uc.reg_write(UC_X86_REG_EDX, r_edx); + uc.reg_write(UC_X86_REG_XMM0, r_xmm0); + uc.reg_write(UC_X86_REG_XMM1, r_xmm1); // tracing all basic blocks with customized callback - uc.hook_add(new MyBlockHook(), 1, 0, null); + uc.hook_add(hook_block, 1, 0, null); // tracing all instruction by having @begin > @end - uc.hook_add(new MyCodeHook(), 1, 0, null); + uc.hook_add(hook_code, 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.printf("Failed on uc_emu_start() with error : %s\n", - uex.getMessage()); - } + uc.emu_start(ADDRESS, ADDRESS + X86_CODE32.length, 0, 0); // now print out some registers - System.out.print(">>> Emulation done. Below is the CPU context\n"); + System.out.println(">>> Emulation done. Below is the CPU context"); - r_ecx = uc.reg_read(Unicorn.UC_X86_REG_ECX); - r_edx = uc.reg_read(Unicorn.UC_X86_REG_EDX); - System.out.printf(">>> ECX = 0x%x\n", r_ecx); - System.out.printf(">>> EDX = 0x%x\n", r_edx); + r_ecx = uc.reg_read(UC_X86_REG_ECX); + r_edx = uc.reg_read(UC_X86_REG_EDX); + r_xmm0 = (BigInteger) uc.reg_read(UC_X86_REG_XMM0, null); + System.out.format(">>> ECX = 0x%x\n", r_ecx); + System.out.format(">>> EDX = 0x%x\n", r_edx); + String xmm0_string = + String.format("%32s", r_xmm0.toString(16)).replace(' ', '0'); + System.out.format(">>> XMM0 = 0x%s\n", xmm0_string); // read from memory - try { - byte[] tmp = uc.mem_read(ADDRESS, 4); - System.out.printf(">>> Read 4 bytes from [0x%x] = 0x%x\n", ADDRESS, - toInt(tmp)); - } catch (UnicornException ex) { - System.out.printf(">>> Failed to read 4 bytes from [0x%x]\n", - ADDRESS); - } - uc.close(); + tmp = Utils.toInt(uc.mem_read(ADDRESS, 4)); + System.out.format(">>> Read 4 bytes from [0x%x] = 0x%x\n", ADDRESS, + tmp); } - public static void test_i386_inout() { - long r_eax = 0x1234L; // ECX register - long r_ecx = 0x6789L; // EDX register + public static void test_i386_map_ptr() { + int tmp; + int r_ecx = 0x1234; // ECX register + int r_edx = 0x7890; // EDX register - System.out.print("===================================\n"); - System.out.print("Emulate i386 code with IN/OUT instructions\n"); + System.out.println("Emulate i386 code - use uc_mem_map_ptr()"); // Initialize emulator in X86-32bit mode - Unicorn u = new Unicorn(Unicorn.UC_ARCH_X86, Unicorn.UC_MODE_32); + Unicorn uc = new Unicorn(UC_ARCH_X86, UC_MODE_32); - // map 2MB memory for this emulation - u.mem_map(ADDRESS, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL); - - // write machine code to be emulated to memory - u.mem_write(ADDRESS, X86_CODE32_INOUT); + // malloc 2MB memory for this emulation + ByteBuffer mem = ByteBuffer.allocateDirect(2 * 1024 * 1024); + uc.mem_map_ptr(ADDRESS, mem, UC_PROT_ALL); + mem.put(X86_CODE32); // initialize machine registers - u.reg_write(Unicorn.UC_X86_REG_EAX, r_eax); - u.reg_write(Unicorn.UC_X86_REG_ECX, r_ecx); + uc.reg_write(UC_X86_REG_ECX, r_ecx); + uc.reg_write(UC_X86_REG_EDX, r_edx); // tracing all basic blocks with customized callback - u.hook_add(new MyBlockHook(), 1, 0, null); + uc.hook_add(hook_block, 1, 0, null); - // tracing all instructions - u.hook_add(new MyCodeHook(), 1, 0, null); - - // handle IN instruction - u.hook_add(new MyInHook(), Unicorn.UC_X86_INS_IN, 1, 0, null); - // handle OUT instruction - u.hook_add(new MyOutHook(), Unicorn.UC_X86_INS_OUT, 1, 0, null); + // tracing all instruction by having @begin > @end + uc.hook_add(hook_code, 1, 0, null); // emulate machine code in infinite time - u.emu_start(ADDRESS, ADDRESS + X86_CODE32_INOUT.length, 0, 0); + uc.emu_start(ADDRESS, ADDRESS + X86_CODE32.length, 0, 0); // now print out some registers - System.out.print(">>> Emulation done. Below is the CPU context\n"); + System.out.println(">>> Emulation done. Below is the CPU context"); + System.out.format(">>> ECX = 0x%x\n", uc.reg_read(UC_X86_REG_ECX)); + System.out.format(">>> EDX = 0x%x\n", uc.reg_read(UC_X86_REG_EDX)); - r_eax = u.reg_read(Unicorn.UC_X86_REG_EAX); - r_ecx = u.reg_read(Unicorn.UC_X86_REG_ECX); - System.out.printf(">>> EAX = 0x%x\n", r_eax); - System.out.printf(">>> ECX = 0x%x\n", r_ecx); - - u.close(); + // read from memory + tmp = Utils.toInt(uc.mem_read(ADDRESS, 4)); + System.out.format(">>> Read 4 bytes from [0x%x] = 0x%x\n", ADDRESS, + tmp); } public static void test_i386_jump() { - System.out.print("===================================\n"); - System.out.print("Emulate i386 code with jump\n"); + System.out.println("Emulate i386 code with jump"); // Initialize emulator in X86-32bit mode - Unicorn u = new Unicorn(Unicorn.UC_ARCH_X86, Unicorn.UC_MODE_32); + Unicorn uc = new Unicorn(UC_ARCH_X86, UC_MODE_32); // map 2MB memory for this emulation - u.mem_map(ADDRESS, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL); + uc.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL); // write machine code to be emulated to memory - u.mem_write(ADDRESS, X86_CODE32_JUMP); + uc.mem_write(ADDRESS, X86_CODE32_JUMP); // tracing 1 basic block with customized callback - u.hook_add(new MyBlockHook(), ADDRESS, ADDRESS, null); + uc.hook_add(hook_block, ADDRESS, ADDRESS, null); // tracing 1 instruction at ADDRESS - u.hook_add(new MyCodeHook(), ADDRESS, ADDRESS, null); + uc.hook_add(hook_code, ADDRESS, ADDRESS, null); // emulate machine code in infinite time - u.emu_start(ADDRESS, ADDRESS + X86_CODE32_JUMP.length, 0, 0); + uc.emu_start(ADDRESS, ADDRESS + X86_CODE32_JUMP.length, 0, 0); - System.out.print(">>> Emulation done. Below is the CPU context\n"); - - u.close(); + System.out.println(">>> Emulation done. Below is the CPU context"); } // emulate code that loop forever public static void test_i386_loop() { - long r_ecx = 0x1234L; // ECX register - long r_edx = 0x7890L; // EDX register + int r_ecx = 0x1234; // ECX register + int r_edx = 0x7890; // EDX register - System.out.print("===================================\n"); - System.out.print("Emulate i386 code that loop forever\n"); + System.out.println("Emulate i386 code that loop forever"); // Initialize emulator in X86-32bit mode - Unicorn u = new Unicorn(Unicorn.UC_ARCH_X86, Unicorn.UC_MODE_32); + Unicorn uc = new Unicorn(UC_ARCH_X86, UC_MODE_32); // map 2MB memory for this emulation - u.mem_map(ADDRESS, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL); + uc.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL); // write machine code to be emulated to memory - u.mem_write(ADDRESS, X86_CODE32_LOOP); + uc.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); + uc.reg_write(UC_X86_REG_ECX, r_ecx); + uc.reg_write(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); + uc.emu_start(ADDRESS, ADDRESS + X86_CODE32_LOOP.length, + 2 * 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); - r_edx = u.reg_read(Unicorn.UC_X86_REG_EDX); - System.out.printf(">>> ECX = 0x%x\n", r_ecx); - System.out.printf(">>> EDX = 0x%x\n", r_edx); - - u.close(); + System.out.println(">>> Emulation done. Below is the CPU context"); + System.out.format(">>> ECX = 0x%x\n", uc.reg_read(UC_X86_REG_ECX)); + System.out.format(">>> EDX = 0x%x\n", uc.reg_read(UC_X86_REG_EDX)); } // emulate code that read invalid memory public static void test_i386_invalid_mem_read() { - long r_ecx = 0x1234L; // ECX register - long r_edx = 0x7890L; // EDX register + int r_ecx = 0x1234; // ECX register + int r_edx = 0x7890; // EDX register - System.out.print("===================================\n"); - System.out.print("Emulate i386 code that read from invalid memory\n"); + System.out.println("Emulate i386 code that read from invalid memory"); // Initialize emulator in X86-32bit mode - Unicorn u = new Unicorn(Unicorn.UC_ARCH_X86, Unicorn.UC_MODE_32); + Unicorn uc = new Unicorn(UC_ARCH_X86, UC_MODE_32); // map 2MB memory for this emulation - u.mem_map(ADDRESS, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL); + uc.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL); // write machine code to be emulated to memory - u.mem_write(ADDRESS, X86_CODE32_MEM_READ); + uc.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); + uc.reg_write(UC_X86_REG_ECX, r_ecx); + uc.reg_write(UC_X86_REG_EDX, r_edx); // tracing all basic blocks with customized callback - u.hook_add(new MyBlockHook(), 1, 0, null); + uc.hook_add(hook_block, 1, 0, null); // tracing all instruction by having @begin > @end - u.hook_add(new MyCodeHook(), 1, 0, null); + uc.hook_add(hook_code, 1, 0, null); // emulate machine code in infinite time try { - u.emu_start(ADDRESS, ADDRESS + X86_CODE32_MEM_READ.length, 0, 0); - } catch (UnicornException uex) { - int err = u.errno(); - System.out.printf( - "Failed on u.emu_start() with error returned: %s\n", - uex.getMessage()); + uc.emu_start(ADDRESS, ADDRESS + X86_CODE32_MEM_READ.length, 0, 0); + throw new RuntimeException("Expected a crash!"); + } catch (UnicornException e) { + System.out.println("uc.emu_start failed as expected: " + e); } // 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); - r_edx = u.reg_read(Unicorn.UC_X86_REG_EDX); - System.out.printf(">>> ECX = 0x%x\n", r_ecx); - System.out.printf(">>> EDX = 0x%x\n", r_edx); - - u.close(); + System.out.println(">>> Emulation done. Below is the CPU context"); + System.out.format(">>> ECX = 0x%x\n", uc.reg_read(UC_X86_REG_ECX)); + System.out.format(">>> EDX = 0x%x\n", uc.reg_read(UC_X86_REG_EDX)); } - // emulate code that read invalid memory + // emulate code that write invalid memory public static void test_i386_invalid_mem_write() { - long r_ecx = 0x1234L; // ECX register - long r_edx = 0x7890L; // EDX register + int r_ecx = 0x1234; // ECX register + int r_edx = 0x7890; // EDX register + int tmp; - System.out.print("===================================\n"); - System.out.print("Emulate i386 code that write to invalid memory\n"); + System.out.println("Emulate i386 code that write to invalid memory"); // Initialize emulator in X86-32bit mode - Unicorn u = new Unicorn(Unicorn.UC_ARCH_X86, Unicorn.UC_MODE_32); + Unicorn uc = new Unicorn(UC_ARCH_X86, UC_MODE_32); // map 2MB memory for this emulation - u.mem_map(ADDRESS, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL); + uc.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL); // write machine code to be emulated to memory - u.mem_write(ADDRESS, X86_CODE32_MEM_WRITE); + uc.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); + uc.reg_write(UC_X86_REG_ECX, r_ecx); + uc.reg_write(UC_X86_REG_EDX, r_edx); // tracing all basic blocks with customized callback - u.hook_add(new MyBlockHook(), 1, 0, null); + uc.hook_add(hook_block, 1, 0, null); // tracing all instruction by having @begin > @end - u.hook_add(new MyCodeHook(), 1, 0, null); + uc.hook_add(hook_code, 1, 0, null); // intercept invalid memory events - u.hook_add(new MyWriteInvalidHook(), Unicorn.UC_HOOK_MEM_WRITE_UNMAPPED, - 1, 0, - null); + uc.hook_add(hook_mem_invalid, + UC_HOOK_MEM_READ_UNMAPPED | UC_HOOK_MEM_WRITE_UNMAPPED, + 1, 0, null); // emulate machine code in infinite time - try { - u.emu_start(ADDRESS, ADDRESS + X86_CODE32_MEM_WRITE.length, 0, 0); - } catch (UnicornException uex) { - System.out.printf( - "Failed on uc_emu_start() with error returned: %s\n", - uex.getMessage()); - } + uc.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); - r_edx = u.reg_read(Unicorn.UC_X86_REG_EDX); - System.out.printf(">>> ECX = 0x%x\n", r_ecx); - System.out.printf(">>> EDX = 0x%x\n", r_edx); + System.out.println(">>> Emulation done. Below is the CPU context"); + System.out.format(">>> ECX = 0x%x\n", uc.reg_read(UC_X86_REG_ECX)); + System.out.format(">>> EDX = 0x%x\n", uc.reg_read(UC_X86_REG_EDX)); // read from memory - byte tmp[] = u.mem_read(0xaaaaaaaa, 4); - System.out.printf(">>> Read 4 bytes from [0x%x] = 0x%x\n", 0xaaaaaaaa, - toInt(tmp)); + tmp = Utils.toInt(uc.mem_read(0xaaaaaaaaL, 4)); + System.out.format(">>> Read 4 bytes from [0x%x] = 0x%x\n", 0xaaaaaaaa, + tmp); try { - u.mem_read(0xffffffaa, 4); - System.out.printf(">>> Read 4 bytes from [0x%x] = 0x%x\n", - 0xffffffaa, toInt(tmp)); - } catch (UnicornException uex) { - System.out.printf(">>> Failed to read 4 bytes from [0x%x]\n", + tmp = Utils.toInt(uc.mem_read(0xffffffaaL, 4)); + throw new RuntimeException("Expected mem_read to fail"); + } catch (UnicornException e) { + System.out.format(">>> Failed to read 4 bytes from [0x%x]\n", 0xffffffaa); } - - u.close(); } // emulate code that jump to invalid memory public static void test_i386_jump_invalid() { - long r_ecx = 0x1234L; // ECX register - long r_edx = 0x7890L; // EDX register + int r_ecx = 0x1234; // ECX register + int r_edx = 0x7890; // EDX register - System.out.print("===================================\n"); - System.out.print("Emulate i386 code that jumps to invalid memory\n"); + System.out.println("Emulate i386 code that jumps to invalid memory"); // Initialize emulator in X86-32bit mode - Unicorn u = new Unicorn(Unicorn.UC_ARCH_X86, Unicorn.UC_MODE_32); + Unicorn uc = new Unicorn(UC_ARCH_X86, UC_MODE_32); // map 2MB memory for this emulation - u.mem_map(ADDRESS, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL); + uc.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL); // write machine code to be emulated to memory - u.mem_write(ADDRESS, X86_CODE32_JMP_INVALID); + uc.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); + uc.reg_write(UC_X86_REG_ECX, r_ecx); + uc.reg_write(UC_X86_REG_EDX, r_edx); // tracing all basic blocks with customized callback - u.hook_add(new MyBlockHook(), 1, 0, null); + uc.hook_add(hook_block, 1, 0, null); // tracing all instructions by having @begin > @end - u.hook_add(new MyCodeHook(), 1, 0, null); + uc.hook_add(hook_code, 1, 0, null); // emulate machine code in infinite time try { - u.emu_start(ADDRESS, ADDRESS + X86_CODE32_JMP_INVALID.length, 0, 0); - } catch (UnicornException uex) { - System.out.printf( - "Failed on uc_emu_start() with error returned: %s\n", - uex.getMessage()); + uc.emu_start(ADDRESS, ADDRESS + X86_CODE32_JMP_INVALID.length, 0, + 0); + throw new RuntimeException("Expected a crash!"); + } catch (UnicornException e) { + System.out.println("uc.emu_start failed as expected: " + e); } // now print out some registers - System.out.print(">>> Emulation done. Below is the CPU context\n"); + System.out.println(">>> Emulation done. Below is the CPU context"); + System.out.format(">>> ECX = 0x%x\n", uc.reg_read(UC_X86_REG_ECX)); + System.out.format(">>> EDX = 0x%x\n", uc.reg_read(UC_X86_REG_EDX)); + } - r_ecx = u.reg_read(Unicorn.UC_X86_REG_ECX); - r_edx = u.reg_read(Unicorn.UC_X86_REG_EDX); - System.out.printf(">>> ECX = 0x%x\n", r_ecx); - System.out.printf(">>> EDX = 0x%x\n", r_edx); + public static void test_i386_inout() { + int r_eax = 0x1234; // EAX register + int r_ecx = 0x6789; // ECX register - u.close(); + System.out.println("Emulate i386 code with IN/OUT instructions"); + + // Initialize emulator in X86-32bit mode + Unicorn uc = new Unicorn(UC_ARCH_X86, UC_MODE_32); + + // map 2MB memory for this emulation + uc.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL); + + // write machine code to be emulated to memory + uc.mem_write(ADDRESS, X86_CODE32_INOUT); + + // initialize machine registers + uc.reg_write(UC_X86_REG_EAX, r_eax); + uc.reg_write(UC_X86_REG_ECX, r_ecx); + + // tracing all basic blocks with customized callback + uc.hook_add(hook_block, 1, 0, null); + + // tracing all instructions + uc.hook_add(hook_code, 1, 0, null); + + // uc IN instruction + uc.hook_add(hook_in, null); + // uc OUT instruction + uc.hook_add(hook_out, null); + + // emulate machine code in infinite time + uc.emu_start(ADDRESS, ADDRESS + X86_CODE32_INOUT.length, 0, 0); + + // now print out some registers + System.out.println(">>> Emulation done. Below is the CPU context"); + System.out.format(">>> EAX = 0x%x\n", uc.reg_read(UC_X86_REG_EAX)); + System.out.format(">>> ECX = 0x%x\n", uc.reg_read(UC_X86_REG_ECX)); + } + + // emulate code and save/restore the CPU context + public static void test_i386_context_save() { + int r_eax = 0x1; // EAX register + + System.out.println("Save/restore CPU context in opaque blob"); + + // initialize emulator in X86-32bit mode + Unicorn uc = new Unicorn(UC_ARCH_X86, UC_MODE_32); + + // map 8KB memory for this emulation + uc.mem_map(ADDRESS, 8 * 1024, UC_PROT_ALL); + + // write machine code to be emulated to memory + uc.mem_write(ADDRESS, X86_CODE32_INC); + + // initialize machine registers + uc.reg_write(UC_X86_REG_EAX, r_eax); + + // emulate machine code in infinite time + System.out.println(">>> Running emulation for the first time"); + uc.emu_start(ADDRESS, ADDRESS + X86_CODE32_INC.length, 0, 0); + + // now print out some registers + System.out.println(">>> Emulation done. Below is the CPU context"); + System.out.format(">>> EAX = 0x%x\n", uc.reg_read(UC_X86_REG_EAX)); + + // allocate and save the CPU context + System.out.println(">>> Saving CPU context"); + Unicorn.Context context = uc.context_save(); + + // emulate machine code again + System.out.println(">>> Running emulation for the second time"); + uc.emu_start(ADDRESS, ADDRESS + X86_CODE32_INC.length, 0, 0); + + // now print out some registers + System.out.println(">>> Emulation done. Below is the CPU context"); + System.out.format(">>> EAX = 0x%x\n", uc.reg_read(UC_X86_REG_EAX)); + + // restore CPU context + uc.context_restore(context); + + // now print out some registers + System.out + .println(">>> CPU context restored. Below is the CPU context"); + System.out.format(">>> EAX = 0x%x\n", uc.reg_read(UC_X86_REG_EAX)); + + // modify some registers of the context + context.reg_write(UC_X86_REG_EAX, 0xc8); + + // and restore CPU context again + uc.context_restore(context); + + // now print out some registers + System.out.format( + ">>> CPU context restored with modification. Below is the CPU context\n"); + System.out.format(">>> EAX = 0x%x\n", uc.reg_read(UC_X86_REG_EAX)); } public static void test_x86_64() { @@ -557,156 +691,370 @@ public class Sample_x86 { long r14 = 0x595f72f6e4017f6eL; long r15 = 0x1efd97aea331ccccL; - long rsp = ADDRESS + 0x200000; + long rsp = ADDRESS + 0x200000L; - System.out.print("Emulate x86_64 code\n"); + System.out.println("Emulate x86_64 code"); // Initialize emulator in X86-64bit mode - Unicorn u = new Unicorn(Unicorn.UC_ARCH_X86, Unicorn.UC_MODE_64); + Unicorn uc = new Unicorn(UC_ARCH_X86, UC_MODE_64); // map 2MB memory for this emulation - u.mem_map(ADDRESS, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL); + uc.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL); // write machine code to be emulated to memory - u.mem_write(ADDRESS, X86_CODE64); + uc.mem_write(ADDRESS, X86_CODE64); // initialize machine registers - u.reg_write(Unicorn.UC_X86_REG_RSP, rsp); + uc.reg_write(UC_X86_REG_RSP, rsp); - u.reg_write(Unicorn.UC_X86_REG_RAX, rax); - u.reg_write(Unicorn.UC_X86_REG_RBX, rbx); - u.reg_write(Unicorn.UC_X86_REG_RCX, rcx); - u.reg_write(Unicorn.UC_X86_REG_RDX, rdx); - u.reg_write(Unicorn.UC_X86_REG_RSI, rsi); - u.reg_write(Unicorn.UC_X86_REG_RDI, rdi); - u.reg_write(Unicorn.UC_X86_REG_R8, r8); - u.reg_write(Unicorn.UC_X86_REG_R9, r9); - u.reg_write(Unicorn.UC_X86_REG_R10, r10); - u.reg_write(Unicorn.UC_X86_REG_R11, r11); - u.reg_write(Unicorn.UC_X86_REG_R12, r12); - u.reg_write(Unicorn.UC_X86_REG_R13, r13); - u.reg_write(Unicorn.UC_X86_REG_R14, r14); - u.reg_write(Unicorn.UC_X86_REG_R15, r15); + uc.reg_write(UC_X86_REG_RAX, rax); + uc.reg_write(UC_X86_REG_RBX, rbx); + uc.reg_write(UC_X86_REG_RCX, rcx); + uc.reg_write(UC_X86_REG_RDX, rdx); + uc.reg_write(UC_X86_REG_RSI, rsi); + uc.reg_write(UC_X86_REG_RDI, rdi); + uc.reg_write(UC_X86_REG_R8, r8); + uc.reg_write(UC_X86_REG_R9, r9); + uc.reg_write(UC_X86_REG_R10, r10); + uc.reg_write(UC_X86_REG_R11, r11); + uc.reg_write(UC_X86_REG_R12, r12); + uc.reg_write(UC_X86_REG_R13, r13); + uc.reg_write(UC_X86_REG_R14, r14); + uc.reg_write(UC_X86_REG_R15, r15); // tracing all basic blocks with customized callback - u.hook_add(new MyBlockHook(), 1, 0, null); + uc.hook_add(hook_block, 1, 0, null); // tracing all instructions in the range [ADDRESS, ADDRESS+20] - u.hook_add(new MyCode64Hook(), ADDRESS, ADDRESS + 20, null); + uc.hook_add(hook_code64, ADDRESS, ADDRESS + 20, null); // tracing all memory WRITE access (with @begin > @end) - u.hook_add(new MyWrite64Hook(), Unicorn.UC_HOOK_MEM_WRITE, 1, 0, null); + uc.hook_add(hook_mem64, UC_HOOK_MEM_WRITE, 1, 0, null); // tracing all memory READ access (with @begin > @end) - u.hook_add(new MyRead64Hook(), Unicorn.UC_HOOK_MEM_READ, 1, 0, null); + uc.hook_add(hook_mem64, UC_HOOK_MEM_READ, 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); + uc.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"); + System.out.println(">>> Emulation done. Below is the CPU context"); - long r_rax = u.reg_read(Unicorn.UC_X86_REG_RAX); - long r_rbx = u.reg_read(Unicorn.UC_X86_REG_RBX); - long r_rcx = u.reg_read(Unicorn.UC_X86_REG_RCX); - long r_rdx = u.reg_read(Unicorn.UC_X86_REG_RDX); - long r_rsi = u.reg_read(Unicorn.UC_X86_REG_RSI); - long r_rdi = u.reg_read(Unicorn.UC_X86_REG_RDI); - long r_r8 = u.reg_read(Unicorn.UC_X86_REG_R8); - long r_r9 = u.reg_read(Unicorn.UC_X86_REG_R9); - long r_r10 = u.reg_read(Unicorn.UC_X86_REG_R10); - long r_r11 = u.reg_read(Unicorn.UC_X86_REG_R11); - long r_r12 = u.reg_read(Unicorn.UC_X86_REG_R12); - long r_r13 = u.reg_read(Unicorn.UC_X86_REG_R13); - long r_r14 = u.reg_read(Unicorn.UC_X86_REG_R14); - long r_r15 = u.reg_read(Unicorn.UC_X86_REG_R15); + System.out.format(">>> RAX = 0x%x\n", uc.reg_read(UC_X86_REG_RAX)); + System.out.format(">>> RBX = 0x%x\n", uc.reg_read(UC_X86_REG_RBX)); + System.out.format(">>> RCX = 0x%x\n", uc.reg_read(UC_X86_REG_RCX)); + System.out.format(">>> RDX = 0x%x\n", uc.reg_read(UC_X86_REG_RDX)); + System.out.format(">>> RSI = 0x%x\n", uc.reg_read(UC_X86_REG_RSI)); + System.out.format(">>> RDI = 0x%x\n", uc.reg_read(UC_X86_REG_RDI)); + System.out.format(">>> R8 = 0x%x\n", uc.reg_read(UC_X86_REG_R8)); + System.out.format(">>> R9 = 0x%x\n", uc.reg_read(UC_X86_REG_R9)); + System.out.format(">>> R10 = 0x%x\n", uc.reg_read(UC_X86_REG_R10)); + System.out.format(">>> R11 = 0x%x\n", uc.reg_read(UC_X86_REG_R11)); + System.out.format(">>> R12 = 0x%x\n", uc.reg_read(UC_X86_REG_R12)); + System.out.format(">>> R13 = 0x%x\n", uc.reg_read(UC_X86_REG_R13)); + System.out.format(">>> R14 = 0x%x\n", uc.reg_read(UC_X86_REG_R14)); + System.out.format(">>> R15 = 0x%x\n", uc.reg_read(UC_X86_REG_R15)); + } - System.out.printf(">>> RAX = 0x%x\n", r_rax); - System.out.printf(">>> RBX = 0x%x\n", r_rbx); - System.out.printf(">>> RCX = 0x%x\n", r_rcx); - System.out.printf(">>> RDX = 0x%x\n", r_rdx); - System.out.printf(">>> RSI = 0x%x\n", r_rsi); - System.out.printf(">>> RDI = 0x%x\n", r_rdi); - System.out.printf(">>> R8 = 0x%x\n", r_r8); - System.out.printf(">>> R9 = 0x%x\n", r_r9); - System.out.printf(">>> R10 = 0x%x\n", r_r10); - System.out.printf(">>> R11 = 0x%x\n", r_r11); - System.out.printf(">>> R12 = 0x%x\n", r_r12); - System.out.printf(">>> R13 = 0x%x\n", r_r13); - System.out.printf(">>> R14 = 0x%x\n", r_r14); - System.out.printf(">>> R15 = 0x%x\n", r_r15); + public static void test_x86_64_syscall() { + long rax = 0x100; - u.close(); + System.out.println("Emulate x86_64 code with 'syscall' instruction"); + + // Initialize emulator in X86-64bit mode + Unicorn uc = new Unicorn(UC_ARCH_X86, UC_MODE_64); + + // map 2MB memory for this emulation + uc.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL); + + // write machine code to be emulated to memory + uc.mem_write(ADDRESS, X86_CODE64_SYSCALL); + + // hook interrupts for syscall + uc.hook_add(hook_syscall, UC_X86_INS_SYSCALL, 1, 0, null); + + // initialize machine registers + uc.reg_write(UC_X86_REG_RAX, rax); + + // emulate machine code in infinite time (last param = 0), or when + // finishing all the code. + uc.emu_start(ADDRESS, ADDRESS + X86_CODE64_SYSCALL.length, 0, 0); + + // now print out some registers + System.out.println(">>> Emulation done. Below is the CPU context"); + System.out.format(">>> RAX = 0x%x\n", uc.reg_read(UC_X86_REG_RAX)); } public static void test_x86_16() { - long eax = 7L; - long ebx = 5L; - long esi = 6L; + int eax = 7; + int ebx = 5; + int esi = 6; - System.out.print("Emulate x86 16-bit code\n"); + System.out.println("Emulate x86 16-bit code"); // Initialize emulator in X86-16bit mode - Unicorn u = new Unicorn(Unicorn.UC_ARCH_X86, Unicorn.UC_MODE_16); + Unicorn uc = new Unicorn(UC_ARCH_X86, UC_MODE_16); // map 8KB memory for this emulation - u.mem_map(0, 8 * 1024, Unicorn.UC_PROT_ALL); + uc.mem_map(0, 8 * 1024, UC_PROT_ALL); // write machine code to be emulated to memory - u.mem_write(0, X86_CODE16); + uc.mem_write(0, X86_CODE16); // initialize machine registers - u.reg_write(Unicorn.UC_X86_REG_EAX, eax); - u.reg_write(Unicorn.UC_X86_REG_EBX, ebx); - u.reg_write(Unicorn.UC_X86_REG_ESI, esi); + uc.reg_write(UC_X86_REG_EAX, eax); + uc.reg_write(UC_X86_REG_EBX, ebx); + uc.reg_write(UC_X86_REG_ESI, esi); // emulate machine code in infinite time (last param = 0), or when // finishing all the code. - u.emu_start(0, X86_CODE16.length, 0, 0); + uc.emu_start(0, X86_CODE16.length, 0, 0); // now print out some registers - System.out.print(">>> Emulation done. Below is the CPU context\n"); + System.out.println(">>> Emulation done. Below is the CPU context"); // read from memory - byte[] tmp = u.mem_read(11, 1); - System.out.printf(">>> Read 1 bytes from [0x%x] = 0x%x\n", 11, - toInt(tmp)); + byte[] result = uc.mem_read(11, 1); + System.out.format(">>> Read 1 bytes from [0x%x] = 0x%x\n", 11, + result[0] & 0xff); + } - u.close(); + public static void test_i386_invalid_mem_read_in_tb() { + int r_eax = 0x1234; // EAX register + int r_edx = 0x7890; // EDX register + + System.out.format( + "Emulate i386 code that read invalid memory in the middle of a TB\n"); + + // Initialize emulator in X86-32bit mode + Unicorn uc = new Unicorn(UC_ARCH_X86, UC_MODE_32); + + // map 2MB memory for this emulation + uc.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL); + + // write machine code to be emulated to memory + uc.mem_write(ADDRESS, X86_CODE32_MEM_READ_IN_TB); + + // initialize machine registers + uc.reg_write(UC_X86_REG_EAX, r_eax); + uc.reg_write(UC_X86_REG_EDX, r_edx); + + // Add a dummy callback. + // Note: if this callback is not added, the EIP will not be updated, + // and EIP will read as ADDRESS after emu_start fails. + uc.hook_add((MemHook) (u, type, address, size, value, user) -> { + }, UC_HOOK_MEM_READ, 1, 0, null); + + // Let it crash by design. + try { + uc.emu_start(ADDRESS, ADDRESS + X86_CODE32_MEM_READ_IN_TB.length, 0, + 0); + throw new RuntimeException("Expected uc.emu_start to fail"); + } catch (UnicornException e) { + System.out.println( + "uc.emu_start() failed BY DESIGN with error returned: " + e); + } + + System.out.println(">>> Emulation done. Below is the CPU context"); + + long r_eip = uc.reg_read(UC_X86_REG_EIP); + System.out.format(">>> EIP = 0x%x\n", r_eip); + + if (r_eip != ADDRESS + 1) { + System.out.format( + ">>> ERROR: Wrong PC 0x%x when reading unmapped memory in the middle of TB!\n", + r_eip); + } else { + System.out.format( + ">>> The PC is correct after reading unmapped memory in the middle of TB.\n"); + } + } + + public static void test_i386_smc_xor() { + long r_edi = ADDRESS; // ECX register + long r_eax = 0xbc4177e6L; // EDX register + + System.out.println("Emulate i386 code that modfies itself"); + + // Initialize emulator in X86-32bit mode + Unicorn uc = new Unicorn(UC_ARCH_X86, UC_MODE_32); + + // map 1KB memory for this emulation + uc.mem_map(ADDRESS, 0x1000, UC_PROT_ALL); + + // write machine code to be emulated to memory + uc.mem_write(ADDRESS, X86_CODE32_SMC); + + // initialize machine registers + uc.reg_write(UC_X86_REG_EDI, r_edi); + uc.reg_write(UC_X86_REG_EAX, r_eax); + + // **Important Note** + // + // Since SMC code will cause TB regeneration, the XOR in fact would executed + // twice (the first execution won't take effect.). Thus, if you would like + // to use count to control the emulation, the count should be set to 2. + // + // uc.emu_start(ADDRESS, ADDRESS + 3, 0, 0); + uc.emu_start(ADDRESS, 0, 0, 2); + + System.out.println(">>> Emulation done. Below is the result."); + + int result = Utils.toInt(uc.mem_read(ADDRESS + 3, 4)); + + if (result == (0x3ea98b13 ^ 0xbc4177e6)) { + System.out.format( + ">>> SMC emulation is correct. 0x3ea98b13 ^ 0xbc4177e6 = 0x%x\n", + result); + } else { + System.out.format( + ">>> SMC emulation is wrong. 0x3ea98b13 ^ 0xbc4177e6 = 0x%x\n", + result); + } + } + + private static final MmioReadHandler mmio_read_callback = + (uc, offset, size, user_data) -> { + System.out.format( + ">>> Read IO memory at offset 0x%d with 0x%d bytes and return 0x19260817\n", + offset, size); + // The value returned here would be written to ecx. + return 0x19260817; + }; + + private static final MmioWriteHandler mmio_write_callback = + (uc, offset, size, value, user_data) -> { + System.out.format( + ">>> Write value 0x%d to IO memory at offset 0x%d with 0x%d bytes\n", + value, offset, size); + }; + + public static void test_i386_mmio() { + long r_ecx = 0xdeadbeefL; + + System.out.println("Emulate i386 code that uses MMIO"); + + // Initialize emulator in X86-32bit mode + Unicorn uc = new Unicorn(UC_ARCH_X86, UC_MODE_32); + + // map 1KB memory for this emulation + uc.mem_map(ADDRESS, 0x1000, UC_PROT_ALL); + + // write machine code to be emulated to memory + uc.mem_write(ADDRESS, X86_MMIO_CODE); + uc.mmio_map(0x20000, 0x4000, mmio_read_callback, null, + mmio_write_callback, null); + + // prepare ecx + uc.reg_write(UC_X86_REG_ECX, r_ecx); + + uc.emu_start(ADDRESS, ADDRESS + X86_MMIO_CODE.length, 0, 0); + System.out.format(">>> Emulation done. ECX=0x%x\n", + uc.reg_read(UC_X86_REG_ECX)); + } + + private static final EventMemHook test_i386_hook_mem_invalid_cb = + (uc, type, address, size, value, user_data) -> { + if (type == UC_MEM_READ_UNMAPPED || type == UC_MEM_WRITE_UNMAPPED) { + System.out.format( + ">>> We have to add a map at 0x%x before continue execution!\n", + address); + uc.mem_map(address, 0x1000, UC_PROT_ALL); + } + + // If you really would like to continue the execution, make sure the memory + // is already mapped properly! + return true; + }; + + public static void test_i386_hook_mem_invalid() { + // mov eax, 0xdeadbeef; + // mov [0x8000], eax; + // mov eax, [0x10000]; + byte[] code = Utils.hexToBytes("b8efbeaddea300800000a100000100"); + + System.out.println( + "Emulate i386 code that triggers invalid memory read/write."); + + Unicorn uc = new Unicorn(UC_ARCH_X86, UC_MODE_32); + uc.mem_map(ADDRESS, 0x1000, UC_PROT_ALL); + uc.mem_write(ADDRESS, code); + long hook = uc.hook_add(test_i386_hook_mem_invalid_cb, + UC_HOOK_MEM_INVALID, 1, 0, null); + uc.emu_start(ADDRESS, ADDRESS + code.length, 0, 0); + + uc.hook_del(hook); } 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(); - } - if (args[0].equals("-16")) { test_x86_16(); - } - - // test memleak - if (args[0].equals("-0")) { - while (true) { - test_i386(); - // test_x86_64(); - } + } else if (args[0].equals("-32")) { + test_miss_code(); + System.out.println("==================================="); + test_i386(); + System.out.println("==================================="); + test_i386_map_ptr(); + System.out.println("==================================="); + test_i386_inout(); + System.out.println("==================================="); + test_i386_context_save(); + System.out.println("==================================="); + test_i386_jump(); + System.out.println("==================================="); + test_i386_loop(); + System.out.println("==================================="); + test_i386_invalid_mem_read(); + System.out.println("==================================="); + test_i386_invalid_mem_write(); + System.out.println("==================================="); + test_i386_jump_invalid(); + // test_i386_invalid_c6c7(); + } else if (args[0].equals("-64")) { + test_x86_64(); + System.out.println("==================================="); + test_x86_64_syscall(); + } else if (args[0].equals("-h")) { + System.out.println( + "Syntax: java samples.Sample_x86 <-16|-32|-64>"); } } else { - System.out.print("Syntax: java Sample_x86 <-16|-32|-64>\n"); + test_x86_16(); + System.out.println("==================================="); + test_miss_code(); + System.out.println("==================================="); + test_i386(); + System.out.println("==================================="); + test_i386_map_ptr(); + System.out.println("==================================="); + test_i386_inout(); + System.out.println("==================================="); + test_i386_context_save(); + System.out.println("==================================="); + test_i386_jump(); + System.out.println("==================================="); + test_i386_loop(); + System.out.println("==================================="); + test_i386_invalid_mem_read(); + System.out.println("==================================="); + test_i386_invalid_mem_write(); + System.out.println("==================================="); + test_i386_jump_invalid(); + // test_i386_invalid_c6c7(); + System.out.println("==================================="); + test_x86_64(); + System.out.println("==================================="); + test_x86_64_syscall(); + System.out.println("==================================="); + test_i386_invalid_mem_read_in_tb(); + System.out.println("==================================="); + test_i386_smc_xor(); + System.out.println("==================================="); + test_i386_mmio(); + System.out.println("==================================="); + test_i386_hook_mem_invalid(); } - } - } diff --git a/bindings/java/samples/Sample_x86_mmr.java b/bindings/java/samples/Sample_x86_mmr.java index 65cd4b76..eaadf878 100644 --- a/bindings/java/samples/Sample_x86_mmr.java +++ b/bindings/java/samples/Sample_x86_mmr.java @@ -25,21 +25,14 @@ package samples; import unicorn.*; -public class Sample_x86_mmr { +public class Sample_x86_mmr implements UnicornConst, X86Const { public static void test_x86_mmr() { // 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; - } + Unicorn uc = new Unicorn(UC_ARCH_X86, UC_MODE_32); // map 4k - uc.mem_map(0x400000, 0x1000, Unicorn.UC_PROT_ALL); + uc.mem_map(0x400000, 0x1000, UC_PROT_ALL); X86_MMR ldtr1 = new X86_MMR(0x1111111122222222L, 0x33333333, 0x44444444, (short) 0x5555); @@ -52,14 +45,14 @@ public class Sample_x86_mmr { // initialize machine registers - uc.reg_write(Unicorn.UC_X86_REG_LDTR, ldtr1); - uc.reg_write(Unicorn.UC_X86_REG_GDTR, gdtr1); - uc.reg_write(Unicorn.UC_X86_REG_EAX, 0xddddddddL); + uc.reg_write(UC_X86_REG_LDTR, ldtr1); + uc.reg_write(UC_X86_REG_GDTR, gdtr1); + uc.reg_write(UC_X86_REG_EAX, 0xddddddddL); // read the registers back out - eax = (int) uc.reg_read(Unicorn.UC_X86_REG_EAX); - ldtr2 = (X86_MMR) uc.reg_read(Unicorn.UC_X86_REG_LDTR, null); - gdtr2 = (X86_MMR) uc.reg_read(Unicorn.UC_X86_REG_GDTR, null); + eax = (int) uc.reg_read(UC_X86_REG_EAX); + ldtr2 = (X86_MMR) uc.reg_read(UC_X86_REG_LDTR, null); + gdtr2 = (X86_MMR) uc.reg_read(UC_X86_REG_GDTR, null); System.out.printf(">>> EAX = 0x%x\n", eax); @@ -70,8 +63,6 @@ public class Sample_x86_mmr { System.out.printf(">>> GDTR.base = 0x%x\n", gdtr2.base); System.out.printf(">>> GDTR.limit = 0x%x\n", gdtr2.limit); - - uc.close(); } public static void main(String args[]) { diff --git a/bindings/java/samples/Shellcode.java b/bindings/java/samples/Shellcode.java index e31dc3a2..6ed1d45f 100644 --- a/bindings/java/samples/Shellcode.java +++ b/bindings/java/samples/Shellcode.java @@ -28,137 +28,107 @@ package samples; import unicorn.*; -public class Shellcode { +public class Shellcode implements UnicornConst, X86Const { - 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 }; + public static final byte[] X86_CODE32_SELF = Utils.hexToBytes( + "eb1c5a89d68b02663dca7d75066605030389" + + "02fec23d4141414175e9ffe6e8dfffffff31" + + "d26a0b589952682f2f7368682f62696e89e3" + + "525389e1ca7d4141414141414141"); // 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)); - - long r_eip = u.reg_read(Unicorn.UC_X86_REG_EIP); - System.out.print( - String.format("*** EIP = %x ***: ", 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 CodeHook hook_code = (u, address, size, user) -> { + System.out.format( + "Tracing instruction at 0x%x, instruction size = 0x%x\n", + address, size); + + long r_eip = u.reg_read(UC_X86_REG_EIP); + System.out.format("*** EIP = %x ***: ", r_eip); + + byte[] tmp = u.mem_read(address, size); + for (int i = 0; i < tmp.length; i++) { + System.out.format("%x ", 0xff & tmp[i]); } + System.out.println(); }; - 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 = u.reg_read(Unicorn.UC_X86_REG_EAX); - long r_eip = u.reg_read(Unicorn.UC_X86_REG_EIP); - - 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 = u.reg_read(Unicorn.UC_X86_REG_ECX); - - // EDX = buffer size - r_edx = u.reg_read(Unicorn.UC_X86_REG_EDX); - - // 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; - } + public static InterruptHook hook_intr = (u, intno, user) -> { + // only handle Linux syscall + if (intno != 0x80) { + return; } - } + + long r_eax = u.reg_read(UC_X86_REG_EAX); + long r_eip = u.reg_read(UC_X86_REG_EIP); + + switch ((int) r_eax) { + default: + System.out.format(">>> 0x%x: interrupt 0x%x, EAX = 0x%x\n", + r_eip, intno, r_eax); + break; + case 1: // sys_exit + System.out.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 + long r_ecx = u.reg_read(UC_X86_REG_ECX); + + // EDX = buffer size + long r_edx = u.reg_read(UC_X86_REG_EDX); + + // read the buffer in + int size = (int) Math.min(256, r_edx); + + try { + byte[] buffer = u.mem_read(r_ecx, size); + System.out.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)); + } catch (UnicornException e) { + System.out.format( + ">>> 0x%x: interrupt 0x%x, SYS_WRITE. buffer = 0x%x, size = %u (cannot get content)\n", + r_eip, intno, r_ecx, r_edx); + } + break; + } + } + }; public static void test_i386() { long r_esp = ADDRESS + 0x200000L; // ESP register - System.out.print("Emulate i386 code\n"); + System.out.println("Emulate i386 code"); // Initialize emulator in X86-32bit mode - Unicorn u = new Unicorn(Unicorn.UC_ARCH_X86, Unicorn.UC_MODE_32); + Unicorn u = new Unicorn(UC_ARCH_X86, UC_MODE_32); // map 2MB memory for this emulation - u.mem_map(ADDRESS, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL); + u.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL); // 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, r_esp); + u.reg_write(UC_X86_REG_ESP, r_esp); // tracing all instructions by having @begin > @end - u.hook_add(new MyCodeHook(), 1, 0, null); + u.hook_add(hook_code, 1, 0, null); // handle interrupt ourself - u.hook_add(new MyInterruptHook(), null); + u.hook_add(hook_intr, null); - System.out.print("\n>>> Start tracing this Linux code\n"); + System.out.println("\n>>> Start tracing this Linux code"); // 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(); + System.out.println("\n>>> Emulation done."); } public static void main(String args[]) { @@ -167,7 +137,7 @@ public class Shellcode { test_i386(); } } else { - System.out.print("Syntax: java Shellcode <-32|-64>\n"); + System.out.println("Syntax: java Shellcode <-32|-64>"); } } diff --git a/bindings/java/samples/Utils.java b/bindings/java/samples/Utils.java new file mode 100644 index 00000000..260fed70 --- /dev/null +++ b/bindings/java/samples/Utils.java @@ -0,0 +1,49 @@ +package samples; + +public class Utils { + public static byte[] hexToBytes(String s) { + int len = s.length(); + byte[] data = new byte[len / 2]; + for (int i = 0; i < len; i += 2) { + data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + + Character.digit(s.charAt(i + 1), 16)); + } + return data; + } + + public static final int toInt(byte val[]) { + int res = 0; + for (int i = 0; i < val.length; i++) { + int v = val[i] & 0xff; + res = res + (v << (i * 8)); + } + return res; + } + + public static final long toLong(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(int val) { + byte[] res = new byte[4]; + for (int i = 0; i < 4; i++) { + res[i] = (byte) (val & 0xff); + val >>>= 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; + } +} diff --git a/bindings/java/tests/FunctionalityTests.java b/bindings/java/tests/FunctionalityTests.java index 38e7908d..d40d0218 100644 --- a/bindings/java/tests/FunctionalityTests.java +++ b/bindings/java/tests/FunctionalityTests.java @@ -122,8 +122,6 @@ public class FunctionalityTests { u.emu_stop(); }).start(); u.emu_start(ADDRESS, ADDRESS + X86_CODE.length, 0, 0); - - u.close(); } @Test @@ -157,8 +155,6 @@ public class FunctionalityTests { uc.context_restore(ctx); assertEquals(0xfee1deadL, uc.reg_read(Unicorn.UC_ARM64_REG_X0)); assertEquals(0xfee1deadL, ctx.reg_read(Unicorn.UC_ARM64_REG_X0)); - - uc.close(); } @Test @@ -188,6 +184,5 @@ public class FunctionalityTests { assertEquals(0xfee1deadL, uc.reg_read(Unicorn.UC_ARM64_REG_X0)); uc.free(ctx); - uc.close(); } } diff --git a/bindings/java/tests/HookTests.java b/bindings/java/tests/HookTests.java index 7b0500fc..330e4e52 100644 --- a/bindings/java/tests/HookTests.java +++ b/bindings/java/tests/HookTests.java @@ -59,7 +59,6 @@ public class HookTests { // TODO(nneonneo): I don't totally understand this output! Why 8 bytes at address 5? assertTranslationBlock(new TranslationBlock(ADDRESS + 5, 3, 8), u.ctl_request_cache(ADDRESS + 5)); - u.close(); } @Test @@ -84,8 +83,6 @@ public class HookTests { u.ctl_tlb_mode(Unicorn.UC_TLB_VIRTUAL); u.emu_start(ADDRESS, ADDRESS + X86_CODE32_MEM_READ.length, 0, 0); assertEquals("ecx", u.reg_read(Unicorn.UC_X86_REG_ECX), 0x04030201); - - u.close(); } @Test @@ -124,7 +121,5 @@ public class HookTests { assertThrows(UnicornException.class, () -> u.hook_del(h1)); assertThrows(UnicornException.class, () -> u.hook_del(h3)); assertThrows(UnicornException.class, () -> u.hook_del(h4)); - - u.close(); } } diff --git a/bindings/java/tests/MemTests.java b/bindings/java/tests/MemTests.java index 976f5d7f..0c553d3a 100644 --- a/bindings/java/tests/MemTests.java +++ b/bindings/java/tests/MemTests.java @@ -29,7 +29,6 @@ public class MemTests { assertEquals("two memory regions", 2, arr.length); assertMemRegion(ADDR1, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL, arr[0]); assertMemRegion(ADDR2, 4096, Unicorn.UC_PROT_READ, arr[1]); - uc.close(); } @Test @@ -71,8 +70,6 @@ public class MemTests { assertMemRegion(0x230000, 0x10000, Unicorn.UC_PROT_READ, mrs[7]); assertMemRegion(0x250000, 0x10000, Unicorn.UC_PROT_WRITE, mrs[8]); assertMemRegion(0x270000, 0x10000, Unicorn.UC_PROT_NONE, mrs[9]); - - u.close(); } @Test @@ -111,8 +108,6 @@ public class MemTests { assertEquals("ecx", 0x44556679, u.reg_read(Unicorn.UC_X86_REG_ECX)); assertEquals("edx", 0x22334453, u.reg_read(Unicorn.UC_X86_REG_EDX)); - - u.close(); } @Test @@ -132,7 +127,5 @@ public class MemTests { u.emu_start(ADDRESS, ADDRESS + X86_CODE32_MEM_WRITE.length, 0, 0); assertEquals("buffer contents", 0x12345678, buffer.getInt(0xaaa)); - - u.close(); } } diff --git a/bindings/java/tests/RegTests.java b/bindings/java/tests/RegTests.java index f9f0183c..356dd69f 100644 --- a/bindings/java/tests/RegTests.java +++ b/bindings/java/tests/RegTests.java @@ -33,7 +33,6 @@ public class RegTests { assertEquals(Math.sin(Math.log(Math.E) / Math.log(2)), reg1.toDouble(), 1e-12); assertEquals(reg1.toDouble(), reg2.toDouble(), 1e-12); - u.close(); } @Test @@ -51,7 +50,6 @@ public class RegTests { u.emu_start(ADDRESS, ADDRESS + X86_CODE.length, 0, 0); reg = (X86_Float80) u.reg_read(Unicorn.UC_X86_REG_ST0, null); assertEquals(Math.sin(-1.1), reg.toDouble(), 1e-12); - u.close(); } @Test @@ -104,8 +102,6 @@ public class RegTests { b[0x70] = -0x80; uc.reg_write(reg, new BigInteger(b)); assertEquals("write untrimmed value", b127, uc.reg_read(reg, null)); - - uc.close(); } @Test @@ -144,8 +140,6 @@ public class RegTests { assertEquals("v0.8h = v1.8h + v2.8h", new BigInteger("4860570d497678b4a5728c3e34a5f85c", 16), uc.reg_read(Unicorn.UC_ARM64_REG_V0, null)); - - uc.close(); } @Test @@ -200,7 +194,5 @@ public class RegTests { uc.reg_read(Unicorn.UC_ARM64_REG_X1)); assertEquals("X1 low bits should be unchanged", 0x0000bbbbccccddddL, uc.reg_read(Unicorn.UC_ARM64_REG_X1) & 0xffffffffffffL); - - uc.close(); } } diff --git a/bindings/java/tests/RegressionTests.java b/bindings/java/tests/RegressionTests.java index af5cdb05..a94090ad 100644 --- a/bindings/java/tests/RegressionTests.java +++ b/bindings/java/tests/RegressionTests.java @@ -24,7 +24,6 @@ public class RegressionTests { uc.reg_read(Unicorn.UC_ARM64_REG_B0)); assertEquals("V0 low halfword", 0x1234, uc.reg_read(Unicorn.UC_ARM64_REG_H0)); - uc.close(); } /** Test for GH #1164: Java binding use CodeHook on Windows, will invoke callback before every instruction */ diff --git a/bindings/java/tests/TestSamples.java b/bindings/java/tests/TestSamples.java index d6e97b08..6c970035 100644 --- a/bindings/java/tests/TestSamples.java +++ b/bindings/java/tests/TestSamples.java @@ -1,14 +1,19 @@ package tests; import static org.junit.Assert.assertEquals; +import static org.junit.Assume.assumeTrue; import java.io.ByteArrayOutputStream; import java.io.PrintStream; import org.junit.Before; +import org.junit.Ignore; import org.junit.After; import org.junit.Test; -public class TestSamples { +import unicorn.Unicorn; +import unicorn.UnicornConst; + +public class TestSamples implements UnicornConst { private final ByteArrayOutputStream outContent = new ByteArrayOutputStream(); private final PrintStream originalOut = System.out; @@ -26,9 +31,37 @@ public class TestSamples { @Test public void testArm() { + assumeTrue(Unicorn.arch_supported(UC_ARCH_ARM)); samples.Sample_arm.test_arm(); - assertEquals("testArm", + assertEquals( "Emulate ARM code\n" + + ">>> Tracing basic block at 0x10000, block size = 0x4\n" + + ">>> Tracing instruction at 0x10000, instruction size = 0x4\n" + + ">>> Emulation done. Below is the CPU context\n" + + ">>> R0 = 0x1234\n" + + ">>> R1 = 0x0\n", + outContent.toString()); + } + + @Test + public void testArmThumb() { + assumeTrue(Unicorn.arch_supported(UC_ARCH_ARM)); + samples.Sample_arm.test_thumb(); + assertEquals( + "Emulate THUMB code\n" + + ">>> Tracing basic block at 0x10000, block size = 0x2\n" + + ">>> Tracing instruction at 0x10000, instruction size = 0x2\n" + + ">>> Emulation done. Below is the CPU context\n" + + ">>> SP = 0x1228\n", + outContent.toString()); + } + + @Test + public void testArmEb() { + assumeTrue(Unicorn.arch_supported(UC_ARCH_ARM)); + samples.Sample_arm.test_armeb(); + assertEquals( + "Emulate ARM Big-Endian code\n" + ">>> Tracing basic block at 0x10000, block size = 0x8\n" + ">>> Tracing instruction at 0x10000, instruction size = 0x4\n" + ">>> Emulation done. Below is the CPU context\n" + @@ -36,4 +69,1107 @@ public class TestSamples { ">>> R1 = 0x3456\n", outContent.toString()); } + + @Test + public void testArmThumbEb() { + assumeTrue(Unicorn.arch_supported(UC_ARCH_ARM)); + samples.Sample_arm.test_thumbeb(); + assertEquals( + "Emulate THUMB Big-Endian code\n" + + ">>> Tracing basic block at 0x10000, block size = 0x2\n" + + ">>> Tracing instruction at 0x10000, instruction size = 0x2\n" + + ">>> Emulation done. Below is the CPU context\n" + + ">>> SP = 0x1228\n", + outContent.toString()); + } + + @Test + public void testArmThumbMrs() { + assumeTrue(Unicorn.arch_supported(UC_ARCH_ARM)); + samples.Sample_arm.test_thumb_mrs(); + assertEquals( + "Emulate THUMB MRS instruction\n" + + ">>> Tracing basic block at 0x10000, block size = 0x4\n" + + ">>> Tracing instruction at 0x10000, instruction size = 0x4\n" + + ">>> Emulation done. Below is the CPU context\n" + + ">>> PC = 0x10004\n", + outContent.toString()); + } + + @Test + public void testArmThumbIte() { + assumeTrue(Unicorn.arch_supported(UC_ARCH_ARM)); + samples.Sample_arm.test_thumb_ite(); + assertEquals( + "Emulate a THUMB ITE block as a whole or per instruction.\n" + + "Running the entire binary.\n" + + ">>> R2: 104\n" + + ">>> R3: 1\n" + + "\n" + + "Running the binary one instruction at a time.\n" + + ">>> R2: 104\n" + + ">>> R3: 1\n" + + "\n", + outContent.toString()); + } + + @Test + public void testArmReadSctlr() { + assumeTrue(Unicorn.arch_supported(UC_ARCH_ARM)); + samples.Sample_arm.test_read_sctlr(); + assertEquals( + "Read the SCTLR register.\n" + + ">>> SCTLR = 0xc50078\n" + + ">>> SCTLR.IE = 0\n" + + ">>> SCTLR.B = 0\n", + outContent.toString()); + } + + @Test + public void testArm64MemFetch() { + assumeTrue(Unicorn.arch_supported(UC_ARCH_ARM64)); + samples.Sample_arm64.test_arm64_mem_fetch(); + assertEquals( + ">>> Emulate ARM64 fetching stack data from high address 10000000000000\n" + + ">>> x0(Exception Level)=1\n" + + ">>> X1 = 0xc8c8c8c8c8c8c8c8\n", + outContent.toString()); + } + + @Test + public void testArm64() { + assumeTrue(Unicorn.arch_supported(UC_ARCH_ARM64)); + samples.Sample_arm64.test_arm64(); + assertEquals( + "Emulate ARM64 code\n" + + ">>> Tracing basic block at 0x10000, block size = 0x8\n" + + ">>> Tracing instruction at 0x10000, instruction size = 0x4\n" + + ">>> Emulation done. Below is the CPU context\n" + + ">>> As little endian, X15 should be 0x78:\n" + + ">>> X15 = 0x78\n", + outContent.toString()); + } + + @Test + public void testArm64Eb() { + assumeTrue(Unicorn.arch_supported(UC_ARCH_ARM64)); + samples.Sample_arm64.test_arm64eb(); + assertEquals( + "Emulate ARM64 Big-Endian code\n" + + ">>> Tracing basic block at 0x10000, block size = 0x8\n" + + ">>> Tracing instruction at 0x10000, instruction size = 0x4\n" + + ">>> Emulation done. Below is the CPU context\n" + + ">>> As big endian, X15 should be 0x78:\n" + + ">>> X15 = 0x12\n", + outContent.toString()); + } + + @Test + public void testArm64Sctlr() { + assumeTrue(Unicorn.arch_supported(UC_ARCH_ARM64)); + samples.Sample_arm64.test_arm64_sctlr(); + assertEquals( + "Read the SCTLR register.\n" + + ">>> SCTLR_EL1 = 0xc50838\n" + + ">>> SCTLR_EL2 = 0x0\n", + outContent.toString()); + } + + @Test + public void testArm64HookMrs() { + assumeTrue(Unicorn.arch_supported(UC_ARCH_ARM64)); + samples.Sample_arm64.test_arm64_hook_mrs(); + assertEquals( + "Hook MRS instruction.\n" + + ">>> Hook MSR instruction. Write 0x114514 to X2.\n" + + ">>> X2 = 0x114514\n", + outContent.toString()); + } + + @Test + public void testArm64Pac() { + assumeTrue(Unicorn.arch_supported(UC_ARCH_ARM64)); + samples.Sample_arm64.test_arm64_pac(); + assertEquals( + "Try ARM64 PAC\n" + + "X1 = 0x1401aaaabbbbcccc\n" + + "SUCCESS: PAC tag found.\n", + outContent.toString()); + } + + @Test + public void testCtlRead() { + samples.Sample_ctl.test_uc_ctl_read(); + assertEquals( + "Reading some properties by uc_ctl.\n" + + ">>> mode = 4, arch = 4, timeout=0, pagesize=4096\n", + outContent.toString()); + } + + @Test + public void testCtlExits() { + samples.Sample_ctl.test_uc_ctl_exits(); + assertEquals( + "Using multiple exits by uc_ctl.\n" + + ">>> Getting a new edge from 0x10004 to 0x10005.\n" + + ">>> eax = 1 and ebx = 0 after the first emulation\n" + + ">>> Getting a new edge from 0x10004 to 0x10007.\n" + + ">>> eax = 1 and ebx = 1 after the second emulation\n", + outContent.toString()); + } + + @Test + public void testM68k() { + assumeTrue(Unicorn.arch_supported(UC_ARCH_M68K)); + samples.Sample_m68k.test_m68k(); + assertEquals( + "Emulate M68K code\n" + + ">>> Tracing basic block at 0x10000, block size = 0x2\n" + + ">>> Tracing instruction at 0x10000, instruction size = 0x2\n" + + ">>> Emulation done. Below is the CPU context\n" + + ">>> A0 = 0x0 >>> D0 = 0x0\n" + + ">>> A1 = 0x0 >>> D1 = 0x0\n" + + ">>> A2 = 0x0 >>> D2 = 0x0\n" + + ">>> A3 = 0x0 >>> D3 = 0xffffffed\n" + + ">>> A4 = 0x0 >>> D4 = 0x0\n" + + ">>> A5 = 0x0 >>> D5 = 0x0\n" + + ">>> A6 = 0x0 >>> D6 = 0x0\n" + + ">>> A7 = 0x0 >>> D7 = 0x0\n" + + ">>> PC = 0x10002\n" + + ">>> SR = 0x0\n", + outContent.toString()); + } + + @Test + public void testMipsEl() { + assumeTrue(Unicorn.arch_supported(UC_ARCH_MIPS)); + samples.Sample_mips.test_mips_el(); + assertEquals( + "Emulate MIPS code (little-endian)\n" + + ">>> Tracing basic block at 0x10000, block size = 0x4\n" + + ">>> Tracing instruction at 0x10000, instruction size = 0x4\n" + + ">>> Emulation done. Below is the CPU context\n" + + ">>> R1 = 0x77df\n", + outContent.toString()); + } + + @Test + public void testMipsEb() { + assumeTrue(Unicorn.arch_supported(UC_ARCH_MIPS)); + samples.Sample_mips.test_mips_eb(); + assertEquals( + "Emulate MIPS code (big-endian)\n" + + ">>> Tracing basic block at 0x10000, block size = 0x4\n" + + ">>> Tracing instruction at 0x10000, instruction size = 0x4\n" + + ">>> Emulation done. Below is the CPU context\n" + + ">>> R1 = 0x77df\n", + outContent.toString()); + } + + @Test + public void testMmuCpuTlb() { + samples.Sample_mmu.cpu_tlb(); + assertEquals( + "Emulate x86 amd64 code with mmu enabled and switch mappings\n" + + "map code\n" + + "map parent memory\n" + + "map child memory\n" + + "map tlb memory\n" + + "set up the tlb\n" + + "run the parent\n" + + "save the context for the child\n" + + "finish the parent\n" + + "write at 0x1000: 0x3c\n" + + "restore the context for the child\n" + + "write at 0x2000: 0x2a\n" + + "parent result == 60\n" + + "child result == 42\n", + outContent.toString()); + } + + @Test + public void testMmuVirtualTlb() { + samples.Sample_mmu.virtual_tlb(); + assertEquals( + "Emulate x86 amd64 code with virtual mmu\n" + + "map code\n" + + "map parent memory\n" + + "map child memory\n" + + "run the parent\n" + + "tlb lookup for address: 0x2000\n" + + "save the context for the child\n" + + "finish the parent\n" + + "tlb lookup for address: 0x4000\n" + + "write at 0x1000: 0x3c\n" + + "restore the context for the child\n" + + "tlb lookup for address: 0x2000\n" + + "tlb lookup for address: 0x4000\n" + + "write at 0x2000: 0x2a\n" + + "parent result == 60\n" + + "child result == 42\n", + outContent.toString()); + } + + @Test + public void testPpc() { + assumeTrue(Unicorn.arch_supported(UC_ARCH_PPC)); + samples.Sample_ppc.test_ppc(); + assertEquals( + "Emulate PPC code\n" + + ">>> Tracing basic block at 0x10000, block size = 0x4\n" + + ">>> Tracing instruction at 0x10000, instruction size = 0x4\n" + + ">>> Emulation done. Below is the CPU context\n" + + ">>> r26 = 0x79bd\n", + outContent.toString()); + } + + @Test + public void testRiscvRecoverFromIllegal() { + assumeTrue(Unicorn.arch_supported(UC_ARCH_RISCV)); + samples.Sample_riscv.test_recover_from_illegal(); + assertEquals( + "Emulate RISCV code: recover_from_illegal\n" + + ">>> Allocating block at 0x1000 (0x1000), block size = 0x2 (0x1000)\n" + + ">>> Tracing basic block at 0x1000, block size = 0x0\n" + + "Expected Illegal Instruction error, got: " + + "unicorn.UnicornException: Unhandled CPU exception (UC_ERR_EXCEPTION)\n" + + ">>> Tracing basic block at 0x10000, block size = 0x8\n" + + ">>> Tracing instruction at 0x10000, instruction size = 0x4\n" + + ">>> Emulation done. Below is the CPU context\n" + + ">>> A0 = 0x1\n" + + ">>> A1 = 0x7890\n", + outContent.toString()); + } + + @Test + public void testRiscv1() { + assumeTrue(Unicorn.arch_supported(UC_ARCH_RISCV)); + samples.Sample_riscv.test_riscv(); + assertEquals( + "Emulate RISCV code\n" + + ">>> Tracing basic block at 0x10000, block size = 0x8\n" + + ">>> Tracing instruction at 0x10000, instruction size = 0x4\n" + + ">>> Tracing instruction at 0x10004, instruction size = 0x4\n" + + ">>> Emulation done. Below is the CPU context\n" + + ">>> A0 = 0x1\n" + + ">>> A1 = 0x78b0\n", + outContent.toString()); + } + + @Test + public void testRiscv2() { + assumeTrue(Unicorn.arch_supported(UC_ARCH_RISCV)); + samples.Sample_riscv.test_riscv2(); + assertEquals( + "Emulate RISCV code: split emulation\n" + + ">>> Tracing basic block at 0x10000, block size = 0x4\n" + + ">>> Tracing instruction at 0x10000, instruction size = 0x4\n" + + ">>> A0 = 0x1\n" + + ">>> A1 = 0x7890\n" + + ">>> Tracing basic block at 0x10004, block size = 0x4\n" + + ">>> Tracing instruction at 0x10004, instruction size = 0x4\n" + + ">>> Emulation done. Below is the CPU context\n" + + ">>> A0 = 0x1\n" + + ">>> A1 = 0x78b0\n", + outContent.toString()); + } + + @Test + public void testRiscv3() { + assumeTrue(Unicorn.arch_supported(UC_ARCH_RISCV)); + samples.Sample_riscv.test_riscv3(); + assertEquals( + "Emulate RISCV code: early stop\n" + + ">>> Tracing basic block at 0x10000, block size = 0x8\n" + + ">>> Tracing instruction at 0x10000, instruction size = 0x4\n" + + "stop emulation\n" + + ">>> Emulation done. Below is the CPU context\n" + + ">>> A0 = 0x1234\n" + + ">>> A1 = 0x7890\n", + outContent.toString()); + } + + @Test + public void testRiscvStep() { + assumeTrue(Unicorn.arch_supported(UC_ARCH_RISCV)); + samples.Sample_riscv.test_riscv_step(); + assertEquals( + "Emulate RISCV code: step\n" + + ">>> Tracing basic block at 0x10000, block size = 0x8\n" + + ">>> Tracing instruction at 0x10000, instruction size = 0x4\n" + + ">>> A0 = 0x1\n" + + ">>> A1 = 0x7890\n" + + ">>> Tracing basic block at 0x10004, block size = 0x4\n" + + ">>> Tracing instruction at 0x10004, instruction size = 0x4\n" + + ">>> Emulation done. Below is the CPU context\n" + + ">>> A0 = 0x1\n" + + ">>> A1 = 0x78b0\n", + outContent.toString()); + } + + @Ignore("timeout test is currently broken") + @Test + public void testRiscvTimeout() { + assumeTrue(Unicorn.arch_supported(UC_ARCH_RISCV)); + samples.Sample_riscv.test_riscv_timeout(); + assertEquals( + "Emulate RISCV code: timeout\n" + + ">>> Tracing basic block at 0x10000, block size = 0x0\n" + + "Failed on uc_emu_start() with error returned: 21\n" + + "Error after step: PC is: 0x10004, expected was 0x10004\n" + + ">>> Tracing basic block at 0x10000, block size = 0x0\n" + + "Failed on uc_emu_start() with error returned: 21\n" + + "Error after step: PC is: 0x10004, expected was 0x10004\n" + + ">>> Emulation done\n", + outContent.toString()); + } + + @Test + public void testRiscvSd64() { + assumeTrue(Unicorn.arch_supported(UC_ARCH_RISCV)); + samples.Sample_riscv.test_riscv_sd64(); + assertEquals( + "Emulate RISCV code: sd64 instruction\n" + + ">>> Tracing basic block at 0x10000, block size = 0x8\n" + + ">>> Tracing instruction at 0x10000, instruction size = 0x4\n" + + ">>> Emulation done.\n", + outContent.toString()); + } + + @Test + public void testRiscvFuncReturn() { + assumeTrue(Unicorn.arch_supported(UC_ARCH_RISCV)); + samples.Sample_riscv.test_riscv_func_return(); + assertEquals( + "Emulate RISCV code: return from func\n" + + ">>> Tracing basic block at 0x10000, block size = 0x4\n" + + ">>> Tracing instruction at 0x10000, instruction size = 0x4\n" + + ">>> Tracing basic block at 0x10006, block size = 0x4\n" + + "Good, PC == RA\n" + + "========\n" + + ">>> Tracing basic block at 0x10004, block size = 0x2\n" + + ">>> Tracing instruction at 0x10004, instruction size = 0x2\n" + + ">>> Tracing basic block at 0x10006, block size = 0x4\n" + + "Good, PC == RA\n" + + ">>> Emulation done.\n", + outContent.toString()); + } + + @Test + public void testS390x() { + assumeTrue(Unicorn.arch_supported(UC_ARCH_S390X)); + samples.Sample_s390x.test_s390x(); + assertEquals( + "Emulate S390X code\n" + + ">>> Tracing basic block at 0x10000, block size = 0x2\n" + + ">>> Tracing instruction at 0x10000, instruction size = 0x2\n" + + ">>> Emulation done. Below is the CPU context\n" + + ">>> R2 = 0x3 >>> R3 = 0x3\n", + outContent.toString()); + } + + @Test + public void testShellcode() { + samples.Shellcode.test_i386(); + assertEquals( + "Emulate i386 code\n" + + "\n" + + ">>> Start tracing this Linux code\n" + + "Tracing instruction at 0x1000000, instruction size = 0x2\n" + + "*** EIP = 1000000 ***: eb 1c \n" + + "Tracing instruction at 0x100001e, instruction size = 0x5\n" + + "*** EIP = 100001e ***: e8 df ff ff ff \n" + + "Tracing instruction at 0x1000002, instruction size = 0x1\n" + + "*** EIP = 1000002 ***: 5a \n" + + "Tracing instruction at 0x1000003, instruction size = 0x2\n" + + "*** EIP = 1000003 ***: 89 d6 \n" + + "Tracing instruction at 0x1000005, instruction size = 0x2\n" + + "*** EIP = 1000005 ***: 8b 2 \n" + + "Tracing instruction at 0x1000007, instruction size = 0x4\n" + + "*** EIP = 1000007 ***: 66 3d ca 7d \n" + + "Tracing instruction at 0x100000b, instruction size = 0x2\n" + + "*** EIP = 100000b ***: 75 6 \n" + + "Tracing instruction at 0x1000013, instruction size = 0x2\n" + + "*** EIP = 1000013 ***: fe c2 \n" + + "Tracing instruction at 0x1000015, instruction size = 0x5\n" + + "*** EIP = 1000015 ***: 3d 41 41 41 41 \n" + + "Tracing instruction at 0x100001a, instruction size = 0x2\n" + + "*** EIP = 100001a ***: 75 e9 \n" + + "Tracing instruction at 0x1000005, instruction size = 0x2\n" + + "*** EIP = 1000005 ***: 8b 2 \n" + + "Tracing instruction at 0x1000007, instruction size = 0x4\n" + + "*** EIP = 1000007 ***: 66 3d ca 7d \n" + + "Tracing instruction at 0x100000b, instruction size = 0x2\n" + + "*** EIP = 100000b ***: 75 6 \n" + + "Tracing instruction at 0x1000013, instruction size = 0x2\n" + + "*** EIP = 1000013 ***: fe c2 \n" + + "Tracing instruction at 0x1000015, instruction size = 0x5\n" + + "*** EIP = 1000015 ***: 3d 41 41 41 41 \n" + + "Tracing instruction at 0x100001a, instruction size = 0x2\n" + + "*** EIP = 100001a ***: 75 e9 \n" + + "Tracing instruction at 0x1000005, instruction size = 0x2\n" + + "*** EIP = 1000005 ***: 8b 2 \n" + + "Tracing instruction at 0x1000007, instruction size = 0x4\n" + + "*** EIP = 1000007 ***: 66 3d ca 7d \n" + + "Tracing instruction at 0x100000b, instruction size = 0x2\n" + + "*** EIP = 100000b ***: 75 6 \n" + + "Tracing instruction at 0x1000013, instruction size = 0x2\n" + + "*** EIP = 1000013 ***: fe c2 \n" + + "Tracing instruction at 0x1000015, instruction size = 0x5\n" + + "*** EIP = 1000015 ***: 3d 41 41 41 41 \n" + + "Tracing instruction at 0x100001a, instruction size = 0x2\n" + + "*** EIP = 100001a ***: 75 e9 \n" + + "Tracing instruction at 0x1000005, instruction size = 0x2\n" + + "*** EIP = 1000005 ***: 8b 2 \n" + + "Tracing instruction at 0x1000007, instruction size = 0x4\n" + + "*** EIP = 1000007 ***: 66 3d ca 7d \n" + + "Tracing instruction at 0x100000b, instruction size = 0x2\n" + + "*** EIP = 100000b ***: 75 6 \n" + + "Tracing instruction at 0x1000013, instruction size = 0x2\n" + + "*** EIP = 1000013 ***: fe c2 \n" + + "Tracing instruction at 0x1000015, instruction size = 0x5\n" + + "*** EIP = 1000015 ***: 3d 41 41 41 41 \n" + + "Tracing instruction at 0x100001a, instruction size = 0x2\n" + + "*** EIP = 100001a ***: 75 e9 \n" + + "Tracing instruction at 0x1000005, instruction size = 0x2\n" + + "*** EIP = 1000005 ***: 8b 2 \n" + + "Tracing instruction at 0x1000007, instruction size = 0x4\n" + + "*** EIP = 1000007 ***: 66 3d ca 7d \n" + + "Tracing instruction at 0x100000b, instruction size = 0x2\n" + + "*** EIP = 100000b ***: 75 6 \n" + + "Tracing instruction at 0x1000013, instruction size = 0x2\n" + + "*** EIP = 1000013 ***: fe c2 \n" + + "Tracing instruction at 0x1000015, instruction size = 0x5\n" + + "*** EIP = 1000015 ***: 3d 41 41 41 41 \n" + + "Tracing instruction at 0x100001a, instruction size = 0x2\n" + + "*** EIP = 100001a ***: 75 e9 \n" + + "Tracing instruction at 0x1000005, instruction size = 0x2\n" + + "*** EIP = 1000005 ***: 8b 2 \n" + + "Tracing instruction at 0x1000007, instruction size = 0x4\n" + + "*** EIP = 1000007 ***: 66 3d ca 7d \n" + + "Tracing instruction at 0x100000b, instruction size = 0x2\n" + + "*** EIP = 100000b ***: 75 6 \n" + + "Tracing instruction at 0x1000013, instruction size = 0x2\n" + + "*** EIP = 1000013 ***: fe c2 \n" + + "Tracing instruction at 0x1000015, instruction size = 0x5\n" + + "*** EIP = 1000015 ***: 3d 41 41 41 41 \n" + + "Tracing instruction at 0x100001a, instruction size = 0x2\n" + + "*** EIP = 100001a ***: 75 e9 \n" + + "Tracing instruction at 0x1000005, instruction size = 0x2\n" + + "*** EIP = 1000005 ***: 8b 2 \n" + + "Tracing instruction at 0x1000007, instruction size = 0x4\n" + + "*** EIP = 1000007 ***: 66 3d ca 7d \n" + + "Tracing instruction at 0x100000b, instruction size = 0x2\n" + + "*** EIP = 100000b ***: 75 6 \n" + + "Tracing instruction at 0x1000013, instruction size = 0x2\n" + + "*** EIP = 1000013 ***: fe c2 \n" + + "Tracing instruction at 0x1000015, instruction size = 0x5\n" + + "*** EIP = 1000015 ***: 3d 41 41 41 41 \n" + + "Tracing instruction at 0x100001a, instruction size = 0x2\n" + + "*** EIP = 100001a ***: 75 e9 \n" + + "Tracing instruction at 0x1000005, instruction size = 0x2\n" + + "*** EIP = 1000005 ***: 8b 2 \n" + + "Tracing instruction at 0x1000007, instruction size = 0x4\n" + + "*** EIP = 1000007 ***: 66 3d ca 7d \n" + + "Tracing instruction at 0x100000b, instruction size = 0x2\n" + + "*** EIP = 100000b ***: 75 6 \n" + + "Tracing instruction at 0x1000013, instruction size = 0x2\n" + + "*** EIP = 1000013 ***: fe c2 \n" + + "Tracing instruction at 0x1000015, instruction size = 0x5\n" + + "*** EIP = 1000015 ***: 3d 41 41 41 41 \n" + + "Tracing instruction at 0x100001a, instruction size = 0x2\n" + + "*** EIP = 100001a ***: 75 e9 \n" + + "Tracing instruction at 0x1000005, instruction size = 0x2\n" + + "*** EIP = 1000005 ***: 8b 2 \n" + + "Tracing instruction at 0x1000007, instruction size = 0x4\n" + + "*** EIP = 1000007 ***: 66 3d ca 7d \n" + + "Tracing instruction at 0x100000b, instruction size = 0x2\n" + + "*** EIP = 100000b ***: 75 6 \n" + + "Tracing instruction at 0x1000013, instruction size = 0x2\n" + + "*** EIP = 1000013 ***: fe c2 \n" + + "Tracing instruction at 0x1000015, instruction size = 0x5\n" + + "*** EIP = 1000015 ***: 3d 41 41 41 41 \n" + + "Tracing instruction at 0x100001a, instruction size = 0x2\n" + + "*** EIP = 100001a ***: 75 e9 \n" + + "Tracing instruction at 0x1000005, instruction size = 0x2\n" + + "*** EIP = 1000005 ***: 8b 2 \n" + + "Tracing instruction at 0x1000007, instruction size = 0x4\n" + + "*** EIP = 1000007 ***: 66 3d ca 7d \n" + + "Tracing instruction at 0x100000b, instruction size = 0x2\n" + + "*** EIP = 100000b ***: 75 6 \n" + + "Tracing instruction at 0x1000013, instruction size = 0x2\n" + + "*** EIP = 1000013 ***: fe c2 \n" + + "Tracing instruction at 0x1000015, instruction size = 0x5\n" + + "*** EIP = 1000015 ***: 3d 41 41 41 41 \n" + + "Tracing instruction at 0x100001a, instruction size = 0x2\n" + + "*** EIP = 100001a ***: 75 e9 \n" + + "Tracing instruction at 0x1000005, instruction size = 0x2\n" + + "*** EIP = 1000005 ***: 8b 2 \n" + + "Tracing instruction at 0x1000007, instruction size = 0x4\n" + + "*** EIP = 1000007 ***: 66 3d ca 7d \n" + + "Tracing instruction at 0x100000b, instruction size = 0x2\n" + + "*** EIP = 100000b ***: 75 6 \n" + + "Tracing instruction at 0x1000013, instruction size = 0x2\n" + + "*** EIP = 1000013 ***: fe c2 \n" + + "Tracing instruction at 0x1000015, instruction size = 0x5\n" + + "*** EIP = 1000015 ***: 3d 41 41 41 41 \n" + + "Tracing instruction at 0x100001a, instruction size = 0x2\n" + + "*** EIP = 100001a ***: 75 e9 \n" + + "Tracing instruction at 0x1000005, instruction size = 0x2\n" + + "*** EIP = 1000005 ***: 8b 2 \n" + + "Tracing instruction at 0x1000007, instruction size = 0x4\n" + + "*** EIP = 1000007 ***: 66 3d ca 7d \n" + + "Tracing instruction at 0x100000b, instruction size = 0x2\n" + + "*** EIP = 100000b ***: 75 6 \n" + + "Tracing instruction at 0x1000013, instruction size = 0x2\n" + + "*** EIP = 1000013 ***: fe c2 \n" + + "Tracing instruction at 0x1000015, instruction size = 0x5\n" + + "*** EIP = 1000015 ***: 3d 41 41 41 41 \n" + + "Tracing instruction at 0x100001a, instruction size = 0x2\n" + + "*** EIP = 100001a ***: 75 e9 \n" + + "Tracing instruction at 0x1000005, instruction size = 0x2\n" + + "*** EIP = 1000005 ***: 8b 2 \n" + + "Tracing instruction at 0x1000007, instruction size = 0x4\n" + + "*** EIP = 1000007 ***: 66 3d ca 7d \n" + + "Tracing instruction at 0x100000b, instruction size = 0x2\n" + + "*** EIP = 100000b ***: 75 6 \n" + + "Tracing instruction at 0x1000013, instruction size = 0x2\n" + + "*** EIP = 1000013 ***: fe c2 \n" + + "Tracing instruction at 0x1000015, instruction size = 0x5\n" + + "*** EIP = 1000015 ***: 3d 41 41 41 41 \n" + + "Tracing instruction at 0x100001a, instruction size = 0x2\n" + + "*** EIP = 100001a ***: 75 e9 \n" + + "Tracing instruction at 0x1000005, instruction size = 0x2\n" + + "*** EIP = 1000005 ***: 8b 2 \n" + + "Tracing instruction at 0x1000007, instruction size = 0x4\n" + + "*** EIP = 1000007 ***: 66 3d ca 7d \n" + + "Tracing instruction at 0x100000b, instruction size = 0x2\n" + + "*** EIP = 100000b ***: 75 6 \n" + + "Tracing instruction at 0x1000013, instruction size = 0x2\n" + + "*** EIP = 1000013 ***: fe c2 \n" + + "Tracing instruction at 0x1000015, instruction size = 0x5\n" + + "*** EIP = 1000015 ***: 3d 41 41 41 41 \n" + + "Tracing instruction at 0x100001a, instruction size = 0x2\n" + + "*** EIP = 100001a ***: 75 e9 \n" + + "Tracing instruction at 0x1000005, instruction size = 0x2\n" + + "*** EIP = 1000005 ***: 8b 2 \n" + + "Tracing instruction at 0x1000007, instruction size = 0x4\n" + + "*** EIP = 1000007 ***: 66 3d ca 7d \n" + + "Tracing instruction at 0x100000b, instruction size = 0x2\n" + + "*** EIP = 100000b ***: 75 6 \n" + + "Tracing instruction at 0x1000013, instruction size = 0x2\n" + + "*** EIP = 1000013 ***: fe c2 \n" + + "Tracing instruction at 0x1000015, instruction size = 0x5\n" + + "*** EIP = 1000015 ***: 3d 41 41 41 41 \n" + + "Tracing instruction at 0x100001a, instruction size = 0x2\n" + + "*** EIP = 100001a ***: 75 e9 \n" + + "Tracing instruction at 0x1000005, instruction size = 0x2\n" + + "*** EIP = 1000005 ***: 8b 2 \n" + + "Tracing instruction at 0x1000007, instruction size = 0x4\n" + + "*** EIP = 1000007 ***: 66 3d ca 7d \n" + + "Tracing instruction at 0x100000b, instruction size = 0x2\n" + + "*** EIP = 100000b ***: 75 6 \n" + + "Tracing instruction at 0x1000013, instruction size = 0x2\n" + + "*** EIP = 1000013 ***: fe c2 \n" + + "Tracing instruction at 0x1000015, instruction size = 0x5\n" + + "*** EIP = 1000015 ***: 3d 41 41 41 41 \n" + + "Tracing instruction at 0x100001a, instruction size = 0x2\n" + + "*** EIP = 100001a ***: 75 e9 \n" + + "Tracing instruction at 0x1000005, instruction size = 0x2\n" + + "*** EIP = 1000005 ***: 8b 2 \n" + + "Tracing instruction at 0x1000007, instruction size = 0x4\n" + + "*** EIP = 1000007 ***: 66 3d ca 7d \n" + + "Tracing instruction at 0x100000b, instruction size = 0x2\n" + + "*** EIP = 100000b ***: 75 6 \n" + + "Tracing instruction at 0x1000013, instruction size = 0x2\n" + + "*** EIP = 1000013 ***: fe c2 \n" + + "Tracing instruction at 0x1000015, instruction size = 0x5\n" + + "*** EIP = 1000015 ***: 3d 41 41 41 41 \n" + + "Tracing instruction at 0x100001a, instruction size = 0x2\n" + + "*** EIP = 100001a ***: 75 e9 \n" + + "Tracing instruction at 0x1000005, instruction size = 0x2\n" + + "*** EIP = 1000005 ***: 8b 2 \n" + + "Tracing instruction at 0x1000007, instruction size = 0x4\n" + + "*** EIP = 1000007 ***: 66 3d ca 7d \n" + + "Tracing instruction at 0x100000b, instruction size = 0x2\n" + + "*** EIP = 100000b ***: 75 6 \n" + + "Tracing instruction at 0x1000013, instruction size = 0x2\n" + + "*** EIP = 1000013 ***: fe c2 \n" + + "Tracing instruction at 0x1000015, instruction size = 0x5\n" + + "*** EIP = 1000015 ***: 3d 41 41 41 41 \n" + + "Tracing instruction at 0x100001a, instruction size = 0x2\n" + + "*** EIP = 100001a ***: 75 e9 \n" + + "Tracing instruction at 0x1000005, instruction size = 0x2\n" + + "*** EIP = 1000005 ***: 8b 2 \n" + + "Tracing instruction at 0x1000007, instruction size = 0x4\n" + + "*** EIP = 1000007 ***: 66 3d ca 7d \n" + + "Tracing instruction at 0x100000b, instruction size = 0x2\n" + + "*** EIP = 100000b ***: 75 6 \n" + + "Tracing instruction at 0x1000013, instruction size = 0x2\n" + + "*** EIP = 1000013 ***: fe c2 \n" + + "Tracing instruction at 0x1000015, instruction size = 0x5\n" + + "*** EIP = 1000015 ***: 3d 41 41 41 41 \n" + + "Tracing instruction at 0x100001a, instruction size = 0x2\n" + + "*** EIP = 100001a ***: 75 e9 \n" + + "Tracing instruction at 0x1000005, instruction size = 0x2\n" + + "*** EIP = 1000005 ***: 8b 2 \n" + + "Tracing instruction at 0x1000007, instruction size = 0x4\n" + + "*** EIP = 1000007 ***: 66 3d ca 7d \n" + + "Tracing instruction at 0x100000b, instruction size = 0x2\n" + + "*** EIP = 100000b ***: 75 6 \n" + + "Tracing instruction at 0x1000013, instruction size = 0x2\n" + + "*** EIP = 1000013 ***: fe c2 \n" + + "Tracing instruction at 0x1000015, instruction size = 0x5\n" + + "*** EIP = 1000015 ***: 3d 41 41 41 41 \n" + + "Tracing instruction at 0x100001a, instruction size = 0x2\n" + + "*** EIP = 100001a ***: 75 e9 \n" + + "Tracing instruction at 0x1000005, instruction size = 0x2\n" + + "*** EIP = 1000005 ***: 8b 2 \n" + + "Tracing instruction at 0x1000007, instruction size = 0x4\n" + + "*** EIP = 1000007 ***: 66 3d ca 7d \n" + + "Tracing instruction at 0x100000b, instruction size = 0x2\n" + + "*** EIP = 100000b ***: 75 6 \n" + + "Tracing instruction at 0x1000013, instruction size = 0x2\n" + + "*** EIP = 1000013 ***: fe c2 \n" + + "Tracing instruction at 0x1000015, instruction size = 0x5\n" + + "*** EIP = 1000015 ***: 3d 41 41 41 41 \n" + + "Tracing instruction at 0x100001a, instruction size = 0x2\n" + + "*** EIP = 100001a ***: 75 e9 \n" + + "Tracing instruction at 0x1000005, instruction size = 0x2\n" + + "*** EIP = 1000005 ***: 8b 2 \n" + + "Tracing instruction at 0x1000007, instruction size = 0x4\n" + + "*** EIP = 1000007 ***: 66 3d ca 7d \n" + + "Tracing instruction at 0x100000b, instruction size = 0x2\n" + + "*** EIP = 100000b ***: 75 6 \n" + + "Tracing instruction at 0x1000013, instruction size = 0x2\n" + + "*** EIP = 1000013 ***: fe c2 \n" + + "Tracing instruction at 0x1000015, instruction size = 0x5\n" + + "*** EIP = 1000015 ***: 3d 41 41 41 41 \n" + + "Tracing instruction at 0x100001a, instruction size = 0x2\n" + + "*** EIP = 100001a ***: 75 e9 \n" + + "Tracing instruction at 0x1000005, instruction size = 0x2\n" + + "*** EIP = 1000005 ***: 8b 2 \n" + + "Tracing instruction at 0x1000007, instruction size = 0x4\n" + + "*** EIP = 1000007 ***: 66 3d ca 7d \n" + + "Tracing instruction at 0x100000b, instruction size = 0x2\n" + + "*** EIP = 100000b ***: 75 6 \n" + + "Tracing instruction at 0x1000013, instruction size = 0x2\n" + + "*** EIP = 1000013 ***: fe c2 \n" + + "Tracing instruction at 0x1000015, instruction size = 0x5\n" + + "*** EIP = 1000015 ***: 3d 41 41 41 41 \n" + + "Tracing instruction at 0x100001a, instruction size = 0x2\n" + + "*** EIP = 100001a ***: 75 e9 \n" + + "Tracing instruction at 0x1000005, instruction size = 0x2\n" + + "*** EIP = 1000005 ***: 8b 2 \n" + + "Tracing instruction at 0x1000007, instruction size = 0x4\n" + + "*** EIP = 1000007 ***: 66 3d ca 7d \n" + + "Tracing instruction at 0x100000b, instruction size = 0x2\n" + + "*** EIP = 100000b ***: 75 6 \n" + + "Tracing instruction at 0x100000d, instruction size = 0x4\n" + + "*** EIP = 100000d ***: 66 5 3 3 \n" + + "Tracing instruction at 0x1000011, instruction size = 0x2\n" + + "*** EIP = 1000011 ***: 89 2 \n" + + "Tracing instruction at 0x1000013, instruction size = 0x2\n" + + "*** EIP = 1000013 ***: fe c2 \n" + + "Tracing instruction at 0x1000015, instruction size = 0x5\n" + + "*** EIP = 1000015 ***: 3d 41 41 41 41 \n" + + "Tracing instruction at 0x100001a, instruction size = 0x2\n" + + "*** EIP = 100001a ***: 75 e9 \n" + + "Tracing instruction at 0x1000005, instruction size = 0x2\n" + + "*** EIP = 1000005 ***: 8b 2 \n" + + "Tracing instruction at 0x1000007, instruction size = 0x4\n" + + "*** EIP = 1000007 ***: 66 3d ca 7d \n" + + "Tracing instruction at 0x100000b, instruction size = 0x2\n" + + "*** EIP = 100000b ***: 75 6 \n" + + "Tracing instruction at 0x1000013, instruction size = 0x2\n" + + "*** EIP = 1000013 ***: fe c2 \n" + + "Tracing instruction at 0x1000015, instruction size = 0x5\n" + + "*** EIP = 1000015 ***: 3d 41 41 41 41 \n" + + "Tracing instruction at 0x100001a, instruction size = 0x2\n" + + "*** EIP = 100001a ***: 75 e9 \n" + + "Tracing instruction at 0x1000005, instruction size = 0x2\n" + + "*** EIP = 1000005 ***: 8b 2 \n" + + "Tracing instruction at 0x1000007, instruction size = 0x4\n" + + "*** EIP = 1000007 ***: 66 3d ca 7d \n" + + "Tracing instruction at 0x100000b, instruction size = 0x2\n" + + "*** EIP = 100000b ***: 75 6 \n" + + "Tracing instruction at 0x1000013, instruction size = 0x2\n" + + "*** EIP = 1000013 ***: fe c2 \n" + + "Tracing instruction at 0x1000015, instruction size = 0x5\n" + + "*** EIP = 1000015 ***: 3d 41 41 41 41 \n" + + "Tracing instruction at 0x100001a, instruction size = 0x2\n" + + "*** EIP = 100001a ***: 75 e9 \n" + + "Tracing instruction at 0x100001c, instruction size = 0x2\n" + + "*** EIP = 100001c ***: ff e6 \n" + + "Tracing instruction at 0x1000023, instruction size = 0x2\n" + + "*** EIP = 1000023 ***: 31 d2 \n" + + "Tracing instruction at 0x1000025, instruction size = 0x2\n" + + "*** EIP = 1000025 ***: 6a b \n" + + "Tracing instruction at 0x1000027, instruction size = 0x1\n" + + "*** EIP = 1000027 ***: 58 \n" + + "Tracing instruction at 0x1000028, instruction size = 0x1\n" + + "*** EIP = 1000028 ***: 99 \n" + + "Tracing instruction at 0x1000029, instruction size = 0x1\n" + + "*** EIP = 1000029 ***: 52 \n" + + "Tracing instruction at 0x100002a, instruction size = 0x5\n" + + "*** EIP = 100002a ***: 68 2f 2f 73 68 \n" + + "Tracing instruction at 0x100002f, instruction size = 0x5\n" + + "*** EIP = 100002f ***: 68 2f 62 69 6e \n" + + "Tracing instruction at 0x1000034, instruction size = 0x2\n" + + "*** EIP = 1000034 ***: 89 e3 \n" + + "Tracing instruction at 0x1000036, instruction size = 0x1\n" + + "*** EIP = 1000036 ***: 52 \n" + + "Tracing instruction at 0x1000037, instruction size = 0x1\n" + + "*** EIP = 1000037 ***: 53 \n" + + "Tracing instruction at 0x1000038, instruction size = 0x2\n" + + "*** EIP = 1000038 ***: 89 e1 \n" + + "Tracing instruction at 0x100003a, instruction size = 0x2\n" + + "*** EIP = 100003a ***: cd 80 \n" + + ">>> 0x100003c: interrupt 0x80, EAX = 0xb\n" + + "Tracing instruction at 0x100003c, instruction size = 0x1\n" + + "*** EIP = 100003c ***: 41 \n" + + "Tracing instruction at 0x100003d, instruction size = 0x1\n" + + "*** EIP = 100003d ***: 41 \n" + + "Tracing instruction at 0x100003e, instruction size = 0x1\n" + + "*** EIP = 100003e ***: 41 \n" + + "Tracing instruction at 0x100003f, instruction size = 0x1\n" + + "*** EIP = 100003f ***: 41 \n" + + "Tracing instruction at 0x1000040, instruction size = 0x1\n" + + "*** EIP = 1000040 ***: 41 \n" + + "Tracing instruction at 0x1000041, instruction size = 0x1\n" + + "*** EIP = 1000041 ***: 41 \n" + + "Tracing instruction at 0x1000042, instruction size = 0x1\n" + + "*** EIP = 1000042 ***: 41 \n" + + "Tracing instruction at 0x1000043, instruction size = 0x1\n" + + "*** EIP = 1000043 ***: 41 \n" + + "\n" + + ">>> Emulation done.\n", + outContent.toString()); + } + + @Test + public void testSparc() { + assumeTrue(Unicorn.arch_supported(UC_ARCH_SPARC)); + samples.Sample_sparc.test_sparc(); + assertEquals( + "Emulate SPARC code\n" + + ">>> Tracing basic block at 0x10000, block size = 0x4\n" + + ">>> Tracing instruction at 0x10000, instruction size = 0x4\n" + + ">>> Emulation done. Below is the CPU context\n" + + ">>> G3 = 0x79b9\n", + outContent.toString()); + } + + @Test + public void testTricore() { + assumeTrue(Unicorn.arch_supported(UC_ARCH_TRICORE)); + samples.Sample_tricore.test_tricore(); + assertEquals( + "Emulate TriCore code\n" + + ">>> Tracing basic block at 0x10000, block size = 0x6\n" + + ">>> Tracing instruction at 0x10000, instruction size = 0x2\n" + + ">>> Tracing instruction at 0x10002, instruction size = 0x4\n" + + ">>> Emulation done. Below is the CPU context\n" + + ">>> d0 = 0x8000\n" + + ">>> d1 = 0x1\n", + outContent.toString()); + } + + @Test + public void testX86_16() { + assumeTrue(Unicorn.arch_supported(UC_ARCH_X86)); + samples.Sample_x86.test_x86_16(); + assertEquals( + "Emulate x86 16-bit code\n" + + ">>> Emulation done. Below is the CPU context\n" + + ">>> Read 1 bytes from [0xb] = 0x7\n", + outContent.toString()); + } + + @Test + public void testX86MissCode() { + assumeTrue(Unicorn.arch_supported(UC_ARCH_X86)); + samples.Sample_x86.test_miss_code(); + assertEquals( + "Emulate i386 code - missing code\n" + + ">>> Allocating block at 0x1000000 (0x1000000), block size = 0x1 (0x1000)\n" + + ">>> Tracing instruction at 0x1000000, instruction size = 0x1\n" + + ">>> --- EFLAGS is 0x2\n" + + ">>> Tracing instruction at 0x1000001, instruction size = 0x1\n" + + ">>> --- EFLAGS is 0x6\n" + + ">>> Tracing instruction at 0x1000002, instruction size = 0x4\n" + + ">>> --- EFLAGS is 0x12\n" + + ">>> Emulation done. Below is the CPU context\n" + + ">>> ECX = 0x1235\n" + + ">>> EDX = 0x788f\n", + outContent.toString()); + } + + @Test + public void testX86() { + assumeTrue(Unicorn.arch_supported(UC_ARCH_X86)); + samples.Sample_x86.test_i386(); + assertEquals( + "Emulate i386 code\n" + + ">>> Tracing basic block at 0x1000000, block size = 0x6\n" + + ">>> Tracing instruction at 0x1000000, instruction size = 0x1\n" + + ">>> --- EFLAGS is 0x2\n" + + ">>> Tracing instruction at 0x1000001, instruction size = 0x1\n" + + ">>> --- EFLAGS is 0x6\n" + + ">>> Tracing instruction at 0x1000002, instruction size = 0x4\n" + + ">>> --- EFLAGS is 0x12\n" + + ">>> Emulation done. Below is the CPU context\n" + + ">>> ECX = 0x1235\n" + + ">>> EDX = 0x788f\n" + + ">>> XMM0 = 0x00112233445566778899aabbccddeeff\n" + + ">>> Read 4 bytes from [0x1000000] = 0xf664a41\n", + outContent.toString()); + } + + @Test + public void testX86MapPtr() { + assumeTrue(Unicorn.arch_supported(UC_ARCH_X86)); + samples.Sample_x86.test_i386_map_ptr(); + assertEquals( + "Emulate i386 code - use uc_mem_map_ptr()\n" + + ">>> Tracing basic block at 0x1000000, block size = 0x6\n" + + ">>> Tracing instruction at 0x1000000, instruction size = 0x1\n" + + ">>> --- EFLAGS is 0x2\n" + + ">>> Tracing instruction at 0x1000001, instruction size = 0x1\n" + + ">>> --- EFLAGS is 0x6\n" + + ">>> Tracing instruction at 0x1000002, instruction size = 0x4\n" + + ">>> --- EFLAGS is 0x12\n" + + ">>> Emulation done. Below is the CPU context\n" + + ">>> ECX = 0x1235\n" + + ">>> EDX = 0x788f\n" + + ">>> Read 4 bytes from [0x1000000] = 0xf664a41\n", + outContent.toString()); + } + + @Test + public void testX86InOut() { + assumeTrue(Unicorn.arch_supported(UC_ARCH_X86)); + samples.Sample_x86.test_i386_inout(); + assertEquals( + "Emulate i386 code with IN/OUT instructions\n" + + ">>> Tracing basic block at 0x1000000, block size = 0x7\n" + + ">>> Tracing instruction at 0x1000000, instruction size = 0x1\n" + + ">>> --- EFLAGS is 0x2\n" + + ">>> Tracing instruction at 0x1000001, instruction size = 0x2\n" + + ">>> --- EFLAGS is 0x2\n" + + "--- reading from port 0x3f, size: 1, address: 0x1000001\n" + + ">>> Tracing instruction at 0x1000003, instruction size = 0x1\n" + + ">>> --- EFLAGS is 0x2\n" + + ">>> Tracing instruction at 0x1000004, instruction size = 0x2\n" + + ">>> --- EFLAGS is 0x96\n" + + "--- writing to port 0x46, size: 1, value: 0xf1, address: 0x1000004\n" + + "--- register value = 0xf1\n" + + ">>> Tracing instruction at 0x1000006, instruction size = 0x1\n" + + ">>> --- EFLAGS is 0x96\n" + + ">>> Emulation done. Below is the CPU context\n" + + ">>> EAX = 0x12f1\n" + + ">>> ECX = 0x678a\n", + outContent.toString()); + } + + @Test + public void testX86ContextSave() { + assumeTrue(Unicorn.arch_supported(UC_ARCH_X86)); + samples.Sample_x86.test_i386_context_save(); + assertEquals( + "Save/restore CPU context in opaque blob\n" + + ">>> Running emulation for the first time\n" + + ">>> Emulation done. Below is the CPU context\n" + + ">>> EAX = 0x2\n" + + ">>> Saving CPU context\n" + + ">>> Running emulation for the second time\n" + + ">>> Emulation done. Below is the CPU context\n" + + ">>> EAX = 0x3\n" + + ">>> CPU context restored. Below is the CPU context\n" + + ">>> EAX = 0x2\n" + + ">>> CPU context restored with modification. Below is the CPU context\n" + + ">>> EAX = 0xc8\n", + outContent.toString()); + } + + @Test + public void testX86Jump() { + assumeTrue(Unicorn.arch_supported(UC_ARCH_X86)); + samples.Sample_x86.test_i386_jump(); + assertEquals( + "Emulate i386 code with jump\n" + + ">>> Tracing basic block at 0x1000000, block size = 0x2\n" + + ">>> Tracing instruction at 0x1000000, instruction size = 0x2\n" + + ">>> --- EFLAGS is 0x2\n" + + ">>> Emulation done. Below is the CPU context\n", + outContent.toString()); + } + + @Test + public void testX86Loop() { + assumeTrue(Unicorn.arch_supported(UC_ARCH_X86)); + samples.Sample_x86.test_i386_loop(); + assertEquals( + "Emulate i386 code that loop forever\n" + + ">>> Emulation done. Below is the CPU context\n" + + ">>> ECX = 0x1235\n" + + ">>> EDX = 0x788f\n", + outContent.toString()); + } + + @Test + public void testX86InvalidMemRead() { + assumeTrue(Unicorn.arch_supported(UC_ARCH_X86)); + samples.Sample_x86.test_i386_invalid_mem_read(); + assertEquals( + "Emulate i386 code that read from invalid memory\n" + + ">>> Tracing basic block at 0x1000000, block size = 0x8\n" + + ">>> Tracing instruction at 0x1000000, instruction size = 0x6\n" + + ">>> --- EFLAGS is 0x2\n" + + "uc.emu_start failed as expected: " + + "unicorn.UnicornException: Invalid memory read (UC_ERR_READ_UNMAPPED)\n" + + ">>> Emulation done. Below is the CPU context\n" + + ">>> ECX = 0x1234\n" + + ">>> EDX = 0x7890\n", + outContent.toString()); + } + + @Test + public void testX86InvalidMemWrite() { + assumeTrue(Unicorn.arch_supported(UC_ARCH_X86)); + samples.Sample_x86.test_i386_invalid_mem_write(); + assertEquals( + "Emulate i386 code that write to invalid memory\n" + + ">>> Tracing basic block at 0x1000000, block size = 0x8\n" + + ">>> Tracing instruction at 0x1000000, instruction size = 0x6\n" + + ">>> --- EFLAGS is 0x2\n" + + ">>> Missing memory is being WRITE at 0xaaaaaaaa, data size = 4, data value = 0x1234\n" + + ">>> Tracing instruction at 0x1000006, instruction size = 0x1\n" + + ">>> --- EFLAGS is 0x2\n" + + ">>> Tracing instruction at 0x1000007, instruction size = 0x1\n" + + ">>> --- EFLAGS is 0x6\n" + + ">>> Emulation done. Below is the CPU context\n" + + ">>> ECX = 0x1235\n" + + ">>> EDX = 0x788f\n" + + ">>> Read 4 bytes from [0xaaaaaaaa] = 0x1234\n" + + ">>> Failed to read 4 bytes from [0xffffffaa]\n", + outContent.toString()); + } + + @Test + public void testX86JumpInvalid() { + assumeTrue(Unicorn.arch_supported(UC_ARCH_X86)); + samples.Sample_x86.test_i386_jump_invalid(); + assertEquals( + "Emulate i386 code that jumps to invalid memory\n" + + ">>> Tracing basic block at 0x1000000, block size = 0x5\n" + + ">>> Tracing instruction at 0x1000000, instruction size = 0x5\n" + + ">>> --- EFLAGS is 0x2\n" + + "uc.emu_start failed as expected: " + + "unicorn.UnicornException: Invalid memory fetch (UC_ERR_FETCH_UNMAPPED)\n" + + ">>> Emulation done. Below is the CPU context\n" + + ">>> ECX = 0x1234\n" + + ">>> EDX = 0x7890\n", + outContent.toString()); + } + + @Test + public void testX86_64() { + assumeTrue(Unicorn.arch_supported(UC_ARCH_X86)); + samples.Sample_x86.test_x86_64(); + assertEquals( + "Emulate x86_64 code\n" + + ">>> Tracing basic block at 0x1000000, block size = 0x4b\n" + + ">>> Tracing instruction at 0x1000000, instruction size = 0x6\n" + + ">>> RIP is 0x1000000\n" + + ">>> Tracing instruction at 0x1000006, instruction size = 0x3\n" + + ">>> RIP is 0x1000006\n" + + ">>> Tracing instruction at 0x1000009, instruction size = 0x1\n" + + ">>> RIP is 0x1000009\n" + + ">>> Tracing instruction at 0x100000a, instruction size = 0x4\n" + + ">>> RIP is 0x100000a\n" + + ">>> Tracing instruction at 0x100000e, instruction size = 0x3\n" + + ">>> RIP is 0x100000e\n" + + ">>> Tracing instruction at 0x1000011, instruction size = 0x1\n" + + ">>> RIP is 0x1000011\n" + + ">>> Tracing instruction at 0x1000012, instruction size = 0x7\n" + + ">>> RIP is 0x1000012\n" + + ">>> Memory is being WRITE at 0x11ffff8, data size = 8, data value = 0x3c091e6a\n" + + ">>> Memory is being READ at 0x11ffff8, data size = 8\n" + + ">>> Emulation done. Below is the CPU context\n" + + ">>> RAX = 0xdb8ee18208cd6d03\n" + + ">>> RBX = 0xd87b45277f133ddb\n" + + ">>> RCX = 0x3c091e6a\n" + + ">>> RDX = 0x25b8d5a4dbb38112\n" + + ">>> RSI = 0xb3db18ac5e815ca7\n" + + ">>> RDI = 0x48288ca5671c5492\n" + + ">>> R8 = 0xec45774f00c5f682\n" + + ">>> R9 = 0xc118b68e7fcfeeff\n" + + ">>> R10 = 0x596b8d4f\n" + + ">>> R11 = 0xe17e9dbec8c074aa\n" + + ">>> R12 = 0x595f72f6b9d8cf32\n" + + ">>> R13 = 0xea5b108cc2b9ab1f\n" + + ">>> R14 = 0x595f72f6e4017f6e\n" + + ">>> R15 = 0x3e04f60c8f7ecbd7\n", + outContent.toString()); + } + + @Test + public void testX86_64Syscall() { + assumeTrue(Unicorn.arch_supported(UC_ARCH_X86)); + samples.Sample_x86.test_x86_64_syscall(); + assertEquals( + "Emulate x86_64 code with 'syscall' instruction\n" + + ">>> Emulation done. Below is the CPU context\n" + + ">>> RAX = 0x200\n", + outContent.toString()); + } + + @Test + public void testX86InvalidMemReadInTb() { + assumeTrue(Unicorn.arch_supported(UC_ARCH_X86)); + samples.Sample_x86.test_i386_invalid_mem_read_in_tb(); + assertEquals( + "Emulate i386 code that read invalid memory in the middle of a TB\n" + + "uc.emu_start() failed BY DESIGN with error returned: " + + "unicorn.UnicornException: Invalid memory read (UC_ERR_READ_UNMAPPED)\n" + + ">>> Emulation done. Below is the CPU context\n" + + ">>> EIP = 0x1000001\n" + + ">>> The PC is correct after reading unmapped memory in the middle of TB.\n", + outContent.toString()); + } + + @Test + public void testX86SmcXor() { + assumeTrue(Unicorn.arch_supported(UC_ARCH_X86)); + samples.Sample_x86.test_i386_smc_xor(); + assertEquals( + "Emulate i386 code that modfies itself\n" + + ">>> Emulation done. Below is the result.\n" + + ">>> SMC emulation is correct. 0x3ea98b13 ^ 0xbc4177e6 = 0x82e8fcf5\n", + outContent.toString()); + } + + @Test + public void testX86Mmio() { + assumeTrue(Unicorn.arch_supported(UC_ARCH_X86)); + samples.Sample_x86.test_i386_mmio(); + assertEquals( + "Emulate i386 code that uses MMIO\n" + + ">>> Write value 0x3735928559 to IO memory at offset 0x4 with 0x4 bytes\n" + + ">>> Read IO memory at offset 0x4 with 0x4 bytes and return 0x19260817\n" + + ">>> Emulation done. ECX=0x19260817\n", + outContent.toString()); + } + + @Test + public void testX86HookMemInvalid() { + assumeTrue(Unicorn.arch_supported(UC_ARCH_X86)); + samples.Sample_x86.test_i386_hook_mem_invalid(); + assertEquals( + "Emulate i386 code that triggers invalid memory read/write.\n" + + ">>> We have to add a map at 0x8000 before continue execution!\n" + + ">>> We have to add a map at 0x10000 before continue execution!\n", + outContent.toString()); + } } diff --git a/samples/sample_arm64.c b/samples/sample_arm64.c index 84f32c29..1d11592a 100644 --- a/samples/sample_arm64.c +++ b/samples/sample_arm64.c @@ -293,9 +293,94 @@ static void test_arm64_hook_mrs() uc_close(uc); } + +#define CHECK(x) do { \ + if((x) != UC_ERR_OK) { \ + fprintf(stderr, "FAIL at %s:%d: %s\n", __FILE__, __LINE__, #x); \ + exit(1); \ + } \ +} while(0) + +static void test_arm64_pac(void) +{ + uc_engine *uc; + uint64_t x1 = 0x0000aaaabbbbccccULL; + + // paciza x1 + #define ARM64_PAC_CODE "\xe1\x23\xc1\xda" + + printf("Try ARM64 PAC\n"); + + // Initialize emulator in ARM mode + CHECK(uc_open(UC_ARCH_ARM64, UC_MODE_ARM, &uc)); + CHECK(uc_ctl_set_cpu_model(uc, UC_CPU_ARM64_MAX)); + CHECK(uc_mem_map(uc, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL)); + CHECK(uc_mem_write(uc, ADDRESS, ARM64_PAC_CODE, sizeof(ARM64_PAC_CODE) - 1)); + CHECK(uc_reg_write(uc, UC_ARM64_REG_X1, &x1)); + + /** Initialize PAC support **/ + uc_arm64_cp_reg reg; + + // SCR_EL3 + reg.op0 = 0b11; + reg.op1 = 0b110; + reg.crn = 0b0001; + reg.crm = 0b0001; + reg.op2 = 0b000; + + CHECK(uc_reg_read(uc, UC_ARM64_REG_CP_REG, ®)); + + // NS && RW && API + reg.val |= (1 | (1<<10) | (1<<17)); + + CHECK(uc_reg_write(uc, UC_ARM64_REG_CP_REG, ®)); + + // SCTLR_EL1 + reg.op0 = 0b11; + reg.op1 = 0b000; + reg.crn = 0b0001; + reg.crm = 0b0000; + reg.op2 = 0b000; + + CHECK(uc_reg_read(uc, UC_ARM64_REG_CP_REG, ®)); + + // EnIA && EnIB + reg.val |= (1<<31) | (1<<30); + + CHECK(uc_reg_write(uc, UC_ARM64_REG_CP_REG, ®)); + + // HCR_EL2 + reg.op0 = 0b11; + reg.op1 = 0b100; + reg.crn = 0b0001; + reg.crm = 0b0001; + reg.op2 = 0b000; + + // HCR.API + reg.val |= (1ULL<<41); + + CHECK(uc_reg_write(uc, UC_ARM64_REG_CP_REG, ®)); + + /** Check that PAC worked **/ + CHECK(uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(ARM64_PAC_CODE) - 1, 0, 0)); + CHECK(uc_reg_read(uc, UC_ARM64_REG_X1, &x1)); + + printf("X1 = 0x%" PRIx64 "\n", x1); + if (x1 == 0x0000aaaabbbbccccULL) { + printf("FAIL: No PAC tag added!\n"); + } else { + // Expect 0x1401aaaabbbbccccULL with the default key + printf("SUCCESS: PAC tag found.\n"); + } + + uc_close(uc); +} + int main(int argc, char **argv, char **envp) { test_arm64_mem_fetch(); + + printf("-------------------------\n"); test_arm64(); printf("-------------------------\n"); @@ -307,5 +392,8 @@ int main(int argc, char **argv, char **envp) printf("-------------------------\n"); test_arm64_hook_mrs(); + printf("-------------------------\n"); + test_arm64_pac(); + return 0; } diff --git a/samples/sample_tricore.c b/samples/sample_tricore.c index 1b7a5551..c3e20655 100644 --- a/samples/sample_tricore.c +++ b/samples/sample_tricore.c @@ -9,7 +9,7 @@ #include // code to be emulated -#define CODE "\x82\x11\xbb\x00\x00\x08" // mov d0, #0x1; mov.u d0, #0x8000 +#define CODE "\x82\x11\xbb\x00\x00\x08" // mov d1, #0x1; mov.u d0, #0x8000 // memory address where emulation starts #define ADDRESS 0x10000 @@ -36,6 +36,7 @@ static void test_tricore(void) uc_hook trace1, trace2; uint32_t d0 = 0x0; // d0 register + uint32_t d1 = 0x0; // d1 register printf("Emulate TriCore code\n"); @@ -73,6 +74,9 @@ static void test_tricore(void) uc_reg_read(uc, UC_TRICORE_REG_D0, &d0); printf(">>> d0 = 0x%x\n", d0); + uc_reg_read(uc, UC_TRICORE_REG_D1, &d1); + printf(">>> d1 = 0x%x\n", d1); + uc_close(uc); } diff --git a/samples/sample_x86.c b/samples/sample_x86.c index 735a9985..9aca8550 100644 --- a/samples/sample_x86.c +++ b/samples/sample_x86.c @@ -360,7 +360,6 @@ static void test_i386_map_ptr(void) int r_ecx = 0x1234; // ECX register int r_edx = 0x7890; // EDX register - printf("===================================\n"); printf("Emulate i386 code - use uc_mem_map_ptr()\n"); // Initialize emulator in X86-32bit mode @@ -426,7 +425,6 @@ static void test_i386_jump(void) uc_err err; uc_hook trace1, trace2; - printf("===================================\n"); printf("Emulate i386 code with jump\n"); // Initialize emulator in X86-32bit mode @@ -474,7 +472,6 @@ static void test_i386_loop(void) int r_ecx = 0x1234; // ECX register int r_edx = 0x7890; // EDX register - printf("===================================\n"); printf("Emulate i386 code that loop forever\n"); // Initialize emulator in X86-32bit mode @@ -528,7 +525,6 @@ static void test_i386_invalid_mem_read(void) int r_ecx = 0x1234; // ECX register int r_edx = 0x7890; // EDX register - printf("===================================\n"); printf("Emulate i386 code that read from invalid memory\n"); // Initialize emulator in X86-32bit mode @@ -588,7 +584,6 @@ static void test_i386_invalid_mem_write(void) int r_ecx = 0x1234; // ECX register int r_edx = 0x7890; // EDX register - printf("===================================\n"); printf("Emulate i386 code that write to invalid memory\n"); // Initialize emulator in X86-32bit mode @@ -663,7 +658,6 @@ static void test_i386_jump_invalid(void) int r_ecx = 0x1234; // ECX register int r_edx = 0x7890; // EDX register - printf("===================================\n"); printf("Emulate i386 code that jumps to invalid memory\n"); // Initialize emulator in X86-32bit mode @@ -721,7 +715,6 @@ static void test_i386_inout(void) int r_eax = 0x1234; // EAX register int r_ecx = 0x6789; // ECX register - printf("===================================\n"); printf("Emulate i386 code with IN/OUT instructions\n"); // Initialize emulator in X86-32bit mode @@ -785,7 +778,6 @@ static void test_i386_context_save(void) int r_eax = 0x1; // EAX register - printf("===================================\n"); printf("Save/restore CPU context in opaque blob\n"); // initialize emulator in X86-32bit mode @@ -908,7 +900,6 @@ static void test_i386_invalid_c6c7(void) }; int i, j, k; - printf("===================================\n"); printf("Emulate i386 C6/C7 opcodes\n"); // Initialize emulator in X86-32bit mode @@ -1077,7 +1068,6 @@ static void test_x86_64_syscall(void) int64_t rax = 0x100; - printf("===================================\n"); printf("Emulate x86_64 code with 'syscall' instruction\n"); // Initialize emulator in X86-64bit mode @@ -1186,7 +1176,6 @@ static void test_i386_invalid_mem_read_in_tb(void) int r_edx = 0x7890; // EDX register int r_eip = 0; - printf("===================================\n"); printf( "Emulate i386 code that read invalid memory in the middle of a TB\n"); @@ -1249,7 +1238,6 @@ static void test_i386_smc_xor() uint32_t r_eax = 0xbc4177e6; // EDX register uint32_t result; - printf("===================================\n"); printf("Emulate i386 code that modfies itself\n"); // Initialize emulator in X86-32bit mode @@ -1325,7 +1313,6 @@ static void test_i386_mmio() int r_ecx = 0xdeadbeef; uc_err err; - printf("===================================\n"); printf("Emulate i386 code that uses MMIO\n"); // Initialize emulator in X86-32bit mode @@ -1403,7 +1390,6 @@ static void test_i386_hook_mem_invalid() "\xb8\xef\xbe\xad\xde\xa3\x00\x80\x00\x00\xa1\x00\x00\x01\x00"; uc_err err; - printf("===================================\n"); printf("Emulate i386 code that triggers invalid memory read/write.\n"); err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc); @@ -1448,40 +1434,66 @@ int main(int argc, char **argv, char **envp) test_x86_16(); } else if (!strcmp(argv[1], "-32")) { test_miss_code(); + printf("===================================\n"); test_i386(); + printf("===================================\n"); test_i386_map_ptr(); + printf("===================================\n"); test_i386_inout(); + printf("===================================\n"); test_i386_context_save(); + printf("===================================\n"); test_i386_jump(); + printf("===================================\n"); test_i386_loop(); + printf("===================================\n"); test_i386_invalid_mem_read(); + printf("===================================\n"); test_i386_invalid_mem_write(); + printf("===================================\n"); test_i386_jump_invalid(); // test_i386_invalid_c6c7(); } else if (!strcmp(argv[1], "-64")) { test_x86_64(); + printf("===================================\n"); test_x86_64_syscall(); } else if (!strcmp(argv[1], "-h")) { printf("Syntax: %s <-16|-32|-64>\n", argv[0]); } } else { test_x86_16(); + printf("===================================\n"); test_miss_code(); + printf("===================================\n"); test_i386(); + printf("===================================\n"); test_i386_map_ptr(); + printf("===================================\n"); test_i386_inout(); + printf("===================================\n"); test_i386_context_save(); + printf("===================================\n"); test_i386_jump(); + printf("===================================\n"); test_i386_loop(); + printf("===================================\n"); test_i386_invalid_mem_read(); + printf("===================================\n"); test_i386_invalid_mem_write(); + printf("===================================\n"); test_i386_jump_invalid(); // test_i386_invalid_c6c7(); + printf("===================================\n"); test_x86_64(); + printf("===================================\n"); test_x86_64_syscall(); + printf("===================================\n"); test_i386_invalid_mem_read_in_tb(); + printf("===================================\n"); test_i386_smc_xor(); + printf("===================================\n"); test_i386_mmio(); + printf("===================================\n"); test_i386_hook_mem_invalid(); } From edd80ddeda78f29f177b61f78e4b9e6e19e0021c Mon Sep 17 00:00:00 2001 From: Robert Xiao Date: Sun, 14 May 2023 17:16:24 -0700 Subject: [PATCH 18/25] Port sample_x86_32_gdt_and_seg_regs over to Sample_x86_mmr --- bindings/java/samples/Sample_x86_mmr.java | 171 +++++++++++++++++++++- bindings/java/tests/TestSamples.java | 36 +++++ 2 files changed, 205 insertions(+), 2 deletions(-) diff --git a/bindings/java/samples/Sample_x86_mmr.java b/bindings/java/samples/Sample_x86_mmr.java index eaadf878..df38d216 100644 --- a/bindings/java/samples/Sample_x86_mmr.java +++ b/bindings/java/samples/Sample_x86_mmr.java @@ -23,11 +23,83 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. package samples; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.util.Arrays; + import unicorn.*; public class Sample_x86_mmr implements UnicornConst, X86Const { + private static final MemHook hook_mem = + (uc, type, address, size, value, user_data) -> { + switch (type) { + case UC_MEM_WRITE: + System.out.format( + "mem write at 0x%x, size = %d, value = 0x%x\n", + address, size, value); + break; + default: + break; + } + }; + private static final CodeHook hook_code = + (uc, address, size, user_data) -> { + System.out.format("Executing at 0x%x, ilen = 0x%x\n", address, + size); + }; + + public static class SegmentDescriptor { + public static final int BYTES = 8; + + int base; + int limit; + + byte type; // 4 bits + byte system; // 1 bit: S flag + byte dpl; // 2 bits + byte present; // 1 bit: P flag + byte avail; // 1 bit + byte is_64_code; // 1 bit: L flag + byte db; // 1 bit: DB flag + byte granularity; // 1 bit: G flag + + public SegmentDescriptor() { + } + + // VERY basic descriptor init function, sets many fields to user space sane + // defaults + public SegmentDescriptor(int base, int limit, boolean is_code) { + this.base = base; + if (limit > 0xfffff) { + // need Giant granularity + limit >>= 12; + this.granularity = 1; + } + this.limit = limit; + + // some sane defaults + this.dpl = 3; + this.present = 1; + this.db = 1; // 32 bit + this.type = is_code ? (byte) 0xb : 3; + this.system = 1; // code or data + } + + public void appendToBuffer(ByteBuffer buf) { + buf.putShort((short) limit); + buf.putShort((short) base); + buf.put((byte) (base >>> 16)); + buf.put( + (byte) (type | (system << 4) | (dpl << 5) | (present << 7))); + buf.put((byte) (((limit >>> 16) & 0xf) | (avail << 4) | + (is_64_code << 5) | (db << 6) | (granularity << 7))); + buf.put((byte) (base >>> 24)); + } + } + public static void test_x86_mmr() { + System.out.println("Test x86 MMR read/write"); // Initialize emulator in X86-32bit mode Unicorn uc = new Unicorn(UC_ARCH_X86, UC_MODE_32); @@ -41,7 +113,7 @@ public class Sample_x86_mmr implements UnicornConst, X86Const { (short) 0xaaaa); X86_MMR gdtr2; - int eax; + long eax; // initialize machine registers @@ -50,7 +122,7 @@ public class Sample_x86_mmr implements UnicornConst, X86Const { uc.reg_write(UC_X86_REG_EAX, 0xddddddddL); // read the registers back out - eax = (int) uc.reg_read(UC_X86_REG_EAX); + eax = uc.reg_read(UC_X86_REG_EAX); ldtr2 = (X86_MMR) uc.reg_read(UC_X86_REG_LDTR, null); gdtr2 = (X86_MMR) uc.reg_read(UC_X86_REG_GDTR, null); @@ -65,8 +137,103 @@ public class Sample_x86_mmr implements UnicornConst, X86Const { System.out.printf(">>> GDTR.limit = 0x%x\n", gdtr2.limit); } + public static void gdt_demo() { + System.out.println("Demonstrate GDT usage"); + /* + bits 32 + + push dword 0x01234567 + push dword 0x89abcdef + + mov dword [fs:0], 0x01234567 + mov dword [fs:4], 0x89abcdef + */ + final byte[] code = + Utils.hexToBytes("686745230168efcdab8964c70500000000" + + "6745230164c70504000000efcdab89"); + final long code_address = 0x1000000L; + final long stack_address = 0x120000L; + final long gdt_address = 0xc0000000L; + final long fs_address = 0x7efdd000L; + + SegmentDescriptor[] gdt = new SegmentDescriptor[31]; + + int r_esp = (int) stack_address + 0x1000; // initial esp + int r_cs = 0x73; + int r_ss = 0x88; // ring 0 + int r_ds = 0x7b; + int r_es = 0x7b; + int r_fs = 0x83; + + X86_MMR gdtr = + new X86_MMR(gdt_address, gdt.length * SegmentDescriptor.BYTES - 1); + + gdt[14] = new SegmentDescriptor(0, 0xfffff000, true); // code segment + gdt[15] = new SegmentDescriptor(0, 0xfffff000, false); // data segment + gdt[16] = new SegmentDescriptor((int) fs_address, 0xfff, false); // one page data segment simulate fs + gdt[17] = new SegmentDescriptor(0, 0xfffff000, false); // ring 0 data + gdt[17].dpl = 0; // set descriptor privilege level + + // Initialize emulator in X86-32bit mode + Unicorn uc = new Unicorn(UC_ARCH_X86, UC_MODE_32); + uc.hook_add(hook_code, code_address, code_address + code.length, null); + uc.hook_add(hook_mem, UC_HOOK_MEM_WRITE, 1, 0, null); + + // map 1 page of code for this emulation + uc.mem_map(code_address, 0x1000, UC_PROT_ALL); + // map 1 page of stack for this emulation + uc.mem_map(stack_address, 0x1000, UC_PROT_READ | UC_PROT_WRITE); + // map 64k for a GDT + uc.mem_map(gdt_address, 0x10000, UC_PROT_WRITE | UC_PROT_READ); + // set up a GDT BEFORE you manipulate any segment registers + uc.reg_write(UC_X86_REG_GDTR, gdtr); + // write gdt to be emulated to memory + ByteBuffer gdt_buf = + ByteBuffer.allocate(gdt.length * SegmentDescriptor.BYTES) + .order(ByteOrder.LITTLE_ENDIAN); + for (SegmentDescriptor desc : gdt) { + if (desc == null) { + gdt_buf.put(new byte[SegmentDescriptor.BYTES]); + } else { + desc.appendToBuffer(gdt_buf); + } + } + uc.mem_write(gdt_address, gdt_buf.array()); + // map 1 page for FS + uc.mem_map(fs_address, 0x1000, UC_PROT_WRITE | UC_PROT_READ); + // write machine code to be emulated to memory + uc.mem_write(code_address, code); + // initialize machine registers + uc.reg_write(UC_X86_REG_ESP, r_esp); + // when setting SS, need rpl == cpl && dpl == cpl + // emulator starts with cpl == 0, so we need a dpl 0 descriptor and rpl 0 + // selector + uc.reg_write(UC_X86_REG_SS, r_ss); + uc.reg_write(UC_X86_REG_CS, r_cs); + uc.reg_write(UC_X86_REG_DS, r_ds); + uc.reg_write(UC_X86_REG_ES, r_es); + uc.reg_write(UC_X86_REG_FS, r_fs); + // emulate machine code in infinite time + uc.emu_start(code_address, code_address + code.length, 0, 0); + + // read from memory + byte[] buf = uc.mem_read(r_esp - 8, 8); + for (int i = 0; i < 8; i++) { + System.out.format("%02x", buf[i] & 0xff); + } + System.out.println(); + + assert Arrays.equals(buf, Utils.hexToBytes("efcdab8967452301")); + + // read from memory + buf = uc.mem_read(fs_address, 8); + assert Arrays.equals(buf, Utils.hexToBytes("67452301efcdab89")); + } + public static void main(String args[]) { test_x86_mmr(); + System.out.println("==================================="); + gdt_demo(); } } diff --git a/bindings/java/tests/TestSamples.java b/bindings/java/tests/TestSamples.java index 6c970035..ea458cd8 100644 --- a/bindings/java/tests/TestSamples.java +++ b/bindings/java/tests/TestSamples.java @@ -1172,4 +1172,40 @@ public class TestSamples implements UnicornConst { ">>> We have to add a map at 0x10000 before continue execution!\n", outContent.toString()); } + + @Test + public void testX86Mmr() { + assumeTrue(Unicorn.arch_supported(UC_ARCH_X86)); + samples.Sample_x86_mmr.test_x86_mmr(); + assertEquals( + "Test x86 MMR read/write\n" + + ">>> EAX = 0xdddddddd\n" + + ">>> LDTR.base = 0x22222222\n" + + ">>> LDTR.limit = 0x33333333\n" + + ">>> LDTR.flags = 0x44444444\n" + + ">>> LDTR.selector = 0x5555\n" + + "\n" + + ">>> GDTR.base = 0x77777777\n" + + ">>> GDTR.limit = 0x8888\n", + outContent.toString()); + } + + @Test + public void testX86Gdt() { + assumeTrue(Unicorn.arch_supported(UC_ARCH_X86)); + samples.Sample_x86_mmr.gdt_demo(); + assertEquals( + "Demonstrate GDT usage\n" + + "Executing at 0x1000000, ilen = 0x5\n" + + "mem write at 0x120ffc, size = 4, value = 0x1234567\n" + + "Executing at 0x1000005, ilen = 0x5\n" + + "mem write at 0x120ff8, size = 4, value = 0x89abcdef\n" + + "Executing at 0x100000a, ilen = 0xb\n" + + "mem write at 0x7efdd000, size = 4, value = 0x1234567\n" + + "Executing at 0x1000015, ilen = 0xb\n" + + "mem write at 0x7efdd004, size = 4, value = 0x89abcdef\n" + + "efcdab8967452301\n", + outContent.toString()); + } + } From 98f70d321343517cef0e11446239a96a205476d4 Mon Sep 17 00:00:00 2001 From: Robert Xiao Date: Sun, 14 May 2023 18:37:30 -0700 Subject: [PATCH 19/25] Port sample_batch_reg.c to Java, incidentally finding a bug in the generic register implementation. --- bindings/java/tests/RegTests.java | 39 ++++++++++++++++++++++++ bindings/java/tests/RegressionTests.java | 2 ++ bindings/java/unicorn/Unicorn.java | 6 ++++ 3 files changed, 47 insertions(+) diff --git a/bindings/java/tests/RegTests.java b/bindings/java/tests/RegTests.java index 356dd69f..a0a65dee 100644 --- a/bindings/java/tests/RegTests.java +++ b/bindings/java/tests/RegTests.java @@ -1,5 +1,6 @@ package tests; +import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertThrows; @@ -9,6 +10,7 @@ import java.math.BigInteger; import org.junit.Test; import unicorn.Arm64_CP; +import unicorn.SyscallHook; import unicorn.Unicorn; import unicorn.UnicornException; import unicorn.X86_Float80; @@ -52,6 +54,43 @@ public class RegTests { assertEquals(Math.sin(-1.1), reg.toDouble(), 1e-12); } + /** Test batch register API. Ported from sample_batch_reg.c. Not a sample + * because the Java version of this API is deprecated. + */ + @Test + public void testBatchReg() { + int[] syscall_abi = { Unicorn.UC_X86_REG_RAX, Unicorn.UC_X86_REG_RDI, + Unicorn.UC_X86_REG_RSI, Unicorn.UC_X86_REG_RDX, + Unicorn.UC_X86_REG_R10, Unicorn.UC_X86_REG_R8, + Unicorn.UC_X86_REG_R9 }; + + Object[] vals = { 200L, 10L, 11L, 12L, 13L, 14L, 15L }; + + long BASE = 0x10000L; + + // mov rax, 100; mov rdi, 1; mov rsi, 2; mov rdx, 3; mov r10, 4; mov r8, 5; mov + // r9, 6; syscall + byte[] CODE = + samples.Utils.hexToBytes("48c7c06400000048c7c70100000048c7c602" + + "00000048c7c20300000049c7c20400000049" + + "c7c00500000049c7c1060000000f05"); + + Unicorn uc = new Unicorn(Unicorn.UC_ARCH_X86, Unicorn.UC_MODE_64); + uc.reg_write_batch(syscall_abi, vals); + Object[] rvals = uc.reg_read_batch(syscall_abi); + assertArrayEquals(vals, rvals); + + uc.hook_add((SyscallHook) (u, user_data) -> { + Object[] nvals = u.reg_read_batch(syscall_abi); + assertArrayEquals(new Object[] { 100L, 1L, 2L, 3L, 4L, 5L, 6L }, + nvals); + }, Unicorn.UC_X86_INS_SYSCALL, 1, 0, null); + + uc.mem_map(BASE, 0x1000, Unicorn.UC_PROT_ALL); + uc.mem_write(BASE, CODE); + uc.emu_start(BASE, BASE + CODE.length, 0, 0); + } + @Test public void testBigIntegerRegister() { Unicorn uc = diff --git a/bindings/java/tests/RegressionTests.java b/bindings/java/tests/RegressionTests.java index a94090ad..52ae143a 100644 --- a/bindings/java/tests/RegressionTests.java +++ b/bindings/java/tests/RegressionTests.java @@ -4,6 +4,7 @@ import static org.junit.Assert.assertEquals; import java.math.BigInteger; +import org.junit.Ignore; import org.junit.Test; import unicorn.Unicorn; @@ -55,6 +56,7 @@ public class RegressionTests { } /** Test that Unicorn instances are properly garbage-collected */ + @Ignore("This test is not deterministic") @Test public void testUnicornsWillGC() { final boolean[] close_called = { false }; diff --git a/bindings/java/unicorn/Unicorn.java b/bindings/java/unicorn/Unicorn.java index e89bd1df..4410df5b 100644 --- a/bindings/java/unicorn/Unicorn.java +++ b/bindings/java/unicorn/Unicorn.java @@ -264,12 +264,14 @@ public class Unicorn X86_MSR reg = (X86_MSR) opt; return (Long) _reg_read_x86_msr(ptr, isContext, reg.rid); } + break; case UC_ARCH_ARM: if (regid == UC_ARM_REG_CP_REG) { Arm_CP reg = (Arm_CP) opt; return (Long) _reg_read_arm_cp(ptr, isContext, reg.cp, reg.is64, reg.sec, reg.crn, reg.crm, reg.opc1, reg.opc2); } + break; case UC_ARCH_ARM64: if (regid == UC_ARM64_REG_CP_REG) { Arm64_CP reg = (Arm64_CP) opt; @@ -280,6 +282,7 @@ public class Unicorn (regid >= UC_ARM64_REG_V0 && regid <= UC_ARM64_REG_V31)) { return do_reg_read_bigint(ptr, isContext, regid, 128); } + break; } return _reg_read_long(ptr, isContext, regid); } @@ -330,6 +333,7 @@ public class Unicorn _reg_write_x86_msr(ptr, isContext, reg.rid, reg.value); return; } + break; case UC_ARCH_ARM: if (regid == UC_ARM_REG_CP_REG) { Arm_CP reg = (Arm_CP) value; @@ -337,6 +341,7 @@ public class Unicorn reg.crn, reg.crm, reg.opc1, reg.opc2, reg.val); return; } + break; case UC_ARCH_ARM64: if (regid == UC_ARM64_REG_CP_REG) { Arm64_CP reg = (Arm64_CP) value; @@ -350,6 +355,7 @@ public class Unicorn 128); return; } + break; } _reg_write_long(ptr, isContext, regid, (Long) value); } From 05f6fb9bf32f0b113289aca92d0c96e4891e9211 Mon Sep 17 00:00:00 2001 From: Robert Xiao Date: Sun, 14 May 2023 19:11:34 -0700 Subject: [PATCH 20/25] Properly check return value of makeHookWrapper --- bindings/java/unicorn_Unicorn.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/bindings/java/unicorn_Unicorn.c b/bindings/java/unicorn_Unicorn.c index 58ce3825..54e90f49 100644 --- a/bindings/java/unicorn_Unicorn.c +++ b/bindings/java/unicorn_Unicorn.c @@ -934,6 +934,9 @@ Java_unicorn_Unicorn__1hook_1add__JILunicorn_Hook_2Ljava_lang_Object_2JJ( struct hook_wrapper *hh = makeHookWrapper(env, self, callback, user_data, "hook", hook_sig); + if (hh == NULL) { + return 0; + } uc_err err = uc_hook_add((uc_engine *)uc, &hh->uc_hh, type, hook_callback, hh, begin, end); if (err != UC_ERR_OK) { @@ -994,6 +997,9 @@ Java_unicorn_Unicorn__1hook_1add__JILunicorn_Hook_2Ljava_lang_Object_2JJI( struct hook_wrapper *hh = makeHookWrapper(env, self, callback, user_data, "hook", hook_sig); + if (hh == NULL) { + return 0; + } uc_err err = uc_hook_add((uc_engine *)uc, &hh->uc_hh, type, hook_callback, hh, begin, end, arg); if (err != UC_ERR_OK) { @@ -1027,6 +1033,9 @@ Java_unicorn_Unicorn__1hook_1add__JILunicorn_Hook_2Ljava_lang_Object_2JJII( struct hook_wrapper *hh = makeHookWrapper(env, self, callback, user_data, "hook", hook_sig); + if (hh == NULL) { + return 0; + } uc_err err = uc_hook_add((uc_engine *)uc, &hh->uc_hh, type, hook_callback, hh, begin, end, arg1, arg2); if (err != UC_ERR_OK) { From d9407c904196de0c8062ba6cb973cb99c2bcb185 Mon Sep 17 00:00:00 2001 From: Robert Xiao Date: Sat, 17 Jun 2023 14:22:56 -0700 Subject: [PATCH 21/25] Add a link to the relevant issue for ARM PAC handling --- bindings/java/samples/Sample_arm64.java | 2 ++ samples/sample_arm64.c | 3 +++ 2 files changed, 5 insertions(+) diff --git a/bindings/java/samples/Sample_arm64.java b/bindings/java/samples/Sample_arm64.java index e8b4a4a7..5364a2c2 100644 --- a/bindings/java/samples/Sample_arm64.java +++ b/bindings/java/samples/Sample_arm64.java @@ -217,6 +217,8 @@ public class Sample_arm64 implements UnicornConst, Arm64Const { System.out.format(">>> X2 = 0x%x\n", uc.reg_read(UC_ARM64_REG_X2)); } + /* Test PAC support in the emulator. Code adapted from + https://github.com/unicorn-engine/unicorn/issues/1789#issuecomment-1536320351 */ public static void test_arm64_pac() { long x1 = 0x0000aaaabbbbccccL; diff --git a/samples/sample_arm64.c b/samples/sample_arm64.c index 1d11592a..2f3afc79 100644 --- a/samples/sample_arm64.c +++ b/samples/sample_arm64.c @@ -301,6 +301,9 @@ static void test_arm64_hook_mrs() } \ } while(0) + +/* Test PAC support in the emulator. Code adapted from +https://github.com/unicorn-engine/unicorn/issues/1789#issuecomment-1536320351 */ static void test_arm64_pac(void) { uc_engine *uc; From 2198ea4f694a12ba677e2ecd4b2991a1f4d9d2bc Mon Sep 17 00:00:00 2001 From: Robert Xiao Date: Sat, 17 Jun 2023 14:34:25 -0700 Subject: [PATCH 22/25] Add comment about unicorn_Unicorn.h to the .c file --- bindings/java/unicorn_Unicorn.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/bindings/java/unicorn_Unicorn.c b/bindings/java/unicorn_Unicorn.c index 54e90f49..86ca7e21 100644 --- a/bindings/java/unicorn_Unicorn.c +++ b/bindings/java/unicorn_Unicorn.c @@ -19,6 +19,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +/** Note: JNI function signatures and names must be kept in sync with + unicorn_Unicorn.h, which is in turn auto-generated by `javac -h`. */ + #include #include "unicorn/platform.h" #include From dfdc8e7e8ebc07e54eef08bba784601a129c8474 Mon Sep 17 00:00:00 2001 From: Robert Xiao Date: Thu, 29 Jun 2023 16:04:51 -0700 Subject: [PATCH 23/25] Switch to Maven to build the Java bits. Maven is now used to update the constants, build the Java code, call make to build the native library, and run all the tests. I have removed the "install" and "uninstall" targets; instead, the expectation will be that the JNI library will be placed somewhere on java.library.path and the JAR file will be used as usual (e.g. in a downstream Maven project, or placed on the classpath of your project). Since Maven is now running our tests, this eliminates the need to bundle test dependencies in `testdep`, and makes the project structured more like a typical Java project. --- .gitignore | 1 - bindings/const_generator.py | 2 +- bindings/java/.gitignore | 2 + bindings/java/Makefile | 80 ++++----------- bindings/java/README.TXT | 37 ------- bindings/java/README.md | 39 ++++++++ bindings/java/pom.xml | 92 ++++++++++++++++++ .../main/java}/unicorn/Arm64Const.java | 0 .../main/java}/unicorn/Arm64SysHook.java | 0 .../{ => src/main/java}/unicorn/Arm64_CP.java | 0 .../{ => src/main/java}/unicorn/ArmConst.java | 0 .../{ => src/main/java}/unicorn/Arm_CP.java | 0 .../main/java}/unicorn/BlockHook.java | 0 .../{ => src/main/java}/unicorn/CodeHook.java | 0 .../main/java}/unicorn/CpuidHook.java | 0 .../main/java}/unicorn/EdgeGeneratedHook.java | 0 .../main/java}/unicorn/EventMemHook.java | 0 .../{ => src/main/java}/unicorn/Hook.java | 0 .../{ => src/main/java}/unicorn/InHook.java | 0 .../main/java}/unicorn/InstructionHook.java | 0 .../main/java}/unicorn/InterruptHook.java | 0 .../java}/unicorn/InvalidInstructionHook.java | 0 .../main/java}/unicorn/M68kConst.java | 0 .../{ => src/main/java}/unicorn/MemHook.java | 0 .../main/java}/unicorn/MemRegion.java | 0 .../main/java}/unicorn/MipsConst.java | 0 .../main/java}/unicorn/MmioReadHandler.java | 0 .../main/java}/unicorn/MmioWriteHandler.java | 0 .../{ => src/main/java}/unicorn/OutHook.java | 0 .../{ => src/main/java}/unicorn/PpcConst.java | 0 .../main/java}/unicorn/RiscvConst.java | 0 .../main/java}/unicorn/S390xConst.java | 0 .../main/java}/unicorn/SparcConst.java | 0 .../main/java}/unicorn/SyscallHook.java | 0 .../main/java}/unicorn/TcgOpcodeHook.java | 0 .../main/java}/unicorn/TlbFillHook.java | 0 .../main/java}/unicorn/TranslationBlock.java | 0 .../main/java}/unicorn/TriCoreConst.java | 0 .../{ => src/main/java}/unicorn/Unicorn.java | 0 .../main/java}/unicorn/UnicornConst.java | 2 + .../main/java}/unicorn/UnicornException.java | 0 .../{ => src/main/java}/unicorn/X86Const.java | 0 .../main/java}/unicorn/X86_Float80.java | 0 .../{ => src/main/java}/unicorn/X86_MMR.java | 0 .../{ => src/main/java}/unicorn/X86_MSR.java | 0 .../java}/samples/SampleNetworkAuditing.java | 0 .../test/java}/samples/Sample_arm.java | 0 .../test/java}/samples/Sample_arm64.java | 0 .../test/java}/samples/Sample_ctl.java | 0 .../test/java}/samples/Sample_m68k.java | 0 .../test/java}/samples/Sample_mips.java | 0 .../test/java}/samples/Sample_mmu.java | 0 .../test/java}/samples/Sample_ppc.java | 0 .../test/java}/samples/Sample_riscv.java | 0 .../test/java}/samples/Sample_s390x.java | 0 .../test/java}/samples/Sample_sparc.java | 0 .../test/java}/samples/Sample_tricore.java | 0 .../test/java}/samples/Sample_x86.java | 0 .../test/java}/samples/Sample_x86_mmr.java | 0 .../test/java}/samples/Shellcode.java | 0 .../{ => src/test/java}/samples/Utils.java | 0 .../test/java}/tests/FunctionalityTests.java | 0 .../{ => src/test/java}/tests/HookTests.java | 0 .../{ => src/test/java}/tests/MemTests.java | 0 .../{ => src/test/java}/tests/RegTests.java | 0 .../test/java}/tests/RegressionTests.java | 0 .../test/java}/tests/TestSamples.java | 0 bindings/java/testdep/hamcrest-2.2.jar | Bin 123360 -> 0 bytes bindings/java/testdep/junit-4.13.2.jar | Bin 384581 -> 0 bytes 69 files changed, 155 insertions(+), 100 deletions(-) create mode 100644 bindings/java/.gitignore delete mode 100644 bindings/java/README.TXT create mode 100644 bindings/java/README.md create mode 100644 bindings/java/pom.xml rename bindings/java/{ => src/main/java}/unicorn/Arm64Const.java (100%) rename bindings/java/{ => src/main/java}/unicorn/Arm64SysHook.java (100%) rename bindings/java/{ => src/main/java}/unicorn/Arm64_CP.java (100%) rename bindings/java/{ => src/main/java}/unicorn/ArmConst.java (100%) rename bindings/java/{ => src/main/java}/unicorn/Arm_CP.java (100%) rename bindings/java/{ => src/main/java}/unicorn/BlockHook.java (100%) rename bindings/java/{ => src/main/java}/unicorn/CodeHook.java (100%) rename bindings/java/{ => src/main/java}/unicorn/CpuidHook.java (100%) rename bindings/java/{ => src/main/java}/unicorn/EdgeGeneratedHook.java (100%) rename bindings/java/{ => src/main/java}/unicorn/EventMemHook.java (100%) rename bindings/java/{ => src/main/java}/unicorn/Hook.java (100%) rename bindings/java/{ => src/main/java}/unicorn/InHook.java (100%) rename bindings/java/{ => src/main/java}/unicorn/InstructionHook.java (100%) rename bindings/java/{ => src/main/java}/unicorn/InterruptHook.java (100%) rename bindings/java/{ => src/main/java}/unicorn/InvalidInstructionHook.java (100%) rename bindings/java/{ => src/main/java}/unicorn/M68kConst.java (100%) rename bindings/java/{ => src/main/java}/unicorn/MemHook.java (100%) rename bindings/java/{ => src/main/java}/unicorn/MemRegion.java (100%) rename bindings/java/{ => src/main/java}/unicorn/MipsConst.java (100%) rename bindings/java/{ => src/main/java}/unicorn/MmioReadHandler.java (100%) rename bindings/java/{ => src/main/java}/unicorn/MmioWriteHandler.java (100%) rename bindings/java/{ => src/main/java}/unicorn/OutHook.java (100%) rename bindings/java/{ => src/main/java}/unicorn/PpcConst.java (100%) rename bindings/java/{ => src/main/java}/unicorn/RiscvConst.java (100%) rename bindings/java/{ => src/main/java}/unicorn/S390xConst.java (100%) rename bindings/java/{ => src/main/java}/unicorn/SparcConst.java (100%) rename bindings/java/{ => src/main/java}/unicorn/SyscallHook.java (100%) rename bindings/java/{ => src/main/java}/unicorn/TcgOpcodeHook.java (100%) rename bindings/java/{ => src/main/java}/unicorn/TlbFillHook.java (100%) rename bindings/java/{ => src/main/java}/unicorn/TranslationBlock.java (100%) rename bindings/java/{ => src/main/java}/unicorn/TriCoreConst.java (100%) rename bindings/java/{ => src/main/java}/unicorn/Unicorn.java (100%) rename bindings/java/{ => src/main/java}/unicorn/UnicornConst.java (98%) rename bindings/java/{ => src/main/java}/unicorn/UnicornException.java (100%) rename bindings/java/{ => src/main/java}/unicorn/X86Const.java (100%) rename bindings/java/{ => src/main/java}/unicorn/X86_Float80.java (100%) rename bindings/java/{ => src/main/java}/unicorn/X86_MMR.java (100%) rename bindings/java/{ => src/main/java}/unicorn/X86_MSR.java (100%) rename bindings/java/{ => src/test/java}/samples/SampleNetworkAuditing.java (100%) rename bindings/java/{ => src/test/java}/samples/Sample_arm.java (100%) rename bindings/java/{ => src/test/java}/samples/Sample_arm64.java (100%) rename bindings/java/{ => src/test/java}/samples/Sample_ctl.java (100%) rename bindings/java/{ => src/test/java}/samples/Sample_m68k.java (100%) rename bindings/java/{ => src/test/java}/samples/Sample_mips.java (100%) rename bindings/java/{ => src/test/java}/samples/Sample_mmu.java (100%) rename bindings/java/{ => src/test/java}/samples/Sample_ppc.java (100%) rename bindings/java/{ => src/test/java}/samples/Sample_riscv.java (100%) rename bindings/java/{ => src/test/java}/samples/Sample_s390x.java (100%) rename bindings/java/{ => src/test/java}/samples/Sample_sparc.java (100%) rename bindings/java/{ => src/test/java}/samples/Sample_tricore.java (100%) rename bindings/java/{ => src/test/java}/samples/Sample_x86.java (100%) rename bindings/java/{ => src/test/java}/samples/Sample_x86_mmr.java (100%) rename bindings/java/{ => src/test/java}/samples/Shellcode.java (100%) rename bindings/java/{ => src/test/java}/samples/Utils.java (100%) rename bindings/java/{ => src/test/java}/tests/FunctionalityTests.java (100%) rename bindings/java/{ => src/test/java}/tests/HookTests.java (100%) rename bindings/java/{ => src/test/java}/tests/MemTests.java (100%) rename bindings/java/{ => src/test/java}/tests/RegTests.java (100%) rename bindings/java/{ => src/test/java}/tests/RegressionTests.java (100%) rename bindings/java/{ => src/test/java}/tests/TestSamples.java (100%) delete mode 100644 bindings/java/testdep/hamcrest-2.2.jar delete mode 100644 bindings/java/testdep/junit-4.13.2.jar diff --git a/.gitignore b/.gitignore index ced6f437..63239606 100644 --- a/.gitignore +++ b/.gitignore @@ -45,7 +45,6 @@ _*.txt _*.diff tmp/ -bindings/java/unicorn_Unicorn.h bindings/python/build/ bindings/python/dist/ bindings/python/src/ diff --git a/bindings/const_generator.py b/bindings/const_generator.py index 00096c6d..40e02048 100644 --- a/bindings/const_generator.py +++ b/bindings/const_generator.py @@ -73,7 +73,7 @@ template = { 'header': "// For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT\n\npackage unicorn;\n\npublic interface %sConst {\n", 'footer': "\n}\n", 'line_format': ' public static final int UC_%s = %s;\n', - 'out_file': './java/unicorn/%sConst.java', + 'out_file': './java/src/main/java/unicorn/%sConst.java', # prefixes for constant filenames of all archs - case sensitive 'arm.h': 'Arm', 'arm64.h': 'Arm64', diff --git a/bindings/java/.gitignore b/bindings/java/.gitignore new file mode 100644 index 00000000..b2a1df87 --- /dev/null +++ b/bindings/java/.gitignore @@ -0,0 +1,2 @@ +target/ +unicorn_Unicorn.h diff --git a/bindings/java/Makefile b/bindings/java/Makefile index 7fb72495..9dae6098 100644 --- a/bindings/java/Makefile +++ b/bindings/java/Makefile @@ -1,18 +1,14 @@ -all: jar lib samples +# Makefile for the native JNI library. Automatically called by Maven. -JC=javac +JAVA_HOME ?= $(shell java -XshowSettings:properties -version 2>&1 | sed -n 's/ *java.home = //p') -JAVA_HOME := $(shell readlink -f `which $(JC)` | sed "s:/bin/$(JC)::") - -JAVA_INC := $(shell realpath $(JAVA_HOME)/include) +ifeq ($(JAVA_HOME),) + $(error JAVA_HOME could not be determined; please set it manually (make JAVA_HOME=...)) +endif +JAVA_INC := $(JAVA_HOME)/include JAVA_PLATFORM_INC := $(shell dirname `find $(JAVA_INC) -name jni_md.h`) - -UNICORN_INC=../../include - -SAMPLES := $(shell ls samples/*.java) -TESTS := $(shell ls tests/*.java) -SRC := $(shell ls unicorn/*.java) +UNICORN_INC := ../../include OS := $(shell uname) ifeq ($(OS),Darwin) @@ -23,67 +19,29 @@ else LIB_EXT=.dll endif +all: libunicorn_java$(LIB_EXT) + CC=gcc CFLAGS=-fPIC LDFLAGS=-shared -fPIC -LIBS=-lunicorn -LIBDIR=-L../../ +# May also use -lunicorn to dynamically link against the installed unicorn +LIBS=../../build/libunicorn.a INCS=-I$(JAVA_INC) -I$(JAVA_PLATFORM_INC) -I$(UNICORN_INC) -CLASSPATH=./ - -.SUFFIXES: .java .class - -tests/%.class: tests/%.java - $(JC) -Xlint:deprecation -classpath .:unicorn.jar:testdep/junit-4.13.2.jar $(JFLAGS) $< - -%.class: %.java - $(JC) -Xlint:deprecation -classpath .:unicorn.jar $(JFLAGS) $< - OBJS=unicorn_Unicorn.o -JARFILE=unicorn.jar - -%.o: %.c - $(CC) -c $(CFLAGS) $(INCS) $< -o $@ - -unicorn_Unicorn.h: unicorn/Unicorn.java - $(JC) -h . $< +unicorn_Unicorn.h: src/main/java/unicorn/Unicorn.java + javah -cp src/main/java -o $@ unicorn.Unicorn unicorn_Unicorn.o: unicorn_Unicorn.c unicorn_Unicorn.h $(CC) -O2 -Wall -Wextra -Wno-unused-parameter -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) -tests: $(TESTS:.java=.class) -jarfiles: $(SRC:.java=.class) - -jar: jarfiles - jar cf $(JARFILE) unicorn/*.class - -test: lib samples tests - java -Xcheck:jni -cp .:testdep/hamcrest-2.2.jar:testdep/junit-4.13.2.jar org.junit.runner.JUnitCore $(subst /,.,$(TESTS:.java=)) - -install: lib jar - cp libunicorn_java$(LIB_EXT) /usr/lib - cp $(JARFILE) /usr/share/java - -uninstall: - rm -f /usr/lib/libunicorn_java$(LIB_EXT) - rm -f /usr/share/java/$(JARFILE) - -gen_const: - cd .. && python3 const_generator.py java +libunicorn_java$(LIB_EXT): $(OBJS) + $(CC) -o $@ $(LDFLAGS) $(OBJS) $(LIBS) clean: - rm -f unicorn/*.class - rm -f samples/*.class - rm -f *.so - rm -f *.dylib - rm -f *.dll + rm -f libunicorn_java$(LIB_EXT) + rm -f unicorn_Unicorn.h + rm -f $(OBJS) -.PHONY: all lib samples jar install uninstall gen_const clean +.PHONY: all clean diff --git a/bindings/java/README.TXT b/bindings/java/README.TXT deleted file mode 100644 index 471adb18..00000000 --- a/bindings/java/README.TXT +++ /dev/null @@ -1,37 +0,0 @@ -This documentation explains how to install the Java binding for Unicorn -from source. - -0. Install the core engine as dependency - - Follow README in the root directory to compile & install the core. - - On *nix, this can simply done by: - - $ sudo ./make.sh install - - -1. Install a JDK for your platform. When done, make sure the JDK tools - are in your PATH. - -2. Change directories into the java bindings, build and install - - $ cd bindings/java - $ make - $ sudo make install - $ make samples - -The samples directory contains some sample code to show how to use Unicorn API. - -- Sample_.java - These show how to access architecture-specific information for each - architecture. - -- Shellcode.java - This shows how to analyze a Linux shellcode. - -- SampleNetworkAuditing.java - Unicorn sample for auditing network connection and file handling in shellcode. - -To uninstall Java binding for Unicorn: - - $ sudo make uninstall diff --git a/bindings/java/README.md b/bindings/java/README.md new file mode 100644 index 00000000..e25827a4 --- /dev/null +++ b/bindings/java/README.md @@ -0,0 +1,39 @@ +This documentation explains how to install the Java binding for Unicorn +from source. + +0. Follow `docs/COMPILE.md` in the root directory to compile the core to the `build` directory. + + Note: by default, the Java binding native library will be built by statically linking to + `../../build/libunicorn.a`, thereby removing `libunicorn` as a runtime dependency, but + making the produced native library `libunicorn_java` bigger. + + If you instead want to dynamically link against the installed `libunicorn`, change + `LIBS=../../build/libunicorn.a` to `LIBS=-lunicorn` in `Makefile`. + +1. Install a JDK for your platform. + +2. Install Maven: https://maven.apache.org/install.html. + +3. Change directories into the java bindings and build the Maven package: + + $ mvn package + +This will automatically build and test the Unicorn Java bindings. + +The bindings consist of the native JNI library (`libunicorn_java.{so,dylib,dll}`) +and the Java JAR (`target/unicorn-2.xx.jar`). You will need to have the native +library on `java.library.path` and the JAR on your classpath. + +The `src/main/test/java` directory contains some sample code to show how to use Unicorn API. +`samples` is a set of sample classes showcasing the various features of the Unicorn API, +while `tests` is a set of JUnit tests for the API. + +- `Sample_.java`: + These show how to access architecture-specific information for each + architecture. + +- `Shellcode.java`: + This shows how to analyze a Linux shellcode. + +- `SampleNetworkAuditing.java`: + Unicorn sample for auditing network connection and file handling in shellcode. diff --git a/bindings/java/pom.xml b/bindings/java/pom.xml new file mode 100644 index 00000000..fa5da8f2 --- /dev/null +++ b/bindings/java/pom.xml @@ -0,0 +1,92 @@ + + + + 4.0.0 + + org.unicorn-engine + unicorn + 2.0 + + unicorn + https://www.unicorn-engine.org + + + UTF-8 + 1.8 + 1.8 + + + + + junit + junit + 4.13.2 + test + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.11.0 + + + + + + org.codehaus.mojo + exec-maven-plugin + 3.1.0 + + + generate-consts + generate-sources + + exec + + + python3 + + const_generator.py + java + + ${project.basedir}/.. + + + + compile-jni-lib + compile + + exec + + + make + + JAVA_HOME=${java.home} + all + + + + + clean-jni-lib + clean + + exec + + + make + + clean + + + + + + + + + diff --git a/bindings/java/unicorn/Arm64Const.java b/bindings/java/src/main/java/unicorn/Arm64Const.java similarity index 100% rename from bindings/java/unicorn/Arm64Const.java rename to bindings/java/src/main/java/unicorn/Arm64Const.java diff --git a/bindings/java/unicorn/Arm64SysHook.java b/bindings/java/src/main/java/unicorn/Arm64SysHook.java similarity index 100% rename from bindings/java/unicorn/Arm64SysHook.java rename to bindings/java/src/main/java/unicorn/Arm64SysHook.java diff --git a/bindings/java/unicorn/Arm64_CP.java b/bindings/java/src/main/java/unicorn/Arm64_CP.java similarity index 100% rename from bindings/java/unicorn/Arm64_CP.java rename to bindings/java/src/main/java/unicorn/Arm64_CP.java diff --git a/bindings/java/unicorn/ArmConst.java b/bindings/java/src/main/java/unicorn/ArmConst.java similarity index 100% rename from bindings/java/unicorn/ArmConst.java rename to bindings/java/src/main/java/unicorn/ArmConst.java diff --git a/bindings/java/unicorn/Arm_CP.java b/bindings/java/src/main/java/unicorn/Arm_CP.java similarity index 100% rename from bindings/java/unicorn/Arm_CP.java rename to bindings/java/src/main/java/unicorn/Arm_CP.java diff --git a/bindings/java/unicorn/BlockHook.java b/bindings/java/src/main/java/unicorn/BlockHook.java similarity index 100% rename from bindings/java/unicorn/BlockHook.java rename to bindings/java/src/main/java/unicorn/BlockHook.java diff --git a/bindings/java/unicorn/CodeHook.java b/bindings/java/src/main/java/unicorn/CodeHook.java similarity index 100% rename from bindings/java/unicorn/CodeHook.java rename to bindings/java/src/main/java/unicorn/CodeHook.java diff --git a/bindings/java/unicorn/CpuidHook.java b/bindings/java/src/main/java/unicorn/CpuidHook.java similarity index 100% rename from bindings/java/unicorn/CpuidHook.java rename to bindings/java/src/main/java/unicorn/CpuidHook.java diff --git a/bindings/java/unicorn/EdgeGeneratedHook.java b/bindings/java/src/main/java/unicorn/EdgeGeneratedHook.java similarity index 100% rename from bindings/java/unicorn/EdgeGeneratedHook.java rename to bindings/java/src/main/java/unicorn/EdgeGeneratedHook.java diff --git a/bindings/java/unicorn/EventMemHook.java b/bindings/java/src/main/java/unicorn/EventMemHook.java similarity index 100% rename from bindings/java/unicorn/EventMemHook.java rename to bindings/java/src/main/java/unicorn/EventMemHook.java diff --git a/bindings/java/unicorn/Hook.java b/bindings/java/src/main/java/unicorn/Hook.java similarity index 100% rename from bindings/java/unicorn/Hook.java rename to bindings/java/src/main/java/unicorn/Hook.java diff --git a/bindings/java/unicorn/InHook.java b/bindings/java/src/main/java/unicorn/InHook.java similarity index 100% rename from bindings/java/unicorn/InHook.java rename to bindings/java/src/main/java/unicorn/InHook.java diff --git a/bindings/java/unicorn/InstructionHook.java b/bindings/java/src/main/java/unicorn/InstructionHook.java similarity index 100% rename from bindings/java/unicorn/InstructionHook.java rename to bindings/java/src/main/java/unicorn/InstructionHook.java diff --git a/bindings/java/unicorn/InterruptHook.java b/bindings/java/src/main/java/unicorn/InterruptHook.java similarity index 100% rename from bindings/java/unicorn/InterruptHook.java rename to bindings/java/src/main/java/unicorn/InterruptHook.java diff --git a/bindings/java/unicorn/InvalidInstructionHook.java b/bindings/java/src/main/java/unicorn/InvalidInstructionHook.java similarity index 100% rename from bindings/java/unicorn/InvalidInstructionHook.java rename to bindings/java/src/main/java/unicorn/InvalidInstructionHook.java diff --git a/bindings/java/unicorn/M68kConst.java b/bindings/java/src/main/java/unicorn/M68kConst.java similarity index 100% rename from bindings/java/unicorn/M68kConst.java rename to bindings/java/src/main/java/unicorn/M68kConst.java diff --git a/bindings/java/unicorn/MemHook.java b/bindings/java/src/main/java/unicorn/MemHook.java similarity index 100% rename from bindings/java/unicorn/MemHook.java rename to bindings/java/src/main/java/unicorn/MemHook.java diff --git a/bindings/java/unicorn/MemRegion.java b/bindings/java/src/main/java/unicorn/MemRegion.java similarity index 100% rename from bindings/java/unicorn/MemRegion.java rename to bindings/java/src/main/java/unicorn/MemRegion.java diff --git a/bindings/java/unicorn/MipsConst.java b/bindings/java/src/main/java/unicorn/MipsConst.java similarity index 100% rename from bindings/java/unicorn/MipsConst.java rename to bindings/java/src/main/java/unicorn/MipsConst.java diff --git a/bindings/java/unicorn/MmioReadHandler.java b/bindings/java/src/main/java/unicorn/MmioReadHandler.java similarity index 100% rename from bindings/java/unicorn/MmioReadHandler.java rename to bindings/java/src/main/java/unicorn/MmioReadHandler.java diff --git a/bindings/java/unicorn/MmioWriteHandler.java b/bindings/java/src/main/java/unicorn/MmioWriteHandler.java similarity index 100% rename from bindings/java/unicorn/MmioWriteHandler.java rename to bindings/java/src/main/java/unicorn/MmioWriteHandler.java diff --git a/bindings/java/unicorn/OutHook.java b/bindings/java/src/main/java/unicorn/OutHook.java similarity index 100% rename from bindings/java/unicorn/OutHook.java rename to bindings/java/src/main/java/unicorn/OutHook.java diff --git a/bindings/java/unicorn/PpcConst.java b/bindings/java/src/main/java/unicorn/PpcConst.java similarity index 100% rename from bindings/java/unicorn/PpcConst.java rename to bindings/java/src/main/java/unicorn/PpcConst.java diff --git a/bindings/java/unicorn/RiscvConst.java b/bindings/java/src/main/java/unicorn/RiscvConst.java similarity index 100% rename from bindings/java/unicorn/RiscvConst.java rename to bindings/java/src/main/java/unicorn/RiscvConst.java diff --git a/bindings/java/unicorn/S390xConst.java b/bindings/java/src/main/java/unicorn/S390xConst.java similarity index 100% rename from bindings/java/unicorn/S390xConst.java rename to bindings/java/src/main/java/unicorn/S390xConst.java diff --git a/bindings/java/unicorn/SparcConst.java b/bindings/java/src/main/java/unicorn/SparcConst.java similarity index 100% rename from bindings/java/unicorn/SparcConst.java rename to bindings/java/src/main/java/unicorn/SparcConst.java diff --git a/bindings/java/unicorn/SyscallHook.java b/bindings/java/src/main/java/unicorn/SyscallHook.java similarity index 100% rename from bindings/java/unicorn/SyscallHook.java rename to bindings/java/src/main/java/unicorn/SyscallHook.java diff --git a/bindings/java/unicorn/TcgOpcodeHook.java b/bindings/java/src/main/java/unicorn/TcgOpcodeHook.java similarity index 100% rename from bindings/java/unicorn/TcgOpcodeHook.java rename to bindings/java/src/main/java/unicorn/TcgOpcodeHook.java diff --git a/bindings/java/unicorn/TlbFillHook.java b/bindings/java/src/main/java/unicorn/TlbFillHook.java similarity index 100% rename from bindings/java/unicorn/TlbFillHook.java rename to bindings/java/src/main/java/unicorn/TlbFillHook.java diff --git a/bindings/java/unicorn/TranslationBlock.java b/bindings/java/src/main/java/unicorn/TranslationBlock.java similarity index 100% rename from bindings/java/unicorn/TranslationBlock.java rename to bindings/java/src/main/java/unicorn/TranslationBlock.java diff --git a/bindings/java/unicorn/TriCoreConst.java b/bindings/java/src/main/java/unicorn/TriCoreConst.java similarity index 100% rename from bindings/java/unicorn/TriCoreConst.java rename to bindings/java/src/main/java/unicorn/TriCoreConst.java diff --git a/bindings/java/unicorn/Unicorn.java b/bindings/java/src/main/java/unicorn/Unicorn.java similarity index 100% rename from bindings/java/unicorn/Unicorn.java rename to bindings/java/src/main/java/unicorn/Unicorn.java diff --git a/bindings/java/unicorn/UnicornConst.java b/bindings/java/src/main/java/unicorn/UnicornConst.java similarity index 98% rename from bindings/java/unicorn/UnicornConst.java rename to bindings/java/src/main/java/unicorn/UnicornConst.java index 24d58c26..8ab6fdb1 100644 --- a/bindings/java/unicorn/UnicornConst.java +++ b/bindings/java/src/main/java/unicorn/UnicornConst.java @@ -77,6 +77,7 @@ public interface UnicornConst { public static final int UC_ERR_HOOK_EXIST = 19; public static final int UC_ERR_RESOURCE = 20; public static final int UC_ERR_EXCEPTION = 21; + public static final int UC_ERR_OVERFLOW = 22; public static final int UC_MEM_READ = 16; public static final int UC_MEM_WRITE = 17; public static final int UC_MEM_FETCH = 18; @@ -142,6 +143,7 @@ public interface UnicornConst { public static final int UC_CTL_TB_FLUSH = 10; public static final int UC_CTL_TLB_FLUSH = 11; public static final int UC_CTL_TLB_TYPE = 12; + public static final int UC_CTL_TCG_BUFFER_SIZE = 13; public static final int UC_PROT_NONE = 0; public static final int UC_PROT_READ = 1; diff --git a/bindings/java/unicorn/UnicornException.java b/bindings/java/src/main/java/unicorn/UnicornException.java similarity index 100% rename from bindings/java/unicorn/UnicornException.java rename to bindings/java/src/main/java/unicorn/UnicornException.java diff --git a/bindings/java/unicorn/X86Const.java b/bindings/java/src/main/java/unicorn/X86Const.java similarity index 100% rename from bindings/java/unicorn/X86Const.java rename to bindings/java/src/main/java/unicorn/X86Const.java diff --git a/bindings/java/unicorn/X86_Float80.java b/bindings/java/src/main/java/unicorn/X86_Float80.java similarity index 100% rename from bindings/java/unicorn/X86_Float80.java rename to bindings/java/src/main/java/unicorn/X86_Float80.java diff --git a/bindings/java/unicorn/X86_MMR.java b/bindings/java/src/main/java/unicorn/X86_MMR.java similarity index 100% rename from bindings/java/unicorn/X86_MMR.java rename to bindings/java/src/main/java/unicorn/X86_MMR.java diff --git a/bindings/java/unicorn/X86_MSR.java b/bindings/java/src/main/java/unicorn/X86_MSR.java similarity index 100% rename from bindings/java/unicorn/X86_MSR.java rename to bindings/java/src/main/java/unicorn/X86_MSR.java diff --git a/bindings/java/samples/SampleNetworkAuditing.java b/bindings/java/src/test/java/samples/SampleNetworkAuditing.java similarity index 100% rename from bindings/java/samples/SampleNetworkAuditing.java rename to bindings/java/src/test/java/samples/SampleNetworkAuditing.java diff --git a/bindings/java/samples/Sample_arm.java b/bindings/java/src/test/java/samples/Sample_arm.java similarity index 100% rename from bindings/java/samples/Sample_arm.java rename to bindings/java/src/test/java/samples/Sample_arm.java diff --git a/bindings/java/samples/Sample_arm64.java b/bindings/java/src/test/java/samples/Sample_arm64.java similarity index 100% rename from bindings/java/samples/Sample_arm64.java rename to bindings/java/src/test/java/samples/Sample_arm64.java diff --git a/bindings/java/samples/Sample_ctl.java b/bindings/java/src/test/java/samples/Sample_ctl.java similarity index 100% rename from bindings/java/samples/Sample_ctl.java rename to bindings/java/src/test/java/samples/Sample_ctl.java diff --git a/bindings/java/samples/Sample_m68k.java b/bindings/java/src/test/java/samples/Sample_m68k.java similarity index 100% rename from bindings/java/samples/Sample_m68k.java rename to bindings/java/src/test/java/samples/Sample_m68k.java diff --git a/bindings/java/samples/Sample_mips.java b/bindings/java/src/test/java/samples/Sample_mips.java similarity index 100% rename from bindings/java/samples/Sample_mips.java rename to bindings/java/src/test/java/samples/Sample_mips.java diff --git a/bindings/java/samples/Sample_mmu.java b/bindings/java/src/test/java/samples/Sample_mmu.java similarity index 100% rename from bindings/java/samples/Sample_mmu.java rename to bindings/java/src/test/java/samples/Sample_mmu.java diff --git a/bindings/java/samples/Sample_ppc.java b/bindings/java/src/test/java/samples/Sample_ppc.java similarity index 100% rename from bindings/java/samples/Sample_ppc.java rename to bindings/java/src/test/java/samples/Sample_ppc.java diff --git a/bindings/java/samples/Sample_riscv.java b/bindings/java/src/test/java/samples/Sample_riscv.java similarity index 100% rename from bindings/java/samples/Sample_riscv.java rename to bindings/java/src/test/java/samples/Sample_riscv.java diff --git a/bindings/java/samples/Sample_s390x.java b/bindings/java/src/test/java/samples/Sample_s390x.java similarity index 100% rename from bindings/java/samples/Sample_s390x.java rename to bindings/java/src/test/java/samples/Sample_s390x.java diff --git a/bindings/java/samples/Sample_sparc.java b/bindings/java/src/test/java/samples/Sample_sparc.java similarity index 100% rename from bindings/java/samples/Sample_sparc.java rename to bindings/java/src/test/java/samples/Sample_sparc.java diff --git a/bindings/java/samples/Sample_tricore.java b/bindings/java/src/test/java/samples/Sample_tricore.java similarity index 100% rename from bindings/java/samples/Sample_tricore.java rename to bindings/java/src/test/java/samples/Sample_tricore.java diff --git a/bindings/java/samples/Sample_x86.java b/bindings/java/src/test/java/samples/Sample_x86.java similarity index 100% rename from bindings/java/samples/Sample_x86.java rename to bindings/java/src/test/java/samples/Sample_x86.java diff --git a/bindings/java/samples/Sample_x86_mmr.java b/bindings/java/src/test/java/samples/Sample_x86_mmr.java similarity index 100% rename from bindings/java/samples/Sample_x86_mmr.java rename to bindings/java/src/test/java/samples/Sample_x86_mmr.java diff --git a/bindings/java/samples/Shellcode.java b/bindings/java/src/test/java/samples/Shellcode.java similarity index 100% rename from bindings/java/samples/Shellcode.java rename to bindings/java/src/test/java/samples/Shellcode.java diff --git a/bindings/java/samples/Utils.java b/bindings/java/src/test/java/samples/Utils.java similarity index 100% rename from bindings/java/samples/Utils.java rename to bindings/java/src/test/java/samples/Utils.java diff --git a/bindings/java/tests/FunctionalityTests.java b/bindings/java/src/test/java/tests/FunctionalityTests.java similarity index 100% rename from bindings/java/tests/FunctionalityTests.java rename to bindings/java/src/test/java/tests/FunctionalityTests.java diff --git a/bindings/java/tests/HookTests.java b/bindings/java/src/test/java/tests/HookTests.java similarity index 100% rename from bindings/java/tests/HookTests.java rename to bindings/java/src/test/java/tests/HookTests.java diff --git a/bindings/java/tests/MemTests.java b/bindings/java/src/test/java/tests/MemTests.java similarity index 100% rename from bindings/java/tests/MemTests.java rename to bindings/java/src/test/java/tests/MemTests.java diff --git a/bindings/java/tests/RegTests.java b/bindings/java/src/test/java/tests/RegTests.java similarity index 100% rename from bindings/java/tests/RegTests.java rename to bindings/java/src/test/java/tests/RegTests.java diff --git a/bindings/java/tests/RegressionTests.java b/bindings/java/src/test/java/tests/RegressionTests.java similarity index 100% rename from bindings/java/tests/RegressionTests.java rename to bindings/java/src/test/java/tests/RegressionTests.java diff --git a/bindings/java/tests/TestSamples.java b/bindings/java/src/test/java/tests/TestSamples.java similarity index 100% rename from bindings/java/tests/TestSamples.java rename to bindings/java/src/test/java/tests/TestSamples.java diff --git a/bindings/java/testdep/hamcrest-2.2.jar b/bindings/java/testdep/hamcrest-2.2.jar deleted file mode 100644 index 71065788d5fea769e71107e3f9641e23a48d29c6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 123360 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 z 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 diff --git a/bindings/java/testdep/junit-4.13.2.jar b/bindings/java/testdep/junit-4.13.2.jar deleted file mode 100644 index 6da55d8b8520dcc03c250a605151cc0d23a45518..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 384581 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%0A|RLyRTZ?5*b0Kn~9_w90>zXi(v|D#%u(jz#g2 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 oKveFPto?=7N*A1c2%g| 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

    `)ZZo?PM~)f*OI;Nlt*N`a@~;G*&9Se} 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

    J{i)CW|Vyp#u)ncg$RUOm9KuH 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Π`%iO}aP>9yumW1a!ct~f>0 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 Date: Thu, 29 Jun 2023 16:37:42 -0700 Subject: [PATCH 24/25] Switch Java bindings to reg2 API. This is mostly an extra safety measure; the front-end Unicorn.java should always be sending an appropriately-sized buffer. --- bindings/java/unicorn_Unicorn.c | 54 +++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 20 deletions(-) diff --git a/bindings/java/unicorn_Unicorn.c b/bindings/java/unicorn_Unicorn.c index 86ca7e21..61cf93ba 100644 --- a/bindings/java/unicorn_Unicorn.c +++ b/bindings/java/unicorn_Unicorn.c @@ -473,22 +473,22 @@ JNIEXPORT void JNICALL Java_unicorn_Unicorn__1emu_1stop(JNIEnv *env, } static uc_err generic_reg_read(jlong ptr, jint isContext, jint regid, - void *result) + void *result, size_t *size) { if (isContext) { - return uc_context_reg_read((uc_context *)ptr, regid, result); + return uc_context_reg_read2((uc_context *)ptr, regid, result, size); } else { - return uc_reg_read((uc_engine *)ptr, regid, result); + return uc_reg_read2((uc_engine *)ptr, regid, result, size); } } static uc_err generic_reg_write(jlong ptr, jint isContext, jint regid, - const void *value) + const void *value, size_t *size) { if (isContext) { - return uc_context_reg_write((uc_context *)ptr, regid, value); + return uc_context_reg_write2((uc_context *)ptr, regid, value, size); } else { - return uc_reg_write((uc_engine *)ptr, regid, value); + return uc_reg_write2((uc_engine *)ptr, regid, value, size); } } @@ -500,10 +500,11 @@ static uc_err generic_reg_write(jlong ptr, jint isContext, jint regid, JNIEXPORT jlong JNICALL Java_unicorn_Unicorn__1reg_1read_1long( JNIEnv *env, jclass clazz, jlong ptr, jint isContext, jint regid) { - /* XXX: This is just *wrong* on big-endian hosts, since a register - smaller than 8 bytes will be written into the MSBs. */ uint64_t result = 0; - uc_err err = generic_reg_read(ptr, isContext, regid, &result); + size_t size = 8; + uc_err err = generic_reg_read(ptr, isContext, regid, &result, &size); + /* TODO: If the host is big-endian and size < 8 after the read, + the result must be transposed to the least-significant bytes. */ if (err != UC_ERR_OK) { throwUnicornException(env, err); return 0; @@ -521,7 +522,8 @@ JNIEXPORT void JNICALL Java_unicorn_Unicorn__1reg_1read_1bytes( jbyteArray data) { jbyte *arr = (*env)->GetByteArrayElements(env, data, NULL); - uc_err err = generic_reg_read(ptr, isContext, regid, arr); + size_t size = (*env)->GetArrayLength(env, data); + uc_err err = generic_reg_read(ptr, isContext, regid, arr, &size); (*env)->ReleaseByteArrayElements(env, data, arr, 0); if (err != UC_ERR_OK) { throwUnicornException(env, err); @@ -539,7 +541,10 @@ Java_unicorn_Unicorn__1reg_1write_1long(JNIEnv *env, jclass clazz, jlong ptr, jint isContext, jint regid, jlong value) { uint64_t cvalue = value; - uc_err err = generic_reg_write(ptr, isContext, regid, &cvalue); + size_t size = 8; + uc_err err = generic_reg_write(ptr, isContext, regid, &cvalue, &size); + /* TODO: If the host is big-endian and size < 8 after the write, + we need to redo the write with the pointer shifted appropriately */ if (err != UC_ERR_OK) { throwUnicornException(env, err); return; @@ -556,7 +561,8 @@ JNIEXPORT void JNICALL Java_unicorn_Unicorn__1reg_1write_1bytes( jbyteArray data) { jbyte *arr = (*env)->GetByteArrayElements(env, data, NULL); - uc_err err = generic_reg_write(ptr, isContext, regid, arr); + size_t size = (*env)->GetArrayLength(env, data); + uc_err err = generic_reg_write(ptr, isContext, regid, arr, &size); (*env)->ReleaseByteArrayElements(env, data, arr, JNI_ABORT); if (err != UC_ERR_OK) { throwUnicornException(env, err); @@ -573,7 +579,8 @@ JNIEXPORT jobject JNICALL Java_unicorn_Unicorn__1reg_1read_1x86_1mmr( JNIEnv *env, jclass clazz, jlong ptr, jint isContext, jint regid) { uc_x86_mmr reg = {0}; - uc_err err = generic_reg_read(ptr, isContext, regid, ®); + size_t size = sizeof(reg); + uc_err err = generic_reg_read(ptr, isContext, regid, ®, &size); if (err != UC_ERR_OK) { throwUnicornException(env, err); return 0; @@ -595,7 +602,8 @@ JNIEXPORT void JNICALL Java_unicorn_Unicorn__1reg_1write_1x86_1mmr( reg.base = base; reg.limit = limit; reg.flags = flags; - uc_err err = generic_reg_write(ptr, isContext, regid, ®); + size_t size = sizeof(reg); + uc_err err = generic_reg_write(ptr, isContext, regid, ®, &size); if (err != UC_ERR_OK) { throwUnicornException(env, err); return; @@ -612,7 +620,8 @@ JNIEXPORT jlong JNICALL Java_unicorn_Unicorn__1reg_1read_1x86_1msr( { uc_x86_msr reg = {0}; reg.rid = rid; - uc_err err = generic_reg_read(ptr, isContext, UC_X86_REG_MSR, ®); + size_t size = sizeof(reg); + uc_err err = generic_reg_read(ptr, isContext, UC_X86_REG_MSR, ®, &size); if (err != UC_ERR_OK) { throwUnicornException(env, err); return 0; @@ -631,7 +640,8 @@ JNIEXPORT void JNICALL Java_unicorn_Unicorn__1reg_1write_1x86_1msr( uc_x86_msr reg = {0}; reg.rid = rid; reg.value = value; - uc_err err = generic_reg_write(ptr, isContext, UC_X86_REG_MSR, ®); + size_t size = sizeof(reg); + uc_err err = generic_reg_write(ptr, isContext, UC_X86_REG_MSR, ®, &size); if (err != UC_ERR_OK) { throwUnicornException(env, err); return; @@ -655,7 +665,8 @@ JNIEXPORT jlong JNICALL Java_unicorn_Unicorn__1reg_1read_1arm_1cp( reg.crm = crm; reg.opc1 = opc1; reg.opc2 = opc2; - uc_err err = generic_reg_read(ptr, isContext, UC_ARM_REG_CP_REG, ®); + size_t size = sizeof(reg); + uc_err err = generic_reg_read(ptr, isContext, UC_ARM_REG_CP_REG, ®, &size); if (err != UC_ERR_OK) { throwUnicornException(env, err); return 0; @@ -681,7 +692,8 @@ JNIEXPORT void JNICALL Java_unicorn_Unicorn__1reg_1write_1arm_1cp( reg.opc1 = opc1; reg.opc2 = opc2; reg.val = value; - uc_err err = generic_reg_write(ptr, isContext, UC_ARM_REG_CP_REG, ®); + size_t size = sizeof(reg); + uc_err err = generic_reg_write(ptr, isContext, UC_ARM_REG_CP_REG, ®, &size); if (err != UC_ERR_OK) { throwUnicornException(env, err); return; @@ -703,7 +715,8 @@ JNIEXPORT jlong JNICALL Java_unicorn_Unicorn__1reg_1read_1arm64_1cp( reg.op0 = op0; reg.op1 = op1; reg.op2 = op2; - uc_err err = generic_reg_read(ptr, isContext, UC_ARM64_REG_CP_REG, ®); + size_t size = sizeof(reg); + uc_err err = generic_reg_read(ptr, isContext, UC_ARM64_REG_CP_REG, ®, &size); if (err != UC_ERR_OK) { throwUnicornException(env, err); return 0; @@ -727,7 +740,8 @@ JNIEXPORT void JNICALL Java_unicorn_Unicorn__1reg_1write_1arm64_1cp( reg.op1 = op1; reg.op2 = op2; reg.val = value; - uc_err err = generic_reg_write(ptr, isContext, UC_ARM64_REG_CP_REG, ®); + size_t size = sizeof(reg); + uc_err err = generic_reg_write(ptr, isContext, UC_ARM64_REG_CP_REG, ®, &size); if (err != UC_ERR_OK) { throwUnicornException(env, err); return; From f55e7834ba8b89cdca452ca8cb83299c7a890149 Mon Sep 17 00:00:00 2001 From: Robert Xiao Date: Thu, 6 Jul 2023 20:12:36 -0700 Subject: [PATCH 25/25] Replace javah by javac -h, only write new constant files if something changes. The const_generator changes help to ensure that e.g. Java rebuilds don't keep rebuilding everything. --- bindings/const_generator.py | 18 ++++++++++++++++-- bindings/java/.gitignore | 1 - bindings/java/Makefile | 8 ++------ bindings/java/pom.xml | 6 ++++++ 4 files changed, 24 insertions(+), 9 deletions(-) diff --git a/bindings/const_generator.py b/bindings/const_generator.py index 40e02048..982b48f4 100644 --- a/bindings/const_generator.py +++ b/bindings/const_generator.py @@ -159,8 +159,9 @@ def gen(lang): templ = template[lang] for target in include: prefix = templ[target] - outfile = open(templ['out_file'] %(prefix), 'wb') # open as binary prevents windows newlines - outfile.write((templ['header'] % (prefix)).encode("utf-8")) + outfn = templ['out_file'] % prefix + outfile = open(outfn + ".tmp", 'wb') # open as binary prevents windows newlines + outfile.write((templ['header'] % prefix).encode("utf-8")) if target == 'unicorn.h': prefix = '' with open(os.path.join(INCL_DIR, target)) as f: @@ -278,6 +279,19 @@ def gen(lang): outfile.write((templ['footer']).encode("utf-8")) outfile.close() + if os.path.isfile(outfn): + with open(outfn, "rb") as infile: + cur_data = infile.read() + with open(outfn + ".tmp", "rb") as infile: + new_data = infile.read() + if cur_data == new_data: + os.unlink(outfn + ".tmp") + else: + os.unlink(outfn) + os.rename(outfn + ".tmp", outfn) + else: + os.rename(outfn + ".tmp", outfn) + def main(): lang = sys.argv[1] if lang == "all": diff --git a/bindings/java/.gitignore b/bindings/java/.gitignore index b2a1df87..2f7896d1 100644 --- a/bindings/java/.gitignore +++ b/bindings/java/.gitignore @@ -1,2 +1 @@ target/ -unicorn_Unicorn.h diff --git a/bindings/java/Makefile b/bindings/java/Makefile index 9dae6098..aa3fe7d1 100644 --- a/bindings/java/Makefile +++ b/bindings/java/Makefile @@ -26,14 +26,11 @@ CFLAGS=-fPIC LDFLAGS=-shared -fPIC # May also use -lunicorn to dynamically link against the installed unicorn LIBS=../../build/libunicorn.a -INCS=-I$(JAVA_INC) -I$(JAVA_PLATFORM_INC) -I$(UNICORN_INC) +INCS=-I target/headers -I$(JAVA_INC) -I$(JAVA_PLATFORM_INC) -I$(UNICORN_INC) OBJS=unicorn_Unicorn.o -unicorn_Unicorn.h: src/main/java/unicorn/Unicorn.java - javah -cp src/main/java -o $@ unicorn.Unicorn - -unicorn_Unicorn.o: unicorn_Unicorn.c unicorn_Unicorn.h +unicorn_Unicorn.o: unicorn_Unicorn.c target/headers/unicorn_Unicorn.h $(CC) -O2 -Wall -Wextra -Wno-unused-parameter -c $(CFLAGS) $(INCS) $< -o $@ libunicorn_java$(LIB_EXT): $(OBJS) @@ -41,7 +38,6 @@ libunicorn_java$(LIB_EXT): $(OBJS) clean: rm -f libunicorn_java$(LIB_EXT) - rm -f unicorn_Unicorn.h rm -f $(OBJS) .PHONY: all clean diff --git a/bindings/java/pom.xml b/bindings/java/pom.xml index fa5da8f2..686f7b66 100644 --- a/bindings/java/pom.xml +++ b/bindings/java/pom.xml @@ -33,6 +33,12 @@ org.apache.maven.plugins maven-compiler-plugin 3.11.0 + + + -h + target/headers + +