libTriton  version 0.9 build 1502
irBuilder.cpp
Go to the documentation of this file.
1 /*
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>
15 #include <triton/memoryAccess.hpp>
17 #include <triton/register.hpp>
18 #include <triton/x86Semantics.hpp>
19 
20 
21 
22 namespace 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->backupSymbolicEngine = new(std::nothrow) triton::engines::symbolic::SymbolicEngine(architecture, modes, astCtxt, nullptr);
43  this->symbolicEngine = symbolicEngine;
44  this->taintEngine = taintEngine;
45  this->aarch64Isa = new(std::nothrow) triton::arch::arm::aarch64::AArch64Semantics(architecture, symbolicEngine, taintEngine, astCtxt);
46  this->arm32Isa = new(std::nothrow) triton::arch::arm::arm32::Arm32Semantics(architecture, symbolicEngine, taintEngine, 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->backupSymbolicEngine == nullptr)
50  throw triton::exceptions::IrBuilder("IrBuilder::IrBuilder(): Not enough memory.");
51  }
52 
53 
55  delete this->backupSymbolicEngine;
56  delete this->aarch64Isa;
57  delete this->arm32Isa;
58  delete this->x86Isa;
59  }
60 
61 
63  triton::arch::architecture_e arch = this->architecture->getArchitecture();
64  bool ret = false;
65 
66  if (arch == triton::arch::ARCH_INVALID)
67  throw triton::exceptions::IrBuilder("IrBuilder::buildSemantics(): You must define an architecture.");
68 
69  /* Initialize the target address of memory operands */
70  for (auto& operand : inst.operands) {
71  if (operand.getType() == triton::arch::OP_MEM) {
72  this->symbolicEngine->initLeaAst(operand.getMemory());
73  }
74  }
75 
76  /* Pre IR processing */
77  this->preIrInit(inst);
78 
79  /* Processing */
80  switch (arch) {
82  ret = this->aarch64Isa->buildSemantics(inst);
83  break;
84 
86  ret = this->arm32Isa->buildSemantics(inst);
87  break;
88 
91  ret = this->x86Isa->buildSemantics(inst);
92  break;
93 
94  default:
95  throw triton::exceptions::IrBuilder("IrBuilder::buildSemantics(): Architecture not supported.");
96  break;
97  }
98 
99  /* Post IR processing */
100  this->postIrInit(inst);
101 
102  return ret;
103  }
104 
105 
107  /* Clear previous expressions if exist */
108  inst.symbolicExpressions.clear();
109 
110  /* Clear implicit and explicit semantics */
111  inst.getLoadAccess().clear();
112  inst.getReadRegisters().clear();
113  inst.getReadImmediates().clear();
114  inst.getStoreAccess().clear();
115  inst.getWrittenRegisters().clear();
116 
117  /* Update instruction address if undefined */
118  if (!inst.getAddress()) {
119  inst.setAddress(this->architecture->getConcreteRegisterValue(this->architecture->getProgramCounter()).convert_to<triton::uint64>());
120  }
121 
122  /* Backup the symbolic engine in the case where only the taint is available. */
123  if (!this->symbolicEngine->isEnabled()) {
124  *this->backupSymbolicEngine = *this->symbolicEngine;
125  }
126  }
127 
128 
130  std::vector<triton::engines::symbolic::SharedSymbolicExpression> newVector;
131 
132  auto& loadAccess = inst.getLoadAccess();
133  auto& readRegisters = inst.getReadRegisters();
134  auto& readImmediates = inst.getReadImmediates();
135  auto& storeAccess = inst.getStoreAccess();
136  auto& writtenRegisters = inst.getWrittenRegisters();
137 
138  /* Set the taint */
139  inst.setTaint();
140 
141  // ----------------------------------------------------------------------
142 
143  /*
144  * If the symbolic engine is disable we delete symbolic
145  * expressions and AST nodes. Note that if the taint engine
146  * is enable we must compute semanitcs to spread the taint.
147  */
148  if (!this->symbolicEngine->isEnabled()) {
149  /* Clear memory operands */
150  this->collectNodes(inst.operands);
151 
152  /* Clear implicit and explicit semantics */
153  loadAccess.clear();
154  readRegisters.clear();
155  readImmediates.clear();
156  storeAccess.clear();
157  writtenRegisters.clear();
158 
159  /* Symbolic Expressions */
160  this->removeSymbolicExpressions(inst);
161 
162  /* Restore backup */
163  *this->symbolicEngine = *this->backupSymbolicEngine;
164  }
165 
166  // ----------------------------------------------------------------------
167 
168  /*
169  * If the symbolic engine is defined to process symbolic
170  * execution only on symbolized expressions, we delete all
171  * concrete expressions and their AST nodes.
172  */
173  if (this->symbolicEngine->isEnabled() && this->modes->isModeEnabled(triton::modes::ONLY_ON_SYMBOLIZED)) {
174  /* Clear memory operands */
175  this->collectUnsymbolizedNodes(inst.operands);
176 
177  /* Clear implicit and explicit semantics - MEM */
178  this->collectUnsymbolizedNodes(loadAccess);
179 
180  /* Clear implicit and explicit semantics - REG */
181  this->collectUnsymbolizedNodes(readRegisters);
182 
183  /* Clear implicit and explicit semantics - IMM */
184  this->collectUnsymbolizedNodes(readImmediates);
185 
186  /* Clear implicit and explicit semantics - MEM */
187  this->collectUnsymbolizedNodes(storeAccess);
188 
189  /* Clear implicit and explicit semantics - REG */
190  this->collectUnsymbolizedNodes(writtenRegisters);
191 
192  /* Clear symbolic expressions */
193  for (const auto& se : inst.symbolicExpressions) {
194  if (se->isSymbolized() == false) {
195  this->symbolicEngine->removeSymbolicExpression(se);
196  }
197  else
198  newVector.push_back(se);
199  }
200  inst.symbolicExpressions = newVector;
201  }
202 
203  // ----------------------------------------------------------------------
204 
205  /*
206  * If the symbolic engine is defined to process symbolic
207  * execution only on tainted instructions, we delete all
208  * expressions untainted and their AST nodes.
209  */
210  else if (this->modes->isModeEnabled(triton::modes::ONLY_ON_TAINTED) && !inst.isTainted()) {
211  /* Memory operands */
212  this->collectNodes(inst.operands);
213 
214  /* Implicit and explicit semantics - MEM */
215  this->collectNodes(loadAccess);
216 
217  /* Implicit and explicit semantics - REG */
218  this->collectNodes(readRegisters);
219 
220  /* Implicit and explicit semantics - IMM */
221  this->collectNodes(readImmediates);
222 
223  /* Implicit and explicit semantics - MEM */
224  this->collectNodes(storeAccess);
225 
226  /* Implicit and explicit semantics - REG */
227  this->collectNodes(writtenRegisters);
228 
229  /* Symbolic Expressions */
230  this->removeSymbolicExpressions(inst);
231  }
232 
233  this->astCtxt->garbage();
234  }
235 
236 
237  void IrBuilder::removeSymbolicExpressions(triton::arch::Instruction& inst) {
238  for (const auto& se : inst.symbolicExpressions) {
239  this->symbolicEngine->removeSymbolicExpression(se);
240  }
241  inst.symbolicExpressions.clear();
242  }
243 
244 
245  template <typename T>
246  void IrBuilder::collectNodes(T& items) const {
247  items.clear();
248  }
249 
250 
251  void IrBuilder::collectNodes(std::vector<triton::arch::OperandWrapper>& operands) const {
252  for (auto& operand : operands) {
253  if (operand.getType() == triton::arch::OP_MEM) {
254  operand.getMemory().setLeaAst(nullptr);
255  }
256  }
257  }
258 
259 
260  template <typename T>
261  void IrBuilder::collectUnsymbolizedNodes(T& items) const {
262  T newItems;
263 
264  for (const auto& item : items) {
265  if (std::get<1>(item) && std::get<1>(item)->isSymbolized() == true)
266  newItems.insert(item);
267  }
268 
269  items.clear();
270  items = newItems;
271  }
272 
273 
274  void IrBuilder::collectUnsymbolizedNodes(std::vector<triton::arch::OperandWrapper>& operands) const {
275  for (auto& operand : operands) {
276  if (operand.getType() == triton::arch::OP_MEM) {
277  if (operand.getMemory().getLeaAst() && operand.getMemory().getLeaAst()->isSymbolized() == false) {
278  operand.getMemory().setLeaAst(nullptr);
279  }
280  }
281  }
282  }
283 
284  }; /* arch namespace */
285 }; /* 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 when to represent an instruction.
Definition: instruction.hpp:48
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:54
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:78
triton::arch::SemanticsInterface * aarch64Isa
AArch64 ISA builder.
Definition: irBuilder.hpp:75
TRITON_EXPORT bool buildSemantics(triton::arch::Instruction &inst)
Builds the semantics of the instruction. Returns true if the instruction is supported.
Definition: irBuilder.cpp:62
TRITON_EXPORT void preIrInit(triton::arch::Instruction &inst)
Everything which must be done before buiding the semantics.
Definition: irBuilder.cpp:106
TRITON_EXPORT void postIrInit(triton::arch::Instruction &inst)
Everything which must be done after building the semantics.
Definition: irBuilder.cpp:129
triton::arch::SemanticsInterface * x86Isa
x86 ISA builder.
Definition: irBuilder.hpp:81
virtual TRITON_EXPORT bool buildSemantics(triton::arch::Instruction &inst)=0
Builds the semantics of the instruction. Returns true if the instruction is supported.
The x86 ISA semantics.
TRITON_EXPORT void initLeaAst(triton::arch::MemoryAccess &mem, bool force=true)
Initializes the memory access AST (LOAD and STORE).
TRITON_EXPORT void removeSymbolicExpression(const SharedSymbolicExpression &expr)
Removes the symbolic expression corresponding to the id.
TRITON_EXPORT bool isEnabled(void) const
Returns true if the symbolic execution engine is enabled.
The exception class used by the IR builder.
Definition: exceptions.hpp:317
@ OP_MEM
memory operand
Definition: archEnums.hpp:50
std::shared_ptr< triton::ast::AstContext > SharedAstContext
Shared AST context.
Definition: ast.hpp:63
std::shared_ptr< triton::modes::Modes > SharedModes
Shared Modes.
Definition: modes.hpp:66
@ ONLY_ON_TAINTED
[symbolic] Perform symbolic execution only on tainted instructions.
Definition: modesEnums.hpp:35
@ ONLY_ON_SYMBOLIZED
[symbolic] Perform symbolic execution only on symbolized expressions.
Definition: modesEnums.hpp:34
std::uint64_t uint64
unisgned 64-bits
Definition: tritonTypes.hpp:34
The Triton namespace.
Definition: api.cpp:227