libTriton  version 1.0 build 1558
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
32 return this->arch;
33 }
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->isMemoryExclusiveAccess();
138 }
139
140
142 if (this->cpu) {
143 this->cpu->setMemoryExclusiveAccess(state);
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
176 std::set<const triton::arch::Register*> Architecture::getParentRegisters(void) const {
177 if (!this->cpu)
178 throw triton::exceptions::Architecture("Architecture::getParentRegisters(): You must define an architecture.");
179 return this->cpu->getParentRegisters();
180 }
181
182
184 if (!this->cpu)
185 throw triton::exceptions::Architecture("Architecture::getProgramCounter(): You must define an architecture.");
186 return this->cpu->getProgramCounter();
187 }
188
189
191 if (!this->cpu)
192 throw triton::exceptions::Architecture("Architecture::getStackPointer(): You must define an architecture.");
193 return this->cpu->getStackPointer();
194 }
195
196
198 if (!this->cpu)
199 throw triton::exceptions::Architecture("Architecture::getRegister(): You must define an architecture.");
200 return this->cpu->getRegister(id);
201 }
202
203
204 const triton::arch::Register& Architecture::getRegister(const std::string& name) const {
205 if (!this->cpu)
206 throw triton::exceptions::Architecture("Architecture::getRegister(): You must define an architecture.");
207 return this->cpu->getRegister(name);
208 }
209
210
212 if (!this->cpu)
213 throw triton::exceptions::Architecture("Architecture::getParentRegister(): You must define an architecture.");
214 return this->cpu->getParentRegister(reg);
215 }
216
217
219 if (!this->cpu)
220 throw triton::exceptions::Architecture("Architecture::getParentRegister(): You must define an architecture.");
221 return this->cpu->getParentRegister(id);
222 }
223
224
226 if (!this->cpu)
227 throw triton::exceptions::Architecture("Architecture::disassembly(): You must define an architecture.");
228 this->cpu->disassembly(inst);
229 }
230
231
233 if (!this->cpu)
234 throw triton::exceptions::Architecture("Architecture::disassembly(): You must define an architecture.");
235
236 for (auto& inst : block.getInstructions()) {
237 inst.setAddress(addr);
238 this->cpu->disassembly(inst);
239 addr += inst.getSize();
240 }
241 }
242
243
244 std::vector<triton::arch::Instruction> Architecture::disassembly(triton::uint64 addr, triton::usize count) const {
245 std::vector<triton::arch::Instruction> ret;
246 ret.reserve(count);
247
248 while (count--) {
249 if (!this->isConcreteMemoryValueDefined(addr)) {
250 break;
251 }
252 auto opcodes = this->getConcreteMemoryAreaValue(addr, 16);
253 auto inst = triton::arch::Instruction(addr, reinterpret_cast<triton::uint8*>(opcodes.data()), opcodes.size());
254 this->disassembly(inst);
255 ret.push_back(inst);
256 addr += inst.getSize();
257 }
258
259 return ret;
260 }
261
262
264 std::vector<triton::arch::Instruction> ret;
265
266 do {
267 if (!this->isConcreteMemoryValueDefined(addr)) {
268 break;
269 }
270 auto opcodes = this->getConcreteMemoryAreaValue(addr, 16);
271 auto inst = triton::arch::Instruction(addr, reinterpret_cast<triton::uint8*>(opcodes.data()), opcodes.size());
272 this->disassembly(inst);
273 ret.push_back(inst);
274 addr += inst.getSize();
275 } while (!ret.back().isControlFlow());
276
277 return triton::arch::BasicBlock(ret);
278 }
279
280
282 if (!this->cpu)
283 throw triton::exceptions::Architecture("Architecture::getConcreteMemoryValue(): You must define an architecture.");
284 return this->cpu->getConcreteMemoryValue(addr, execCallbacks);
285 }
286
287
289 if (!this->cpu)
290 throw triton::exceptions::Architecture("Architecture::getConcreteMemoryValue(): You must define an architecture.");
291 return this->cpu->getConcreteMemoryValue(mem, execCallbacks);
292 }
293
294
295 std::vector<triton::uint8> Architecture::getConcreteMemoryAreaValue(triton::uint64 baseAddr, triton::usize size, bool execCallbacks) const {
296 if (!this->cpu)
297 throw triton::exceptions::Architecture("Architecture::getConcreteMemoryAreaValue(): You must define an architecture.");
298 return this->cpu->getConcreteMemoryAreaValue(baseAddr, size, execCallbacks);
299 }
300
301
303 if (!this->cpu)
304 throw triton::exceptions::Architecture("Architecture::getConcreteRegisterValue(): You must define an architecture.");
305 return this->cpu->getConcreteRegisterValue(reg, execCallbacks);
306 }
307
308
310 if (!this->cpu)
311 throw triton::exceptions::Architecture("Architecture::setConcreteMemoryValue(): You must define an architecture.");
312 this->cpu->setConcreteMemoryValue(addr, value, execCallbacks);
313 }
314
315
316 void Architecture::setConcreteMemoryValue(const triton::arch::MemoryAccess& mem, const triton::uint512& value, bool execCallbacks) {
317 if (!this->cpu)
318 throw triton::exceptions::Architecture("Architecture::setConcreteMemoryValue(): You must define an architecture.");
319 this->cpu->setConcreteMemoryValue(mem, value, execCallbacks);
320 }
321
322
323 void Architecture::setConcreteMemoryAreaValue(triton::uint64 baseAddr, const std::vector<triton::uint8>& values, bool execCallbacks) {
324 if (!this->cpu)
325 throw triton::exceptions::Architecture("Architecture::setConcreteMemoryAreaValue(): You must define an architecture.");
326 this->cpu->setConcreteMemoryAreaValue(baseAddr, values, execCallbacks);
327 }
328
329
330 void Architecture::setConcreteMemoryAreaValue(triton::uint64 baseAddr, const void* area, triton::usize size, bool execCallbacks) {
331 if (!this->cpu)
332 throw triton::exceptions::Architecture("Architecture::setConcreteMemoryAreaValue(): You must define an architecture.");
333 this->cpu->setConcreteMemoryAreaValue(baseAddr, area, size, execCallbacks);
334 }
335
336
337 void Architecture::setConcreteRegisterValue(const triton::arch::Register& reg, const triton::uint512& value, bool execCallbacks) {
338 if (!this->cpu)
339 throw triton::exceptions::Architecture("Architecture::setConcreteRegisterValue(): You must define an architecture.");
340 this->cpu->setConcreteRegisterValue(reg, value, execCallbacks);
341 }
342
343
345 if (!this->cpu)
346 throw triton::exceptions::Architecture("Architecture::isConcreteMemoryValueDefined(): You must define an architecture.");
347 return this->cpu->isConcreteMemoryValueDefined(mem);
348 }
349
350
352 if (!this->cpu)
353 throw triton::exceptions::Architecture("Architecture::isConcreteMemoryValueDefined(): You must define an architecture.");
354 return this->cpu->isConcreteMemoryValueDefined(baseAddr, size);
355 }
356
357
359 if (!this->cpu)
360 throw triton::exceptions::Architecture("Architecture::clearConcreteMemoryValue(): You must define an architecture.");
361 this->cpu->clearConcreteMemoryValue(mem);
362 }
363
364
366 if (!this->cpu)
367 throw triton::exceptions::Architecture("Architecture::clearConcreteMemoryValue(): You must define an architecture.");
368 this->cpu->clearConcreteMemoryValue(baseAddr, size);
369 }
370
371
373 if (!this->cpu)
374 throw triton::exceptions::Architecture("Architecture::getNopInstruction(): You must define an architecture.");
375
376 switch (this->getArchitecture()) {
379
381 if (this->isThumb())
383 else
385 }
386
390
391 default:
392 throw triton::exceptions::Architecture("Architecture::getNopInstruction(): Invalid architecture.");
393 }
394 }
395
396 }; /* arch namespace */
397}; /* 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 bool isMemoryExclusiveAccess(void) const
Returns true if the exclusive memory access flag is set. 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 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 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 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 setMemoryExclusiveAccess(bool state)
Sets exclusive memory access flag. Only valid for Arm32.
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.
Definition: basicBlock.hpp:38
TRITON_EXPORT std::vector< triton::arch::Instruction > & getInstructions(void)
Gets all instructions of the block.
Definition: basicBlock.cpp:58
This interface is used as abstract CPU interface. All CPU must use this interface.
This class is used to represent an instruction.
Definition: instruction.hpp:48
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.
Definition: aarch64Cpu.hpp:61
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.
Definition: exceptions.hpp:221
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
Definition: tritonTypes.hpp:42
std::uint32_t uint32
unisgned 32-bits
Definition: tritonTypes.hpp:39
std::uint8_t uint8
unisgned 8-bits
Definition: tritonTypes.hpp:33
const triton::arch::Instruction nop
x86 NOP instruction
The Triton namespace.