1#include "r_anal.h" 2static int hack_handle_dp_reg(ut32 insn, RAnalOp *op) { 3 const bool op0 = (insn >> 30) & 0x1; 4 const bool op1 = (insn >> 28) & 0x1; 5 const ut8 op2 = (insn >> 21) & 0xf; 6 7 // Data-processing (2 source) 8 if (!op0 && op1 && op2 == 6) { 9 const bool sf = (insn >> 31) & 0x1; 10 const bool S = (insn >> 29) & 0x1; 11 const ut8 opcode = (insn >> 10) & 0x1f; 12 if (sf) { 13 if (!S) { 14 if (opcode == 4) { 15 // irg 16 op->type = R_ANAL_OP_TYPE_MOV; 17 return op->size = 4; 18 } else if (opcode == 0) { 19 // subp 20 op->type = R_ANAL_OP_TYPE_SUB; 21 return op->size = 4; 22 } else if (opcode == 5) { 23 // gmi 24 op->type = R_ANAL_OP_TYPE_MOV; 25 return op->size = 4; 26 } 27 } else if (S && opcode == 0) { 28 // subps 29 op->type = R_ANAL_OP_TYPE_SUB; 30 return op->size = 4; 31 } 32 } 33 } 34 return -1; 35} 36 37static int hack_handle_ldst(ut32 insn, RAnalOp *op) { 38 const ut8 op0 = (insn >> 28) & 0xf; 39 const bool op1 = (insn >> 26) & 0x1; 40 ut8 op2 = (insn >> 23) & 0x3; 41 const bool op3 = (insn >> 21) & 0x1; 42 43 // Load/store memory tags 44 if (op0 == 13 && !op1 && (op2 == 2 || op2 == 3) && op3) { 45 const ut8 opc = (insn >> 22) & 0x3; 46 op2 = (insn >> 10) & 0x3; 47 if (op2 > 0) { 48 switch (opc) { 49 case 0: 50 // stg 51 op->type = R_ANAL_OP_TYPE_STORE; 52 return op->size = 4; 53 case 1: 54 // stzg 55 op->type = R_ANAL_OP_TYPE_STORE; 56 return op->size = 4; 57 case 2: 58 // st2g 59 op->type = R_ANAL_OP_TYPE_STORE; 60 return op->size = 4; 61 case 3: 62 // stz2g 63 op->type = R_ANAL_OP_TYPE_STORE; 64 return op->size = 4; 65 } 66 } else if (op2 == 0) { 67 switch (opc) { 68 case 0: 69 // stzgm 70 op->type = R_ANAL_OP_TYPE_STORE; 71 return op->size = 4; 72 case 1: 73 // ldg 74 op->type = R_ANAL_OP_TYPE_LOAD; 75 return op->size = 4; 76 case 2: 77 // stgm 78 op->type = R_ANAL_OP_TYPE_STORE; 79 return op->size = 4; 80 case 3: 81 // ldgm 82 op->type = R_ANAL_OP_TYPE_LOAD; 83 return op->size = 4; 84 } 85 } 86 // Load/store register pair 87 } else if ((op0 & 0x3) == 2) { 88 const ut8 opc = (insn >> 30) & 0x3; 89 const bool V = (insn >> 26) & 0x1; 90 const bool L = (insn >> 22) & 0x1; 91 if (opc == 1 && !V && !L) { 92 // stgp 93 op->type = R_ANAL_OP_TYPE_STORE; 94 return op->size = 4; 95 } 96 } 97 return -1; 98} 99 100static int hack_handle_dp_imm(ut32 insn, RAnalOp *op) { 101 const ut8 op0 = (insn >> 23) & 0x7; 102 103 // Add/subtract (immediate, with tags) 104 if (op0 == 3) { 105 const bool sf = (insn >> 31) & 0x1; 106 const bool op_ = (insn >> 30) & 0x1; 107 const bool S = (insn >> 29) & 0x1; 108 const bool o2 = (insn >> 22) & 0x1; 109 if (sf && !S && !o2) { 110 if (op_ ) { 111 // subg 112 op->type = R_ANAL_OP_TYPE_SUB; 113 return op->size = 4; 114 } 115 // addg 116 op->type = R_ANAL_OP_TYPE_ADD; 117 return op->size = 4; 118 } 119 } 120 return -1; 121} 122 123static int hack_handle_br_exc_sys(ut32 insn, RAnalOp *op) { 124 const ut8 op0 = (insn >> 29) & 0x7; 125 const ut16 op1 = (insn >> 12) & 0x3fff; 126 ut8 op2 = insn & 0x1f; 127 128 // Hints 129 if (op0 == 6 && op1 == 4146 && op2 == 31) { 130 const ut8 CRm = (insn >> 8) & 0xf; 131 op2 = (insn >> 5) & 0x7; 132 if (CRm == 4 && (op2 & 1) == 0) { 133 switch (op2) { 134 case 0: 135 case 2: 136 case 4: 137 case 6: 138 op->type = R_ANAL_OP_TYPE_CMP; 139 return op->size = 4; 140 } 141 } 142 } 143 return -1; 144} 145 146static inline int hackyArmAnal(RAnal *a, RAnalOp *op, const ut8 *buf, int len) { 147 int ret = -1; 148 // Hacky support for ARMv8.3 and ARMv8.5 149 if (a->bits == 64 && len >= 4) { 150 ut32 insn = r_read_ble32 (buf, a->big_endian); 151 int insn_class = (insn >> 25) & 0xf; 152 // xpaci // e#43c1da 153 if (!memcmp (buf + 1, "\x43\xc1\xda", 3)) { 154 op->type = R_ANAL_OP_TYPE_MOV; 155 return op->size = 4; 156 } 157 // retaa 158 if (!memcmp (buf, "\xff\x0b\x5f\xd6", 4)) { 159 op->type = R_ANAL_OP_TYPE_RET; 160 return op->size = 4; 161 } 162 // retab 163 if (!memcmp (buf, "\xff\x0f\x5f\xd6", 4)) { 164 op->type = R_ANAL_OP_TYPE_RET; 165 return op->size = 4; 166 } 167 168 switch (insn_class) { 169 // Data Processing -- Register 170 case 5: 171 case 13: 172 // irg, subp, gmi, subps 173 ret = hack_handle_dp_reg (insn, op); 174 break; 175 // Data Processing -- Immediate 176 case 8: 177 case 9: 178 // addg, subg 179 ret = hack_handle_dp_imm (insn, op); 180 break; 181 case 10: 182 case 11: 183 // bti 184 ret = hack_handle_br_exc_sys (insn, op); 185 break; 186 // Loads and Stores 187 case 4: 188 case 6: 189 case 12: 190 case 14: 191 // stg, stzgm, ldg, stzg, st2g, stgm, stz2g, ldgm, stgp 192 ret = hack_handle_ldst (insn, op); 193 break; 194 default: 195 break; 196 } 197 198 if (ret > 0) { 199 op->family = R_ANAL_OP_FAMILY_SECURITY; 200 } 201 202 } 203 return ret; 204} 205