139 lines
5.3 KiB
Java
139 lines
5.3 KiB
Java
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();
|
|
}
|
|
}
|