Loading [MathJax]/extensions/tex2jax.js
libTriton version 1.0 build 1599
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
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>
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->riscvIsa = new(std::nothrow) triton::arch::riscv::riscvSemantics(architecture, symbolicEngine, taintEngine, modes, astCtxt);
47 this->x86Isa = new(std::nothrow) triton::arch::x86::x86Semantics(architecture, symbolicEngine, taintEngine, modes, astCtxt);
48
49 if (this->x86Isa == nullptr || this->aarch64Isa == nullptr || this->arm32Isa == nullptr
50 || this->riscvIsa == nullptr
51 )
52 throw triton::exceptions::IrBuilder("IrBuilder::IrBuilder(): Not enough memory.");
53 }
54
55
57 delete this->aarch64Isa;
58 delete this->arm32Isa;
59 delete this->riscvIsa;
60 delete this->x86Isa;
61 }
62
63
65 triton::arch::architecture_e arch = this->architecture->getArchitecture();
67
69 throw triton::exceptions::IrBuilder("IrBuilder::buildSemantics(): You must define an architecture.");
70
71 /* Initialize the target address of memory operands */
72 for (auto& operand : inst.operands) {
73 if (operand.getType() == triton::arch::OP_MEM) {
74 this->symbolicEngine->initLeaAst(operand.getMemory());
75 }
76 }
77
78 /* Pre IR processing */
79 this->preIrInit(inst);
80
81 /* Processing */
82 switch (arch) {
84 ret = this->aarch64Isa->buildSemantics(inst);
85 break;
86
88 ret = this->arm32Isa->buildSemantics(inst);
89 break;
90
93 ret = this->x86Isa->buildSemantics(inst);
94 break;
95
98 ret = this->riscvIsa->buildSemantics(inst);
99 break;
100
101 default:
102 throw triton::exceptions::IrBuilder("IrBuilder::buildSemantics(): Architecture not supported.");
103 break;
104 }
105
106 /* Post IR processing */
107 this->postIrInit(inst);
108
109 return ret;
110 }
111
112
115 triton::usize count = block.getSize();
116
117 for (auto& inst : block.getInstructions()) {
118 ret = this->buildSemantics(inst);
119 if (ret != triton::arch::NO_FAULT) {
120 return ret;
121 }
122 count--;
123 if (inst.isControlFlow() && count) {
124 throw triton::exceptions::IrBuilder("IrBuilder::buildSemantics(): Do not add instructions in a block after a branch instruction.");
125 }
126 }
127
128 return ret;
129 }
130
131
133 /* Clear previous expressions if exist */
134 inst.symbolicExpressions.clear();
135
136 /* Clear implicit and explicit previous semantics */
137 inst.getLoadAccess().clear();
138 inst.getReadRegisters().clear();
139 inst.getReadImmediates().clear();
140 inst.getStoreAccess().clear();
141 inst.getWrittenRegisters().clear();
142
143 /* Update instruction address if undefined */
144 if (!inst.getAddress()) {
145 inst.setAddress(static_cast<triton::uint64>(this->architecture->getConcreteRegisterValue(this->architecture->getProgramCounter())));
146 }
147 }
148
149
151 std::vector<triton::engines::symbolic::SharedSymbolicExpression> newVector;
152
153 /* Set the taint */
154 inst.setTaint();
155
156 /*
157 * If the symbolic engine is defined to process symbolic
158 * execution only on symbolized expressions, we delete all
159 * concrete expressions and their AST nodes.
160 */
161 if (this->modes->isModeEnabled(triton::modes::ONLY_ON_SYMBOLIZED)) {
162 /* Clear memory operands */
163 this->collectUnsymbolizedNodes(inst.operands);
164
165 /* Clear implicit and explicit semantics - MEM */
166 this->collectUnsymbolizedNodes(inst.getLoadAccess());
167
168 /* Clear implicit and explicit semantics - REG */
169 this->collectUnsymbolizedNodes(inst.getReadRegisters());
170
171 /* Clear implicit and explicit semantics - IMM */
172 this->collectUnsymbolizedNodes(inst.getReadImmediates());
173
174 /* Clear implicit and explicit semantics - MEM */
175 this->collectUnsymbolizedNodes(inst.getStoreAccess());
176
177 /* Clear implicit and explicit semantics - REG */
178 this->collectUnsymbolizedNodes(inst.getWrittenRegisters());
179
180 /* Clear symbolic expressions */
181 for (const auto& se : inst.symbolicExpressions) {
182 if (se->isSymbolized() == false) {
183 this->symbolicEngine->removeSymbolicExpression(se);
184 }
185 else
186 newVector.push_back(se);
187 }
188 inst.symbolicExpressions = newVector;
189 }
190
191 /*
192 * If the symbolic engine is defined to process symbolic
193 * execution only on tainted instructions, we delete all
194 * expressions untainted and their AST nodes.
195 */
196 else if (this->modes->isModeEnabled(triton::modes::ONLY_ON_TAINTED) && !inst.isTainted()) {
197 /* Memory operands */
198 this->collectNodes(inst.operands);
199
200 /* Implicit and explicit semantics - MEM */
201 this->collectNodes(inst.getLoadAccess());
202
203 /* Implicit and explicit semantics - REG */
204 this->collectNodes(inst.getReadRegisters());
205
206 /* Implicit and explicit semantics - IMM */
207 this->collectNodes(inst.getReadImmediates());
208
209 /* Implicit and explicit semantics - MEM */
210 this->collectNodes(inst.getStoreAccess());
211
212 /* Implicit and explicit semantics - REG */
213 this->collectNodes(inst.getWrittenRegisters());
214
215 /* Symbolic Expressions */
216 this->removeSymbolicExpressions(inst);
217 }
218
219 this->astCtxt->garbage();
220 }
221
222
223 void IrBuilder::removeSymbolicExpressions(triton::arch::Instruction& inst) {
224 for (const auto& se : inst.symbolicExpressions) {
225 this->symbolicEngine->removeSymbolicExpression(se);
226 }
227 inst.symbolicExpressions.clear();
228 }
229
230
231 template <typename T>
232 void IrBuilder::collectNodes(T& items) const {
233 items.clear();
234 }
235
236
237 void IrBuilder::collectNodes(std::vector<triton::arch::OperandWrapper>& operands) const {
238 for (auto& operand : operands) {
239 if (operand.getType() == triton::arch::OP_MEM) {
240 operand.getMemory().setLeaAst(nullptr);
241 }
242 }
243 }
244
245
246 template <typename T>
247 void IrBuilder::collectUnsymbolizedNodes(T& items) const {
248 T newItems;
249
250 for (const auto& item : items) {
251 if (std::get<1>(item) && std::get<1>(item)->isSymbolized() == true)
252 newItems.insert(item);
253 }
254
255 items.clear();
256 items = newItems;
257 }
258
259
260 void IrBuilder::collectUnsymbolizedNodes(std::vector<triton::arch::OperandWrapper>& operands) const {
261 for (auto& operand : operands) {
262 if (operand.getType() == triton::arch::OP_MEM) {
263 if (operand.getMemory().getLeaAst() && operand.getMemory().getLeaAst()->isSymbolized() == false) {
264 operand.getMemory().setLeaAst(nullptr);
265 }
266 }
267 }
268 }
269
270 }; /* arch namespace */
271}; /* 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:56
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:64
TRITON_EXPORT void preIrInit(triton::arch::Instruction &inst)
Everything which must be done before buiding the semantics.
triton::arch::SemanticsInterface * riscvIsa
RISCV ISA builder.
Definition irBuilder.hpp:83
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) const
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.