1 //! \file
2 /*
3 **  Copyright (C) - Triton
4 **
5 **  This program is under the terms of the Apache License 2.0.
6 */
7 
8 #include <triton/api.hpp>
9 #include <triton/config.hpp>
10 #include <triton/exceptions.hpp>
11 
12 #include <list>
13 #include <map>
14 #include <memory>
15 #include <new>
16 
17 
18 /*!
19 
20 \mainpage Triton: Dynamic Binary Analysis Framework
21 
22 \tableofcontents
23 
24 \section description_sec Description
25 
26 <b>Triton</b> is a dynamic binary analysis (DBA) framework. It provides internal components
27 like a <b>Dynamic Symbolic Execution</b> (DSE) engine, a <b>Taint</b> engine, <b>AST representations</b>
28 of the <b>x86</b>, <b>x86-64</b>, <b>ARM32</b> and <b>AArch64</b> instructions set architecture (ISA), <b>SMT simplification</b> passes,
29 an <b>SMT solver</b> interface and, the last but not least, <b>Python bindings</b>.
30 
31 
32 <br>
33 <hr>
34 \section publications_sec Presentations and Publications
35 
36 <ul>
37   <li><b>Symbolic Deobfuscation: From Virtualized Code Back to the Original</b><br>
38   Talk at DIMVA, Paris-Saclay, 2018.
39   [<a href="https://triton.quarkslab.com/files/DIMVA2018-deobfuscation-salwan-bardin-potet.pdf">paper</a>]
40   [<a href="https://triton.quarkslab.com/files/DIMVA2018-slide-deobfuscation-salwan-bardin-potet.pdf">slide</a>]
41   [<a href="https://triton.quarkslab.com/files/DeobfuscationDIMVA2018.txt">bibtex</a>]<br>
42   Abstract: <i>Software protection has taken an important place during the last decade in order to protect legit
43   software against reverse engineering or tampering. Virtualization is considered as one of the very best defenses
44   against such attacks. We present a generic approach based on symbolic path exploration, taint and recompilation
45   allowing to recover, from a virtualized code, a devirtualized code semantically identical to the original one
46   and close in size. We define criteria and metrics to evaluate the relevance of the deobfuscated results in terms
47   of correctness and precision. Finally we propose an open-source setup allowing to evaluate the proposed approach
48   against several forms of virtualization.
49   </i></li>
50 
51   <li><b>Deobfuscation of VM based software protection </b><br>
52   Talk at SSTIC, Rennes, 2017.
53   [<a href="https://triton.quarkslab.com/files/sstic2017-salwan-bardin-potet-paper.pdf">french paper</a>]
54   [<a href="https://triton.quarkslab.com/files/sstic2017-salwan-bardin-potet-slide.pdf">english slide</a>]
55   [<a href="https://static.sstic.org/videos2017/SSTIC_2017-06-07_P08.mp4">french video</a>]
56   [<a href="https://triton.quarkslab.com/files/DeobfuscationSSTIC2017.txt">bibtex</a>]<br>
57   Abstract: <i>In this presentation we describe an approach which consists to automatically analyze virtual
58   machine based software protections and which recompiles a new version of the binary without such protections. This
59   automated approach relies on a symbolic execution guide by a taint analysis and some concretization policies, then
60   on a binary rewriting using LLVM transition.
61   </i></li>
62 
63   <li><b>How Triton can help to reverse virtual machine based software protections</b><br>
64   Talk at CSAW SOS, NYC, 2016.
65   [<a href="https://triton.quarkslab.com/files/csaw2016-sos-rthomas-jsalwan.pdf">slide</a>]<br>
66   Abstract: <i>The first part of the talk is going to be an introduction to the Triton framework
67   to expose its components and to explain how they work together. Then, the second part will
68   include demonstrations on how it's possible to reverse virtual machine based protections using
69   taint analysis, symbolic execution, SMT simplifications and LLVM-IR optimizations.
70   </i></li>
71 
72   <li><b>Dynamic Binary Analysis and Obfuscated Codes</b><br>
73   Talk at St'Hack, Bordeaux, 2016.
74   [<a href="https://triton.quarkslab.com/files/sthack2016-rthomas-jsalwan.pdf">slide</a>]<br>
75   Abstract: <i>At this presentation we will talk about how a DBA (Dynamic Binary Analysis) may
76   help a reverse engineer to reverse obfuscated code. We will first introduce some basic obfuscation
77   techniques and then expose how it's possible to break some stuffs (using our open-source DBA framework - Triton) like
78   detect opaque predicates, reconstruct CFG, find the original algorithm, isolate sensible
79   data and many more... Then, we will conclude with a demo and few words about our future work.
80   </i></li>
81 
82   <li><b>How Triton may help to analyse obfuscated binaries</b><br>
83   MISC magazine 82, 2015.
84   [<a href="https://triton.quarkslab.com/files/misc82-triton.pdf">french article</a>]<br>
85   Abstract: <i>Binary obfuscation is used to protect software's intellectual property.
86   There exist different kinds of obfucation but roughly, it transforms a binary structure
87   into another binary structure by preserving the same semantic. The aim of obfuscation is
88   to ensure that the original information is "drown" in useless information that will make
89   reverse engineering harder. In this article we will show how we can analyse an ofbuscated
90   program and break some obfuscations using the Triton framework.</i></li>
91 
92   <li><b>Triton: A Concolic Execution Framework</b><br>
93   Talk at SSTIC, Rennes, 2015.
94   [<a href="https://triton.quarkslab.com/files/sstic2015_wp_fr_saudel_salwan.pdf">french paper</a>]
95   [<a href="https://triton.quarkslab.com/files/sstic2015_slide_en_saudel_salwan.pdf">detailed english slide</a>]
96   [<a href="https://triton.quarkslab.com/files/sstic2015_slide_fr_saudel_salwan.pdf">light french slide</a>]
97   [<a href="https://triton.quarkslab.com/files/TritonSSTIC2015.txt">bibtex</a>]<br>
98   Abstract: <i>This talk is about the release of Triton, a concolic execution framework based on Pin.
99   It provides components like a taint engine, a dynamic symbolic execution engine, a snapshot engine,
100   translation of x64 instruction to SMT2, a Z3 interface to solve constraints and Python bindings.
101   Based on these components, Triton offers the possibility to build tools for vulnerabilities research or
102   reverse-engineering assistance.</i></li>
103 
104   <li><b>Dynamic Behavior Analysis Using Binary Instrumentation</b><br>
105   Talk at St'Hack, Bordeaux, 2015.
106   [<a href="https://triton.quarkslab.com/files/sthack2015_salwan.pdf">slide</a>]<br>
107   Abstract: <i>This talk can be considered like the part 2 of our talk at SecurityDay.
108   In the previous part, we talked about how it was possible to cover a targeted
109   function in memory using the DSE (Dynamic Symbolic Execution) approach. Cover
110   a function (or its states) doesn't mean find all vulnerabilities, some vulnerability
111   doesn't crashes the program. That's why we must implement specific analysis to
112   find specific bugs. These analysis are based on the binary instrumentation and
113   the runtime behavior analysis of the program. In this talk, we will see how it's
114   possible to find these following kind of bugs : off-by-one, stack / heap overflow,
115   use-after-free, format string and {write, read}-what-where.</i></li>
116 
117   <li><b>Covering a function using a Dynamic Symbolic Execution approach</b><br>
118   Talk at Security Day, Lille, 2015.
119   [<a href="https://triton.quarkslab.com/files/secday2015_salwan.pdf">slide</a>]<br>
120   Abstract: <i>This talk is about binary analysis and instrumentation. We will see how it's possible to
121   target a specific function, snapshot the context memory/registers before the function, translate the instrumentation
122   into an intermediate representation,apply a taint analysis based on this IR, build/keep formulas for a Dynamic
123   Symbolic Execution (DSE), generate a concrete value to go through a specific path, restore the context memory/register and
124   generate another concrete value to go through another path then repeat this operation until the target function is covered.</i></li>
125 </ul>
126 
127 
128 <br>
129 <hr>
130 \section install_sec Installation
131 
132 To be able to compile Triton, you must install these libraries before:
133 
134  lib name                                                                      | version
135 -------------------------------------------------------------------------------|------------------
136  [libboost](http://www.boost.org/)                                             | >= 1.68
137  [libpython](https://www.python.org/)                                          | == 2.7.x or 3.6.x
138  [libz3](https://github.com/Z3Prover/z3)                                       | >= 4.6.0
139  [libcapstone](http://www.capstone-engine.org/)                                | >= 4.0.x
140  [Pin](https://software.intel.com/en-us/articles/pintool-downloads) (optional) | == 71313
141 
142 <hr>
143 \subsection linux_install_sec Linux Installation
144 
145 Once the libraries are installed, you can use `cmake` and `make` to build `libTriton`.
146 
147 ~~~~~~~~~~~~~{.sh}
148 $ git clone https://github.com/JonathanSalwan/Triton.git
149 $ cd Triton
150 $ mkdir build
151 $ cd build
152 $ cmake ..
153 $ sudo make -j2 install
154 ~~~~~~~~~~~~~
155 
156 <hr>
157 \subsection osx_install_sec OSX Installation
158 
159 On OSX `cmake` might have some difficulties finding the correct Python include/library paths.
160 You can run the following to build independent of your Python version:
161 
162 ~~~~~~~~~~~~~{.sh}
163 $ brew install boost capstone z3
164 $ git clone https://github.com/JonathanSalwan/Triton.git
165 $ cd Triton
166 $ mkdir build
167 $ cd build
168 $ cmake $(echo 'from os.path import abspath, join; from distutils.sysconfig import get_python_inc, get_python_lib; print "-DPYTHON_INCLUDE_DIR=%s -DPYTHON_LIBRARY=%s" % (get_python_inc(), abspath(join(get_python_lib(), "../../libpython2.7.dylib")))' | python) ..
169 $ sudo make -j2 install
170 ~~~~~~~~~~~~~
171 
172 <hr>
173 \subsection windows_install_sec Windows Installation
174 
175 Once libraries installed, you can use `cmake` to generate the `.sln` file of `libTriton`.
176 
177 ~~~~~~~~~~~~~{.sh}
178 > git clone https://github.com/JonathanSalwan/Triton.git
179 > cd Triton
180 > mkdir build
181 > cd build
182 > cmake -G "Visual Studio 14 2015 Win64" \
183   -DBOOST_ROOT="C:/Users/jonathan/Works/Tools/boost_1_61_0" \
184   -DPYTHON_INCLUDE_DIRS="C:/Python27/include" \
185   -DPYTHON_LIBRARIES="C:/Python27/libs/python27.lib" \
186   -DZ3_INCLUDE_DIRS="C:/Users/jonathan/Works/Tools/z3-4.6.0-x64-win/include" \
187   -DZ3_LIBRARIES="C:/Users/jonathan/Works/Tools/z3-4.6.0-x64-win/bin/libz3.lib" \
188   -DCAPSTONE_INCLUDE_DIRS="C:/Users/jonathan/Works/Tools/capstone-3.0.5-win64/include" \
189   -DCAPSTONE_LIBRARIES="C:/Users/jonathan/Works/Tools/capstone-3.0.5-win64/capstone.lib" ..
190 ~~~~~~~~~~~~~
191 
192 However, if you prefer to directly download precompiled libraries, check out our [AppVeyor's artefacts](https://ci.appveyor.com/project/JonathanSalwan/triton/history).
193 Note that if you use AppVeyor's artefacts, you probably have to install the [Visual C++ Redistributable](https://www.microsoft.com/en-US/download/details.aspx?id=30679)
194 packages for Visual Studio 2012.
195 
196 <hr>
197 \subsection libpintool_install_sec Pintool for Linux users
198 
199 This project is also shipped with a \ref Tracer_page and may be compiled with these following commands:
200 
201 ~~~~~~~~~~~~~{.sh}
202 $ cd pin-2.14-71313-gcc.4.4.7-linux/source/tools/
203 $ git clone https://github.com/JonathanSalwan/Triton.git
204 $ cd Triton
205 $ mkdir build
206 $ cd build
207 $ cmake -DPINTOOL=on ..
208 $ make -j2
209 $ cd ..
210 $ ./build/triton ./src/examples/pin/ir.py /usr/bin/id
211 ~~~~~~~~~~~~~
212 
213 It's not recommended to use the pintool on a kernel `4.x`. The version `71313` of Pin doesn't support very well
214 this branch (`4.x`). Anyway, if you feel lucky, you can compile the Triton pintool with the `-DKERNEL4=on` flag.
215 
216 ~~~~~~~~~~~~~{.sh}
217 $ cmake -DPINTOOL=on -DKERNEL4=on ..
218 $ make
219 ~~~~~~~~~~~~~
220 
221 Note that only the version `71313` of Pin is supported.
222 
223 */
224 
225 
226 
227 namespace triton {
228 
API()229   API::API() :
230     callbacks(*this),
231     arch(&this->callbacks) {
232     this->modes   = std::make_shared<triton::modes::Modes>();
233     this->astCtxt = std::make_shared<triton::ast::AstContext>(this->modes);
234   }
235 
236 
API(triton::arch::architecture_e arch)237   API::API(triton::arch::architecture_e arch) :
238     API() {
239     this->setArchitecture(arch);
240   }
241 
242 
~API()243   API::~API() {
244     this->removeEngines();
245   }
246 
247 
checkArchitecture(void) const248   inline void API::checkArchitecture(void) const {
249     if (!this->isArchitectureValid())
250       throw triton::exceptions::API("API::checkArchitecture(): You must define an architecture.");
251   }
252 
253 
checkIrBuilder(void) const254   inline void API::checkIrBuilder(void) const {
255     if (!this->irBuilder)
256       throw triton::exceptions::API("API::checkIrBuilder(): IR builder is undefined, you should define an architecture first.");
257   }
258 
259 
checkSymbolic(void) const260   inline void API::checkSymbolic(void) const {
261     if (!this->symbolic)
262       throw triton::exceptions::API("API::checkSymbolic(): Symbolic engine is undefined, you should define an architecture first.");
263   }
264 
265 
checkSolver(void) const266   inline void API::checkSolver(void) const {
267     if (!this->solver)
268       throw triton::exceptions::API("API::checkSolver(): Solver engine is undefined, you should define an architecture first.");
269   }
270 
271 
checkTaint(void) const272   inline void API::checkTaint(void) const {
273     if (!this->taint)
274       throw triton::exceptions::API("API::checkTaint(): Taint engine is undefined, you should define an architecture first.");
275   }
276 
277 
278 
279   /* Architecture API ============================================================================== */
280 
isArchitectureValid(void) const281   bool API::isArchitectureValid(void) const {
282     return this->arch.isValid();
283   }
284 
285 
getArchitecture(void) const286   triton::arch::architecture_e API::getArchitecture(void) const {
287     return this->arch.getArchitecture();
288   }
289 
290 
getEndianness(void) const291   triton::arch::endianness_e API::getEndianness(void) const {
292     return this->arch.getEndianness();
293   }
294 
295 
getCpuInstance(void)296   triton::arch::CpuInterface* API::getCpuInstance(void) {
297     if (!this->isArchitectureValid())
298       throw triton::exceptions::API("API::checkArchitecture(): You must define an architecture.");
299     return this->arch.getCpuInstance();
300   }
301 
302 
setArchitecture(triton::arch::architecture_e arch)303   void API::setArchitecture(triton::arch::architecture_e arch) {
304     /* Setup and init the targeted architecture */
305     this->arch.setArchitecture(arch);
306 
307     /* remove and re-init previous engines (when setArchitecture() has been called twice) */
308     this->removeEngines();
309     this->initEngines();
310   }
311 
312 
clearArchitecture(void)313   void API::clearArchitecture(void) {
314     this->checkArchitecture();
315     this->arch.clearArchitecture();
316   }
317 
318 
isFlag(triton::arch::register_e regId) const319   bool API::isFlag(triton::arch::register_e regId) const {
320     return this->arch.isFlag(regId);
321   }
322 
323 
isFlag(const triton::arch::Register & reg) const324   bool API::isFlag(const triton::arch::Register& reg) const {
325     return this->arch.isFlag(reg);
326   }
327 
328 
isRegister(triton::arch::register_e regId) const329   bool API::isRegister(triton::arch::register_e regId) const {
330     return this->arch.isRegister(regId);
331   }
332 
333 
isRegister(const triton::arch::Register & reg) const334   bool API::isRegister(const triton::arch::Register& reg) const {
335     return this->arch.isRegister(reg);
336   }
337 
338 
getRegister(triton::arch::register_e id) const339   const triton::arch::Register& API::getRegister(triton::arch::register_e id) const {
340     return this->arch.getRegister(id);
341   }
342 
343 
getParentRegister(const triton::arch::Register & reg) const344   const triton::arch::Register& API::getParentRegister(const triton::arch::Register& reg) const {
345     return this->arch.getParentRegister(reg);
346   }
347 
348 
getParentRegister(triton::arch::register_e id) const349   const triton::arch::Register& API::getParentRegister(triton::arch::register_e id) const {
350     return this->arch.getParentRegister(id);
351   }
352 
353 
isRegisterValid(triton::arch::register_e regId) const354   bool API::isRegisterValid(triton::arch::register_e regId) const {
355     return this->arch.isRegisterValid(regId);
356   }
357 
358 
isRegisterValid(const triton::arch::Register & reg) const359   bool API::isRegisterValid(const triton::arch::Register& reg) const {
360     return this->arch.isRegisterValid(reg);
361   }
362 
363 
isThumb(void) const364   bool API::isThumb(void) const {
365     return this->arch.isThumb();
366   }
367 
368 
setThumb(bool state)369   void API::setThumb(bool state) {
370     this->arch.setThumb(state);
371   }
372 
373 
getGprBitSize(void) const374   triton::uint32 API::getGprBitSize(void) const {
375     return this->arch.gprBitSize();
376   }
377 
378 
getGprSize(void) const379   triton::uint32 API::getGprSize(void) const {
380     return this->arch.gprSize();
381   }
382 
383 
getNumberOfRegisters(void) const384   triton::uint32 API::getNumberOfRegisters(void) const {
385     return this->arch.numberOfRegisters();
386   }
387 
388 
getAllRegisters(void) const389   const std::unordered_map<triton::arch::register_e, const triton::arch::Register>& API::getAllRegisters(void) const {
390     this->checkArchitecture();
391     return this->arch.getAllRegisters();
392   }
393 
394 
getParentRegisters(void) const395   std::set<const triton::arch::Register*> API::getParentRegisters(void) const {
396     this->checkArchitecture();
397     return this->arch.getParentRegisters();
398   }
399 
400 
getConcreteMemoryValue(triton::uint64 addr,bool execCallbacks) const401   triton::uint8 API::getConcreteMemoryValue(triton::uint64 addr, bool execCallbacks) const {
402     this->checkArchitecture();
403     return this->arch.getConcreteMemoryValue(addr, execCallbacks);
404   }
405 
406 
getConcreteMemoryValue(const triton::arch::MemoryAccess & mem,bool execCallbacks) const407   triton::uint512 API::getConcreteMemoryValue(const triton::arch::MemoryAccess& mem, bool execCallbacks) const {
408     this->checkArchitecture();
409     return this->arch.getConcreteMemoryValue(mem, execCallbacks);
410   }
411 
412 
getConcreteMemoryAreaValue(triton::uint64 baseAddr,triton::usize size,bool execCallbacks) const413   std::vector<triton::uint8> API::getConcreteMemoryAreaValue(triton::uint64 baseAddr, triton::usize size, bool execCallbacks) const {
414     this->checkArchitecture();
415     return this->arch.getConcreteMemoryAreaValue(baseAddr, size, execCallbacks);
416   }
417 
418 
getConcreteRegisterValue(const triton::arch::Register & reg,bool execCallbacks) const419   triton::uint512 API::getConcreteRegisterValue(const triton::arch::Register& reg, bool execCallbacks) const {
420     this->checkArchitecture();
421     return this->arch.getConcreteRegisterValue(reg, execCallbacks);
422   }
423 
424 
setConcreteMemoryValue(triton::uint64 addr,triton::uint8 value)425   void API::setConcreteMemoryValue(triton::uint64 addr, triton::uint8 value) {
426     this->checkArchitecture();
427     this->arch.setConcreteMemoryValue(addr, value);
428     /*
429      * In order to synchronize the concrete state with the symbolic
430      * one, the symbolic expression is concretized.
431      */
432     this->concretizeMemory(addr);
433   }
434 
435 
setConcreteMemoryValue(const triton::arch::MemoryAccess & mem,const triton::uint512 & value)436   void API::setConcreteMemoryValue(const triton::arch::MemoryAccess& mem, const triton::uint512& value) {
437     this->checkArchitecture();
438     this->arch.setConcreteMemoryValue(mem, value);
439     /*
440      * In order to synchronize the concrete state with the symbolic
441      * one, the symbolic expression is concretized.
442      */
443     this->concretizeMemory(mem);
444   }
445 
446 
setConcreteMemoryAreaValue(triton::uint64 baseAddr,const std::vector<triton::uint8> & values)447   void API::setConcreteMemoryAreaValue(triton::uint64 baseAddr, const std::vector<triton::uint8>& values) {
448     this->checkArchitecture();
449     this->arch.setConcreteMemoryAreaValue(baseAddr, values);
450     /*
451      * In order to synchronize the concrete state with the symbolic
452      * one, the symbolic expression is concretized.
453      */
454     for (triton::usize index = 0 ; index < values.size() ; index++) {
455       this->concretizeMemory(baseAddr + index);
456     }
457   }
458 
459 
setConcreteMemoryAreaValue(triton::uint64 baseAddr,const triton::uint8 * area,triton::usize size)460   void API::setConcreteMemoryAreaValue(triton::uint64 baseAddr, const triton::uint8* area, triton::usize size) {
461     this->checkArchitecture();
462     this->arch.setConcreteMemoryAreaValue(baseAddr, area, size);
463     /*
464      * In order to synchronize the concrete state with the symbolic
465      * one, the symbolic expression is concretized.
466      */
467     for (triton::usize index = 0 ; index < size ; index++) {
468       this->concretizeMemory(baseAddr + index);
469     }
470   }
471 
472 
setConcreteRegisterValue(const triton::arch::Register & reg,const triton::uint512 & value)473   void API::setConcreteRegisterValue(const triton::arch::Register& reg, const triton::uint512& value) {
474     this->checkArchitecture();
475     this->arch.setConcreteRegisterValue(reg, value);
476     /*
477      * In order to synchronize the concrete state with the symbolic
478      * one, the symbolic expression is concretized.
479      */
480     this->concretizeRegister(reg);
481   }
482 
483 
isConcreteMemoryValueDefined(const triton::arch::MemoryAccess & mem) const484   bool API::isConcreteMemoryValueDefined(const triton::arch::MemoryAccess& mem) const {
485     this->checkArchitecture();
486     return this->arch.isConcreteMemoryValueDefined(mem);
487   }
488 
489 
isConcreteMemoryValueDefined(triton::uint64 baseAddr,triton::usize size) const490   bool API::isConcreteMemoryValueDefined(triton::uint64 baseAddr, triton::usize size) const {
491     this->checkArchitecture();
492     return this->arch.isConcreteMemoryValueDefined(baseAddr, size);
493   }
494 
495 
clearConcreteMemoryValue(const triton::arch::MemoryAccess & mem)496   void API::clearConcreteMemoryValue(const triton::arch::MemoryAccess& mem) {
497     this->checkArchitecture();
498     this->arch.clearConcreteMemoryValue(mem);
499   }
500 
501 
clearConcreteMemoryValue(triton::uint64 baseAddr,triton::usize size)502   void API::clearConcreteMemoryValue(triton::uint64 baseAddr, triton::usize size) {
503     this->checkArchitecture();
504     this->arch.clearConcreteMemoryValue(baseAddr, size);
505   }
506 
507 
disassembly(triton::arch::Instruction & inst) const508   void API::disassembly(triton::arch::Instruction& inst) const {
509     this->checkArchitecture();
510     this->arch.disassembly(inst);
511   }
512 
513 
514 
515   /* Processing API ================================================================================ */
516 
initEngines(void)517   void API::initEngines(void) {
518     this->checkArchitecture();
519 
520     this->symbolic = new(std::nothrow) triton::engines::symbolic::SymbolicEngine(&this->arch, this->modes, this->astCtxt, &this->callbacks);
521     if (this->symbolic == nullptr)
522       throw triton::exceptions::API("API::initEngines(): Not enough memory.");
523 
524     this->solver = new(std::nothrow) triton::engines::solver::SolverEngine();
525     if (this->solver == nullptr)
526       throw triton::exceptions::API("API::initEngines(): Not enough memory.");
527 
528     this->taint = new(std::nothrow) triton::engines::taint::TaintEngine(this->modes, this->symbolic, *this->getCpuInstance());
529     if (this->taint == nullptr)
530       throw triton::exceptions::API("API::initEngines(): Not enough memory.");
531 
532     this->irBuilder = new(std::nothrow) triton::arch::IrBuilder(&this->arch, this->modes, this->astCtxt, this->symbolic, this->taint);
533     if (this->irBuilder == nullptr)
534       throw triton::exceptions::API("API::initEngines(): Not enough memory.");
535 
536     /* Setup registers shortcut */
537     this->registers.init(this->arch.getArchitecture());
538   }
539 
540 
removeEngines(void)541   void API::removeEngines(void) {
542     if (this->isArchitectureValid()) {
543       delete this->irBuilder;
544       delete this->solver;
545       delete this->symbolic;
546       delete this->taint;
547 
548       this->astCtxt   = nullptr;
549       this->irBuilder = nullptr;
550       this->solver    = nullptr;
551       this->symbolic  = nullptr;
552       this->taint     = nullptr;
553     }
554 
555     // Clean up the ast context
556     this->astCtxt = std::make_shared<triton::ast::AstContext>(this->modes);
557 
558     // Clean up the registers shortcut
559     this->registers.clear();
560   }
561 
562 
reset(void)563   void API::reset(void) {
564     if (this->isArchitectureValid()) {
565       this->removeEngines();
566       this->initEngines();
567       this->clearArchitecture();
568       this->clearCallbacks();
569       this->clearModes();
570     }
571   }
572 
573 
processing(triton::arch::Instruction & inst)574   bool API::processing(triton::arch::Instruction& inst) {
575     this->checkArchitecture();
576     this->arch.disassembly(inst);
577     return this->irBuilder->buildSemantics(inst);
578   }
579 
580 
581 
582   /* IR builder API ================================================================================= */
583 
buildSemantics(triton::arch::Instruction & inst)584   bool API::buildSemantics(triton::arch::Instruction& inst) {
585     this->checkIrBuilder();
586     return this->irBuilder->buildSemantics(inst);
587   }
588 
589 
getAstContext(void)590   triton::ast::SharedAstContext API::getAstContext(void) {
591     return this->astCtxt;
592   }
593 
594 
595 
596   /* AST representation API ========================================================================= */
597 
getAstRepresentationMode(void) const598   triton::uint32 API::getAstRepresentationMode(void) const {
599     return this->astCtxt->getRepresentationMode();
600   }
601 
602 
setAstRepresentationMode(triton::uint32 mode)603   void API::setAstRepresentationMode(triton::uint32 mode) {
604     this->astCtxt->setRepresentationMode(mode);
605   }
606 
607 
608 
609   /* Callbacks API ================================================================================= */
610 
addCallback(triton::callbacks::getConcreteMemoryValueCallback cb)611   void API::addCallback(triton::callbacks::getConcreteMemoryValueCallback cb) {
612     this->callbacks.addCallback(cb);
613   }
614 
615 
addCallback(triton::callbacks::getConcreteRegisterValueCallback cb)616   void API::addCallback(triton::callbacks::getConcreteRegisterValueCallback cb) {
617     this->callbacks.addCallback(cb);
618   }
619 
620 
addCallback(triton::callbacks::setConcreteMemoryValueCallback cb)621   void API::addCallback(triton::callbacks::setConcreteMemoryValueCallback cb) {
622     this->callbacks.addCallback(cb);
623   }
624 
625 
addCallback(triton::callbacks::setConcreteRegisterValueCallback cb)626   void API::addCallback(triton::callbacks::setConcreteRegisterValueCallback cb) {
627     this->callbacks.addCallback(cb);
628   }
629 
630 
addCallback(triton::callbacks::symbolicSimplificationCallback cb)631   void API::addCallback(triton::callbacks::symbolicSimplificationCallback cb) {
632     this->callbacks.addCallback(cb);
633   }
634 
635 
clearCallbacks(void)636   void API::clearCallbacks(void) {
637     this->callbacks.clearCallbacks();
638   }
639 
640 
removeCallback(triton::callbacks::getConcreteMemoryValueCallback cb)641   void API::removeCallback(triton::callbacks::getConcreteMemoryValueCallback cb) {
642     this->callbacks.removeCallback(cb);
643   }
644 
645 
removeCallback(triton::callbacks::getConcreteRegisterValueCallback cb)646   void API::removeCallback(triton::callbacks::getConcreteRegisterValueCallback cb) {
647     this->callbacks.removeCallback(cb);
648   }
649 
650 
removeCallback(triton::callbacks::setConcreteMemoryValueCallback cb)651   void API::removeCallback(triton::callbacks::setConcreteMemoryValueCallback cb) {
652     this->callbacks.removeCallback(cb);
653   }
654 
655 
removeCallback(triton::callbacks::setConcreteRegisterValueCallback cb)656   void API::removeCallback(triton::callbacks::setConcreteRegisterValueCallback cb) {
657     this->callbacks.removeCallback(cb);
658   }
659 
660 
removeCallback(triton::callbacks::symbolicSimplificationCallback cb)661   void API::removeCallback(triton::callbacks::symbolicSimplificationCallback cb) {
662     this->callbacks.removeCallback(cb);
663   }
664 
665 
processCallbacks(triton::callbacks::callback_e kind,triton::ast::SharedAbstractNode node)666   triton::ast::SharedAbstractNode API::processCallbacks(triton::callbacks::callback_e kind, triton::ast::SharedAbstractNode node) {
667     if (this->callbacks.isDefined)
668       return this->callbacks.processCallbacks(kind, node);
669     return node;
670   }
671 
672 
processCallbacks(triton::callbacks::callback_e kind,const triton::arch::MemoryAccess & mem)673   void API::processCallbacks(triton::callbacks::callback_e kind, const triton::arch::MemoryAccess& mem) {
674     if (this->callbacks.isDefined)
675       this->callbacks.processCallbacks(kind, mem);
676   }
677 
678 
processCallbacks(triton::callbacks::callback_e kind,const triton::arch::Register & reg)679   void API::processCallbacks(triton::callbacks::callback_e kind, const triton::arch::Register& reg) {
680     if (this->callbacks.isDefined)
681       this->callbacks.processCallbacks(kind, reg);
682   }
683 
684 
685 
686   /* Modes API======================================================================================= */
687 
setMode(triton::modes::mode_e mode,bool flag)688   void API::setMode(triton::modes::mode_e mode, bool flag) {
689     this->modes->setMode(mode, flag);
690   }
691 
692 
isModeEnabled(triton::modes::mode_e mode) const693   bool API::isModeEnabled(triton::modes::mode_e mode) const {
694     return this->modes->isModeEnabled(mode);
695   }
696 
697 
clearModes(void)698   void API::clearModes(void) {
699     this->modes->clearModes();
700   }
701 
702 
703 
704   /* Symbolic engine API ============================================================================ */
705 
getSymbolicEngine(void)706   triton::engines::symbolic::SymbolicEngine* API::getSymbolicEngine(void) {
707     this->checkSymbolic();
708     return this->symbolic;
709   }
710 
711 
symbolizeExpression(triton::usize exprId,triton::uint32 symVarSize,const std::string & symVarAlias)712   triton::engines::symbolic::SharedSymbolicVariable API::symbolizeExpression(triton::usize exprId, triton::uint32 symVarSize, const std::string& symVarAlias) {
713     this->checkSymbolic();
714     return this->symbolic->symbolizeExpression(exprId, symVarSize, symVarAlias);
715   }
716 
717 
symbolizeMemory(const triton::arch::MemoryAccess & mem,const std::string & symVarAlias)718   triton::engines::symbolic::SharedSymbolicVariable API::symbolizeMemory(const triton::arch::MemoryAccess& mem, const std::string& symVarAlias) {
719     this->checkSymbolic();
720     return this->symbolic->symbolizeMemory(mem, symVarAlias);
721   }
722 
723 
symbolizeRegister(const triton::arch::Register & reg,const std::string & symVarAlias)724   triton::engines::symbolic::SharedSymbolicVariable API::symbolizeRegister(const triton::arch::Register& reg, const std::string& symVarAlias) {
725     this->checkSymbolic();
726     return this->symbolic->symbolizeRegister(reg, symVarAlias);
727   }
728 
729 
getOperandAst(const triton::arch::OperandWrapper & op)730   triton::ast::SharedAbstractNode API::getOperandAst(const triton::arch::OperandWrapper& op) {
731     this->checkSymbolic();
732     return this->symbolic->getOperandAst(op);
733   }
734 
735 
getOperandAst(triton::arch::Instruction & inst,const triton::arch::OperandWrapper & op)736   triton::ast::SharedAbstractNode API::getOperandAst(triton::arch::Instruction& inst, const triton::arch::OperandWrapper& op) {
737     this->checkSymbolic();
738     return this->symbolic->getOperandAst(inst, op);
739   }
740 
741 
getImmediateAst(const triton::arch::Immediate & imm)742   triton::ast::SharedAbstractNode API::getImmediateAst(const triton::arch::Immediate& imm) {
743     this->checkSymbolic();
744     return this->symbolic->getImmediateAst(imm);
745   }
746 
747 
getImmediateAst(triton::arch::Instruction & inst,const triton::arch::Immediate & imm)748   triton::ast::SharedAbstractNode API::getImmediateAst(triton::arch::Instruction& inst, const triton::arch::Immediate& imm) {
749     this->checkSymbolic();
750     return this->symbolic->getImmediateAst(inst, imm);
751   }
752 
753 
getMemoryAst(const triton::arch::MemoryAccess & mem)754   triton::ast::SharedAbstractNode API::getMemoryAst(const triton::arch::MemoryAccess& mem) {
755     this->checkSymbolic();
756     return this->symbolic->getMemoryAst(mem);
757   }
758 
759 
getMemoryAst(triton::arch::Instruction & inst,const triton::arch::MemoryAccess & mem)760   triton::ast::SharedAbstractNode API::getMemoryAst(triton::arch::Instruction& inst, const triton::arch::MemoryAccess& mem) {
761     this->checkSymbolic();
762     return this->symbolic->getMemoryAst(inst, mem);
763   }
764 
765 
getRegisterAst(const triton::arch::Register & reg)766   triton::ast::SharedAbstractNode API::getRegisterAst(const triton::arch::Register& reg) {
767     this->checkSymbolic();
768     return this->symbolic->getRegisterAst(reg);
769   }
770 
771 
getRegisterAst(triton::arch::Instruction & inst,const triton::arch::Register & reg)772   triton::ast::SharedAbstractNode API::getRegisterAst(triton::arch::Instruction& inst, const triton::arch::Register& reg) {
773     this->checkSymbolic();
774     return this->symbolic->getRegisterAst(inst, reg);
775   }
776 
777 
newSymbolicExpression(const triton::ast::SharedAbstractNode & node,const std::string & comment)778   triton::engines::symbolic::SharedSymbolicExpression API::newSymbolicExpression(const triton::ast::SharedAbstractNode& node, const std::string& comment) {
779     this->checkSymbolic();
780     return this->symbolic->newSymbolicExpression(node, triton::engines::symbolic::VOLATILE_EXPRESSION, comment);
781   }
782 
783 
newSymbolicVariable(triton::uint32 varSize,const std::string & alias)784   triton::engines::symbolic::SharedSymbolicVariable API::newSymbolicVariable(triton::uint32 varSize, const std::string& alias) {
785     this->checkSymbolic();
786     return this->symbolic->newSymbolicVariable(triton::engines::symbolic::UNDEFINED_VARIABLE, 0, varSize, alias);
787   }
788 
789 
removeSymbolicExpression(const triton::engines::symbolic::SharedSymbolicExpression & expr)790   void API::removeSymbolicExpression(const triton::engines::symbolic::SharedSymbolicExpression& expr) {
791     this->checkSymbolic();
792     return this->symbolic->removeSymbolicExpression(expr);
793   }
794 
795 
createSymbolicExpression(triton::arch::Instruction & inst,const triton::ast::SharedAbstractNode & node,const triton::arch::OperandWrapper & dst,const std::string & comment)796   const triton::engines::symbolic::SharedSymbolicExpression& API::createSymbolicExpression(triton::arch::Instruction& inst, const triton::ast::SharedAbstractNode& node, const triton::arch::OperandWrapper& dst, const std::string& comment) {
797     this->checkSymbolic();
798     return this->symbolic->createSymbolicExpression(inst, node, dst, comment);
799   }
800 
801 
createSymbolicMemoryExpression(triton::arch::Instruction & inst,const triton::ast::SharedAbstractNode & node,const triton::arch::MemoryAccess & mem,const std::string & comment)802   const triton::engines::symbolic::SharedSymbolicExpression& API::createSymbolicMemoryExpression(triton::arch::Instruction& inst, const triton::ast::SharedAbstractNode& node, const triton::arch::MemoryAccess& mem, const std::string& comment) {
803     this->checkSymbolic();
804     return this->symbolic->createSymbolicMemoryExpression(inst, node, mem, comment);
805   }
806 
807 
createSymbolicRegisterExpression(triton::arch::Instruction & inst,const triton::ast::SharedAbstractNode & node,const triton::arch::Register & reg,const std::string & comment)808   const triton::engines::symbolic::SharedSymbolicExpression& API::createSymbolicRegisterExpression(triton::arch::Instruction& inst, const triton::ast::SharedAbstractNode& node, const triton::arch::Register& reg, const std::string& comment) {
809     this->checkSymbolic();
810     return this->symbolic->createSymbolicRegisterExpression(inst, node, reg, comment);
811   }
812 
813 
createSymbolicVolatileExpression(triton::arch::Instruction & inst,const triton::ast::SharedAbstractNode & node,const std::string & comment)814   const triton::engines::symbolic::SharedSymbolicExpression& API::createSymbolicVolatileExpression(triton::arch::Instruction& inst, const triton::ast::SharedAbstractNode& node, const std::string& comment) {
815     this->checkSymbolic();
816     return this->symbolic->createSymbolicVolatileExpression(inst, node, comment);
817   }
818 
819 
assignSymbolicExpressionToMemory(const triton::engines::symbolic::SharedSymbolicExpression & se,const triton::arch::MemoryAccess & mem)820   void API::assignSymbolicExpressionToMemory(const triton::engines::symbolic::SharedSymbolicExpression& se, const triton::arch::MemoryAccess& mem) {
821     this->checkSymbolic();
822     this->symbolic->assignSymbolicExpressionToMemory(se, mem);
823   }
824 
825 
assignSymbolicExpressionToRegister(const triton::engines::symbolic::SharedSymbolicExpression & se,const triton::arch::Register & reg)826   void API::assignSymbolicExpressionToRegister(const triton::engines::symbolic::SharedSymbolicExpression& se, const triton::arch::Register& reg) {
827     this->checkSymbolic();
828     this->symbolic->assignSymbolicExpressionToRegister(se, reg);
829   }
830 
831 
getSymbolicMemory(triton::uint64 addr) const832   triton::engines::symbolic::SharedSymbolicExpression API::getSymbolicMemory(triton::uint64 addr) const {
833     this->checkSymbolic();
834     return this->symbolic->getSymbolicMemory(addr);
835   }
836 
837 
getSymbolicRegisters(void) const838   std::unordered_map<triton::arch::register_e, triton::engines::symbolic::SharedSymbolicExpression> API::getSymbolicRegisters(void) const {
839     this->checkSymbolic();
840     return this->symbolic->getSymbolicRegisters();
841   }
842 
843 
getSymbolicMemory(void) const844   std::unordered_map<triton::uint64, triton::engines::symbolic::SharedSymbolicExpression> API::getSymbolicMemory(void) const {
845     this->checkSymbolic();
846     return this->symbolic->getSymbolicMemory();
847   }
848 
849 
getSymbolicRegister(const triton::arch::Register & reg) const850   const triton::engines::symbolic::SharedSymbolicExpression& API::getSymbolicRegister(const triton::arch::Register& reg) const {
851     this->checkSymbolic();
852     return this->symbolic->getSymbolicRegister(reg);
853   }
854 
855 
getSymbolicMemoryValue(triton::uint64 address)856   triton::uint8 API::getSymbolicMemoryValue(triton::uint64 address) {
857     this->checkSymbolic();
858     return this->symbolic->getSymbolicMemoryValue(address);
859   }
860 
861 
getSymbolicMemoryValue(const triton::arch::MemoryAccess & mem)862   triton::uint512 API::getSymbolicMemoryValue(const triton::arch::MemoryAccess& mem) {
863     this->checkSymbolic();
864     return this->symbolic->getSymbolicMemoryValue(mem);
865   }
866 
867 
getSymbolicMemoryAreaValue(triton::uint64 baseAddr,triton::usize size)868   std::vector<triton::uint8> API::getSymbolicMemoryAreaValue(triton::uint64 baseAddr, triton::usize size) {
869     this->checkSymbolic();
870     return this->symbolic->getSymbolicMemoryAreaValue(baseAddr, size);
871   }
872 
873 
getSymbolicRegisterValue(const triton::arch::Register & reg)874   triton::uint512 API::getSymbolicRegisterValue(const triton::arch::Register& reg) {
875     this->checkSymbolic();
876     return this->symbolic->getSymbolicRegisterValue(reg);
877   }
878 
879 
processSimplification(const triton::ast::SharedAbstractNode & node,bool z3) const880   triton::ast::SharedAbstractNode API::processSimplification(const triton::ast::SharedAbstractNode& node, bool z3) const {
881     this->checkSymbolic();
882     if (z3 == true) {
883       auto snode = this->processZ3Simplification(node);
884       return this->symbolic->processSimplification(snode);
885     }
886     return this->symbolic->processSimplification(node);
887   }
888 
889 
getSymbolicExpression(triton::usize symExprId) const890   triton::engines::symbolic::SharedSymbolicExpression API::getSymbolicExpression(triton::usize symExprId) const {
891     this->checkSymbolic();
892     return this->symbolic->getSymbolicExpression(symExprId);
893   }
894 
895 
getConcreteVariableValue(const triton::engines::symbolic::SharedSymbolicVariable & symVar) const896   triton::uint512 API::getConcreteVariableValue(const triton::engines::symbolic::SharedSymbolicVariable& symVar) const {
897     this->checkSymbolic();
898     return this->symbolic->getConcreteVariableValue(symVar);
899   }
900 
901 
setConcreteVariableValue(const triton::engines::symbolic::SharedSymbolicVariable & symVar,const triton::uint512 & value)902   void API::setConcreteVariableValue(const triton::engines::symbolic::SharedSymbolicVariable& symVar, const triton::uint512& value) {
903     this->checkSymbolic();
904     this->symbolic->setConcreteVariableValue(symVar, value);
905   }
906 
907 
getSymbolicVariable(triton::usize symVarId) const908   triton::engines::symbolic::SharedSymbolicVariable API::getSymbolicVariable(triton::usize symVarId) const {
909     this->checkSymbolic();
910     return this->symbolic->getSymbolicVariable(symVarId);
911   }
912 
913 
getSymbolicVariable(const std::string & symVarName) const914   triton::engines::symbolic::SharedSymbolicVariable API::getSymbolicVariable(const std::string& symVarName) const {
915     this->checkSymbolic();
916     return this->symbolic->getSymbolicVariable(symVarName);
917   }
918 
919 
getPathConstraints(void) const920   const std::vector<triton::engines::symbolic::PathConstraint>& API::getPathConstraints(void) const {
921     this->checkSymbolic();
922     return this->symbolic->getPathConstraints();
923   }
924 
925 
getPathPredicate(void)926   triton::ast::SharedAbstractNode API::getPathPredicate(void) {
927     this->checkSymbolic();
928     return this->symbolic->getPathPredicate();
929   }
930 
931 
getPredicatesToReachAddress(triton::uint64 addr)932   std::vector<triton::ast::SharedAbstractNode> API::getPredicatesToReachAddress(triton::uint64 addr) {
933     this->checkSymbolic();
934     return this->symbolic->getPredicatesToReachAddress(addr);
935   }
936 
937 
pushPathConstraint(const triton::ast::SharedAbstractNode & node)938   void API::pushPathConstraint(const triton::ast::SharedAbstractNode& node) {
939     this->checkSymbolic();
940     this->symbolic->pushPathConstraint(node);
941   }
942 
943 
popPathConstraint(void)944   void API::popPathConstraint(void) {
945     this->checkSymbolic();
946     this->symbolic->popPathConstraint();
947   }
948 
949 
clearPathConstraints(void)950   void API::clearPathConstraints(void) {
951     this->checkSymbolic();
952     this->symbolic->clearPathConstraints();
953   }
954 
955 
enableSymbolicEngine(bool flag)956   void API::enableSymbolicEngine(bool flag) {
957     this->checkSymbolic();
958     this->symbolic->enable(flag);
959   }
960 
961 
isSymbolicEngineEnabled(void) const962   bool API::isSymbolicEngineEnabled(void) const {
963     this->checkSymbolic();
964     return this->symbolic->isEnabled();
965   }
966 
967 
isSymbolicExpressionExists(triton::usize symExprId) const968   bool API::isSymbolicExpressionExists(triton::usize symExprId) const {
969     this->checkSymbolic();
970     return this->symbolic->isSymbolicExpressionExists(symExprId);
971   }
972 
973 
isMemorySymbolized(const triton::arch::MemoryAccess & mem) const974   bool API::isMemorySymbolized(const triton::arch::MemoryAccess& mem) const {
975     this->checkSymbolic();
976     return this->symbolic->isMemorySymbolized(mem);
977   }
978 
979 
isMemorySymbolized(triton::uint64 addr,triton::uint32 size) const980   bool API::isMemorySymbolized(triton::uint64 addr, triton::uint32 size) const {
981     this->checkSymbolic();
982     return this->symbolic->isMemorySymbolized(addr, size);
983   }
984 
985 
isRegisterSymbolized(const triton::arch::Register & reg) const986   bool API::isRegisterSymbolized(const triton::arch::Register& reg) const {
987     this->checkSymbolic();
988     return this->symbolic->isRegisterSymbolized(reg);
989   }
990 
991 
concretizeAllMemory(void)992   void API::concretizeAllMemory(void) {
993     this->checkSymbolic();
994     this->symbolic->concretizeAllMemory();
995   }
996 
997 
concretizeAllRegister(void)998   void API::concretizeAllRegister(void) {
999     this->checkSymbolic();
1000     this->symbolic->concretizeAllRegister();
1001   }
1002 
1003 
concretizeMemory(const triton::arch::MemoryAccess & mem)1004   void API::concretizeMemory(const triton::arch::MemoryAccess& mem) {
1005     this->checkSymbolic();
1006     this->symbolic->concretizeMemory(mem);
1007   }
1008 
1009 
concretizeMemory(triton::uint64 addr)1010   void API::concretizeMemory(triton::uint64 addr) {
1011     this->checkSymbolic();
1012     this->symbolic->concretizeMemory(addr);
1013   }
1014 
1015 
concretizeRegister(const triton::arch::Register & reg)1016   void API::concretizeRegister(const triton::arch::Register& reg) {
1017     this->checkSymbolic();
1018     this->symbolic->concretizeRegister(reg);
1019   }
1020 
1021 
sliceExpressions(const triton::engines::symbolic::SharedSymbolicExpression & expr)1022   std::unordered_map<triton::usize, triton::engines::symbolic::SharedSymbolicExpression> API::sliceExpressions(const triton::engines::symbolic::SharedSymbolicExpression& expr) {
1023     this->checkSymbolic();
1024     return this->symbolic->sliceExpressions(expr);
1025   }
1026 
1027 
getTaintedSymbolicExpressions(void) const1028   std::vector<triton::engines::symbolic::SharedSymbolicExpression> API::getTaintedSymbolicExpressions(void) const {
1029     this->checkSymbolic();
1030     return this->symbolic->getTaintedSymbolicExpressions();
1031   }
1032 
1033 
getSymbolicExpressions(void) const1034   std::unordered_map<triton::usize, triton::engines::symbolic::SharedSymbolicExpression> API::getSymbolicExpressions(void) const {
1035     this->checkSymbolic();
1036     return this->symbolic->getSymbolicExpressions();
1037   }
1038 
1039 
getSymbolicVariables(void) const1040   std::unordered_map<triton::usize, triton::engines::symbolic::SharedSymbolicVariable> API::getSymbolicVariables(void) const {
1041     this->checkSymbolic();
1042     return this->symbolic->getSymbolicVariables();
1043   }
1044 
1045 
1046 
1047   /* Solver engine API ============================================================================= */
1048 
getSolver(void) const1049   triton::engines::solver::solver_e API::getSolver(void) const {
1050     this->checkSolver();
1051     return this->solver->getSolver();
1052   }
1053 
1054 
getSolverInstance(void) const1055   const triton::engines::solver::SolverInterface* API::getSolverInstance(void) const {
1056     this->checkSolver();
1057     return this->solver->getSolverInstance();
1058   }
1059 
1060 
setSolver(triton::engines::solver::solver_e kind)1061   void API::setSolver(triton::engines::solver::solver_e kind) {
1062     this->checkSolver();
1063     this->solver->setSolver(kind);
1064   }
1065 
1066 
setCustomSolver(triton::engines::solver::SolverInterface * customSolver)1067   void API::setCustomSolver(triton::engines::solver::SolverInterface* customSolver) {
1068     this->checkSolver();
1069     this->solver->setCustomSolver(customSolver);
1070   }
1071 
1072 
isSolverValid(void) const1073   bool API::isSolverValid(void) const {
1074     this->checkSolver();
1075     return this->solver->isValid();
1076   }
1077 
1078 
getModel(const triton::ast::SharedAbstractNode & node) const1079   std::unordered_map<triton::usize, triton::engines::solver::SolverModel> API::getModel(const triton::ast::SharedAbstractNode& node) const {
1080     this->checkSolver();
1081     return this->solver->getModel(node);
1082   }
1083 
1084 
getModels(const triton::ast::SharedAbstractNode & node,triton::uint32 limit) const1085   std::vector<std::unordered_map<triton::usize, triton::engines::solver::SolverModel>> API::getModels(const triton::ast::SharedAbstractNode& node, triton::uint32 limit) const {
1086     this->checkSolver();
1087     return this->solver->getModels(node, limit);
1088   }
1089 
1090 
isSat(const triton::ast::SharedAbstractNode & node) const1091   bool API::isSat(const triton::ast::SharedAbstractNode& node) const {
1092     this->checkSolver();
1093     return this->solver->isSat(node);
1094   }
1095 
1096 
evaluateAstViaZ3(const triton::ast::SharedAbstractNode & node) const1097   triton::uint512 API::evaluateAstViaZ3(const triton::ast::SharedAbstractNode& node) const {
1098     this->checkSolver();
1099     #ifdef TRITON_Z3_INTERFACE
1100     if (this->getSolver() == triton::engines::solver::SOLVER_Z3) {
1101       return reinterpret_cast<const triton::engines::solver::Z3Solver*>(this->getSolverInstance())->evaluate(node);
1102     }
1103     #endif
1104     throw triton::exceptions::API("API::evaluateAstViaZ3(): Solver instance must be a SOLVER_Z3.");
1105   }
1106 
1107 
processZ3Simplification(const triton::ast::SharedAbstractNode & node) const1108   triton::ast::SharedAbstractNode API::processZ3Simplification(const triton::ast::SharedAbstractNode& node) const {
1109     this->checkSolver();
1110     #ifdef TRITON_Z3_INTERFACE
1111     if (this->getSolver() == triton::engines::solver::SOLVER_Z3) {
1112       return reinterpret_cast<const triton::engines::solver::Z3Solver*>(this->getSolverInstance())->simplify(node);
1113     }
1114     #endif
1115     throw triton::exceptions::API("API::processZ3Simplification(): Solver instance must be a SOLVER_Z3.");
1116   }
1117 
1118 
1119 
1120   /* Taint engine API ============================================================================== */
1121 
getTaintEngine(void)1122   triton::engines::taint::TaintEngine* API::getTaintEngine(void) {
1123     this->checkTaint();
1124     return this->taint;
1125   }
1126 
1127 
getTaintedMemory(void) const1128   const std::unordered_set<triton::uint64>& API::getTaintedMemory(void) const {
1129     this->checkTaint();
1130     return this->taint->getTaintedMemory();
1131   }
1132 
1133 
getTaintedRegisters(void) const1134   std::unordered_set<const triton::arch::Register*> API::getTaintedRegisters(void) const {
1135     this->checkTaint();
1136     return this->taint->getTaintedRegisters();
1137   }
1138 
1139 
enableTaintEngine(bool flag)1140   void API::enableTaintEngine(bool flag) {
1141     this->checkTaint();
1142     this->taint->enable(flag);
1143   }
1144 
1145 
isTaintEngineEnabled(void) const1146   bool API::isTaintEngineEnabled(void) const {
1147     this->checkTaint();
1148     return this->taint->isEnabled();
1149   }
1150 
1151 
isTainted(const triton::arch::OperandWrapper & op) const1152   bool API::isTainted(const triton::arch::OperandWrapper& op) const {
1153     this->checkTaint();
1154     return this->taint->isTainted(op);
1155   }
1156 
1157 
isMemoryTainted(triton::uint64 addr,uint32 size) const1158   bool API::isMemoryTainted(triton::uint64 addr, uint32 size) const {
1159     this->checkTaint();
1160     return this->taint->isMemoryTainted(addr, size);
1161   }
1162 
1163 
isMemoryTainted(const triton::arch::MemoryAccess & mem) const1164   bool API::isMemoryTainted(const triton::arch::MemoryAccess& mem) const {
1165     this->checkTaint();
1166     return this->taint->isMemoryTainted(mem);
1167   }
1168 
1169 
isRegisterTainted(const triton::arch::Register & reg) const1170   bool API::isRegisterTainted(const triton::arch::Register& reg) const {
1171     this->checkTaint();
1172     return this->taint->isRegisterTainted(reg);
1173   }
1174 
1175 
setTaint(const triton::arch::OperandWrapper & op,bool flag)1176   bool API::setTaint(const triton::arch::OperandWrapper& op, bool flag) {
1177     this->checkTaint();
1178     return this->taint->setTaint(op, flag);
1179   }
1180 
1181 
setTaintMemory(const triton::arch::MemoryAccess & mem,bool flag)1182   bool API::setTaintMemory(const triton::arch::MemoryAccess& mem, bool flag) {
1183     this->checkTaint();
1184     this->taint->setTaintMemory(mem, flag);
1185     return flag;
1186   }
1187 
1188 
setTaintRegister(const triton::arch::Register & reg,bool flag)1189   bool API::setTaintRegister(const triton::arch::Register& reg, bool flag) {
1190     this->checkTaint();
1191     this->taint->setTaintRegister(reg, flag);
1192     return flag;
1193   }
1194 
1195 
taintMemory(triton::uint64 addr)1196   bool API::taintMemory(triton::uint64 addr) {
1197     this->checkTaint();
1198     return this->taint->taintMemory(addr);
1199   }
1200 
1201 
taintMemory(const triton::arch::MemoryAccess & mem)1202   bool API::taintMemory(const triton::arch::MemoryAccess& mem) {
1203     this->checkTaint();
1204     return this->taint->taintMemory(mem);
1205   }
1206 
1207 
taintRegister(const triton::arch::Register & reg)1208   bool API::taintRegister(const triton::arch::Register& reg) {
1209     this->checkTaint();
1210     return this->taint->taintRegister(reg);
1211   }
1212 
1213 
untaintMemory(triton::uint64 addr)1214   bool API::untaintMemory(triton::uint64 addr) {
1215     this->checkTaint();
1216     return this->taint->untaintMemory(addr);
1217   }
1218 
1219 
untaintMemory(const triton::arch::MemoryAccess & mem)1220   bool API::untaintMemory(const triton::arch::MemoryAccess& mem) {
1221     this->checkTaint();
1222     return this->taint->untaintMemory(mem);
1223   }
1224 
1225 
untaintRegister(const triton::arch::Register & reg)1226   bool API::untaintRegister(const triton::arch::Register& reg) {
1227     this->checkTaint();
1228     return this->taint->untaintRegister(reg);
1229   }
1230 
1231 
taintUnion(const triton::arch::OperandWrapper & op1,const triton::arch::OperandWrapper & op2)1232   bool API::taintUnion(const triton::arch::OperandWrapper& op1, const triton::arch::OperandWrapper& op2) {
1233     this->checkTaint();
1234     return this->taint->taintUnion(op1, op2);
1235   }
1236 
1237 
taintUnion(const triton::arch::MemoryAccess & memDst,const triton::arch::Immediate & imm)1238   bool API::taintUnion(const triton::arch::MemoryAccess& memDst, const triton::arch::Immediate& imm) {
1239     this->checkTaint();
1240     return this->taint->taintUnion(memDst, imm);
1241   }
1242 
1243 
taintUnion(const triton::arch::MemoryAccess & memDst,const triton::arch::MemoryAccess & memSrc)1244   bool API::taintUnion(const triton::arch::MemoryAccess& memDst, const triton::arch::MemoryAccess& memSrc) {
1245     this->checkTaint();
1246     return this->taint->taintUnion(memDst, memSrc);
1247   }
1248 
1249 
taintUnion(const triton::arch::MemoryAccess & memDst,const triton::arch::Register & regSrc)1250   bool API::taintUnion(const triton::arch::MemoryAccess& memDst, const triton::arch::Register& regSrc) {
1251     this->checkTaint();
1252     return this->taint->taintUnion(memDst, regSrc);
1253   }
1254 
1255 
taintUnion(const triton::arch::Register & regDst,const triton::arch::Immediate & imm)1256   bool API::taintUnion(const triton::arch::Register& regDst, const triton::arch::Immediate& imm) {
1257     this->checkTaint();
1258     return this->taint->taintUnion(regDst, imm);
1259   }
1260 
1261 
taintUnion(const triton::arch::Register & regDst,const triton::arch::MemoryAccess & memSrc)1262   bool API::taintUnion(const triton::arch::Register& regDst, const triton::arch::MemoryAccess& memSrc) {
1263     this->checkTaint();
1264     return this->taint->taintUnion(regDst, memSrc);
1265   }
1266 
1267 
taintUnion(const triton::arch::Register & regDst,const triton::arch::Register & regSrc)1268   bool API::taintUnion(const triton::arch::Register& regDst, const triton::arch::Register& regSrc) {
1269     this->checkTaint();
1270     return this->taint->taintUnion(regDst, regSrc);
1271   }
1272 
1273 
taintAssignment(const triton::arch::OperandWrapper & op1,const triton::arch::OperandWrapper & op2)1274   bool API::taintAssignment(const triton::arch::OperandWrapper& op1, const triton::arch::OperandWrapper& op2) {
1275     this->checkTaint();
1276     return this->taint->taintAssignment(op1, op2);
1277   }
1278 
1279 
taintAssignment(const triton::arch::MemoryAccess & memDst,const triton::arch::Immediate & imm)1280   bool API::taintAssignment(const triton::arch::MemoryAccess& memDst, const triton::arch::Immediate& imm) {
1281     this->checkTaint();
1282     return this->taint->taintAssignment(memDst, imm);
1283   }
1284 
1285 
taintAssignment(const triton::arch::MemoryAccess & memDst,const triton::arch::MemoryAccess & memSrc)1286   bool API::taintAssignment(const triton::arch::MemoryAccess& memDst, const triton::arch::MemoryAccess& memSrc) {
1287     this->checkTaint();
1288     return this->taint->taintAssignment(memDst, memSrc);
1289   }
1290 
1291 
taintAssignment(const triton::arch::MemoryAccess & memDst,const triton::arch::Register & regSrc)1292   bool API::taintAssignment(const triton::arch::MemoryAccess& memDst, const triton::arch::Register& regSrc) {
1293     this->checkTaint();
1294     return this->taint->taintAssignment(memDst, regSrc);
1295   }
1296 
1297 
taintAssignment(const triton::arch::Register & regDst,const triton::arch::Immediate & imm)1298   bool API::taintAssignment(const triton::arch::Register& regDst, const triton::arch::Immediate& imm) {
1299     this->checkTaint();
1300     return this->taint->taintAssignment(regDst, imm);
1301   }
1302 
1303 
taintAssignment(const triton::arch::Register & regDst,const triton::arch::MemoryAccess & memSrc)1304   bool API::taintAssignment(const triton::arch::Register& regDst, const triton::arch::MemoryAccess& memSrc) {
1305     this->checkTaint();
1306     return this->taint->taintAssignment(regDst, memSrc);
1307   }
1308 
1309 
taintAssignment(const triton::arch::Register & regDst,const triton::arch::Register & regSrc)1310   bool API::taintAssignment(const triton::arch::Register& regDst, const triton::arch::Register& regSrc) {
1311     this->checkTaint();
1312     return this->taint->taintAssignment(regDst, regSrc);
1313   }
1314 
1315 }; /* triton namespace */
1316