libTriton version 1.0 build 1590
Loading...
Searching...
No Matches
architecture.cpp
Go to the documentation of this file.
1
2/*
3** Copyright (C) - Triton
4**
5** This program is under the terms of the Apache License 2.0.
6*/
7
8#include <new>
9
10#include <triton/aarch64Cpu.hpp>
13#include <triton/arm32Cpu.hpp>
15#include <triton/exceptions.hpp>
16#include <triton/x8664Cpu.hpp>
17#include <triton/x86Cpu.hpp>
19
20
21
22namespace triton {
23 namespace arch {
24
27 this->callbacks = callbacks;
28 }
29
30
34
35
37 if (!this->cpu)
38 throw triton::exceptions::Architecture("Architecture::getEndianness(): You must define an architecture.");
39 return this->cpu->getEndianness();
40 }
41
42
44 if (!this->cpu)
45 throw triton::exceptions::Architecture("Architecture::getCpuInstance(): CPU undefined.");
46 return this->cpu.get();
47 }
48
49
51 /* Allocate and init the good arch */
52 switch (arch) {
53 case triton::arch::ARCH_X86_64: this->cpu.reset(new(std::nothrow) triton::arch::x86::x8664Cpu(this->callbacks)); break;
54 case triton::arch::ARCH_X86: this->cpu.reset(new(std::nothrow) triton::arch::x86::x86Cpu(this->callbacks)); break;
55 case triton::arch::ARCH_AARCH64: this->cpu.reset(new(std::nothrow) triton::arch::arm::aarch64::AArch64Cpu(this->callbacks)); break;
56 case triton::arch::ARCH_ARM32: this->cpu.reset(new(std::nothrow) triton::arch::arm::arm32::Arm32Cpu(this->callbacks)); break;
57 default:
58 throw triton::exceptions::Architecture("Architecture::setArchitecture(): Architecture not supported.");
59 }
60
61 if (this->cpu == nullptr) {
62 throw triton::exceptions::Architecture("Architecture::setArchitecture(): Not enough memory.");
63 }
64
65 /* Setup global variables */
66 this->arch = arch;
67 }
68
69
71 if (!this->cpu)
72 throw triton::exceptions::Architecture("Architecture::clearArchitecture(): You must define an architecture.");
73 this->cpu->clear();
74 }
75
76
77 bool Architecture::isValid(void) const {
79 return false;
80 return true;
81 }
82
83
85 if (!this->cpu)
86 return false;
87 return this->cpu->isFlag(regId);
88 }
89
90
92 return this->isFlag(reg.getId());
93 }
94
95
97 if (!this->cpu)
98 return false;
99 return this->cpu->isRegister(regId);
100 }
101
102
104 return this->isRegister(reg.getId());
105 }
106
107
109 if (!this->cpu)
110 return false;
111 return this->cpu->isRegisterValid(regId);
112 }
113
114
116 return this->isRegisterValid(reg.getId());
117 }
118
119
120 bool Architecture::isThumb(void) const {
121 if (!this->cpu)
122 return false;
123 return this->cpu->isThumb();
124 }
125
126
127 void Architecture::setThumb(bool state) {
128 if (this->cpu) {
129 this->cpu->setThumb(state);
130 }
131 }
132
133
135 if (!this->cpu)
136 return false;
137 return this->cpu->isMemoryExclusive(mem);
138 }
139
140
142 if (this->cpu) {
143 this->cpu->setMemoryExclusiveTag(mem, tag);
144 }
145 }
146
147
149 if (!this->cpu)
150 return 0;
151 return this->cpu->numberOfRegisters();
152 }
153
154
156 if (!this->cpu)
157 return 0;
158 return this->cpu->gprSize();
159 }
160
161
163 if (!this->cpu)
164 return 0;
165 return this->cpu->gprBitSize();
166 }
167
168
169 const std::unordered_map<triton::arch::register_e, const triton::arch::Register>& Architecture::getAllRegisters(void) const {
170 if (!this->cpu)
171 throw triton::exceptions::Architecture("Architecture::getAllRegisters(): You must define an architecture.");
172 return this->cpu->getAllRegisters();
173 }
174
175 const std::unordered_map<triton::uint64, triton::uint8, IdentityHash<triton::uint64>>& Architecture::getConcreteMemory(void) const {
176 if (!this->cpu)
177 throw triton::exceptions::Architecture("Architecture::getConcreteMemory(): You must define an architecture.");
178 return this->cpu->getConcreteMemory();
179 }
180
181
182 std::set<const triton::arch::Register*> Architecture::getParentRegisters(void) const {
183 if (!this->cpu)
184 throw triton::exceptions::Architecture("Architecture::getParentRegisters(): You must define an architecture.");
185 return this->cpu->getParentRegisters();
186 }
187
188
190 if (!this->cpu)
191 throw triton::exceptions::Architecture("Architecture::getProgramCounter(): You must define an architecture.");
192 return this->cpu->getProgramCounter();
193 }
194
195
197 if (!this->cpu)
198 throw triton::exceptions::Architecture("Architecture::getStackPointer(): You must define an architecture.");
199 return this->cpu->getStackPointer();
200 }
201
202
204 if (!this->cpu)
205 throw triton::exceptions::Architecture("Architecture::getRegister(): You must define an architecture.");
206 return this->cpu->getRegister(id);
207 }
208
209
210 const triton::arch::Register& Architecture::getRegister(const std::string& name) const {
211 if (!this->cpu)
212 throw triton::exceptions::Architecture("Architecture::getRegister(): You must define an architecture.");
213 return this->cpu->getRegister(name);
214 }
215
216
218 if (!this->cpu)
219 throw triton::exceptions::Architecture("Architecture::getParentRegister(): You must define an architecture.");
220 return this->cpu->getParentRegister(reg);
221 }
222
223
225 if (!this->cpu)
226 throw triton::exceptions::Architecture("Architecture::getParentRegister(): You must define an architecture.");
227 return this->cpu->getParentRegister(id);
228 }
229
230
232 if (!this->cpu)
233 throw triton::exceptions::Architecture("Architecture::disassembly(): You must define an architecture.");
234 this->cpu->disassembly(inst);
235 }
236
237
239 if (!this->cpu)
240 throw triton::exceptions::Architecture("Architecture::disassembly(): You must define an architecture.");
241
242 for (auto& inst : block.getInstructions()) {
243 inst.setAddress(addr);
244 this->cpu->disassembly(inst);
245 addr += inst.getSize();
246 }
247 }
248
249
250 std::vector<triton::arch::Instruction> Architecture::disassembly(triton::uint64 addr, triton::usize count) const {
251 std::vector<triton::arch::Instruction> ret;
252 ret.reserve(count);
253
254 while (count--) {
255 if (!this->isConcreteMemoryValueDefined(addr)) {
256 break;
257 }
258 auto opcodes = this->getConcreteMemoryAreaValue(addr, 16);
259 auto inst = triton::arch::Instruction(addr, reinterpret_cast<triton::uint8*>(opcodes.data()), opcodes.size());
260 this->disassembly(inst);
261 ret.push_back(inst);
262 addr += inst.getSize();
263 }
264
265 return ret;
266 }
267
268
270 std::vector<triton::arch::Instruction> ret;
271
272 do {
273 if (!this->isConcreteMemoryValueDefined(addr)) {
274 break;
275 }
276 auto opcodes = this->getConcreteMemoryAreaValue(addr, 16);
277 auto inst = triton::arch::Instruction(addr, reinterpret_cast<triton::uint8*>(opcodes.data()), opcodes.size());
278 this->disassembly(inst);
279 ret.push_back(inst);
280 addr += inst.getSize();
281 } while (!ret.back().isControlFlow());
282
283 return triton::arch::BasicBlock(ret);
284 }
285
286
288 if (!this->cpu)
289 throw triton::exceptions::Architecture("Architecture::getConcreteMemoryValue(): You must define an architecture.");
290 return this->cpu->getConcreteMemoryValue(addr, execCallbacks);
291 }
292
293
295 if (!this->cpu)
296 throw triton::exceptions::Architecture("Architecture::getConcreteMemoryValue(): You must define an architecture.");
297 return this->cpu->getConcreteMemoryValue(mem, execCallbacks);
298 }
299
300
301 std::vector<triton::uint8> Architecture::getConcreteMemoryAreaValue(triton::uint64 baseAddr, triton::usize size, bool execCallbacks) const {
302 if (!this->cpu)
303 throw triton::exceptions::Architecture("Architecture::getConcreteMemoryAreaValue(): You must define an architecture.");
304 return this->cpu->getConcreteMemoryAreaValue(baseAddr, size, execCallbacks);
305 }
306
307
309 if (!this->cpu)
310 throw triton::exceptions::Architecture("Architecture::getConcreteRegisterValue(): You must define an architecture.");
311 return this->cpu->getConcreteRegisterValue(reg, execCallbacks);
312 }
313
314
316 if (!this->cpu)
317 throw triton::exceptions::Architecture("Architecture::setConcreteMemoryValue(): You must define an architecture.");
318 this->cpu->setConcreteMemoryValue(addr, value, execCallbacks);
319 }
320
321
322 void Architecture::setConcreteMemoryValue(const triton::arch::MemoryAccess& mem, const triton::uint512& value, bool execCallbacks) {
323 if (!this->cpu)
324 throw triton::exceptions::Architecture("Architecture::setConcreteMemoryValue(): You must define an architecture.");
325 this->cpu->setConcreteMemoryValue(mem, value, execCallbacks);
326 }
327
328
329 void Architecture::setConcreteMemoryAreaValue(triton::uint64 baseAddr, const std::vector<triton::uint8>& values, bool execCallbacks) {
330 if (!this->cpu)
331 throw triton::exceptions::Architecture("Architecture::setConcreteMemoryAreaValue(): You must define an architecture.");
332 this->cpu->setConcreteMemoryAreaValue(baseAddr, values, execCallbacks);
333 }
334
335
336 void Architecture::setConcreteMemoryAreaValue(triton::uint64 baseAddr, const void* area, triton::usize size, bool execCallbacks) {
337 if (!this->cpu)
338 throw triton::exceptions::Architecture("Architecture::setConcreteMemoryAreaValue(): You must define an architecture.");
339 this->cpu->setConcreteMemoryAreaValue(baseAddr, area, size, execCallbacks);
340 }
341
342
343 void Architecture::setConcreteRegisterValue(const triton::arch::Register& reg, const triton::uint512& value, bool execCallbacks) {
344 if (!this->cpu)
345 throw triton::exceptions::Architecture("Architecture::setConcreteRegisterValue(): You must define an architecture.");
346 this->cpu->setConcreteRegisterValue(reg, value, execCallbacks);
347 }
348
349
351 if (!this->cpu)
352 throw triton::exceptions::Architecture("Architecture::isConcreteMemoryValueDefined(): You must define an architecture.");
353 return this->cpu->isConcreteMemoryValueDefined(mem);
354 }
355
356
358 if (!this->cpu)
359 throw triton::exceptions::Architecture("Architecture::isConcreteMemoryValueDefined(): You must define an architecture.");
360 return this->cpu->isConcreteMemoryValueDefined(baseAddr, size);
361 }
362
363
365 if (!this->cpu)
366 throw triton::exceptions::Architecture("Architecture::clearConcreteMemoryValue(): You must define an architecture.");
367 this->cpu->clearConcreteMemoryValue(mem);
368 }
369
370
372 if (!this->cpu)
373 throw triton::exceptions::Architecture("Architecture::clearConcreteMemoryValue(): You must define an architecture.");
374 this->cpu->clearConcreteMemoryValue(baseAddr, size);
375 }
376
377
379 if (!this->cpu)
380 throw triton::exceptions::Architecture("Architecture::getNopInstruction(): You must define an architecture.");
381
382 switch (this->getArchitecture()) {
385
387 if (this->isThumb())
389 else
391 }
392
396
397 default:
398 throw triton::exceptions::Architecture("Architecture::getNopInstruction(): Invalid architecture.");
399 }
400 }
401
402 }; /* arch namespace */
403}; /* triton namespace */
TRITON_EXPORT const triton::arch::Register & getRegister(triton::arch::register_e id) const
Returns register from id.
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_EXPORT std::set< const triton::arch::Register * > getParentRegisters(void) const
Returns all parent registers.
TRITON_EXPORT void setThumb(bool state)
Sets CPU state to Thumb mode. Only valid for Arm32.
TRITON_EXPORT const triton::arch::Register & getStackPointer(void) const
Returns the stack pointer register.
TRITON_EXPORT triton::uint32 numberOfRegisters(void) const
Returns the number of registers according to the CPU architecture.
TRITON_EXPORT triton::uint32 gprBitSize(void) const
Returns the bit in bit of the General Purpose Registers.
TRITON_EXPORT void setConcreteRegisterValue(const triton::arch::Register &reg, const triton::uint512 &value, bool execCallbacks=true)
[architecture api] - Sets the concrete value of a register.
TRITON_EXPORT void setConcreteMemoryValue(triton::uint64 addr, triton::uint8 value, bool execCallbacks=true)
[architecture api] - Sets the concrete value of a memory cell.
TRITON_EXPORT void setArchitecture(triton::arch::architecture_e arch)
Initializes an architecture.
TRITON_EXPORT const std::unordered_map< triton::uint64, triton::uint8, IdentityHash< triton::uint64 > > & getConcreteMemory(void) const
Return all memory.
TRITON_EXPORT void disassembly(triton::arch::Instruction &inst) const
Disassembles the instruction according to the architecture.
TRITON_EXPORT void clearArchitecture(void)
Clears the architecture states (registers and memory).
TRITON_EXPORT bool isMemoryExclusive(const triton::arch::MemoryAccess &mem) const
Returns true if the memory access is tagged as exclusive. Only valid for Arm32 and AArch64.
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_EXPORT const triton::arch::Instruction getNopInstruction(void) const
Returns a NOP instruction according to the architecture.
TRITON_EXPORT bool isConcreteMemoryValueDefined(const triton::arch::MemoryAccess &mem) const
Returns true if memory cells have a defined concrete value.
TRITON_EXPORT const std::unordered_map< triton::arch::register_e, const triton::arch::Register > & getAllRegisters(void) const
Returns all registers.
TRITON_EXPORT Architecture(triton::callbacks::Callbacks *callbacks=nullptr)
Constructor.
TRITON_EXPORT bool isFlag(triton::arch::register_e regId) const
Returns true if the register ID is a flag.
TRITON_EXPORT const triton::arch::Register & getProgramCounter(void) const
Returns the program counter register.
std::unique_ptr< triton::arch::CpuInterface > cpu
Instance to the real CPU class.
TRITON_EXPORT void setMemoryExclusiveTag(const triton::arch::MemoryAccess &mem, bool tag)
Sets exclusive memory access tag. Only valid for Arm32 and AArch64.
TRITON_EXPORT triton::uint8 getConcreteMemoryValue(triton::uint64 addr, bool execCallbacks=true) const
Returns the concrete value of a memory cell.
triton::arch::architecture_e arch
The kind of architecture used.
TRITON_EXPORT triton::uint512 getConcreteRegisterValue(const triton::arch::Register &reg, bool execCallbacks=true) const
Returns the concrete value of a register.
TRITON_EXPORT void clearConcreteMemoryValue(const triton::arch::MemoryAccess &mem)
Clears concrete values assigned to the memory cells.
TRITON_EXPORT bool isRegisterValid(triton::arch::register_e regId) const
Returns true if the register ID is a register or a flag.
TRITON_EXPORT bool isRegister(triton::arch::register_e regId) const
Returns true if the register ID is a register.
TRITON_EXPORT bool isThumb(void) const
Returns true if the execution mode is Thumb. Only valid for Arm32.
TRITON_EXPORT triton::arch::architecture_e getArchitecture(void) const
Returns the kind of architecture as triton::arch::architecture_e.
TRITON_EXPORT bool isValid(void) const
Returns true if the architecture is valid.
TRITON_EXPORT triton::arch::endianness_e getEndianness(void) const
Returns the kind of endianness as triton::arch::endianness_e.
TRITON_EXPORT triton::uint32 gprSize(void) const
Returns the bit in byte of the General Purpose Registers.
TRITON_EXPORT const triton::arch::Register & getParentRegister(triton::arch::register_e id) const
Returns parent register from id.
TRITON_EXPORT triton::arch::CpuInterface * getCpuInstance(void)
Returns the instance of the current CPU used.
This class is used to represent a basic block.
TRITON_EXPORT std::vector< triton::arch::Instruction > & getInstructions(void)
Gets all instructions of the block.
This interface is used as abstract CPU interface. All CPU must use this interface.
This class is used to represent an instruction.
This class is used to represent a memory access.
This class is used when an instruction has a register operand.
Definition register.hpp:44
TRITON_EXPORT triton::arch::register_e getId(void) const
Returns the id of the register.
Definition register.cpp:53
This class is used to describe the ARM (64-bits) spec.
This class is used to describe the ARM (32-bits) spec.
Definition arm32Cpu.hpp:61
This class is used to describe the x86 (64-bits) spec.
Definition x8664Cpu.hpp:53
This class is used to describe the x86 (32-bits) spec.
Definition x86Cpu.hpp:53
The callbacks class.
Definition callbacks.hpp:79
The exception class used by architectures.
const triton::arch::Instruction nop
AArch64 NOP instruction.
register_e
Types of register.
Definition archEnums.hpp:64
const triton::arch::Instruction nop
ARM32 NOP instruction.
const triton::arch::Instruction thumbnop
ARM32 Thumb NOP instruction.
std::size_t usize
unsigned MAX_INT 32 or 64 bits according to the CPU.
std::uint64_t uint64
unisgned 64-bits
math::wide_integer::uint512_t uint512
unsigned 512-bits
std::uint32_t uint32
unisgned 32-bits
std::uint8_t uint8
unisgned 8-bits
const triton::arch::Instruction nop
x86 NOP instruction
The Triton namespace.