Write some code to test out ARM64 CP register handling.
This commit is contained in:
@@ -1,12 +1,14 @@
|
|||||||
package tests;
|
package tests;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNotEquals;
|
||||||
import static org.junit.Assert.assertThrows;
|
import static org.junit.Assert.assertThrows;
|
||||||
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import unicorn.Arm64_CP;
|
||||||
import unicorn.Unicorn;
|
import unicorn.Unicorn;
|
||||||
import unicorn.UnicornException;
|
import unicorn.UnicornException;
|
||||||
import unicorn.X86_Float80;
|
import unicorn.X86_Float80;
|
||||||
@@ -145,4 +147,60 @@ public class RegTests {
|
|||||||
|
|
||||||
uc.close();
|
uc.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testArm64EnablePAC() {
|
||||||
|
// paciza x1
|
||||||
|
final byte[] ARM64_CODE =
|
||||||
|
{ (byte) 0xe1, 0x23, (byte) 0xc1, (byte) 0xda };
|
||||||
|
|
||||||
|
long ADDRESS = 0x100000;
|
||||||
|
|
||||||
|
Unicorn uc = new Unicorn(Unicorn.UC_ARCH_ARM64, Unicorn.UC_MODE_ARM);
|
||||||
|
uc.ctl_set_cpu_model(Unicorn.UC_CPU_ARM64_MAX);
|
||||||
|
uc.mem_map(ADDRESS, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL);
|
||||||
|
uc.mem_write(ADDRESS, ARM64_CODE);
|
||||||
|
|
||||||
|
Arm64_CP sctlr_el3 = new Arm64_CP(1, 1, 3, 6, 0);
|
||||||
|
sctlr_el3.val =
|
||||||
|
(Long) uc.reg_read(Unicorn.UC_ARM64_REG_CP_REG, sctlr_el3);
|
||||||
|
// NS | RW | API
|
||||||
|
sctlr_el3.val |= 1L | (1L << 10) | (1L << 17);
|
||||||
|
uc.reg_write(Unicorn.UC_ARM64_REG_CP_REG, sctlr_el3);
|
||||||
|
sctlr_el3.val =
|
||||||
|
(Long) uc.reg_read(Unicorn.UC_ARM64_REG_CP_REG, sctlr_el3);
|
||||||
|
|
||||||
|
Arm64_CP sctlr_el1 = new Arm64_CP(1, 0, 3, 0, 0);
|
||||||
|
sctlr_el1.val =
|
||||||
|
(Long) uc.reg_read(Unicorn.UC_ARM64_REG_CP_REG, sctlr_el1);
|
||||||
|
// EnIA | EnIB
|
||||||
|
sctlr_el1.val |= (1L << 31) | (1L << 30) | (1L << 27) | (1L << 13);
|
||||||
|
uc.reg_write(Unicorn.UC_ARM64_REG_CP_REG, sctlr_el1);
|
||||||
|
sctlr_el1.val =
|
||||||
|
(Long) uc.reg_read(Unicorn.UC_ARM64_REG_CP_REG, sctlr_el1);
|
||||||
|
|
||||||
|
Arm64_CP hcr_el2 = new Arm64_CP(1, 1, 3, 4, 0);
|
||||||
|
hcr_el2.val =
|
||||||
|
(Long) uc.reg_read(Unicorn.UC_ARM64_REG_CP_REG, hcr_el2);
|
||||||
|
// API
|
||||||
|
hcr_el2.val |= (1L << 41);
|
||||||
|
uc.reg_write(Unicorn.UC_ARM64_REG_CP_REG, hcr_el2);
|
||||||
|
|
||||||
|
Arm64_CP apiakeylo_el1 = new Arm64_CP(2, 1, 3, 0, 0);
|
||||||
|
apiakeylo_el1.val = 0x4141424243434444L;
|
||||||
|
uc.reg_write(Unicorn.UC_ARM64_REG_CP_REG, apiakeylo_el1);
|
||||||
|
|
||||||
|
Arm64_CP apiakeyhi_el1 = new Arm64_CP(2, 1, 3, 0, 1);
|
||||||
|
apiakeyhi_el1.val = 0x1234abcd4444aaaaL;
|
||||||
|
uc.reg_write(Unicorn.UC_ARM64_REG_CP_REG, apiakeyhi_el1);
|
||||||
|
|
||||||
|
uc.reg_write(Unicorn.UC_ARM64_REG_X1, 0x0000bbbbccccddddL);
|
||||||
|
uc.emu_start(ADDRESS, ADDRESS + ARM64_CODE.length, 0, 0);
|
||||||
|
assertNotEquals("X1 should be signed", 0x0000bbbbccccddddL,
|
||||||
|
uc.reg_read(Unicorn.UC_ARM64_REG_X1));
|
||||||
|
assertEquals("X1 low bits should be unchanged", 0x0000bbbbccccddddL,
|
||||||
|
uc.reg_read(Unicorn.UC_ARM64_REG_X1) & 0xffffffffffffL);
|
||||||
|
|
||||||
|
uc.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,10 @@ public class Arm64_CP {
|
|||||||
public int crn, crm, op0, op1, op2;
|
public int crn, crm, op0, op1, op2;
|
||||||
public long val;
|
public long val;
|
||||||
|
|
||||||
|
public Arm64_CP(int crn, int crm, int op0, int op1, int op2) {
|
||||||
|
this(crn, crm, op0, op1, op2, 0);
|
||||||
|
}
|
||||||
|
|
||||||
public Arm64_CP(int crn, int crm, int op0, int op1, int op2, long val) {
|
public Arm64_CP(int crn, int crm, int op0, int op1, int op2, long val) {
|
||||||
this.crn = crn;
|
this.crn = crn;
|
||||||
this.crm = crm;
|
this.crm = crm;
|
||||||
|
|||||||
@@ -5,6 +5,11 @@ public class Arm_CP {
|
|||||||
public int cp, is64, sec, crn, crm, opc1, opc2;
|
public int cp, is64, sec, crn, crm, opc1, opc2;
|
||||||
public long val;
|
public long val;
|
||||||
|
|
||||||
|
public Arm_CP(int cp, int is64, int sec, int crn, int crm, int opc1,
|
||||||
|
int opc2) {
|
||||||
|
this(cp, is64, sec, crn, crm, opc1, opc2, 0);
|
||||||
|
}
|
||||||
|
|
||||||
public Arm_CP(int cp, int is64, int sec, int crn, int crm, int opc1,
|
public Arm_CP(int cp, int is64, int sec, int crn, int crm, int opc1,
|
||||||
int opc2, long val) {
|
int opc2, long val) {
|
||||||
this.cp = cp;
|
this.cp = cp;
|
||||||
|
|||||||
@@ -26,6 +26,10 @@ public class X86_MSR {
|
|||||||
public int rid;
|
public int rid;
|
||||||
public long value;
|
public long value;
|
||||||
|
|
||||||
|
public X86_MSR(int rid) {
|
||||||
|
this(rid, 0);
|
||||||
|
}
|
||||||
|
|
||||||
public X86_MSR(int rid, long value) {
|
public X86_MSR(int rid, long value) {
|
||||||
this.rid = rid;
|
this.rid = rid;
|
||||||
this.value = value;
|
this.value = value;
|
||||||
|
|||||||
Reference in New Issue
Block a user