libTriton version 1.0 build 1590
Loading...
Searching...
No Matches
instruction.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 <cstring>
9
10#include <triton/coreUtils.hpp>
11#include <triton/exceptions.hpp>
12#include <triton/immediate.hpp>
14
15
16
17namespace triton {
18 namespace arch {
19
21 this->address = 0;
23 this->branch = false;
25 this->conditionTaken = 0;
26 this->controlFlow = false;
28 this->size = 0;
29 this->tainted = false;
30 this->thumb = false;
31 this->tid = 0;
32 this->type = 0;
33 this->updateFlag = false;
34 this->writeBack = false;
35
36 std::memset(this->opcode, 0x00, sizeof(this->opcode));
37 }
38
39
40 Instruction::Instruction(const void* opcode, triton::uint32 opSize)
42 this->setOpcode(opcode, opSize);
43 }
44
45
46 Instruction::Instruction(triton::uint64 addr, const void* opcode, triton::uint32 opSize)
47 : Instruction::Instruction(opcode, opSize) {
48 this->setAddress(addr);
49 }
50
51
53 this->copy(other);
54 }
55
56
58 /* See #828: Release ownership before calling container destructor */
59 this->loadAccess.clear();
60 this->readImmediates.clear();
61 this->readRegisters.clear();
62 this->storeAccess.clear();
63 this->symbolicExpressions.clear();
64 this->writtenRegisters.clear();
65 }
66
67
69 this->copy(other);
70 return *this;
71 }
72
73
74 void Instruction::copy(const Instruction& other) {
75 this->address = other.address;
76 this->arch = other.arch;
77 this->branch = other.branch;
78 this->codeCondition = other.codeCondition;
79 this->conditionTaken = other.conditionTaken;
80 this->controlFlow = other.controlFlow;
81 this->loadAccess = other.loadAccess;
82 this->operands = other.operands;
83 this->prefix = other.prefix;
84 this->readImmediates = other.readImmediates;
85 this->readRegisters = other.readRegisters;
86 this->size = other.size;
87 this->storeAccess = other.storeAccess;
89 this->tainted = other.tainted;
90 this->tid = other.tid;
91 this->type = other.type;
93 this->updateFlag = other.updateFlag;
94 this->writeBack = other.writeBack;
96
97 std::memcpy(this->opcode, other.opcode, sizeof(this->opcode));
98
99 this->disassembly.clear();
100 this->disassembly.str(other.disassembly.str());
101 }
102
103
105 return this->tid;
106 }
107
108
110 this->tid = tid;
111 }
112
113
115 return this->address;
116 }
117
118
120 return this->address + this->size;
121 }
122
123
125 this->address = addr;
126 }
127
128
129 std::string Instruction::getDisassembly(void) const {
130 return this->disassembly.str();
131 }
132
133
135 return this->opcode;
136 }
137
138
139 void Instruction::setOpcode(const void* opcode, triton::uint32 size) {
140 if (size > sizeof(this->opcode))
141 throw triton::exceptions::Instruction("Instruction::setOpcode(): Invalid size (too big).");
142 std::memcpy(this->opcode, opcode, size);
143 this->size = size;
144 }
145
146
148 return this->size;
149 }
150
151
153 return this->type;
154 }
155
156
160
161
163 return this->prefix;
164 }
165
166
170
171
172 std::set<std::pair<triton::arch::MemoryAccess, triton::ast::SharedAbstractNode>>& Instruction::getLoadAccess(void) {
173 return this->loadAccess;
174 }
175
176
177 std::set<std::pair<triton::arch::MemoryAccess, triton::ast::SharedAbstractNode>>& Instruction::getStoreAccess(void) {
178 return this->storeAccess;
179 }
180
181
182 std::set<std::pair<triton::arch::Register, triton::ast::SharedAbstractNode>>& Instruction::getReadRegisters(void) {
183 return this->readRegisters;
184 }
185
186
187 std::set<std::pair<triton::arch::Register, triton::ast::SharedAbstractNode>>& Instruction::getWrittenRegisters(void) {
188 return this->writtenRegisters;
189 }
190
191
192 std::set<std::pair<triton::arch::Immediate, triton::ast::SharedAbstractNode>>& Instruction::getReadImmediates(void) {
193 return this->readImmediates;
194 }
195
196
197 std::set<triton::arch::Register>& Instruction::getUndefinedRegisters(void) {
198 return this->undefinedRegisters;
199 }
200
201
203 this->loadAccess.insert(std::make_pair(mem, node));
204 }
205
206
208 auto it = this->loadAccess.begin();
209
210 while (it != this->loadAccess.end()) {
211 if (it->first.getAddress() == mem.getAddress())
212 it = this->loadAccess.erase(it);
213 else
214 ++it;
215 }
216 }
217
218
220 this->storeAccess.insert(std::make_pair(mem, node));
221 }
222
223
225 auto it = this->storeAccess.begin();
226
227 while (it != this->storeAccess.end()) {
228 if (it->first.getAddress() == mem.getAddress())
229 it = this->storeAccess.erase(it);
230 else
231 ++it;
232 }
233 }
234
235
237 this->readRegisters.insert(std::make_pair(reg, node));
238 }
239
240
242 auto it = this->readRegisters.begin();
243
244 while (it != this->readRegisters.end()) {
245 if (it->first.getId() == reg.getId())
246 it = this->readRegisters.erase(it);
247 else
248 ++it;
249 }
250 }
251
252
254 this->writtenRegisters.insert(std::make_pair(reg, node));
255 }
256
257
259 auto it = this->writtenRegisters.begin();
260
261 while (it != this->writtenRegisters.end()) {
262 if (it->first.getId() == reg.getId())
263 it = this->writtenRegisters.erase(it);
264 else
265 ++it;
266 }
267 }
268
269
271 this->readImmediates.insert(std::make_pair(imm, node));
272 }
273
274
276 auto it = this->readImmediates.begin();
277
278 while (it != this->readImmediates.end()) {
279 if (it->first.getValue() == imm.getValue())
280 it = this->readImmediates.erase(it);
281 else
282 ++it;
283 }
284 }
285
286
288 this->undefinedRegisters.insert(reg);
289 }
290
291
295
296
300
301
303 this->size = size;
304 }
305
306
308 this->type = type;
309 }
310
311
313 this->prefix = prefix;
314 }
315
316
317 void Instruction::setWriteBack(bool state) {
318 this->writeBack = state;
319 }
320
321
322 void Instruction::setUpdateFlag(bool state) {
323 this->updateFlag = state;
324 }
325
326
328 this->codeCondition = codeCondition;
329 }
330
331
332 void Instruction::setThumb(bool state) {
333 this->thumb = state;
334 }
335
336
337 void Instruction::setDisassembly(const std::string& str) {
338 this->disassembly.clear();
339 this->disassembly.str(str);
340 }
341
342
343 void Instruction::setTaint(bool state) {
344 this->tainted = state;
345 }
346
347
349 for (auto it = this->symbolicExpressions.begin(); it != this->symbolicExpressions.end(); it++) {
350 if ((*it)->isTainted == true) {
351 this->tainted = true;
352 break;
353 }
354 }
355 }
356
357
359 if (expr == nullptr)
360 throw triton::exceptions::Instruction("Instruction::addSymbolicExpression(): Cannot add a null expression.");
361 expr->writeBackDisassembly(triton::utils::toString(*this));
362 expr->setAddress(this->getAddress());
363 this->symbolicExpressions.push_back(expr);
364 }
365
366
367 bool Instruction::isBranch(void) const {
368 return this->branch;
369 }
370
371
372 bool Instruction::isControlFlow(void) const {
373 return this->controlFlow;
374 }
375
376
378 return this->conditionTaken;
379 }
380
381
382 bool Instruction::isTainted(void) const {
383 return this->tainted;
384 }
385
386
387 bool Instruction::isSymbolized(void) const {
388 for (auto it = this->symbolicExpressions.begin(); it != this->symbolicExpressions.end(); it++) {
389 if ((*it)->isSymbolized() == true)
390 return true;
391 }
392 return false;
393 }
394
395
396 bool Instruction::isMemoryRead(void) const {
397 if (this->loadAccess.size() >= 1)
398 return true;
399 return false;
400 }
401
402
403 bool Instruction::isMemoryWrite(void) const {
404 if (this->storeAccess.size() >= 1)
405 return true;
406 return false;
407 }
408
409
411 switch(target.getType()) {
412
414 for (auto&& pair : this->readImmediates) {
415 if (pair.first == target.getConstImmediate())
416 return true;
417 }
418 break;
419
421 for (auto&& pair : this->loadAccess) {
422 const triton::arch::MemoryAccess& m1 = pair.first;
423 const triton::arch::MemoryAccess& m2 = target.getConstMemory();
424
425 if (m1.isOverlapWith(m2))
426 return true;
427 }
428 break;
429
431 for (auto&& pair : this->readRegisters) {
432 const triton::arch::Register& r1 = pair.first;
433 const triton::arch::Register& r2 = target.getConstRegister();
434
435 if (r1.isOverlapWith(r2))
436 return true;
437 }
438 break;
439
440 default:
441 throw triton::exceptions::Instruction("Instruction::isReadFrom(): Invalid type operand.");
442 }
443
444 return false;
445 }
446
447
449 switch(target.getType()) {
450
452 break;
453
455 for (auto&& pair : this->storeAccess) {
456 const triton::arch::MemoryAccess& m1 = pair.first;
457 const triton::arch::MemoryAccess& m2 = target.getConstMemory();
458
459 if (m1.isOverlapWith(m2))
460 return true;
461 }
462 break;
463
465 for (auto&& pair : this->writtenRegisters) {
466 const triton::arch::Register& r1 = pair.first;
467 const triton::arch::Register& r2 = target.getConstRegister();
468
469 if (r1.isOverlapWith(r2))
470 return true;
471 }
472 break;
473
474 default:
475 throw triton::exceptions::Instruction("Instruction::isWriteTo(): Invalid type operand.");
476 }
477
478 return false;
479 }
480
481
482 bool Instruction::isPrefixed(void) const {
484 return false;
485 return true;
486 }
487
488
489 bool Instruction::isWriteBack(void) const {
490 return this->writeBack;
491 }
492
493
494 bool Instruction::isUpdateFlag(void) const {
495 return this->updateFlag;
496 }
497
498
499 bool Instruction::isThumb(void) const {
500 return this->thumb;
501 }
502
503
504 void Instruction::setBranch(bool flag) {
505 this->branch = flag;
506 }
507
508
510 this->controlFlow = flag;
511 }
512
513
515 this->conditionTaken = flag;
516 }
517
518
520 this->address = 0;
521 this->branch = false;
523 this->conditionTaken = 0;
524 this->controlFlow = false;
526 this->size = 0;
527 this->tainted = false;
528 this->tid = 0;
529 this->type = 0;
530 this->updateFlag = false;
531 this->writeBack = false;
532
533 /* Clear the stringstream (See #975) */
534 std::stringstream().swap(this->disassembly);
535
536 this->loadAccess.clear();
537 this->operands.clear();
538 this->readImmediates.clear();
539 this->readRegisters.clear();
540 this->storeAccess.clear();
541 this->symbolicExpressions.clear();
542 this->writtenRegisters.clear();
543
544 std::memset(this->opcode, 0x00, sizeof(this->opcode));
545 }
546
547
548 std::ostream& operator<<(std::ostream& stream, const Instruction& inst) {
549 std::string dis = inst.getDisassembly();
550 stream << "0x" << std::hex << inst.getAddress() << ": " << (!dis.empty() ? dis : "<not disassembled>") << std::dec;
551 return stream;
552 }
553
554
555 std::ostream& operator<<(std::ostream& stream, const Instruction* inst) {
556 stream << *inst;
557 return stream;
558 }
559
560 };
561};
This class is used to represent an immediate.
Definition immediate.hpp:37
TRITON_EXPORT triton::uint64 getValue(void) const
Returns the value of the operand.
Definition immediate.cpp:34
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 setLoadAccess(const triton::arch::MemoryAccess &mem, const triton::ast::SharedAbstractNode &node)
Sets a load access.
TRITON_EXPORT std::set< std::pair< triton::arch::Register, triton::ast::SharedAbstractNode > > & getReadRegisters(void)
Returns the list of all implicit and explicit register (flags includes) inputs (read)
TRITON_EXPORT Instruction & operator=(const Instruction &other)
Copies an Instruction.
TRITON_EXPORT void setUpdateFlag(bool state)
Sets the updateFlag of the instruction.
TRITON_EXPORT triton::arch::architecture_e getArchitecture(void) const
Returns the instruction's architecture.
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.
std::set< std::pair< triton::arch::Immediate, triton::ast::SharedAbstractNode > > readImmediates
Implicit and explicit immediate inputs (read). This field is set at the semantics level.
TRITON_EXPORT bool isWriteBack(void) const
Returns true if the instruction performs a write back. Mainly used for AArch64 instructions like LDR.
TRITON_EXPORT void removeLoadAccess(const triton::arch::MemoryAccess &mem)
Removes a load access.
TRITON_EXPORT void setThumb(bool state)
Sets the Thumb mode of the instruction.
TRITON_EXPORT void setConditionTaken(bool flag)
Sets flag to define if the condition is taken or not.
std::stringstream disassembly
The disassembly of the instruction. This field is set at the disassembly level.
TRITON_EXPORT bool isWriteTo(const triton::arch::OperandWrapper &target) const
Returns whether the instruction writes the specified operand.
TRITON_EXPORT void setWrittenRegister(const triton::arch::Register &reg, const triton::ast::SharedAbstractNode &node)
Sets a written register.
TRITON_EXPORT const triton::uint8 * getOpcode(void) const
Returns the opcode of the instruction.
triton::uint32 size
The size of the instruction.
triton::arch::x86::prefix_e prefix
The prefix of the instruction. This field is set at the disassembly level. Mainly used for X86.
bool thumb
True if this is a Thumb instruction. (Note that isThumb() in Arm32Cpu is used to determine the curren...
triton::uint8 opcode[16]
The opcode of the instruction.
std::set< std::pair< triton::arch::MemoryAccess, triton::ast::SharedAbstractNode > > storeAccess
Implicit and explicit store access (write). This field is set at the semantics level.
triton::arch::arm::condition_e codeCondition
The code condition of the instruction. This field is set at the disassembly level....
TRITON_EXPORT bool isThumb(void) const
Returns true if it is a Thumb instruction.
TRITON_EXPORT std::set< std::pair< triton::arch::MemoryAccess, triton::ast::SharedAbstractNode > > & getStoreAccess(void)
Returns the list of all implicit and explicit store access.
TRITON_EXPORT void setType(triton::uint32 type)
Sets the type of the instruction.
TRITON_EXPORT void setPrefix(triton::arch::x86::prefix_e prefix)
Sets the prefix of the instruction (mainly for X86).
TRITON_EXPORT void setAddress(triton::uint64 addr)
Sets the address of the instruction.
TRITON_EXPORT std::set< std::pair< triton::arch::MemoryAccess, triton::ast::SharedAbstractNode > > & getLoadAccess(void)
Returns the list of all implicit and explicit load access.
TRITON_EXPORT void clear(void)
Clears all instruction information.
TRITON_EXPORT void setTaint(void)
Sets the taint of the instruction based on its expressions.
bool writeBack
True if this instruction performs a write back. Mainly used for AArch64 instruction like LDR.
TRITON_EXPORT void setStoreAccess(const triton::arch::MemoryAccess &mem, const triton::ast::SharedAbstractNode &node)
Sets a store access.
TRITON_EXPORT triton::uint32 getType(void) const
Returns the type of the instruction.
TRITON_EXPORT void removeReadRegister(const triton::arch::Register &reg)
Removes a read register.
TRITON_EXPORT bool isConditionTaken(void) const
Returns true if the condition is taken (e.g x86: jcc, cmovcc, setcc, ...).
TRITON_EXPORT void setArchitecture(triton::arch::architecture_e arch)
Sets the instruction's architecture.
TRITON_EXPORT bool isReadFrom(const triton::arch::OperandWrapper &target) const
Returns whether the instruction reads the specified operand.
TRITON_EXPORT bool isTainted(void) const
Returns true if at least one of its expressions is tainted.
std::set< std::pair< triton::arch::MemoryAccess, triton::ast::SharedAbstractNode > > loadAccess
Implicit and explicit load access (read). This field is set at the semantics level.
triton::uint32 type
The type of the instruction. This field is set at the disassembly level.
TRITON_EXPORT std::set< triton::arch::Register > & getUndefinedRegisters(void)
Returns the list of all implicit and explicit undefined registers.
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 bool isSymbolized(void) const
Returns true if at least one of its expressions contains a symbolic variable.
TRITON_EXPORT bool isMemoryRead(void) const
Returns true if the instruction contains an expression which reads the memory.
TRITON_EXPORT void removeUndefinedRegister(const triton::arch::Register &reg)
Removes an undefined register.
bool controlFlow
True if this instruction changes the control flow. This field is set at the disassembly level.
TRITON_EXPORT bool isMemoryWrite(void) const
Returns true if the instruction contains an expression which writes into the memory.
TRITON_EXPORT void setUndefinedRegister(const triton::arch::Register &reg)
Sets an undefined register.
TRITON_EXPORT triton::uint32 getThreadId(void) const
Returns the thread id of the instruction.
TRITON_EXPORT void removeReadImmediate(const triton::arch::Immediate &imm)
Removes a read immediate.
TRITON_EXPORT bool isBranch(void) const
Returns true if this instruction is a branch.
TRITON_EXPORT bool isPrefixed(void) const
Returns true if the instruction has a prefix (mainly for X86).
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 Instruction()
Constructor.
TRITON_EXPORT void setCodeCondition(triton::arch::arm::condition_e codeCondition)
Sets the code condition of the instruction (mainly for AArch64).
TRITON_EXPORT std::set< std::pair< triton::arch::Register, triton::ast::SharedAbstractNode > > & getWrittenRegisters(void)
Returns the list of all implicit and explicit register (flags includes) outputs (write)
std::vector< triton::arch::OperandWrapper > operands
A list of operands.
bool tainted
True if this instruction is tainted. This field is set at the semantics level.
TRITON_EXPORT void removeWrittenRegister(const triton::arch::Register &reg)
Removes a written register.
TRITON_EXPORT void addSymbolicExpression(const triton::engines::symbolic::SharedSymbolicExpression &expr)
Adds a symbolic expression.
std::set< triton::arch::Register > undefinedRegisters
Implicit and explicit undefined registers. This field is set at the semantics level.
TRITON_EXPORT void setReadImmediate(const triton::arch::Immediate &imm, const triton::ast::SharedAbstractNode &node)
Sets a read immediate.
std::set< std::pair< triton::arch::Register, triton::ast::SharedAbstractNode > > readRegisters
Implicit and explicit register inputs (read). This field is set at the semantics level.
TRITON_EXPORT void setControlFlow(bool flag)
Sets flag to define this instruction changes the control flow or not.
TRITON_EXPORT bool isUpdateFlag(void) const
Returns true if the instruction updates flags. Mainly used for AArch64 instructions like ADDS.
bool updateFlag
True if this instruction updartes flags. Mainly used for AArch64 instruction like ADDS.
TRITON_EXPORT triton::arch::x86::prefix_e getPrefix(void) const
Returns the prefix of the instruction (mainly for X86).
triton::arch::architecture_e arch
The instruction's architecture.
TRITON_EXPORT ~Instruction()
Destructor.
std::set< std::pair< triton::arch::Register, triton::ast::SharedAbstractNode > > writtenRegisters
Implicit and explicit register outputs (write). This field is set at the semantics level.
std::vector< triton::engines::symbolic::SharedSymbolicExpression > symbolicExpressions
The semantics set of the instruction.
TRITON_EXPORT std::set< std::pair< triton::arch::Immediate, triton::ast::SharedAbstractNode > > & getReadImmediates(void)
Returns the list of all implicit and explicit immediate inputs (read)
TRITON_EXPORT void setReadRegister(const triton::arch::Register &reg, const triton::ast::SharedAbstractNode &node)
Sets a read register.
triton::uint64 address
The address of the instruction.
TRITON_EXPORT void removeStoreAccess(const triton::arch::MemoryAccess &mem)
Removes a store access.
TRITON_EXPORT void setThreadId(triton::uint32 tid)
Sets the thread id of the instruction.
bool conditionTaken
True if the condition is taken (i.g x86: jcc, cmocc, setcc, ...). This field is set at the semantics ...
triton::uint32 tid
The thread id of the instruction.
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.
bool branch
True if this instruction is a branch. This field is set at the disassembly level.
TRITON_EXPORT triton::uint64 getNextAddress(void) const
Returns the next address of the instruction.
TRITON_EXPORT bool isControlFlow(void) const
Returns true if this instruction changes the control flow (e.g x86: JMP, JCC, CALL,...
This class is used to represent a memory access.
TRITON_EXPORT bool isOverlapWith(const MemoryAccess &other) const
Returns true if other and self overlap.
TRITON_EXPORT triton::uint64 getAddress(void) const
Returns the address of the memory.
This class is used as operand wrapper.
TRITON_EXPORT triton::arch::operand_e getType(void) const
Returns the abstract type of the operand.
TRITON_EXPORT const triton::arch::MemoryAccess & getConstMemory(void) const
Returns the memory operand as const.
TRITON_EXPORT const triton::arch::Register & getConstRegister(void) const
Returns the register operand.
TRITON_EXPORT const triton::arch::Immediate & getConstImmediate(void) const
Returns the immediate operand.
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
TRITON_EXPORT bool isOverlapWith(const Register &other) const
Returns true if other and self overlap.
Definition register.cpp:86
The exception class used by an instruction.
std::ostream & operator<<(std::ostream &stream, BasicBlock &block)
Displays an BasicBlock.
condition_e
Types of condition.
@ ID_CONDITION_INVALID
invalid
std::shared_ptr< triton::ast::AbstractNode > SharedAbstractNode
Shared Abstract Node.
Definition ast.hpp:59
std::shared_ptr< triton::engines::symbolic::SymbolicExpression > SharedSymbolicExpression
Shared Symbolic Expression.
Definition ast.hpp:40
std::uint64_t uint64
unisgned 64-bits
std::uint32_t uint32
unisgned 32-bits
std::uint8_t uint8
unisgned 8-bits
std::string toString(const T &obj)
Converts an object to a string.
Definition coreUtils.hpp:38
prefix_e
Types of prefix.
@ ID_PREFIX_INVALID
invalid
The Triton namespace.