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/pythonObjects.hpp>
9
#include <triton/pythonUtils.hpp>
10
#include <triton/pythonXFunctions.hpp>
11
#include <triton/exceptions.hpp>
12
#include <triton/symbolicExpression.hpp>
13

14

15

16
/*! \page py_SymbolicExpression_page SymbolicExpression
17
    \brief [**python api**] All information about the SymbolicExpression Python object.
18

19
\tableofcontents
20

21
\section py_SymbolicExpression_description Description
22
<hr>
23

24
This object is used to represent a symbolic expression.
25

26
~~~~~~~~~~~~~{.py}
27
>>> from __future__ import print_function
28
>>> from triton import TritonContext, ARCH, Instruction, REG
29

30
>>> ctxt = TritonContext()
31
>>> ctxt.setArchitecture(ARCH.X86_64)
32

33
>>> opcode = b"\x48\x31\xD0"
34
>>> inst = Instruction()
35

36
>>> inst.setOpcode(opcode)
37
>>> inst.setAddress(0x400000)
38
>>> ctxt.setConcreteRegisterValue(ctxt.registers.rax, 12345)
39
>>> ctxt.setConcreteRegisterValue(ctxt.registers.rdx, 67890)
40

41
>>> ctxt.processing(inst)
42
True
43
>>> print(inst)
44
0x400000: xor rax, rdx
45

46
>>> for expr in inst.getSymbolicExpressions():
47
...     print(expr)
48
...
49
(define-fun ref!0 () (_ BitVec 64) (bvxor (_ bv12345 64) (_ bv67890 64))) ; XOR operation
50
(define-fun ref!1 () (_ BitVec 1) (_ bv0 1)) ; Clears carry flag
51
(define-fun ref!2 () (_ BitVec 1) (_ bv0 1)) ; Clears overflow flag
52
(define-fun ref!3 () (_ BitVec 1) (bvxor (bvxor (bvxor (bvxor (bvxor (bvxor (bvxor (bvxor (_ bv1 1) ((_ extract 0 0) (bvlshr ((_ extract 7 0) ref!0) (_ bv0 8)))) ((_ extract 0 0) (bvlshr ((_ extract 7 0) ref!0) (_ bv1 8)))) ((_ extract 0 0) (bvlshr ((_ extract 7 0) ref!0) (_ bv2 8)))) ((_ extract 0 0) (bvlshr ((_ extract 7 0) ref!0) (_ bv3 8)))) ((_ extract 0 0) (bvlshr ((_ extract 7 0) ref!0) (_ bv4 8)))) ((_ extract 0 0) (bvlshr ((_ extract 7 0) ref!0) (_ bv5 8)))) ((_ extract 0 0) (bvlshr ((_ extract 7 0) ref!0) (_ bv6 8)))) ((_ extract 0 0) (bvlshr ((_ extract 7 0) ref!0) (_ bv7 8))))) ; Parity flag
53
(define-fun ref!4 () (_ BitVec 1) ((_ extract 63 63) ref!0)) ; Sign flag
54
(define-fun ref!5 () (_ BitVec 1) (ite (= ref!0 (_ bv0 64)) (_ bv1 1) (_ bv0 1))) ; Zero flag
55
(define-fun ref!6 () (_ BitVec 64) (_ bv4194307 64)) ; Program Counter
56

57
>>> expr_1 = inst.getSymbolicExpressions()[0]
58
>>> print(expr_1)
59
(define-fun ref!0 () (_ BitVec 64) (bvxor (_ bv12345 64) (_ bv67890 64))) ; XOR operation
60

61
>>> print(expr_1.getId())
62
0
63

64
>>> ast = expr_1.getAst()
65
>>> print(ast)
66
(bvxor (_ bv12345 64) (_ bv67890 64))
67

68

69
>>> expr_1.isMemory()
70
False
71

72
>>> expr_1.isRegister()
73
True
74

75
>>> print(expr_1.getOrigin())
76
rax:64 bv[63..0]
77

78
~~~~~~~~~~~~~
79

80
\section SymbolicExpression_py_api Python API - Methods of the SymbolicExpression class
81
<hr>
82

83
- <b>\ref py_AstNode_page getAst(void)</b><br>
84
Returns the AST root node of the symbolic expression.
85

86
- <b>string getComment(void)</b><br>
87
Returns the comment (if exists) of the symbolic expression.
88

89
- <b>integer getId(void)</b><br>
90
Returns the id of the symbolic expression. This id is always unique.<br>
91
e.g: `2387`
92

93
- <b>\ref py_AstNode_page getNewAst(void)</b><br>
94
Returns a new AST root node of the symbolic expression. This new instance is a duplicate of the original node and may be changed without changing the original semantics.
95

96
- <b>\ref py_MemoryAccess_page / \ref py_Register_page getOrigin(void)</b><br>
97
Returns the origin of the symbolic expression. For example, if the symbolic expression is assigned to a memory cell, this function returns
98
a \ref py_MemoryAccess_page, else if it is assigned to a register, this function returns a \ref py_Register_page otherwise it returns None. Note that
99
for a \ref py_MemoryAccess_page all information about LEA are lost at this level.
100

101
- <b>\ref py_SYMBOLIC_page getType(void)</b><br>
102
Returns the type of the symbolic expression.<br>
103
e.g: `SYMBOLIC.REGISTER_EXPRESSION`
104

105
- <b>bool isMemory(void)</b><br>
106
Returns true if the expression is assigned to memory.
107

108
- <b>bool isRegister(void)</b><br>
109
Returns true if the expression is assigned to a register.
110

111
- <b>bool isSymbolized(void)</b><br>
112
Returns true if the expression contains a symbolic variable.
113

114
- <b>bool isTainted(void)</b><br>
115
Returns true if the expression is tainted.
116

117
- <b>void setAst(\ref py_AstNode_page node)</b><br>
118
Sets a root node.
119

120
- <b>void setComment(string comment)</b><br>
121
Sets a comment to the symbolic expression.
122

123
*/
124

125

126

127
namespace triton {
128
  namespace bindings {
129
    namespace python {
130

131
      //! SymbolicExpression destructor.
132 1
      void SymbolicExpression_dealloc(PyObject* self) {
133 1
        std::cout << std::flush;
134 1
        PySymbolicExpression_AsSymbolicExpression(self) = nullptr; // decref the shared_ptr
135 1
        Py_TYPE(self)->tp_free((PyObject*)self);
136
      }
137

138

139 1
      static PyObject* SymbolicExpression_getAst(PyObject* self, PyObject* noarg) {
140
        try {
141 1
          return PyAstNode(PySymbolicExpression_AsSymbolicExpression(self)->getAst());
142
        }
143 0
        catch (const triton::exceptions::Exception& e) {
144 0
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
145
        }
146
      }
147

148

149 1
      static PyObject* SymbolicExpression_getComment(PyObject* self, PyObject* noarg) {
150
        try {
151 1
          return Py_BuildValue("s", PySymbolicExpression_AsSymbolicExpression(self)->getComment().c_str());
152
        }
153 0
        catch (const triton::exceptions::Exception& e) {
154 0
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
155
        }
156
      }
157

158

159 1
      static PyObject* SymbolicExpression_getId(PyObject* self, PyObject* noarg) {
160
        try {
161 1
          return PyLong_FromUsize(PySymbolicExpression_AsSymbolicExpression(self)->getId());
162
        }
163 0
        catch (const triton::exceptions::Exception& e) {
164 0
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
165
        }
166
      }
167

168

169 1
      static PyObject* SymbolicExpression_getNewAst(PyObject* self, PyObject* noarg) {
170
        try {
171 1
          return PyAstNode(PySymbolicExpression_AsSymbolicExpression(self)->getNewAst());
172
        }
173 0
        catch (const triton::exceptions::Exception& e) {
174 0
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
175
        }
176
      }
177

178

179 1
      static PyObject* SymbolicExpression_getOrigin(PyObject* self, PyObject* noarg) {
180
        try {
181 1
          if (PySymbolicExpression_AsSymbolicExpression(self)->isMemory())
182 1
            return PyMemoryAccess(PySymbolicExpression_AsSymbolicExpression(self)->getOriginMemory());
183

184 1
          else if (PySymbolicExpression_AsSymbolicExpression(self)->isRegister())
185 1
            return PyRegister(PySymbolicExpression_AsSymbolicExpression(self)->getOriginRegister());
186

187 0
          Py_INCREF(Py_None);
188 0
          return Py_None;
189
        }
190 0
        catch (const triton::exceptions::Exception& e) {
191 0
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
192
        }
193
      }
194

195

196 1
      static PyObject* SymbolicExpression_getType(PyObject* self, PyObject* noarg) {
197
        try {
198 1
          return PyLong_FromUint32(PySymbolicExpression_AsSymbolicExpression(self)->getType());
199
        }
200 0
        catch (const triton::exceptions::Exception& e) {
201 0
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
202
        }
203
      }
204

205

206 1
      static PyObject* SymbolicExpression_isMemory(PyObject* self, PyObject* noarg) {
207
        try {
208 1
          if (PySymbolicExpression_AsSymbolicExpression(self)->isMemory() == true)
209 0
            Py_RETURN_TRUE;
210 1
          Py_RETURN_FALSE;
211
        }
212 0
        catch (const triton::exceptions::Exception& e) {
213 0
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
214
        }
215
      }
216

217

218 1
      static PyObject* SymbolicExpression_isRegister(PyObject* self, PyObject* noarg) {
219
        try {
220 1
          if (PySymbolicExpression_AsSymbolicExpression(self)->isRegister() == true)
221 1
            Py_RETURN_TRUE;
222 0
          Py_RETURN_FALSE;
223
        }
224 0
        catch (const triton::exceptions::Exception& e) {
225 0
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
226
        }
227
      }
228

229

230 1
      static PyObject* SymbolicExpression_isSymbolized(PyObject* self, PyObject* noarg) {
231
        try {
232 1
          if (PySymbolicExpression_AsSymbolicExpression(self)->isSymbolized() == true)
233 1
            Py_RETURN_TRUE;
234 1
          Py_RETURN_FALSE;
235
        }
236 0
        catch (const triton::exceptions::Exception& e) {
237 0
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
238
        }
239
      }
240

241

242 1
      static PyObject* SymbolicExpression_isTainted(PyObject* self, PyObject* noarg) {
243
        try {
244 1
          if (PySymbolicExpression_AsSymbolicExpression(self)->isTainted == true)
245 0
            Py_RETURN_TRUE;
246 1
          Py_RETURN_FALSE;
247
        }
248
        catch (const triton::exceptions::Exception& e) {
249
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
250
        }
251
      }
252

253

254 1
      static PyObject* SymbolicExpression_setAst(PyObject* self, PyObject* node) {
255
        try {
256 1
          if (!PyAstNode_Check(node))
257 0
            return PyErr_Format(PyExc_TypeError, "SymbolicExpression::setAst(): Expected a AstNode as argument.");
258 1
          PySymbolicExpression_AsSymbolicExpression(self)->setAst(PyAstNode_AsAstNode(node));
259 1
          Py_INCREF(Py_None);
260 1
        return Py_None;
261
        }
262 0
        catch (const triton::exceptions::Exception& e) {
263 0
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
264
        }
265
      }
266

267

268 1
      static PyObject* SymbolicExpression_setComment(PyObject* self, PyObject* comment) {
269
        try {
270 1
          if (!PyStr_Check(comment))
271 0
            return PyErr_Format(PyExc_TypeError, "SymbolicExpression::setComment(): Expected a string as argument.");
272 1
          PySymbolicExpression_AsSymbolicExpression(self)->setComment(PyStr_AsString(comment));
273 1
          Py_INCREF(Py_None);
274 1
          return Py_None;
275
        }
276 0
        catch (const triton::exceptions::Exception& e) {
277 0
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
278
        }
279
      }
280

281

282
      #if !defined(IS_PY3_8) || !IS_PY3_8
283 0
      static int SymbolicExpression_print(PyObject* self, void* io, int s) {
284 0
        std::cout << PySymbolicExpression_AsSymbolicExpression(self);
285 0
        return 0;
286
      }
287
      #endif
288

289

290 1
      static PyObject* SymbolicExpression_str(PyObject* self) {
291
        try {
292 1
          std::stringstream str;
293 1
          str << PySymbolicExpression_AsSymbolicExpression(self);
294 1
          return PyStr_FromFormat("%s", str.str().c_str());
295
        }
296 0
        catch (const triton::exceptions::Exception& e) {
297 0
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
298
        }
299
      }
300

301

302 1
      static int SymbolicExpression_init(AstNode_Object *self, PyObject *args, PyObject *kwds) {
303 1
        return 0;
304
      }
305

306

307 1
      static PyObject* SymbolicExpression_new(PyTypeObject* type, PyObject* args, PyObject* kwds) {
308 1
        return type->tp_alloc(type, 0);
309
      }
310

311

312
      //! SymbolicExpression methods.
313
      PyMethodDef SymbolicExpression_callbacks[] = {
314
        {"getAst",            SymbolicExpression_getAst,            METH_NOARGS,    ""},
315
        {"getComment",        SymbolicExpression_getComment,        METH_NOARGS,    ""},
316
        {"getId",             SymbolicExpression_getId,             METH_NOARGS,    ""},
317
        {"getNewAst",         SymbolicExpression_getNewAst,         METH_NOARGS,    ""},
318
        {"getOrigin",         SymbolicExpression_getOrigin,         METH_NOARGS,    ""},
319
        {"getType",           SymbolicExpression_getType,           METH_NOARGS,    ""},
320
        {"isMemory",          SymbolicExpression_isMemory,          METH_NOARGS,    ""},
321
        {"isRegister",        SymbolicExpression_isRegister,        METH_NOARGS,    ""},
322
        {"isSymbolized",      SymbolicExpression_isSymbolized,      METH_NOARGS,    ""},
323
        {"isTainted",         SymbolicExpression_isTainted,         METH_NOARGS,    ""},
324
        {"setAst",            SymbolicExpression_setAst,            METH_O,         ""},
325
        {"setComment",        SymbolicExpression_setComment,        METH_O,         ""},
326
        {nullptr,             nullptr,                              0,              nullptr}
327
      };
328

329

330
      PyTypeObject SymbolicExpression_Type = {
331
        PyVarObject_HEAD_INIT(&PyType_Type, 0)
332
        "SymbolicExpression",                       /* tp_name */
333
        sizeof(SymbolicExpression_Object),          /* tp_basicsize */
334
        0,                                          /* tp_itemsize */
335
        (destructor)SymbolicExpression_dealloc,     /* tp_dealloc */
336
        #if IS_PY3_8
337
        0,                                          /* tp_vectorcall_offset */
338
        #else
339
        (printfunc)SymbolicExpression_print,        /* tp_print */
340
        #endif
341
        0,                                          /* tp_getattr */
342
        0,                                          /* tp_setattr */
343
        0,                                          /* tp_compare */
344
        (reprfunc)SymbolicExpression_str,           /* tp_repr */
345
        0,                                          /* tp_as_number */
346
        0,                                          /* tp_as_sequence */
347
        0,                                          /* tp_as_mapping */
348
        0,                                          /* tp_hash */
349
        0,                                          /* tp_call */
350
        (reprfunc)SymbolicExpression_str,           /* tp_str */
351
        0,                                          /* tp_getattro */
352
        0,                                          /* tp_setattro */
353
        0,                                          /* tp_as_buffer */
354
        Py_TPFLAGS_DEFAULT,                         /* tp_flags */
355
        "SymbolicExpression objects",               /* tp_doc */
356
        0,                                          /* tp_traverse */
357
        0,                                          /* tp_clear */
358
        0,                                          /* tp_richcompare */
359
        0,                                          /* tp_weaklistoffset */
360
        0,                                          /* tp_iter */
361
        0,                                          /* tp_iternext */
362
        SymbolicExpression_callbacks,               /* tp_methods */
363
        0,                                          /* tp_members */
364
        0,                                          /* tp_getset */
365
        0,                                          /* tp_base */
366
        0,                                          /* tp_dict */
367
        0,                                          /* tp_descr_get */
368
        0,                                          /* tp_descr_set */
369
        0,                                          /* tp_dictoffset */
370
        (initproc)SymbolicExpression_init,          /* tp_init */
371
        0,                                          /* tp_alloc */
372
        (newfunc)SymbolicExpression_new,            /* tp_new */
373
        0,                                          /* tp_free */
374
        0,                                          /* tp_is_gc */
375
        0,                                          /* tp_bases */
376
        0,                                          /* tp_mro */
377
        0,                                          /* tp_cache */
378
        0,                                          /* tp_subclasses */
379
        0,                                          /* tp_weaklist */
380
        0,                                          /* tp_del */
381
        #if IS_PY3
382
        0,                                          /* tp_version_tag */
383
        0,                                          /* tp_finalize */
384
        #if IS_PY3_8
385
        0,                                          /* tp_vectorcall */
386
        0,                                          /* bpo-37250: kept for backwards compatibility in CPython 3.8 only */
387
        #endif
388
        #else
389
        0                                           /* tp_version_tag */
390
        #endif
391
      };
392

393

394 1
      PyObject* PySymbolicExpression(const triton::engines::symbolic::SharedSymbolicExpression& symExpr) {
395 1
        if (symExpr == nullptr) {
396 0
          Py_INCREF(Py_None);
397 0
          return Py_None;
398
        }
399

400 1
        PyType_Ready(&SymbolicExpression_Type);
401 1
        auto* object = (triton::bindings::python::SymbolicExpression_Object*)PyObject_CallObject((PyObject*)&SymbolicExpression_Type, nullptr);
402 1
        if (object != NULL) {
403 1
          object->symExpr = symExpr;
404
        }
405

406
        return (PyObject*)object;
407
      }
408

409
    }; /* python namespace */
410
  }; /* bindings namespace */
411 1
}; /* triton namespace */

Read our documentation on viewing source code .

Loading