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/symbolicVariable.hpp>
|
13
|
|
|
14
|
|
|
15
|
|
|
16
|
|
/* setup doctest context
|
17
|
|
|
18
|
|
>>> from triton import TritonContext, REG, ARCH
|
19
|
|
>>> ctxt = TritonContext()
|
20
|
|
>>> ctxt.setArchitecture(ARCH.X86_64)
|
21
|
|
|
22
|
|
*/
|
23
|
|
|
24
|
|
/*! \page py_SymbolicVariable_page SymbolicVariable
|
25
|
|
\brief [**python api**] All information about the SymbolicVariable Python object.
|
26
|
|
|
27
|
|
\tableofcontents
|
28
|
|
|
29
|
|
\section py_SymbolicVariable_description Description
|
30
|
|
<hr>
|
31
|
|
|
32
|
|
This object is used to represent a symbolic variable.
|
33
|
|
|
34
|
|
~~~~~~~~~~~~~{.py}
|
35
|
|
>>> symvar = ctxt.symbolizeRegister(ctxt.registers.rax)
|
36
|
|
>>> print(symvar)
|
37
|
|
SymVar_0:64
|
38
|
|
|
39
|
|
~~~~~~~~~~~~~
|
40
|
|
|
41
|
|
\section SymbolicVariable_py_api Python API - Methods of the SymbolicVariable class
|
42
|
|
<hr>
|
43
|
|
|
44
|
|
- <b>string getAlias(void)</b><br>
|
45
|
|
Returns the alias (if exists) of the symbolic variable.
|
46
|
|
|
47
|
|
- <b>integer getBitSize(void)</b><br>
|
48
|
|
Returns the size of the symbolic variable.
|
49
|
|
|
50
|
|
- <b>string getComment(void)</b><br>
|
51
|
|
Returns the comment (if exists) of the symbolic variable.
|
52
|
|
|
53
|
|
- <b>integer getId(void)</b><br>
|
54
|
|
Returns the id of the symbolic variable. This id is always unique.<br>
|
55
|
|
e.g: `18`
|
56
|
|
|
57
|
|
- <b>string getName(void)</b><br>
|
58
|
|
Returns name of the symbolic variable.<br>
|
59
|
|
e.g: `SymVar_18`
|
60
|
|
|
61
|
|
- <b>integer getOrigin(void)</b><br>
|
62
|
|
Returns the origin according to the \ref py_SYMBOLIC_page value.<br>
|
63
|
|
If `getType()` returns triton::engines::symbolic::REGISTER_VARIABLE, then `getOrigin()` returns the id of the register.<br>
|
64
|
|
Otherwise, if `getType()` returns triton::engines::symbolic::MEMORY_VARIABLE, then `getOrigin()` returns the address of the memory access.<br>
|
65
|
|
Then, if `getType()` returns triton::engines::symbolic::UNDEFINED_VARIABLE, then `getOrigin()` returns `0`.
|
66
|
|
|
67
|
|
- <b>\ref py_SYMBOLIC_page getType(void)</b><br>
|
68
|
|
Returns the type of the symbolic variable.<br>
|
69
|
|
e.g: `SYMBOLIC.REGISTER_VARIABLE`
|
70
|
|
|
71
|
|
- <b>void setAlias(string comment)</b><br>
|
72
|
|
Sets an alias to the symbolic variable.
|
73
|
|
|
74
|
|
- <b>void setComment(string comment)</b><br>
|
75
|
|
Sets a comment to the symbolic variable.
|
76
|
|
|
77
|
|
*/
|
78
|
|
|
79
|
|
|
80
|
|
|
81
|
|
namespace triton {
|
82
|
|
namespace bindings {
|
83
|
|
namespace python {
|
84
|
|
|
85
|
|
//! SymbolicVariable destructor.
|
86
|
1
|
void SymbolicVariable_dealloc(PyObject* self) {
|
87
|
1
|
std::cout << std::flush;
|
88
|
1
|
PySymbolicVariable_AsSymbolicVariable(self) = nullptr; // decref the shared_ptr
|
89
|
1
|
Py_TYPE(self)->tp_free((PyObject*)self);
|
90
|
|
}
|
91
|
|
|
92
|
|
|
93
|
1
|
static PyObject* SymbolicVariable_getAlias(PyObject* self, PyObject* noarg) {
|
94
|
|
try {
|
95
|
1
|
return Py_BuildValue("s", PySymbolicVariable_AsSymbolicVariable(self)->getAlias().c_str());
|
96
|
|
}
|
97
|
0
|
catch (const triton::exceptions::Exception& e) {
|
98
|
0
|
return PyErr_Format(PyExc_TypeError, "%s", e.what());
|
99
|
|
}
|
100
|
|
}
|
101
|
|
|
102
|
|
|
103
|
1
|
static PyObject* SymbolicVariable_getName(PyObject* self, PyObject* noarg) {
|
104
|
|
try {
|
105
|
1
|
return Py_BuildValue("s", PySymbolicVariable_AsSymbolicVariable(self)->getName().c_str());
|
106
|
|
}
|
107
|
0
|
catch (const triton::exceptions::Exception& e) {
|
108
|
0
|
return PyErr_Format(PyExc_TypeError, "%s", e.what());
|
109
|
|
}
|
110
|
|
}
|
111
|
|
|
112
|
|
|
113
|
1
|
static PyObject* SymbolicVariable_getId(PyObject* self, PyObject* noarg) {
|
114
|
|
try {
|
115
|
1
|
return PyLong_FromUsize(PySymbolicVariable_AsSymbolicVariable(self)->getId());
|
116
|
|
}
|
117
|
0
|
catch (const triton::exceptions::Exception& e) {
|
118
|
0
|
return PyErr_Format(PyExc_TypeError, "%s", e.what());
|
119
|
|
}
|
120
|
|
}
|
121
|
|
|
122
|
|
|
123
|
1
|
static PyObject* SymbolicVariable_getType(PyObject* self, PyObject* noarg) {
|
124
|
|
try {
|
125
|
1
|
return PyLong_FromUint32(PySymbolicVariable_AsSymbolicVariable(self)->getType());
|
126
|
|
}
|
127
|
0
|
catch (const triton::exceptions::Exception& e) {
|
128
|
0
|
return PyErr_Format(PyExc_TypeError, "%s", e.what());
|
129
|
|
}
|
130
|
|
}
|
131
|
|
|
132
|
|
|
133
|
1
|
static PyObject* SymbolicVariable_getOrigin(PyObject* self, PyObject* noarg) {
|
134
|
|
try {
|
135
|
1
|
return PyLong_FromUint64(PySymbolicVariable_AsSymbolicVariable(self)->getOrigin());
|
136
|
|
}
|
137
|
0
|
catch (const triton::exceptions::Exception& e) {
|
138
|
0
|
return PyErr_Format(PyExc_TypeError, "%s", e.what());
|
139
|
|
}
|
140
|
|
}
|
141
|
|
|
142
|
|
|
143
|
1
|
static PyObject* SymbolicVariable_getBitSize(PyObject* self, PyObject* noarg) {
|
144
|
|
try {
|
145
|
1
|
return PyLong_FromUint32(PySymbolicVariable_AsSymbolicVariable(self)->getSize());
|
146
|
|
}
|
147
|
0
|
catch (const triton::exceptions::Exception& e) {
|
148
|
0
|
return PyErr_Format(PyExc_TypeError, "%s", e.what());
|
149
|
|
}
|
150
|
|
}
|
151
|
|
|
152
|
|
|
153
|
1
|
static PyObject* SymbolicVariable_getComment(PyObject* self, PyObject* noarg) {
|
154
|
|
try {
|
155
|
1
|
return Py_BuildValue("s", PySymbolicVariable_AsSymbolicVariable(self)->getComment().c_str());
|
156
|
|
}
|
157
|
0
|
catch (const triton::exceptions::Exception& e) {
|
158
|
0
|
return PyErr_Format(PyExc_TypeError, "%s", e.what());
|
159
|
|
}
|
160
|
|
}
|
161
|
|
|
162
|
|
|
163
|
1
|
static PyObject* SymbolicVariable_setAlias(PyObject* self, PyObject* alias) {
|
164
|
|
try {
|
165
|
1
|
if (!PyStr_Check(alias))
|
166
|
0
|
return PyErr_Format(PyExc_TypeError, "SymbolicVariable::setAlias(): Expected a string as argument.");
|
167
|
1
|
PySymbolicVariable_AsSymbolicVariable(self)->setAlias(PyStr_AsString(alias));
|
168
|
1
|
Py_INCREF(Py_None);
|
169
|
1
|
return Py_None;
|
170
|
|
}
|
171
|
0
|
catch (const triton::exceptions::Exception& e) {
|
172
|
0
|
return PyErr_Format(PyExc_TypeError, "%s", e.what());
|
173
|
|
}
|
174
|
|
}
|
175
|
|
|
176
|
|
|
177
|
1
|
static PyObject* SymbolicVariable_setComment(PyObject* self, PyObject* comment) {
|
178
|
|
try {
|
179
|
1
|
if (!PyStr_Check(comment))
|
180
|
0
|
return PyErr_Format(PyExc_TypeError, "SymbolicVariable::setComment(): Expected a string as argument.");
|
181
|
1
|
PySymbolicVariable_AsSymbolicVariable(self)->setComment(PyStr_AsString(comment));
|
182
|
1
|
Py_INCREF(Py_None);
|
183
|
1
|
return Py_None;
|
184
|
|
}
|
185
|
0
|
catch (const triton::exceptions::Exception& e) {
|
186
|
0
|
return PyErr_Format(PyExc_TypeError, "%s", e.what());
|
187
|
|
}
|
188
|
|
}
|
189
|
|
|
190
|
|
|
191
|
|
#if !defined(IS_PY3_8) || !IS_PY3_8
|
192
|
0
|
static int SymbolicVariable_print(PyObject* self, void* io, int s) {
|
193
|
0
|
std::cout << PySymbolicVariable_AsSymbolicVariable(self);
|
194
|
0
|
return 0;
|
195
|
|
}
|
196
|
|
#endif
|
197
|
|
|
198
|
|
|
199
|
1
|
static PyObject* SymbolicVariable_str(PyObject* self) {
|
200
|
|
try {
|
201
|
1
|
std::stringstream str;
|
202
|
1
|
str << PySymbolicVariable_AsSymbolicVariable(self);
|
203
|
1
|
return PyStr_FromFormat("%s", str.str().c_str());
|
204
|
|
}
|
205
|
0
|
catch (const triton::exceptions::Exception& e) {
|
206
|
0
|
return PyErr_Format(PyExc_TypeError, "%s", e.what());
|
207
|
|
}
|
208
|
|
}
|
209
|
|
|
210
|
|
|
211
|
1
|
static int SymbolicVariable_init(AstNode_Object* self, PyObject* args, PyObject* kwds) {
|
212
|
1
|
return 0;
|
213
|
|
}
|
214
|
|
|
215
|
|
|
216
|
1
|
static PyObject* SymbolicVariable_new(PyTypeObject* type, PyObject* args, PyObject* kwds) {
|
217
|
1
|
return type->tp_alloc(type, 0);
|
218
|
|
}
|
219
|
|
|
220
|
|
|
221
|
0
|
static long SymbolicVariable_hash(PyObject* self) {
|
222
|
|
/* NOTE: Should be a problem if there is more than 0xffffffff variables (casting from usize to long). */
|
223
|
0
|
return static_cast<long>(PySymbolicVariable_AsSymbolicVariable(self)->getId());
|
224
|
|
}
|
225
|
|
|
226
|
|
|
227
|
0
|
static PyObject* SymbolicVariable_richcompare(PyObject* self, PyObject* other, int op) {
|
228
|
0
|
PyObject* result = nullptr;
|
229
|
0
|
triton::usize id1 = 0;
|
230
|
0
|
triton::usize id2 = 0;
|
231
|
|
|
232
|
0
|
if (!PySymbolicVariable_Check(other)) {
|
233
|
|
result = Py_NotImplemented;
|
234
|
|
}
|
235
|
|
else {
|
236
|
0
|
id1 = PySymbolicVariable_AsSymbolicVariable(self)->getId();
|
237
|
0
|
id2 = PySymbolicVariable_AsSymbolicVariable(other)->getId();
|
238
|
|
|
239
|
0
|
switch (op) {
|
240
|
|
case Py_LT:
|
241
|
0
|
result = (id1 < id2) ? Py_True : Py_False;
|
242
|
|
break;
|
243
|
|
case Py_LE:
|
244
|
0
|
result = (id1 <= id2) ? Py_True : Py_False;
|
245
|
|
break;
|
246
|
|
case Py_EQ:
|
247
|
0
|
result = (id1 == id2) ? Py_True : Py_False;
|
248
|
|
break;
|
249
|
|
case Py_NE:
|
250
|
0
|
result = (id1 != id2) ? Py_True : Py_False;
|
251
|
|
break;
|
252
|
|
case Py_GT:
|
253
|
0
|
result = (id1 > id2) ? Py_True : Py_False;
|
254
|
|
break;
|
255
|
|
case Py_GE:
|
256
|
0
|
result = (id1 >= id2) ? Py_True : Py_False;
|
257
|
|
break;
|
258
|
|
}
|
259
|
|
}
|
260
|
|
|
261
|
0
|
Py_INCREF(result);
|
262
|
0
|
return result;
|
263
|
|
}
|
264
|
|
|
265
|
|
//! SymbolicVariable methods.
|
266
|
|
PyMethodDef SymbolicVariable_callbacks[] = {
|
267
|
|
{"getAlias", SymbolicVariable_getAlias, METH_NOARGS, ""},
|
268
|
|
{"getBitSize", SymbolicVariable_getBitSize, METH_NOARGS, ""},
|
269
|
|
{"getComment", SymbolicVariable_getComment, METH_NOARGS, ""},
|
270
|
|
{"getId", SymbolicVariable_getId, METH_NOARGS, ""},
|
271
|
|
{"getName", SymbolicVariable_getName, METH_NOARGS, ""},
|
272
|
|
{"getOrigin", SymbolicVariable_getOrigin, METH_NOARGS, ""},
|
273
|
|
{"getType", SymbolicVariable_getType, METH_NOARGS, ""},
|
274
|
|
{"setAlias", SymbolicVariable_setAlias, METH_O, ""},
|
275
|
|
{"setComment", SymbolicVariable_setComment, METH_O, ""},
|
276
|
|
{nullptr, nullptr, 0, nullptr}
|
277
|
|
};
|
278
|
|
|
279
|
|
|
280
|
|
PyTypeObject SymbolicVariable_Type = {
|
281
|
|
PyVarObject_HEAD_INIT(&PyType_Type, 0)
|
282
|
|
"SymbolicVariable", /* tp_name */
|
283
|
|
sizeof(SymbolicVariable_Object), /* tp_basicsize */
|
284
|
|
0, /* tp_itemsize */
|
285
|
|
(destructor)SymbolicVariable_dealloc, /* tp_dealloc */
|
286
|
|
#if IS_PY3_8
|
287
|
|
0, /* tp_vectorcall_offset */
|
288
|
|
#else
|
289
|
|
(printfunc)SymbolicVariable_print, /* tp_print */
|
290
|
|
#endif
|
291
|
|
0, /* tp_getattr */
|
292
|
|
0, /* tp_setattr */
|
293
|
|
0, /* tp_compare */
|
294
|
|
(reprfunc)SymbolicVariable_str, /* tp_repr */
|
295
|
|
0, /* tp_as_number */
|
296
|
|
0, /* tp_as_sequence */
|
297
|
|
0, /* tp_as_mapping */
|
298
|
|
(hashfunc)SymbolicVariable_hash, /* tp_hash */
|
299
|
|
0, /* tp_call */
|
300
|
|
(reprfunc)SymbolicVariable_str, /* tp_str */
|
301
|
|
0, /* tp_getattro */
|
302
|
|
0, /* tp_setattro */
|
303
|
|
0, /* tp_as_buffer */
|
304
|
|
Py_TPFLAGS_DEFAULT, /* tp_flags */
|
305
|
|
"SymbolicVariable objects", /* tp_doc */
|
306
|
|
0, /* tp_traverse */
|
307
|
|
0, /* tp_clear */
|
308
|
|
SymbolicVariable_richcompare, /* tp_richcompare */
|
309
|
|
0, /* tp_weaklistoffset */
|
310
|
|
0, /* tp_iter */
|
311
|
|
0, /* tp_iternext */
|
312
|
|
SymbolicVariable_callbacks, /* tp_methods */
|
313
|
|
0, /* tp_members */
|
314
|
|
0, /* tp_getset */
|
315
|
|
0, /* tp_base */
|
316
|
|
0, /* tp_dict */
|
317
|
|
0, /* tp_descr_get */
|
318
|
|
0, /* tp_descr_set */
|
319
|
|
0, /* tp_dictoffset */
|
320
|
|
(initproc)SymbolicVariable_init, /* tp_init */
|
321
|
|
0, /* tp_alloc */
|
322
|
|
(newfunc)SymbolicVariable_new, /* tp_new */
|
323
|
|
0, /* tp_free */
|
324
|
|
0, /* tp_is_gc */
|
325
|
|
0, /* tp_bases */
|
326
|
|
0, /* tp_mro */
|
327
|
|
0, /* tp_cache */
|
328
|
|
0, /* tp_subclasses */
|
329
|
|
0, /* tp_weaklist */
|
330
|
|
0, /* tp_del */
|
331
|
|
#if IS_PY3
|
332
|
|
0, /* tp_version_tag */
|
333
|
|
0, /* tp_finalize */
|
334
|
|
#if IS_PY3_8
|
335
|
|
0, /* tp_vectorcall */
|
336
|
|
#if !IS_PY3_9
|
337
|
|
0, /* bpo-37250: kept for backwards compatibility in CPython 3.8 only */
|
338
|
|
#endif
|
339
|
|
#endif
|
340
|
|
#else
|
341
|
|
0 /* tp_version_tag */
|
342
|
|
#endif
|
343
|
|
};
|
344
|
|
|
345
|
|
|
346
|
1
|
PyObject* PySymbolicVariable(const triton::engines::symbolic::SharedSymbolicVariable& symVar) {
|
347
|
1
|
if (symVar == nullptr) {
|
348
|
0
|
Py_INCREF(Py_None);
|
349
|
0
|
return Py_None;
|
350
|
|
}
|
351
|
|
|
352
|
1
|
PyType_Ready(&SymbolicVariable_Type);
|
353
|
|
// Build the new object the python way (calling operator() on the type) as
|
354
|
|
// it crash otherwise (certainly due to incorrect shared_ptr initialization).
|
355
|
1
|
auto* object = (triton::bindings::python::SymbolicVariable_Object*)PyObject_CallObject((PyObject*)&SymbolicVariable_Type, nullptr);
|
356
|
1
|
if (object != NULL) {
|
357
|
1
|
object->symVar = symVar;
|
358
|
|
}
|
359
|
|
|
360
|
|
return (PyObject*)object;
|
361
|
|
}
|
362
|
|
|
363
|
|
}; /* python namespace */
|
364
|
|
}; /* bindings namespace */
|
365
|
1
|
}; /* triton namespace */
|