1 //! \file 2 /* 3 ** Copyright (C) - Triton 4 ** 5 ** This program is under the terms of the Apache License 2.0. 6 */ 7 8 #include <cstring> 9 10 #include <triton/aarch64Cpu.hpp> 11 #include <triton/architecture.hpp> 12 #include <triton/coreUtils.hpp> 13 #include <triton/cpuSize.hpp> 14 #include <triton/exceptions.hpp> 15 #include <triton/immediate.hpp> 16 17 18 19 namespace triton { 20 namespace arch { 21 namespace arm { 22 namespace aarch64 { 23 AArch64Cpu(triton::callbacks::Callbacks * callbacks)24 AArch64Cpu::AArch64Cpu(triton::callbacks::Callbacks* callbacks) : AArch64Specifications(ARCH_AARCH64) { 25 this->callbacks = callbacks; 26 this->handle = 0; 27 28 this->clear(); 29 this->disassInit(); 30 } 31 32 AArch64Cpu(const AArch64Cpu & other)33 AArch64Cpu::AArch64Cpu(const AArch64Cpu& other) : AArch64Specifications(ARCH_AARCH64) { 34 this->copy(other); 35 } 36 37 ~AArch64Cpu()38 AArch64Cpu::~AArch64Cpu() { 39 this->memory.clear(); 40 if (this->handle) { 41 triton::extlibs::capstone::cs_close(&this->handle); 42 } 43 } 44 45 disassInit(void)46 void AArch64Cpu::disassInit(void) { 47 if (this->handle) { 48 triton::extlibs::capstone::cs_close(&this->handle); 49 } 50 51 if (triton::extlibs::capstone::cs_open(triton::extlibs::capstone::CS_ARCH_ARM64, triton::extlibs::capstone::CS_MODE_ARM, &this->handle) != triton::extlibs::capstone::CS_ERR_OK) 52 throw triton::exceptions::Disassembly("AArch64Cpu::disassInit(): Cannot open capstone."); 53 54 triton::extlibs::capstone::cs_option(this->handle, triton::extlibs::capstone::CS_OPT_DETAIL, triton::extlibs::capstone::CS_OPT_ON); 55 } 56 57 copy(const AArch64Cpu & other)58 void AArch64Cpu::copy(const AArch64Cpu& other) { 59 this->callbacks = other.callbacks; 60 this->memory = other.memory; 61 62 this->disassInit(); 63 64 std::memcpy(this->x0, other.x0, sizeof(this->x0)); 65 std::memcpy(this->x1, other.x1, sizeof(this->x1)); 66 std::memcpy(this->x2, other.x2, sizeof(this->x2)); 67 std::memcpy(this->x3, other.x3, sizeof(this->x3)); 68 std::memcpy(this->x4, other.x4, sizeof(this->x4)); 69 std::memcpy(this->x5, other.x5, sizeof(this->x5)); 70 std::memcpy(this->x6, other.x6, sizeof(this->x6)); 71 std::memcpy(this->x7, other.x7, sizeof(this->x7)); 72 std::memcpy(this->x8, other.x8, sizeof(this->x8)); 73 std::memcpy(this->x9, other.x9, sizeof(this->x9)); 74 std::memcpy(this->x10, other.x10, sizeof(this->x10)); 75 std::memcpy(this->x11, other.x11, sizeof(this->x11)); 76 std::memcpy(this->x12, other.x12, sizeof(this->x12)); 77 std::memcpy(this->x13, other.x13, sizeof(this->x13)); 78 std::memcpy(this->x14, other.x14, sizeof(this->x14)); 79 std::memcpy(this->x15, other.x15, sizeof(this->x15)); 80 std::memcpy(this->x16, other.x16, sizeof(this->x16)); 81 std::memcpy(this->x17, other.x17, sizeof(this->x17)); 82 std::memcpy(this->x18, other.x18, sizeof(this->x18)); 83 std::memcpy(this->x19, other.x19, sizeof(this->x19)); 84 std::memcpy(this->x20, other.x20, sizeof(this->x20)); 85 std::memcpy(this->x21, other.x21, sizeof(this->x21)); 86 std::memcpy(this->x22, other.x22, sizeof(this->x22)); 87 std::memcpy(this->x23, other.x23, sizeof(this->x23)); 88 std::memcpy(this->x24, other.x24, sizeof(this->x24)); 89 std::memcpy(this->x25, other.x25, sizeof(this->x25)); 90 std::memcpy(this->x26, other.x26, sizeof(this->x26)); 91 std::memcpy(this->x27, other.x27, sizeof(this->x27)); 92 std::memcpy(this->x28, other.x28, sizeof(this->x28)); 93 std::memcpy(this->x29, other.x29, sizeof(this->x29)); 94 std::memcpy(this->x30, other.x30, sizeof(this->x30)); 95 std::memcpy(this->sp, other.sp, sizeof(this->sp)); 96 std::memcpy(this->pc, other.pc, sizeof(this->pc)); 97 std::memcpy(this->spsr, other.spsr, sizeof(this->spsr)); 98 } 99 100 clear(void)101 void AArch64Cpu::clear(void) { 102 /* Clear memory */ 103 this->memory.clear(); 104 105 /* Clear registers */ 106 std::memset(this->x0, 0x00, sizeof(this->x0)); 107 std::memset(this->x1, 0x00, sizeof(this->x1)); 108 std::memset(this->x2, 0x00, sizeof(this->x2)); 109 std::memset(this->x3, 0x00, sizeof(this->x3)); 110 std::memset(this->x4, 0x00, sizeof(this->x4)); 111 std::memset(this->x5, 0x00, sizeof(this->x5)); 112 std::memset(this->x6, 0x00, sizeof(this->x6)); 113 std::memset(this->x7, 0x00, sizeof(this->x7)); 114 std::memset(this->x8, 0x00, sizeof(this->x8)); 115 std::memset(this->x9, 0x00, sizeof(this->x9)); 116 std::memset(this->x10, 0x00, sizeof(this->x10)); 117 std::memset(this->x11, 0x00, sizeof(this->x11)); 118 std::memset(this->x12, 0x00, sizeof(this->x12)); 119 std::memset(this->x13, 0x00, sizeof(this->x13)); 120 std::memset(this->x14, 0x00, sizeof(this->x14)); 121 std::memset(this->x15, 0x00, sizeof(this->x15)); 122 std::memset(this->x16, 0x00, sizeof(this->x16)); 123 std::memset(this->x17, 0x00, sizeof(this->x17)); 124 std::memset(this->x18, 0x00, sizeof(this->x18)); 125 std::memset(this->x19, 0x00, sizeof(this->x19)); 126 std::memset(this->x20, 0x00, sizeof(this->x20)); 127 std::memset(this->x21, 0x00, sizeof(this->x21)); 128 std::memset(this->x22, 0x00, sizeof(this->x22)); 129 std::memset(this->x23, 0x00, sizeof(this->x23)); 130 std::memset(this->x24, 0x00, sizeof(this->x24)); 131 std::memset(this->x25, 0x00, sizeof(this->x25)); 132 std::memset(this->x26, 0x00, sizeof(this->x26)); 133 std::memset(this->x27, 0x00, sizeof(this->x27)); 134 std::memset(this->x28, 0x00, sizeof(this->x28)); 135 std::memset(this->x29, 0x00, sizeof(this->x29)); 136 std::memset(this->x30, 0x00, sizeof(this->x30)); 137 std::memset(this->sp, 0x00, sizeof(this->sp)); 138 std::memset(this->pc, 0x00, sizeof(this->pc)); 139 std::memset(this->spsr, 0x00, sizeof(this->spsr)); 140 } 141 142 operator =(const AArch64Cpu & other)143 AArch64Cpu& AArch64Cpu::operator=(const AArch64Cpu& other) { 144 this->copy(other); 145 return *this; 146 } 147 148 getEndianness(void) const149 triton::arch::endianness_e AArch64Cpu::getEndianness(void) const { 150 return triton::arch::LE_ENDIANNESS; 151 } 152 153 isFlag(triton::arch::register_e regId) const154 bool AArch64Cpu::isFlag(triton::arch::register_e regId) const { 155 return ((regId >= triton::arch::ID_REG_AARCH64_C && regId <= triton::arch::ID_REG_AARCH64_Z) ? true : false); 156 } 157 158 isRegister(triton::arch::register_e regId) const159 bool AArch64Cpu::isRegister(triton::arch::register_e regId) const { 160 return this->isGPR(regId); 161 } 162 163 isRegisterValid(triton::arch::register_e regId) const164 bool AArch64Cpu::isRegisterValid(triton::arch::register_e regId) const { 165 return (this->isFlag(regId) || this->isRegister(regId)); 166 } 167 168 isGPR(triton::arch::register_e regId) const169 bool AArch64Cpu::isGPR(triton::arch::register_e regId) const { 170 return ((regId >= triton::arch::ID_REG_AARCH64_X0 && regId <= triton::arch::ID_REG_AARCH64_WZR) ? true : false); 171 } 172 173 numberOfRegisters(void) const174 triton::uint32 AArch64Cpu::numberOfRegisters(void) const { 175 return triton::arch::ID_REG_LAST_ITEM; 176 } 177 178 gprSize(void) const179 triton::uint32 AArch64Cpu::gprSize(void) const { 180 return triton::size::qword; 181 } 182 183 gprBitSize(void) const184 triton::uint32 AArch64Cpu::gprBitSize(void) const { 185 return triton::bitsize::qword; 186 } 187 188 getAllRegisters(void) const189 const std::unordered_map<triton::arch::register_e, const triton::arch::Register>& AArch64Cpu::getAllRegisters(void) const { 190 return this->registers_; 191 } 192 193 getParentRegisters(void) const194 std::set<const triton::arch::Register*> AArch64Cpu::getParentRegisters(void) const { 195 std::set<const triton::arch::Register*> ret; 196 197 for (const auto& kv: this->registers_) { 198 auto regId = kv.first; 199 const auto& reg = kv.second; 200 201 /* Add GPR */ 202 if (reg.getSize() == this->gprSize()) 203 ret.insert(®); 204 205 /* Add Flags */ 206 else if (this->isFlag(regId)) 207 ret.insert(®); 208 } 209 210 return ret; 211 } 212 213 getRegister(triton::arch::register_e id) const214 const triton::arch::Register& AArch64Cpu::getRegister(triton::arch::register_e id) const { 215 try { 216 return this->registers_.at(id); 217 } catch (const std::out_of_range&) { 218 throw triton::exceptions::Cpu("AArch64Cpu::getRegister(): Invalid register for this architecture."); 219 } 220 } 221 222 getParentRegister(const triton::arch::Register & reg) const223 const triton::arch::Register& AArch64Cpu::getParentRegister(const triton::arch::Register& reg) const { 224 return this->getRegister(reg.getParent()); 225 } 226 227 getParentRegister(triton::arch::register_e id) const228 const triton::arch::Register& AArch64Cpu::getParentRegister(triton::arch::register_e id) const { 229 return this->getParentRegister(this->getRegister(id)); 230 } 231 232 getProgramCounter(void) const233 const triton::arch::Register& AArch64Cpu::getProgramCounter(void) const { 234 return this->getRegister(this->pcId); 235 } 236 237 getStackPointer(void) const238 const triton::arch::Register& AArch64Cpu::getStackPointer(void) const { 239 return this->getRegister(this->spId); 240 } 241 242 disassembly(triton::arch::Instruction & inst) const243 void AArch64Cpu::disassembly(triton::arch::Instruction& inst) const { 244 triton::extlibs::capstone::cs_insn* insn; 245 triton::usize count = 0; 246 triton::uint32 size = 0; 247 248 /* Check if the opcode and opcode' size are defined */ 249 if (inst.getOpcode() == nullptr || inst.getSize() == 0) 250 throw triton::exceptions::Disassembly("AArch64Cpu::disassembly(): Opcode and opcodeSize must be definied."); 251 252 /* Clear instructicon's operands if alredy defined */ 253 inst.operands.clear(); 254 255 /* Let's disass and build our operands */ 256 count = triton::extlibs::capstone::cs_disasm(this->handle, inst.getOpcode(), inst.getSize(), inst.getAddress(), 0, &insn); 257 if (count > 0) { 258 /* Detail information */ 259 triton::extlibs::capstone::cs_detail* detail = insn->detail; 260 261 /* Init the disassembly */ 262 std::stringstream str; 263 264 str << insn[0].mnemonic; 265 if (detail->arm64.op_count) 266 str << " " << insn[0].op_str; 267 268 inst.setDisassembly(str.str()); 269 270 /* Refine the size */ 271 inst.setSize(insn[0].size); 272 273 /* Init the instruction's type */ 274 inst.setType(this->capstoneInstructionToTritonInstruction(insn[0].id)); 275 276 /* Init the instruction's code codition */ 277 inst.setCodeCondition(this->capstoneConditionToTritonCondition(detail->arm64.cc)); 278 279 /* Init the instruction's write back flag */ 280 inst.setWriteBack(detail->arm64.writeback); 281 282 /* Set True if the instruction udpate flags */ 283 inst.setUpdateFlag(detail->arm64.update_flags); 284 285 /* Init operands */ 286 for (triton::uint32 n = 0; n < detail->arm64.op_count; n++) { 287 triton::extlibs::capstone::cs_arm64_op* op = &(detail->arm64.operands[n]); 288 switch(op->type) { 289 290 case triton::extlibs::capstone::ARM64_OP_IMM: { 291 triton::arch::Immediate imm(op->imm, size ? size : triton::size::qword); 292 293 /* 294 * Instruction such that CBZ, CBNZ or TBZ may imply a wrong size. 295 * So, if Triton truncates the value by setting a size less than 296 * the original one, we redefine the size automatically. 297 */ 298 if (static_cast<triton::uint64>(op->imm) > imm.getValue()) { 299 imm = Immediate(); 300 imm.setValue(op->imm, 0); /* By setting 0 as size, we automatically identify the size of the value */ 301 } 302 303 /* Set Shift type and value */ 304 imm.setShiftType(this->capstoneShiftToTritonShift(op->shift.type)); 305 imm.setShiftValue(op->shift.value); 306 307 inst.operands.push_back(triton::arch::OperandWrapper(imm)); 308 break; 309 } 310 311 case triton::extlibs::capstone::ARM64_OP_MEM: { 312 triton::arch::MemoryAccess mem; 313 314 /* Set the size of the memory access */ 315 mem.setPair(std::make_pair(size ? ((size * triton::bitsize::byte) - 1) : triton::bitsize::qword - 1, 0)); 316 317 /* LEA if exists */ 318 triton::arch::Register base(*this, this->capstoneRegisterToTritonRegister(op->mem.base)); 319 triton::arch::Register index(*this, this->capstoneRegisterToTritonRegister(op->mem.index)); 320 321 triton::uint32 immsize = ( 322 this->isRegisterValid(base.getId()) ? base.getSize() : 323 this->isRegisterValid(index.getId()) ? index.getSize() : 324 this->gprSize() 325 ); 326 327 triton::arch::Immediate disp(op->mem.disp, immsize); 328 329 /* Specify that LEA contains a PC relative */ 330 /* FIXME: Valid in ARM64 ? */ 331 if (base.getId() == this->pcId) { 332 mem.setPcRelative(inst.getNextAddress()); 333 } 334 335 /* Set extend type and size */ 336 index.setExtendType(this->capstoneExtendToTritonExtend(op->ext)); 337 if (op->ext != triton::extlibs::capstone::ARM64_EXT_INVALID) { 338 index.setExtendedSize(base.getBitSize()); 339 } 340 341 /* Note that in ARM64 there is no segment register and scale value */ 342 mem.setBaseRegister(base); 343 mem.setIndexRegister(index); 344 mem.setDisplacement(disp); 345 346 /* If there is an index register available, set scale to 1 to perform this following computation (base) + (index * scale) */ 347 if (this->isRegisterValid(index.getId())) { 348 mem.setScale(triton::arch::Immediate(1, immsize)); 349 } 350 351 inst.operands.push_back(triton::arch::OperandWrapper(mem)); 352 break; 353 } 354 355 case triton::extlibs::capstone::ARM64_OP_REG: { 356 triton::arch::Register reg(*this, this->capstoneRegisterToTritonRegister(op->reg)); 357 358 /* Set Shift type and value */ 359 reg.setShiftType(this->capstoneShiftToTritonShift(op->shift.type)); 360 reg.setShiftValue(op->shift.value); 361 362 /* Set extend type and size */ 363 reg.setExtendType(this->capstoneExtendToTritonExtend(op->ext)); 364 if (op->ext != triton::extlibs::capstone::ARM64_EXT_INVALID) { 365 reg.setExtendedSize(size * triton::bitsize::byte); 366 } 367 368 /* Define a base address for next operand */ 369 if (!size) { 370 size = reg.getSize(); 371 } 372 373 inst.operands.push_back(triton::arch::OperandWrapper(reg)); 374 break; 375 } 376 377 default: 378 /* NOTE: FP, CIMM, and missing one are not supported yet. */ 379 throw triton::exceptions::Disassembly("AArch64Cpu::disassembly(): Invalid operand."); 380 } // switch 381 } // for operand 382 383 /* Set control flow */ 384 if (insn[0].id == triton::extlibs::capstone::ARM64_INS_RET) 385 inst.setControlFlow(true); 386 387 /* Set branch */ 388 if (detail->groups_count > 0) { 389 for (triton::uint32 n = 0; n < detail->groups_count; n++) { 390 if (detail->groups[n] == triton::extlibs::capstone::ARM64_GRP_JUMP) { 391 inst.setBranch(true); 392 inst.setControlFlow(true); 393 } 394 } 395 } 396 397 /* Free capstone stuffs */ 398 triton::extlibs::capstone::cs_free(insn, count); 399 } 400 else 401 throw triton::exceptions::Disassembly("AArch64Cpu::disassembly(): Failed to disassemble the given code."); 402 } 403 404 getConcreteMemoryValue(triton::uint64 addr,bool execCallbacks) const405 triton::uint8 AArch64Cpu::getConcreteMemoryValue(triton::uint64 addr, bool execCallbacks) const { 406 if (execCallbacks && this->callbacks) 407 this->callbacks->processCallbacks(triton::callbacks::GET_CONCRETE_MEMORY_VALUE, MemoryAccess(addr, triton::size::byte)); 408 409 auto it = this->memory.find(addr); 410 if (it == this->memory.end()) 411 return 0x00; 412 413 return it->second; 414 } 415 416 getConcreteMemoryValue(const triton::arch::MemoryAccess & mem,bool execCallbacks) const417 triton::uint512 AArch64Cpu::getConcreteMemoryValue(const triton::arch::MemoryAccess& mem, bool execCallbacks) const { 418 triton::uint512 ret = 0; 419 triton::uint64 addr = 0; 420 triton::uint32 size = 0; 421 422 if (execCallbacks && this->callbacks) 423 this->callbacks->processCallbacks(triton::callbacks::GET_CONCRETE_MEMORY_VALUE, mem); 424 425 addr = mem.getAddress(); 426 size = mem.getSize(); 427 428 if (size == 0 || size > triton::size::dqqword) 429 throw triton::exceptions::Cpu("AArch64Cpu::getConcreteMemoryValue(): Invalid size memory."); 430 431 for (triton::sint32 i = size-1; i >= 0; i--) 432 ret = ((ret << triton::bitsize::byte) | this->getConcreteMemoryValue(addr+i, false)); 433 434 return ret; 435 } 436 437 getConcreteMemoryAreaValue(triton::uint64 baseAddr,triton::usize size,bool execCallbacks) const438 std::vector<triton::uint8> AArch64Cpu::getConcreteMemoryAreaValue(triton::uint64 baseAddr, triton::usize size, bool execCallbacks) const { 439 std::vector<triton::uint8> area; 440 441 for (triton::usize index = 0; index < size; index++) 442 area.push_back(this->getConcreteMemoryValue(baseAddr+index)); 443 444 return area; 445 } 446 447 getConcreteRegisterValue(const triton::arch::Register & reg,bool execCallbacks) const448 triton::uint512 AArch64Cpu::getConcreteRegisterValue(const triton::arch::Register& reg, bool execCallbacks) const { 449 triton::uint512 value = 0; 450 451 if (execCallbacks && this->callbacks) 452 this->callbacks->processCallbacks(triton::callbacks::GET_CONCRETE_REGISTER_VALUE, reg); 453 454 switch (reg.getId()) { 455 case triton::arch::ID_REG_AARCH64_X0: return (*((triton::uint64*)(this->x0))); 456 case triton::arch::ID_REG_AARCH64_W0: return (*((triton::uint32*)(this->x0))); 457 case triton::arch::ID_REG_AARCH64_X1: return (*((triton::uint64*)(this->x1))); 458 case triton::arch::ID_REG_AARCH64_W1: return (*((triton::uint32*)(this->x1))); 459 case triton::arch::ID_REG_AARCH64_X2: return (*((triton::uint64*)(this->x2))); 460 case triton::arch::ID_REG_AARCH64_W2: return (*((triton::uint32*)(this->x2))); 461 case triton::arch::ID_REG_AARCH64_X3: return (*((triton::uint64*)(this->x3))); 462 case triton::arch::ID_REG_AARCH64_W3: return (*((triton::uint32*)(this->x3))); 463 case triton::arch::ID_REG_AARCH64_X4: return (*((triton::uint64*)(this->x4))); 464 case triton::arch::ID_REG_AARCH64_W4: return (*((triton::uint32*)(this->x4))); 465 case triton::arch::ID_REG_AARCH64_X5: return (*((triton::uint64*)(this->x5))); 466 case triton::arch::ID_REG_AARCH64_W5: return (*((triton::uint32*)(this->x5))); 467 case triton::arch::ID_REG_AARCH64_X6: return (*((triton::uint64*)(this->x6))); 468 case triton::arch::ID_REG_AARCH64_W6: return (*((triton::uint32*)(this->x6))); 469 case triton::arch::ID_REG_AARCH64_X7: return (*((triton::uint64*)(this->x7))); 470 case triton::arch::ID_REG_AARCH64_W7: return (*((triton::uint32*)(this->x7))); 471 case triton::arch::ID_REG_AARCH64_X8: return (*((triton::uint64*)(this->x8))); 472 case triton::arch::ID_REG_AARCH64_W8: return (*((triton::uint32*)(this->x8))); 473 case triton::arch::ID_REG_AARCH64_X9: return (*((triton::uint64*)(this->x9))); 474 case triton::arch::ID_REG_AARCH64_W9: return (*((triton::uint32*)(this->x9))); 475 case triton::arch::ID_REG_AARCH64_X10: return (*((triton::uint64*)(this->x10))); 476 case triton::arch::ID_REG_AARCH64_W10: return (*((triton::uint32*)(this->x10))); 477 case triton::arch::ID_REG_AARCH64_X11: return (*((triton::uint64*)(this->x11))); 478 case triton::arch::ID_REG_AARCH64_W11: return (*((triton::uint32*)(this->x11))); 479 case triton::arch::ID_REG_AARCH64_X12: return (*((triton::uint64*)(this->x12))); 480 case triton::arch::ID_REG_AARCH64_W12: return (*((triton::uint32*)(this->x12))); 481 case triton::arch::ID_REG_AARCH64_X13: return (*((triton::uint64*)(this->x13))); 482 case triton::arch::ID_REG_AARCH64_W13: return (*((triton::uint32*)(this->x13))); 483 case triton::arch::ID_REG_AARCH64_X14: return (*((triton::uint64*)(this->x14))); 484 case triton::arch::ID_REG_AARCH64_W14: return (*((triton::uint32*)(this->x14))); 485 case triton::arch::ID_REG_AARCH64_X15: return (*((triton::uint64*)(this->x15))); 486 case triton::arch::ID_REG_AARCH64_W15: return (*((triton::uint32*)(this->x15))); 487 case triton::arch::ID_REG_AARCH64_X16: return (*((triton::uint64*)(this->x16))); 488 case triton::arch::ID_REG_AARCH64_W16: return (*((triton::uint32*)(this->x16))); 489 case triton::arch::ID_REG_AARCH64_X17: return (*((triton::uint64*)(this->x17))); 490 case triton::arch::ID_REG_AARCH64_W17: return (*((triton::uint32*)(this->x17))); 491 case triton::arch::ID_REG_AARCH64_X18: return (*((triton::uint64*)(this->x18))); 492 case triton::arch::ID_REG_AARCH64_W18: return (*((triton::uint32*)(this->x18))); 493 case triton::arch::ID_REG_AARCH64_X19: return (*((triton::uint64*)(this->x19))); 494 case triton::arch::ID_REG_AARCH64_W19: return (*((triton::uint32*)(this->x19))); 495 case triton::arch::ID_REG_AARCH64_X20: return (*((triton::uint64*)(this->x20))); 496 case triton::arch::ID_REG_AARCH64_W20: return (*((triton::uint32*)(this->x20))); 497 case triton::arch::ID_REG_AARCH64_X21: return (*((triton::uint64*)(this->x21))); 498 case triton::arch::ID_REG_AARCH64_W21: return (*((triton::uint32*)(this->x21))); 499 case triton::arch::ID_REG_AARCH64_X22: return (*((triton::uint64*)(this->x22))); 500 case triton::arch::ID_REG_AARCH64_W22: return (*((triton::uint32*)(this->x22))); 501 case triton::arch::ID_REG_AARCH64_X23: return (*((triton::uint64*)(this->x23))); 502 case triton::arch::ID_REG_AARCH64_W23: return (*((triton::uint32*)(this->x23))); 503 case triton::arch::ID_REG_AARCH64_X24: return (*((triton::uint64*)(this->x24))); 504 case triton::arch::ID_REG_AARCH64_W24: return (*((triton::uint32*)(this->x24))); 505 case triton::arch::ID_REG_AARCH64_X25: return (*((triton::uint64*)(this->x25))); 506 case triton::arch::ID_REG_AARCH64_W25: return (*((triton::uint32*)(this->x25))); 507 case triton::arch::ID_REG_AARCH64_X26: return (*((triton::uint64*)(this->x26))); 508 case triton::arch::ID_REG_AARCH64_W26: return (*((triton::uint32*)(this->x26))); 509 case triton::arch::ID_REG_AARCH64_X27: return (*((triton::uint64*)(this->x27))); 510 case triton::arch::ID_REG_AARCH64_W27: return (*((triton::uint32*)(this->x27))); 511 case triton::arch::ID_REG_AARCH64_X28: return (*((triton::uint64*)(this->x28))); 512 case triton::arch::ID_REG_AARCH64_W28: return (*((triton::uint32*)(this->x28))); 513 case triton::arch::ID_REG_AARCH64_X29: return (*((triton::uint64*)(this->x29))); 514 case triton::arch::ID_REG_AARCH64_W29: return (*((triton::uint32*)(this->x29))); 515 case triton::arch::ID_REG_AARCH64_X30: return (*((triton::uint64*)(this->x30))); 516 case triton::arch::ID_REG_AARCH64_W30: return (*((triton::uint32*)(this->x30))); 517 case triton::arch::ID_REG_AARCH64_SP: return (*((triton::uint64*)(this->sp))); 518 case triton::arch::ID_REG_AARCH64_WSP: return (*((triton::uint32*)(this->sp))); 519 case triton::arch::ID_REG_AARCH64_PC: return (*((triton::uint64*)(this->pc))); 520 case triton::arch::ID_REG_AARCH64_XZR: return 0; 521 case triton::arch::ID_REG_AARCH64_WZR: return 0; 522 case triton::arch::ID_REG_AARCH64_SPSR: return (*((triton::uint32*)(this->spsr))); 523 case triton::arch::ID_REG_AARCH64_N: return (((*((triton::uint32*)(this->spsr))) >> 31) & 1); 524 case triton::arch::ID_REG_AARCH64_Z: return (((*((triton::uint32*)(this->spsr))) >> 30) & 1); 525 case triton::arch::ID_REG_AARCH64_C: return (((*((triton::uint32*)(this->spsr))) >> 29) & 1); 526 case triton::arch::ID_REG_AARCH64_V: return (((*((triton::uint32*)(this->spsr))) >> 28) & 1); 527 default: 528 throw triton::exceptions::Cpu("AArch64Cpu::getConcreteRegisterValue(): Invalid register."); 529 } 530 531 return value; 532 } 533 534 setConcreteMemoryValue(triton::uint64 addr,triton::uint8 value)535 void AArch64Cpu::setConcreteMemoryValue(triton::uint64 addr, triton::uint8 value) { 536 if (this->callbacks) 537 this->callbacks->processCallbacks(triton::callbacks::SET_CONCRETE_MEMORY_VALUE, MemoryAccess(addr, triton::size::byte), value); 538 this->memory[addr] = value; 539 } 540 541 setConcreteMemoryValue(const triton::arch::MemoryAccess & mem,const triton::uint512 & value)542 void AArch64Cpu::setConcreteMemoryValue(const triton::arch::MemoryAccess& mem, const triton::uint512& value) { 543 triton::uint64 addr = mem.getAddress(); 544 triton::uint32 size = mem.getSize(); 545 triton::uint512 cv = value; 546 547 if (cv > mem.getMaxValue()) 548 throw triton::exceptions::Register("AArch64Cpu::setConcreteMemoryValue(): You cannot set this concrete value (too big) to this memory access."); 549 550 if (size == 0 || size > triton::size::dqqword) 551 throw triton::exceptions::Cpu("AArch64Cpu::setConcreteMemoryValue(): Invalid size memory."); 552 553 if (this->callbacks) 554 this->callbacks->processCallbacks(triton::callbacks::SET_CONCRETE_MEMORY_VALUE, mem, value); 555 556 for (triton::uint32 i = 0; i < size; i++) { 557 this->memory[addr+i] = (cv & 0xff).convert_to<triton::uint8>(); 558 cv >>= 8; 559 } 560 } 561 562 setConcreteMemoryAreaValue(triton::uint64 baseAddr,const std::vector<triton::uint8> & values)563 void AArch64Cpu::setConcreteMemoryAreaValue(triton::uint64 baseAddr, const std::vector<triton::uint8>& values) { 564 for (triton::usize index = 0; index < values.size(); index++) { 565 this->setConcreteMemoryValue(baseAddr+index, values[index]); 566 } 567 } 568 569 setConcreteMemoryAreaValue(triton::uint64 baseAddr,const triton::uint8 * area,triton::usize size)570 void AArch64Cpu::setConcreteMemoryAreaValue(triton::uint64 baseAddr, const triton::uint8* area, triton::usize size) { 571 for (triton::usize index = 0; index < size; index++) { 572 this->setConcreteMemoryValue(baseAddr+index, area[index]); 573 } 574 } 575 576 setConcreteRegisterValue(const triton::arch::Register & reg,const triton::uint512 & value)577 void AArch64Cpu::setConcreteRegisterValue(const triton::arch::Register& reg, const triton::uint512& value) { 578 if (value > reg.getMaxValue()) 579 throw triton::exceptions::Register("AArch64Cpu::setConcreteRegisterValue(): You cannot set this concrete value (too big) to this register."); 580 581 if (this->callbacks) 582 this->callbacks->processCallbacks(triton::callbacks::SET_CONCRETE_REGISTER_VALUE, reg, value); 583 584 switch (reg.getId()) { 585 case triton::arch::ID_REG_AARCH64_X0: (*((triton::uint64*)(this->x0))) = value.convert_to<triton::uint64>(); break; 586 case triton::arch::ID_REG_AARCH64_W0: (*((triton::uint32*)(this->x0))) = value.convert_to<triton::uint32>(); break; 587 case triton::arch::ID_REG_AARCH64_X1: (*((triton::uint64*)(this->x1))) = value.convert_to<triton::uint64>(); break; 588 case triton::arch::ID_REG_AARCH64_W1: (*((triton::uint32*)(this->x1))) = value.convert_to<triton::uint32>(); break; 589 case triton::arch::ID_REG_AARCH64_X2: (*((triton::uint64*)(this->x2))) = value.convert_to<triton::uint64>(); break; 590 case triton::arch::ID_REG_AARCH64_W2: (*((triton::uint32*)(this->x2))) = value.convert_to<triton::uint32>(); break; 591 case triton::arch::ID_REG_AARCH64_X3: (*((triton::uint64*)(this->x3))) = value.convert_to<triton::uint64>(); break; 592 case triton::arch::ID_REG_AARCH64_W3: (*((triton::uint32*)(this->x3))) = value.convert_to<triton::uint32>(); break; 593 case triton::arch::ID_REG_AARCH64_X4: (*((triton::uint64*)(this->x4))) = value.convert_to<triton::uint64>(); break; 594 case triton::arch::ID_REG_AARCH64_W4: (*((triton::uint32*)(this->x4))) = value.convert_to<triton::uint32>(); break; 595 case triton::arch::ID_REG_AARCH64_X5: (*((triton::uint64*)(this->x5))) = value.convert_to<triton::uint64>(); break; 596 case triton::arch::ID_REG_AARCH64_W5: (*((triton::uint32*)(this->x5))) = value.convert_to<triton::uint32>(); break; 597 case triton::arch::ID_REG_AARCH64_X6: (*((triton::uint64*)(this->x6))) = value.convert_to<triton::uint64>(); break; 598 case triton::arch::ID_REG_AARCH64_W6: (*((triton::uint32*)(this->x6))) = value.convert_to<triton::uint32>(); break; 599 case triton::arch::ID_REG_AARCH64_X7: (*((triton::uint64*)(this->x7))) = value.convert_to<triton::uint64>(); break; 600 case triton::arch::ID_REG_AARCH64_W7: (*((triton::uint32*)(this->x7))) = value.convert_to<triton::uint32>(); break; 601 case triton::arch::ID_REG_AARCH64_X8: (*((triton::uint64*)(this->x8))) = value.convert_to<triton::uint64>(); break; 602 case triton::arch::ID_REG_AARCH64_W8: (*((triton::uint32*)(this->x8))) = value.convert_to<triton::uint32>(); break; 603 case triton::arch::ID_REG_AARCH64_X9: (*((triton::uint64*)(this->x9))) = value.convert_to<triton::uint64>(); break; 604 case triton::arch::ID_REG_AARCH64_W9: (*((triton::uint32*)(this->x9))) = value.convert_to<triton::uint32>(); break; 605 case triton::arch::ID_REG_AARCH64_X10: (*((triton::uint64*)(this->x10))) = value.convert_to<triton::uint64>(); break; 606 case triton::arch::ID_REG_AARCH64_W10: (*((triton::uint32*)(this->x10))) = value.convert_to<triton::uint32>(); break; 607 case triton::arch::ID_REG_AARCH64_X11: (*((triton::uint64*)(this->x11))) = value.convert_to<triton::uint64>(); break; 608 case triton::arch::ID_REG_AARCH64_W11: (*((triton::uint32*)(this->x11))) = value.convert_to<triton::uint32>(); break; 609 case triton::arch::ID_REG_AARCH64_X12: (*((triton::uint64*)(this->x12))) = value.convert_to<triton::uint64>(); break; 610 case triton::arch::ID_REG_AARCH64_W12: (*((triton::uint32*)(this->x12))) = value.convert_to<triton::uint32>(); break; 611 case triton::arch::ID_REG_AARCH64_X13: (*((triton::uint64*)(this->x13))) = value.convert_to<triton::uint64>(); break; 612 case triton::arch::ID_REG_AARCH64_W13: (*((triton::uint32*)(this->x13))) = value.convert_to<triton::uint32>(); break; 613 case triton::arch::ID_REG_AARCH64_X14: (*((triton::uint64*)(this->x14))) = value.convert_to<triton::uint64>(); break; 614 case triton::arch::ID_REG_AARCH64_W14: (*((triton::uint32*)(this->x14))) = value.convert_to<triton::uint32>(); break; 615 case triton::arch::ID_REG_AARCH64_X15: (*((triton::uint64*)(this->x15))) = value.convert_to<triton::uint64>(); break; 616 case triton::arch::ID_REG_AARCH64_W15: (*((triton::uint32*)(this->x15))) = value.convert_to<triton::uint32>(); break; 617 case triton::arch::ID_REG_AARCH64_X16: (*((triton::uint64*)(this->x16))) = value.convert_to<triton::uint64>(); break; 618 case triton::arch::ID_REG_AARCH64_W16: (*((triton::uint32*)(this->x16))) = value.convert_to<triton::uint32>(); break; 619 case triton::arch::ID_REG_AARCH64_X17: (*((triton::uint64*)(this->x17))) = value.convert_to<triton::uint64>(); break; 620 case triton::arch::ID_REG_AARCH64_W17: (*((triton::uint32*)(this->x17))) = value.convert_to<triton::uint32>(); break; 621 case triton::arch::ID_REG_AARCH64_X18: (*((triton::uint64*)(this->x18))) = value.convert_to<triton::uint64>(); break; 622 case triton::arch::ID_REG_AARCH64_W18: (*((triton::uint32*)(this->x18))) = value.convert_to<triton::uint32>(); break; 623 case triton::arch::ID_REG_AARCH64_X19: (*((triton::uint64*)(this->x19))) = value.convert_to<triton::uint64>(); break; 624 case triton::arch::ID_REG_AARCH64_W19: (*((triton::uint32*)(this->x19))) = value.convert_to<triton::uint32>(); break; 625 case triton::arch::ID_REG_AARCH64_X20: (*((triton::uint64*)(this->x20))) = value.convert_to<triton::uint64>(); break; 626 case triton::arch::ID_REG_AARCH64_W20: (*((triton::uint32*)(this->x20))) = value.convert_to<triton::uint32>(); break; 627 case triton::arch::ID_REG_AARCH64_X21: (*((triton::uint64*)(this->x21))) = value.convert_to<triton::uint64>(); break; 628 case triton::arch::ID_REG_AARCH64_W21: (*((triton::uint32*)(this->x21))) = value.convert_to<triton::uint32>(); break; 629 case triton::arch::ID_REG_AARCH64_X22: (*((triton::uint64*)(this->x22))) = value.convert_to<triton::uint64>(); break; 630 case triton::arch::ID_REG_AARCH64_W22: (*((triton::uint32*)(this->x22))) = value.convert_to<triton::uint32>(); break; 631 case triton::arch::ID_REG_AARCH64_X23: (*((triton::uint64*)(this->x23))) = value.convert_to<triton::uint64>(); break; 632 case triton::arch::ID_REG_AARCH64_W23: (*((triton::uint32*)(this->x23))) = value.convert_to<triton::uint32>(); break; 633 case triton::arch::ID_REG_AARCH64_X24: (*((triton::uint64*)(this->x24))) = value.convert_to<triton::uint64>(); break; 634 case triton::arch::ID_REG_AARCH64_W24: (*((triton::uint32*)(this->x24))) = value.convert_to<triton::uint32>(); break; 635 case triton::arch::ID_REG_AARCH64_X25: (*((triton::uint64*)(this->x25))) = value.convert_to<triton::uint64>(); break; 636 case triton::arch::ID_REG_AARCH64_W25: (*((triton::uint32*)(this->x25))) = value.convert_to<triton::uint32>(); break; 637 case triton::arch::ID_REG_AARCH64_X26: (*((triton::uint64*)(this->x26))) = value.convert_to<triton::uint64>(); break; 638 case triton::arch::ID_REG_AARCH64_W26: (*((triton::uint32*)(this->x26))) = value.convert_to<triton::uint32>(); break; 639 case triton::arch::ID_REG_AARCH64_X27: (*((triton::uint64*)(this->x27))) = value.convert_to<triton::uint64>(); break; 640 case triton::arch::ID_REG_AARCH64_W27: (*((triton::uint32*)(this->x27))) = value.convert_to<triton::uint32>(); break; 641 case triton::arch::ID_REG_AARCH64_X28: (*((triton::uint64*)(this->x28))) = value.convert_to<triton::uint64>(); break; 642 case triton::arch::ID_REG_AARCH64_W28: (*((triton::uint32*)(this->x28))) = value.convert_to<triton::uint32>(); break; 643 case triton::arch::ID_REG_AARCH64_X29: (*((triton::uint64*)(this->x29))) = value.convert_to<triton::uint64>(); break; 644 case triton::arch::ID_REG_AARCH64_W29: (*((triton::uint32*)(this->x29))) = value.convert_to<triton::uint32>(); break; 645 case triton::arch::ID_REG_AARCH64_X30: (*((triton::uint64*)(this->x30))) = value.convert_to<triton::uint64>(); break; 646 case triton::arch::ID_REG_AARCH64_W30: (*((triton::uint32*)(this->x30))) = value.convert_to<triton::uint32>(); break; 647 case triton::arch::ID_REG_AARCH64_SP: (*((triton::uint64*)(this->sp))) = value.convert_to<triton::uint64>(); break; 648 case triton::arch::ID_REG_AARCH64_WSP: (*((triton::uint32*)(this->sp))) = value.convert_to<triton::uint32>(); break; 649 case triton::arch::ID_REG_AARCH64_PC: (*((triton::uint64*)(this->pc))) = value.convert_to<triton::uint64>(); break; 650 case triton::arch::ID_REG_AARCH64_SPSR: (*((triton::uint32*)(this->spsr))) = value.convert_to<triton::uint32>(); break; 651 case triton::arch::ID_REG_AARCH64_XZR: break; // Just do nothing 652 case triton::arch::ID_REG_AARCH64_WZR: break; // Just do nothing 653 case triton::arch::ID_REG_AARCH64_N: { 654 triton::uint32 b = (*((triton::uint32*)(this->spsr))); 655 (*((triton::uint32*)(this->spsr))) = !value.is_zero() ? b | (1 << 31) : b & ~(1 << 31); 656 break; 657 } 658 case triton::arch::ID_REG_AARCH64_Z: { 659 triton::uint32 b = (*((triton::uint32*)(this->spsr))); 660 (*((triton::uint32*)(this->spsr))) = !value.is_zero() ? b | (1 << 30) : b & ~(1 << 30); 661 break; 662 } 663 case triton::arch::ID_REG_AARCH64_C: { 664 triton::uint32 b = (*((triton::uint32*)(this->spsr))); 665 (*((triton::uint32*)(this->spsr))) = !value.is_zero() ? b | (1 << 29) : b & ~(1 << 29); 666 break; 667 } 668 case triton::arch::ID_REG_AARCH64_V: { 669 triton::uint32 b = (*((triton::uint32*)(this->spsr))); 670 (*((triton::uint32*)(this->spsr))) = !value.is_zero() ? b | (1 << 28) : b & ~(1 << 28); 671 break; 672 } 673 default: 674 throw triton::exceptions::Cpu("AArch64Cpu:setConcreteRegisterValue(): Invalid register."); 675 } 676 } 677 678 isThumb(void) const679 bool AArch64Cpu::isThumb(void) const { 680 /* There is no thumb mode in aarch64 */ 681 return false; 682 } 683 684 setThumb(bool state)685 void AArch64Cpu::setThumb(bool state) { 686 /* There is no thumb mode in aarch64 */ 687 } 688 689 isConcreteMemoryValueDefined(const triton::arch::MemoryAccess & mem) const690 bool AArch64Cpu::isConcreteMemoryValueDefined(const triton::arch::MemoryAccess& mem) const { 691 return this->isConcreteMemoryValueDefined(mem.getAddress(), mem.getSize()); 692 } 693 694 isConcreteMemoryValueDefined(triton::uint64 baseAddr,triton::usize size) const695 bool AArch64Cpu::isConcreteMemoryValueDefined(triton::uint64 baseAddr, triton::usize size) const { 696 for (triton::usize index = 0; index < size; index++) { 697 if (this->memory.find(baseAddr + index) == this->memory.end()) 698 return false; 699 } 700 return true; 701 } 702 703 clearConcreteMemoryValue(const triton::arch::MemoryAccess & mem)704 void AArch64Cpu::clearConcreteMemoryValue(const triton::arch::MemoryAccess& mem) { 705 this->clearConcreteMemoryValue(mem.getAddress(), mem.getSize()); 706 } 707 708 clearConcreteMemoryValue(triton::uint64 baseAddr,triton::usize size)709 void AArch64Cpu::clearConcreteMemoryValue(triton::uint64 baseAddr, triton::usize size) { 710 for (triton::usize index = 0; index < size; index++) { 711 if (this->memory.find(baseAddr + index) != this->memory.end()) { 712 this->memory.erase(baseAddr + index); 713 } 714 } 715 } 716 717 }; /* aarch64 namespace */ 718 }; /* arm namespace */ 719 }; /* arch namespace */ 720 }; /* triton namespace */ 721