28 this->callbacks = callbacks;
30 this->handleThumb = 0;
32 this->itInstrsCount = 0;
33 this->itInstrIndex = 0;
50 if (this->handleArm) {
51 triton::extlibs::capstone::cs_close(&this->handleArm);
54 if (this->handleThumb) {
55 triton::extlibs::capstone::cs_close(&this->handleThumb);
60 void Arm32Cpu::disassInit(
void) {
62 if (this->handleArm) {
63 triton::extlibs::capstone::cs_close(&this->handleArm);
67 if (this->handleThumb) {
68 triton::extlibs::capstone::cs_close(&this->handleThumb);
71 if (triton::extlibs::capstone::cs_open(triton::extlibs::capstone::CS_ARCH_ARM, triton::extlibs::capstone::CS_MODE_ARM, &this->handleArm) != triton::extlibs::capstone::CS_ERR_OK) {
75 if (triton::extlibs::capstone::cs_open(triton::extlibs::capstone::CS_ARCH_ARM, triton::extlibs::capstone::CS_MODE_THUMB, &this->handleThumb) != triton::extlibs::capstone::CS_ERR_OK) {
79 triton::extlibs::capstone::cs_option(this->handleThumb, triton::extlibs::capstone::CS_OPT_DETAIL, triton::extlibs::capstone::CS_OPT_ON);
80 triton::extlibs::capstone::cs_option(this->handleArm, triton::extlibs::capstone::CS_OPT_DETAIL, triton::extlibs::capstone::CS_OPT_ON);
84 void Arm32Cpu::copy(
const Arm32Cpu& other) {
85 this->callbacks = other.callbacks;
86 this->exclusiveMemoryTags = other.exclusiveMemoryTags;
87 this->
memory = other.memory;
89 std::memcpy(this->
r0, other.r0,
sizeof(this->r0));
90 std::memcpy(this->
r1, other.r1,
sizeof(this->r1));
91 std::memcpy(this->
r2, other.r2,
sizeof(this->r2));
92 std::memcpy(this->
r3, other.r3,
sizeof(this->r3));
93 std::memcpy(this->
r4, other.r4,
sizeof(this->r4));
94 std::memcpy(this->
r5, other.r5,
sizeof(this->r5));
95 std::memcpy(this->
r6, other.r6,
sizeof(this->r6));
96 std::memcpy(this->
r7, other.r7,
sizeof(this->r7));
97 std::memcpy(this->
r8, other.r8,
sizeof(this->r8));
98 std::memcpy(this->
r9, other.r9,
sizeof(this->r9));
99 std::memcpy(this->
r10, other.r10,
sizeof(this->r10));
100 std::memcpy(this->
r11, other.r11,
sizeof(this->r11));
101 std::memcpy(this->
r12, other.r12,
sizeof(this->r12));
102 std::memcpy(this->
sp, other.sp,
sizeof(this->sp));
103 std::memcpy(this->
r14, other.r14,
sizeof(this->r14));
104 std::memcpy(this->
pc, other.pc,
sizeof(this->pc));
105 std::memcpy(this->apsr, other.apsr,
sizeof(this->apsr));
114 std::memset(this->
r0, 0x00,
sizeof(this->
r0));
115 std::memset(this->
r1, 0x00,
sizeof(this->
r1));
116 std::memset(this->
r2, 0x00,
sizeof(this->
r2));
117 std::memset(this->
r3, 0x00,
sizeof(this->
r3));
118 std::memset(this->
r4, 0x00,
sizeof(this->
r4));
119 std::memset(this->
r5, 0x00,
sizeof(this->
r5));
120 std::memset(this->
r6, 0x00,
sizeof(this->
r6));
121 std::memset(this->
r7, 0x00,
sizeof(this->
r7));
122 std::memset(this->
r8, 0x00,
sizeof(this->
r8));
123 std::memset(this->
r9, 0x00,
sizeof(this->
r9));
124 std::memset(this->
r10, 0x00,
sizeof(this->
r10));
125 std::memset(this->
r11, 0x00,
sizeof(this->
r11));
126 std::memset(this->
r12, 0x00,
sizeof(this->
r12));
127 std::memset(this->
sp, 0x00,
sizeof(this->
sp));
128 std::memset(this->
r14, 0x00,
sizeof(this->
r14));
129 std::memset(this->
pc, 0x00,
sizeof(this->
pc));
130 std::memset(this->apsr, 0x00,
sizeof(this->apsr));
146 return ((regId >= triton::arch::ID_REG_ARM32_C && regId <= triton::arch::ID_REG_ARM32_Z) ?
true :
false);
151 return this->
isGPR(regId);
161 return ((regId >= triton::arch::ID_REG_ARM32_R0 && regId <= triton::arch::ID_REG_ARM32_APSR) ?
true :
false);
190 std::set<const triton::arch::Register*> ret;
192 for (
const auto& kv: this->
id2reg) {
193 auto regId = kv.first;
194 const auto& reg = kv.second;
197 if (reg.getSize() == this->
gprSize())
201 else if (this->
isFlag(regId))
211 return this->
id2reg.at(
id);
212 }
catch (
const std::out_of_range&) {
219 std::string lower = name;
220 std::transform(lower.begin(), lower.end(), lower.begin(), [](
unsigned char c){ return std::tolower(c); });
223 }
catch (
const std::out_of_range&) {
250 triton::extlibs::capstone::csh handle;
251 triton::extlibs::capstone::cs_insn* insn;
259 handle = (this->
thumb ? this->handleThumb : this->handleArm);
272 triton::extlibs::capstone::cs_detail* detail = insn->detail;
275 inst.
setOpcode(insn[0].bytes, insn[0].size);
299 std::stringstream str;
302 str << insn[0].mnemonic;
306 str <<
" " << insn[0].op_str;
313 if (this->itInstrsCount > 0)
317 strncpy(this->itStateArray, &insn[0].mnemonic[1], 5);
318 this->itStateArray[4] = 0;
320 this->itInstrsCount = strlen(this->itStateArray);
321 this->itInstrIndex = 0;
324 this->itCCInv = this->invertCodeCondition(this->itCC);
342 this->itInstrsCount--;
343 this->itInstrIndex++;
348 triton::extlibs::capstone::cs_arm_op* op = &(detail->arm.operands[n]);
351 case triton::extlibs::capstone::ARM_OP_IMM: {
361 case triton::extlibs::capstone::ARM_OP_MEM: {
410 if (op->subtracted) {
423 if (base.
getId() == this->pcId) {
430 auto offset = this->
thumb ? 4 : 8;
434 address = address & 0xfffffffc;
452 case triton::extlibs::capstone::ARM_OP_REG: {
507 if (detail->groups_count > 0) {
509 if (detail->groups[n] == triton::extlibs::capstone::ARM_GRP_JUMP) {
517 this->postDisassembly(inst);
520 triton::extlibs::capstone::cs_free(insn, count);
582 for (
auto& op : inst.operands) {
593 if (execCallbacks && this->callbacks)
596 auto it = this->
memory.find(addr);
597 if (it == this->
memory.end())
609 if (execCallbacks && this->callbacks)
626 std::vector<triton::uint8> area;
629 area.push_back(this->getConcreteMemoryValue(baseAddr+index, execCallbacks));
638 if (execCallbacks && this->callbacks)
641 switch (reg.
getId()) {
642 case triton::arch::ID_REG_ARM32_R0:
return (*((
triton::uint32*)(this->
r0)));
643 case triton::arch::ID_REG_ARM32_R1:
return (*((
triton::uint32*)(this->
r1)));
644 case triton::arch::ID_REG_ARM32_R2:
return (*((
triton::uint32*)(this->
r2)));
645 case triton::arch::ID_REG_ARM32_R3:
return (*((
triton::uint32*)(this->
r3)));
646 case triton::arch::ID_REG_ARM32_R4:
return (*((
triton::uint32*)(this->
r4)));
647 case triton::arch::ID_REG_ARM32_R5:
return (*((
triton::uint32*)(this->
r5)));
648 case triton::arch::ID_REG_ARM32_R6:
return (*((
triton::uint32*)(this->
r6)));
649 case triton::arch::ID_REG_ARM32_R7:
return (*((
triton::uint32*)(this->
r7)));
650 case triton::arch::ID_REG_ARM32_R8:
return (*((
triton::uint32*)(this->
r8)));
651 case triton::arch::ID_REG_ARM32_R9:
return (*((
triton::uint32*)(this->
r9)));
655 case triton::arch::ID_REG_ARM32_SP:
return (*((
triton::uint32*)(this->
sp)));
657 case triton::arch::ID_REG_ARM32_PC:
return (*((
triton::uint32*)(this->
pc)));
658 case triton::arch::ID_REG_ARM32_APSR:
return (*((
triton::uint32*)(this->apsr)));
659 case triton::arch::ID_REG_ARM32_N:
return (((*((
triton::uint32*)(this->apsr))) >> 31) & 1);
660 case triton::arch::ID_REG_ARM32_Z:
return (((*((
triton::uint32*)(this->apsr))) >> 30) & 1);
661 case triton::arch::ID_REG_ARM32_C:
return (((*((
triton::uint32*)(this->apsr))) >> 29) & 1);
662 case triton::arch::ID_REG_ARM32_V:
return (((*((
triton::uint32*)(this->apsr))) >> 28) & 1);
672 if (execCallbacks && this->callbacks)
674 this->
memory[addr] = value;
684 throw triton::exceptions::Register(
"Arm32Cpu::setConcreteMemoryValue(): You cannot set this concrete value (too big) to this memory access.");
689 if (execCallbacks && this->callbacks)
700 this->
memory.reserve(values.size() + this->memory.size());
701 for (
triton::usize index = 0; index < values.size(); index++) {
717 throw triton::exceptions::Register(
"Arm32Cpu::setConcreteRegisterValue(): You cannot set this concrete value (too big) to this register.");
719 if (execCallbacks && this->callbacks)
722 switch (reg.
getId()) {
738 case triton::arch::ID_REG_ARM32_PC: {
747 if (this->
isThumb() ==
false && (
pc & 0x1) == 0x1) {
754 case triton::arch::ID_REG_ARM32_N: {
756 (*((
triton::uint32*)(this->apsr))) = !value.is_zero() ? b | (1 << 31) : b & ~(1 << 31);
759 case triton::arch::ID_REG_ARM32_Z: {
761 (*((
triton::uint32*)(this->apsr))) = !value.is_zero() ? b | (1 << 30) : b & ~(1 << 30);
764 case triton::arch::ID_REG_ARM32_C: {
766 (*((
triton::uint32*)(this->apsr))) = !value.is_zero() ? b | (1 << 29) : b & ~(1 << 29);
769 case triton::arch::ID_REG_ARM32_V: {
771 (*((
triton::uint32*)(this->apsr))) = !value.is_zero() ? b | (1 << 28) : b & ~(1 << 28);
794 if (this->exclusiveMemoryTags.find(base + index) != this->exclusiveMemoryTags.end()) {
808 this->exclusiveMemoryTags.insert(base + index);
811 this->exclusiveMemoryTags.erase(base + index);
824 if (this->
memory.find(baseAddr + index) == this->memory.end())
838 if (this->
memory.find(baseAddr + index) != this->memory.end()) {
839 this->
memory.erase(baseAddr + index);
TRITON_EXPORT triton::uint512 getMaxValue(void) const
Returns the max possible value of the bitvector.
TRITON_EXPORT void setBits(triton::uint32 high, triton::uint32 low)
Sets the bits (high, low) position.
This class is used to represent an instruction.
TRITON_EXPORT void setOpcode(const void *opcode, triton::uint32 size)
Sets the opcode of the instruction.
TRITON_EXPORT void setUpdateFlag(bool state)
Sets the updateFlag of the instruction.
TRITON_EXPORT triton::uint32 getSize(void) const
Returns the size of the instruction.
TRITON_EXPORT void setDisassembly(const std::string &str)
Sets the disassembly of the instruction.
TRITON_EXPORT void setThumb(bool state)
Sets the Thumb mode of the instruction.
TRITON_EXPORT const triton::uint8 * getOpcode(void) const
Returns the opcode of the instruction.
TRITON_EXPORT bool isThumb(void) const
Returns true if it is a Thumb instruction.
TRITON_EXPORT void setType(triton::uint32 type)
Sets the type of the instruction.
TRITON_EXPORT void setAddress(triton::uint64 addr)
Sets the address of the instruction.
TRITON_EXPORT triton::uint32 getType(void) const
Returns the type of the instruction.
TRITON_EXPORT void setArchitecture(triton::arch::architecture_e arch)
Sets the instruction's architecture.
TRITON_EXPORT void setWriteBack(bool state)
Sets the writeBack flag of the instruction.
TRITON_EXPORT triton::uint64 getAddress(void) const
Returns the address of the instruction.
TRITON_EXPORT void setBranch(bool flag)
Sets flag to define this instruction as branch or not.
TRITON_EXPORT void setSize(triton::uint32 size)
Sets the size of the instruction.
TRITON_EXPORT void setCodeCondition(triton::arch::arm::condition_e codeCondition)
Sets the code condition of the instruction (mainly for AArch64).
std::vector< triton::arch::OperandWrapper > operands
A list of operands.
TRITON_EXPORT void setControlFlow(bool flag)
Sets flag to define this instruction changes the control flow or not.
TRITON_EXPORT triton::arch::arm::condition_e getCodeCondition(void) const
Returns the code codition of the instruction (mainly for AArch64).
TRITON_EXPORT std::string getDisassembly(void) const
Returns the disassembly of the instruction.
This class is used to represent a memory access.
TRITON_EXPORT void setDisplacement(const triton::arch::Immediate &displacement)
LEA - Sets the displacement operand.
TRITON_EXPORT void setScale(const triton::arch::Immediate &scale)
LEA - Sets the scale operand.
TRITON_EXPORT triton::uint64 getAddress(void) const
Returns the address of the memory.
TRITON_EXPORT void setPcRelative(triton::uint64 addr)
LEA - Sets pc relative.
TRITON_EXPORT triton::uint32 getSize(void) const
Returns the size (in bytes) of the memory vector.
TRITON_EXPORT void setIndexRegister(const triton::arch::Register &index)
LEA - Sets the index register operand.
TRITON_EXPORT void setBaseRegister(const triton::arch::Register &base)
LEA - Sets the base register operand.
This class is used as operand wrapper.
This class is used when an instruction has a register operand.
TRITON_EXPORT triton::arch::register_e getParent(void) const
Returns the parent id of the register.
TRITON_EXPORT triton::arch::register_e getId(void) const
Returns the id of the register.
TRITON_EXPORT triton::uint32 getSize(void) const
Returns the size (in bytes) of the register.
TRITON_EXPORT void setShiftType(triton::arch::arm::shift_e type)
Sets the type of the shift.
TRITON_EXPORT void setSubtracted(bool value)
Sets subtracted flag.
TRITON_EXPORT void setShiftValue(triton::uint32 imm)
Sets the value of the shift immediate.
This class is used to describe the ARM (32-bits) spec.
TRITON_EXPORT void setMemoryExclusiveTag(const triton::arch::MemoryAccess &mem, bool tag)
Sets exclusive memory access tag. Only valid for Arm32 and AArch64.
TRITON_EXPORT std::set< const triton::arch::Register * > getParentRegisters(void) const
Returns all parent registers.
triton::uint8 r2[triton::size::dword]
Concrete value of r2.
TRITON_EXPORT const std::unordered_map< triton::uint64, triton::uint8, IdentityHash< triton::uint64 > > & getConcreteMemory(void) const
Return all memory.
TRITON_EXPORT triton::uint32 gprSize(void) const
Returns the bit in byte of the General Purpose Registers.
triton::uint8 pc[triton::size::dword]
Concrete value of pc.
triton::uint8 r7[triton::size::dword]
Concrete value of r7.
triton::uint8 sp[triton::size::dword]
Concrete value of sp.
triton::uint8 r1[triton::size::dword]
Concrete value of r1.
TRITON_EXPORT const triton::arch::Register & getStackPointer(void) const
Returns the stack pointer register.
TRITON_EXPORT bool isGPR(triton::arch::register_e regId) const
Returns true if regId is a GRP.
TRITON_EXPORT triton::arch::endianness_e getEndianness(void) const
Returns the kind of endianness as triton::arch::endianness_e.
triton::uint8 r14[triton::size::dword]
Concrete value of r14.
TRITON_EXPORT void clearConcreteMemoryValue(const triton::arch::MemoryAccess &mem)
Clears concrete values assigned to the memory cells.
TRITON_EXPORT triton::uint512 getConcreteRegisterValue(const triton::arch::Register ®, bool execCallbacks=true) const
Returns the concrete value of a register.
triton::uint8 r6[triton::size::dword]
Concrete value of r6.
TRITON_EXPORT bool isFlag(triton::arch::register_e regId) const
Returns true if the register ID is a flag.
TRITON_EXPORT bool isConcreteMemoryValueDefined(const triton::arch::MemoryAccess &mem) const
Returns true if memory cells have a defined concrete value.
TRITON_EXPORT void setConcreteMemoryValue(const triton::arch::MemoryAccess &mem, const triton::uint512 &value, bool execCallbacks=true)
[architecture api] - Sets the concrete value of memory cells.
TRITON_EXPORT bool isRegisterValid(triton::arch::register_e regId) const
Returns true if the register ID is valid.
TRITON_EXPORT bool isThumb(void) const
Returns true if the execution mode is Thumb. Only useful for Arm32.
TRITON_EXPORT const triton::arch::Register & getRegister(triton::arch::register_e id) const
Returns register from id.
TRITON_EXPORT const triton::arch::Register & getProgramCounter(void) const
Returns the program counter register.
virtual TRITON_EXPORT ~Arm32Cpu()
Destructor.
TRITON_EXPORT void clear(void)
Clears the architecture states (registers and memory).
bool thumb
Thumb mode flag.
std::unordered_map< triton::uint64, triton::uint8, IdentityHash< triton::uint64 > > memory
map of address -> concrete value
TRITON_EXPORT void disassembly(triton::arch::Instruction &inst)
Disassembles the instruction according to the architecture.
TRITON_EXPORT triton::uint32 gprBitSize(void) const
Returns the bit in bit of the General Purpose Registers.
TRITON_EXPORT Arm32Cpu(triton::callbacks::Callbacks *callbacks=nullptr)
Constructor.
triton::uint8 r5[triton::size::dword]
Concrete value of r5.
triton::uint8 r11[triton::size::dword]
Concrete value of r11.
triton::uint8 r8[triton::size::dword]
Concrete value of r8.
TRITON_EXPORT std::vector< triton::uint8 > getConcreteMemoryAreaValue(triton::uint64 baseAddr, triton::usize size, bool execCallbacks=true) const
Returns the concrete value of a memory area.
triton::uint8 r10[triton::size::dword]
Concrete value of r10.
TRITON_EXPORT triton::uint512 getConcreteMemoryValue(const triton::arch::MemoryAccess &mem, bool execCallbacks=true) const
Returns the concrete value of memory cells.
triton::uint8 r12[triton::size::dword]
Concrete value of r12.
TRITON_EXPORT bool isRegister(triton::arch::register_e regId) const
Returns true if the register ID is a register.
TRITON_EXPORT triton::uint32 numberOfRegisters(void) const
Returns the number of registers according to the CPU architecture.
TRITON_EXPORT Arm32Cpu & operator=(const Arm32Cpu &other)
Copies a Arm32Cpu class.
TRITON_EXPORT void setConcreteRegisterValue(const triton::arch::Register ®, const triton::uint512 &value, bool execCallbacks=true)
[architecture api] - Sets the concrete value of a register.
TRITON_EXPORT const std::unordered_map< triton::arch::register_e, const triton::arch::Register > & getAllRegisters(void) const
Returns all registers.
TRITON_EXPORT const triton::arch::Register & getParentRegister(const triton::arch::Register ®) const
Returns parent register from a given one.
triton::uint8 r3[triton::size::dword]
Concrete value of r3.
TRITON_EXPORT bool isMemoryExclusive(const triton::arch::MemoryAccess &mem) const
Returns true if the given memory access is tagged as exclusive. Only valid for Arm32 and AArch64.
triton::uint8 r0[triton::size::dword]
Concrete value of r0.
TRITON_EXPORT void setThumb(bool state)
Sets CPU state to Thumb mode.
TRITON_EXPORT void setConcreteMemoryAreaValue(triton::uint64 baseAddr, const std::vector< triton::uint8 > &values, bool execCallbacks=true)
[architecture api] - Sets the concrete value of a memory area.
triton::uint8 r4[triton::size::dword]
Concrete value of r4.
triton::uint8 r9[triton::size::dword]
Concrete value of r9.
The Arm32Specifications class defines specifications about the Arm32 CPU.
std::unordered_map< triton::arch::register_e, const triton::arch::Register > id2reg
List of registers specification available for this architecture.
TRITON_EXPORT triton::arch::register_e capstoneRegisterToTritonRegister(triton::uint32 id) const
Converts a capstone's register id to a triton's register id.
TRITON_EXPORT triton::uint32 capstoneInstructionToTritonInstruction(triton::uint32 id) const
Converts a capstone's instruction id to a triton's instruction id.
TRITON_EXPORT triton::arch::arm::shift_e capstoneShiftToTritonShift(triton::uint32 id) const
Converts a capstone's shift id to a triton's shift id.
TRITON_EXPORT triton::arch::arm::condition_e capstoneConditionToTritonCondition(triton::uint32 id) const
Converts a capstone's condition id to a triton's condition id.
TRITON_EXPORT triton::uint32 getMemoryOperandSpecialSize(triton::uint32 id) const
Returns memory access size if it is specified by instruction.
TRITON_EXPORT triton::ast::SharedAbstractNode processCallbacks(triton::callbacks::callback_e kind, triton::ast::SharedAbstractNode node)
Processes callbacks according to the kind and the C++ polymorphism.
The exception class used by all CPUs.
The exception class used by the disassembler.
The exception class used by register operands.
register_e
Types of register.
@ ID_REG_LAST_ITEM
must be the last item
condition_e
Types of condition.
@ ID_SHIFT_LSR
Logical Shift Right (immediate)
@ ID_SHIFT_LSR_REG
Logical Shift Right (register)
@ ID_SHIFT_ASR
Arithmetic Shift Right (immediate)
@ ID_SHIFT_ROR_REG
Rotate Right (register)
@ ID_SHIFT_ROR
Rotate Right (immediate)
@ ID_SHIFT_ASR_REG
Arithmetic Shift Right (register)
@ ID_SHIFT_RRX
Rotate Right with Extend (immediate)
@ ID_SHIFT_RRX_REG
Rotate Right with Extend (register)
@ ID_SHIFT_LSL_REG
Logical Shift Left (register)
@ ID_SHIFT_INVALID
invalid
@ ID_SHIFT_LSL
Logical Shift Left (immediate)
@ ID_CONDITION_HS
Higher or same (unsigned >=). C set.
@ ID_CONDITION_PL
Positive or zero. N clear.
@ ID_CONDITION_VC
No overflow. V clear.
@ ID_CONDITION_LE
Signed <=. Z set, N and V differ.
@ ID_CONDITION_VS
Overflow. V set.
@ ID_CONDITION_MI
Negative. N set.
@ ID_CONDITION_GE
Signed >=. N and V the same.
@ ID_CONDITION_GT
Signed >. Z clear, N and V the same.
@ ID_CONDITION_HI
Higher (unsigned >). C set and Z clear.
@ ID_CONDITION_NE
Not equal. Z clear.
@ ID_CONDITION_AL
Always. Any flags. This suffix is normally omitted.
@ ID_CONDITION_LO
Lower (unsigned <). C clear.
@ ID_CONDITION_LT
Signed <. N and V differ.
@ ID_CONDITION_LS
Lower or same (unsigned <=). C clear or Z set.
@ ID_CONDITION_INVALID
invalid
@ ID_CONDITION_EQ
Equal. Z set.
constexpr triton::uint32 byte
byte size in bit
constexpr triton::uint32 dword
dword size in bit
@ GET_CONCRETE_REGISTER_VALUE
@ GET_CONCRETE_MEMORY_VALUE
@ SET_CONCRETE_MEMORY_VALUE
@ SET_CONCRETE_REGISTER_VALUE
constexpr triton::uint32 dword
dword size in byte
constexpr triton::uint32 dqqword
dqqword size in byte
constexpr triton::uint32 byte
byte size in byte
std::int32_t sint32
signed 32-bits
std::size_t usize
unsigned MAX_INT 32 or 64 bits according to the CPU.
std::uint64_t uint64
unisgned 64-bits
std::uint32_t uint32
unisgned 32-bits
std::uint8_t uint8
unisgned 8-bits