libTriton version 1.0 build 1592
Loading...
Searching...
No Matches
irBuilder.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
12#include <triton/astContext.hpp>
13#include <triton/exceptions.hpp>
14#include <triton/irBuilder.hpp>
17#include <triton/register.hpp>
19
20
21
22namespace triton {
23 namespace arch {
24
26 const triton::modes::SharedModes& modes,
27 const triton::ast::SharedAstContext& astCtxt,
30 : modes(modes), astCtxt(astCtxt) {
31
32 if (architecture == nullptr)
33 throw triton::exceptions::IrBuilder("IrBuilder::IrBuilder(): The architecture API must be defined.");
34
35 if (symbolicEngine == nullptr)
36 throw triton::exceptions::IrBuilder("IrBuilder::IrBuilder(): The symbolic engine API must be defined.");
37
38 if (taintEngine == nullptr)
39 throw triton::exceptions::IrBuilder("IrBuilder::IrBuilder(): The taint engines API must be defined.");
40
41 this->architecture = architecture;
42 this->symbolicEngine = symbolicEngine;
43 this->taintEngine = taintEngine;
44 this->aarch64Isa = new(std::nothrow) triton::arch::arm::aarch64::AArch64Semantics(architecture, symbolicEngine, taintEngine, astCtxt);
45 this->arm32Isa = new(std::nothrow) triton::arch::arm::arm32::Arm32Semantics(architecture, symbolicEngine, taintEngine, astCtxt);
46 this->x86Isa = new(std::nothrow) triton::arch::x86::x86Semantics(architecture, symbolicEngine, taintEngine, modes, astCtxt);
47
48 if (this->x86Isa == nullptr || this->aarch64Isa == nullptr || this->arm32Isa == nullptr)
49 throw triton::exceptions::IrBuilder("IrBuilder::IrBuilder(): Not enough memory.");
50 }
51
52
54 delete this->aarch64Isa;
55 delete this->arm32Isa;
56 delete this->x86Isa;
57 }
58
59
61 triton::arch::architecture_e arch = this->architecture->getArchitecture();
63
65 throw triton::exceptions::IrBuilder("IrBuilder::buildSemantics(): You must define an architecture.");
66
67 /* Initialize the target address of memory operands */
68 for (auto& operand : inst.operands) {
69 if (operand.getType() == triton::arch::OP_MEM) {
70 this->symbolicEngine->initLeaAst(operand.getMemory());
71 }
72 }
73
74 /* Pre IR processing */
75 this->preIrInit(inst);
76
77 /* Processing */
78 switch (arch) {
80 ret = this->aarch64Isa->buildSemantics(inst);
81 break;
82
84 ret = this->arm32Isa->buildSemantics(inst);
85 break;
86
89 ret = this->x86Isa->buildSemantics(inst);
90 break;
91
92 default:
93 throw triton::exceptions::IrBuilder("IrBuilder::buildSemantics(): Architecture not supported.");
94 break;
95 }
96
97 /* Post IR processing */
98 this->postIrInit(inst);
99
100 return ret;
101 }
102
103
106 triton::usize count = block.getSize();
107
108 for (auto& inst : block.getInstructions()) {
109 ret = this->buildSemantics(inst);
110 if (ret != triton::arch::NO_FAULT) {
111 return ret;
112 }
113 count--;
114 if (inst.isControlFlow() && count) {
115 throw triton::exceptions::IrBuilder("IrBuilder::buildSemantics(): Do not add instructions in a block after a branch instruction.");
116 }
117 }
118
119 return ret;
120 }
121
122
124 /* Clear previous expressions if exist */
125 inst.symbolicExpressions.clear();
126
127 /* Clear implicit and explicit previous semantics */
128 inst.getLoadAccess().clear();
129 inst.getReadRegisters().clear();
130 inst.getReadImmediates().clear();
131 inst.getStoreAccess().clear();
132 inst.getWrittenRegisters().clear();
133
134 /* Update instruction address if undefined */
135 if (!inst.getAddress()) {
136 inst.setAddress(static_cast<triton::uint64>(this->architecture->getConcreteRegisterValue(this->architecture->getProgramCounter())));
137 }
138 }
139
140
142 std::vector<triton::engines::symbolic::SharedSymbolicExpression> newVector;
143
144 /* Set the taint */
145 inst.setTaint();
146
147 /*
148 * If the symbolic engine is defined to process symbolic
149 * execution only on symbolized expressions, we delete all
150 * concrete expressions and their AST nodes.
151 */
152 if (this->modes->isModeEnabled(triton::modes::ONLY_ON_SYMBOLIZED)) {
153 /* Clear memory operands */
154 this->collectUnsymbolizedNodes(inst.operands);
155
156 /* Clear implicit and explicit semantics - MEM */
157 this->collectUnsymbolizedNodes(inst.getLoadAccess());
158
159 /* Clear implicit and explicit semantics - REG */
160 this->collectUnsymbolizedNodes(inst.getReadRegisters());
161
162 /* Clear implicit and explicit semantics - IMM */
163 this->collectUnsymbolizedNodes(inst.getReadImmediates());
164
165 /* Clear implicit and explicit semantics - MEM */
166 this->collectUnsymbolizedNodes(inst.getStoreAccess());
167
168 /* Clear implicit and explicit semantics - REG */
169 this->collectUnsymbolizedNodes(inst.getWrittenRegisters());
170
171 /* Clear symbolic expressions */
172 for (const auto& se : inst.symbolicExpressions) {
173 if (se->isSymbolized() == false) {
174 this->symbolicEngine->removeSymbolicExpression(se);
175 }
176 else
177 newVector.push_back(se);
178 }
179 inst.symbolicExpressions = newVector;
180 }
181
182 /*
183 * If the symbolic engine is defined to process symbolic
184 * execution only on tainted instructions, we delete all
185 * expressions untainted and their AST nodes.
186 */
187 else if (this->modes->isModeEnabled(triton::modes::ONLY_ON_TAINTED) && !inst.isTainted()) {
188 /* Memory operands */
189 this->collectNodes(inst.operands);
190
191 /* Implicit and explicit semantics - MEM */
192 this->collectNodes(inst.getLoadAccess());
193
194 /* Implicit and explicit semantics - REG */
195 this->collectNodes(inst.getReadRegisters());
196
197 /* Implicit and explicit semantics - IMM */
198 this->collectNodes(inst.getReadImmediates());
199
200 /* Implicit and explicit semantics - MEM */
201 this->collectNodes(inst.getStoreAccess());
202
203 /* Implicit and explicit semantics - REG */
204 this->collectNodes(inst.getWrittenRegisters());
205
206 /* Symbolic Expressions */
207 this->removeSymbolicExpressions(inst);
208 }
209
210 this->astCtxt->garbage();
211 }
212
213
214 void IrBuilder::removeSymbolicExpressions(triton::arch::Instruction& inst) {
215 for (const auto& se : inst.symbolicExpressions) {
216 this->symbolicEngine->removeSymbolicExpression(se);
217 }
218 inst.symbolicExpressions.clear();
219 }
220
221
222 template <typename T>
223 void IrBuilder::collectNodes(T& items) const {
224 items.clear();
225 }
226
227
228 void IrBuilder::collectNodes(std::vector<triton::arch::OperandWrapper>& operands) const {
229 for (auto& operand : operands) {
230 if (operand.getType() == triton::arch::OP_MEM) {
231 operand.getMemory().setLeaAst(nullptr);
232 }
233 }
234 }
235
236
237 template <typename T>
238 void IrBuilder::collectUnsymbolizedNodes(T& items) const {
239 T newItems;
240
241 for (const auto& item : items) {
242 if (std::get<1>(item) && std::get<1>(item)->isSymbolized() == true)
243 newItems.insert(item);
244 }
245
246 items.clear();
247 items = newItems;
248 }
249
250
251 void IrBuilder::collectUnsymbolizedNodes(std::vector<triton::arch::OperandWrapper>& operands) const {
252 for (auto& operand : operands) {
253 if (operand.getType() == triton::arch::OP_MEM) {
254 if (operand.getMemory().getLeaAst() && operand.getMemory().getLeaAst()->isSymbolized() == false) {
255 operand.getMemory().setLeaAst(nullptr);
256 }
257 }
258 }
259 }
260
261 }; /* arch namespace */
262}; /* triton namespace */
The abstract architecture class.
TRITON_EXPORT triton::uint512 getConcreteRegisterValue(const triton::arch::Register &reg, bool execCallbacks=true) const
Returns the concrete value of a register.
TRITON_EXPORT triton::arch::architecture_e getArchitecture(void) const
Returns the kind of architecture as triton::arch::architecture_e.
This class is used to represent a basic block.
TRITON_EXPORT triton::usize getSize(void) const
Returns the number of instructions in the block.
TRITON_EXPORT std::vector< triton::arch::Instruction > & getInstructions(void)
Gets all instructions of the block.
This class is used to represent an instruction.
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 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 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 bool isTainted(void) const
Returns true if at least one of its expressions is tainted.
TRITON_EXPORT triton::uint64 getAddress(void) const
Returns the address of the instruction.
TRITON_EXPORT void setTaint(bool state)
Sets the taint of the instruction.
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.
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)
virtual TRITON_EXPORT ~IrBuilder()
Destructor.
Definition irBuilder.cpp:53
TRITON_EXPORT IrBuilder(triton::arch::Architecture *architecture, const triton::modes::SharedModes &modes, const triton::ast::SharedAstContext &astCtxt, triton::engines::symbolic::SymbolicEngine *symbolicEngine, triton::engines::taint::TaintEngine *taintEngine)
Constructor.
Definition irBuilder.cpp:25
triton::arch::SemanticsInterface * arm32Isa
ARM32 ISA builder.
Definition irBuilder.hpp:77
triton::arch::SemanticsInterface * aarch64Isa
AArch64 ISA builder.
Definition irBuilder.hpp:74
TRITON_EXPORT triton::arch::exception_e buildSemantics(triton::arch::Instruction &inst)
Builds the semantics of the instruction. Returns triton::arch::NO_FAULT if succeed.
Definition irBuilder.cpp:60
TRITON_EXPORT void preIrInit(triton::arch::Instruction &inst)
Everything which must be done before buiding the semantics.
TRITON_EXPORT void postIrInit(triton::arch::Instruction &inst)
Everything which must be done after building the semantics.
triton::arch::SemanticsInterface * x86Isa
x86 ISA builder.
Definition irBuilder.hpp:80
virtual TRITON_EXPORT triton::arch::exception_e buildSemantics(triton::arch::Instruction &inst)=0
Builds the semantics of the instruction. Returns triton::arch::NO_FAULT if succeed.
TRITON_EXPORT void initLeaAst(triton::arch::MemoryAccess &mem, bool force=true)
Initializes the effective address of a memory access.
TRITON_EXPORT void removeSymbolicExpression(const SharedSymbolicExpression &expr)
Removes the symbolic expression corresponding to the id.
The exception class used by the IR builder.
std::shared_ptr< triton::ast::AstContext > SharedAstContext
Shared AST context.
Definition ast.hpp:65
std::shared_ptr< triton::modes::Modes > SharedModes
Shared Modes.
Definition modes.hpp:66
@ ONLY_ON_TAINTED
[symbolic] Perform symbolic execution only on tainted instructions.
@ ONLY_ON_SYMBOLIZED
[symbolic] Perform symbolic execution only on symbolized expressions.
std::size_t usize
unsigned MAX_INT 32 or 64 bits according to the CPU.
std::uint64_t uint64
unisgned 64-bits
The Triton namespace.