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/register.hpp>
13

14

15

16
/* setup doctest context
17

18
>>> from __future__ import print_function
19
>>> from triton import ARCH, TritonContext, Instruction, REG
20
>>> ctxt = TritonContext()
21
>>> ctxt.setArchitecture(ARCH.X86_64)
22

23
>>> inst = Instruction(b"\x8A\xA4\x4A\x00\x01\x00\x00")
24
>>> inst.setAddress(0x40000)
25

26
*/
27

28
/*! \page py_Register_page Register
29
    \brief [**python api**] All information about the Register Python object.
30

31
\tableofcontents
32

33
\section py_Register_description Description
34
<hr>
35

36
This object is used to represent a register operand according to the CPU architecture.
37

38

39
\subsection py_Register_example Example
40

41
~~~~~~~~~~~~~{.py}
42
>>> ctxt.processing(inst)
43
True
44
>>> print(inst)
45
0x40000: mov ah, byte ptr [rdx + rcx*2 + 0x100]
46

47
>>> op0 = inst.getOperands()[0]
48
>>> print(op0)
49
ah:8 bv[15..8]
50

51
>>> op0.getName()
52
'ah'
53

54
>>> op0.getSize()
55
1
56

57
>>> op0.getBitSize()
58
8
59

60
>>> ctxt.getParentRegister(op0).getName()
61
'rax'
62

63
~~~~~~~~~~~~~
64

65
\subsection py_Register_constructor Constructor
66

67
~~~~~~~~~~~~~{.py}
68
>>> ah = ctxt.getRegister(REG.X86_64.AH)
69
>>> print(ah)
70
ah:8 bv[15..8]
71

72
>>> print(ah.getBitSize())
73
8
74

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

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

80
\section Register_py_api Python API - Methods of the Register class
81
<hr>
82

83
- <b>integer getBitSize(void)</b><br>
84
Returns the size (in bits) of the register.<br>
85
e.g: `64`
86

87
- <b>\ref py_BitsVector_page getBitvector(void)</b><br>
88
Returns the bit vector of the register.
89

90
- <b>\ref py_EXTEND_page getExtendSize(void)</b><br>
91
Returns the size (in bits) of the extend. Mainly used for AArch64.<br>
92
e.g: `16`
93

94
- <b>\ref py_EXTEND_page getExtendType(void)</b><br>
95
Returns the extend type of the operand. Mainly used for AArch64.<br>
96
e.g: `EXTEND.ARM.UXTW`
97

98
- <b>\ref py_REG_page getId(void)</b><br>
99
Returns the enum of the register.<br>
100
e.g: `REG.X86_64.RBX`
101

102
- <b>string getName(void)</b><br>
103
Returns the name of the register.<br>
104
e.g: `rbx`
105

106
- <b>\ref py_SHIFT_page getShiftType(void)</b><br>
107
Returns the shift type of the operand. Mainly used for AArch64.<br>
108
e.g: `SHIFT.ARM.LSL`
109

110
- <b>integer getShiftImmediate(void)</b><br>
111
Returns the shift immediate value of the operand. Mainly used for AArch64 and ARM32.<br>
112
e.g: `2`
113

114
- <b>\ref py_REG_page getShiftRegister(void)</b><br>
115
Returns the shift register of the operand. Mainly used for ARM32.<br>
116
e.g: `REG.ARM32.R0`
117

118
- <b>integer getSize(void)</b><br>
119
Returns the size (in bytes) of the register.<br>
120
e.g: `8`
121

122
- <b>\ref py_OPERAND_page getType(void)</b><br>
123
Returns the type of the register. In this case this function returns `OPERAND.REG`.
124

125
- <b>bool isMutable(void)</b><br>
126
Returns true if this register is mutable. Mainly used in AArch64 to define that some registers like XZR are immutable.
127

128
- <b>bool isOverlapWith(\ref py_Register_page other)</b><br>
129
Returns true if `other` and `self` overlap.
130

131
*/
132

133

134

135
namespace triton {
136
  namespace bindings {
137
    namespace python {
138

139
      //! Register destructor.
140 1
      void Register_dealloc(PyObject* self) {
141 1
        std::cout << std::flush;
142 1
        delete PyRegister_AsRegister(self);
143 1
        Py_TYPE(self)->tp_free((PyObject*)self);
144
      }
145

146

147 1
      static PyObject* Register_getBitSize(PyObject* self, PyObject* noarg) {
148
        try {
149 1
          return PyLong_FromUint32(PyRegister_AsRegister(self)->getBitSize());
150
        }
151 0
        catch (const triton::exceptions::Exception& e) {
152 0
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
153
        }
154
      }
155

156

157 1
      static PyObject* Register_getBitvector(PyObject* self, PyObject* noarg) {
158
        try {
159 1
          return PyBitsVector(*PyRegister_AsRegister(self));
160
        }
161 0
        catch (const triton::exceptions::Exception& e) {
162 0
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
163
        }
164
      }
165

166

167 1
      static PyObject* Register_getExtendSize(PyObject* self, PyObject* noarg) {
168
        try {
169 1
          return PyLong_FromUint32(PyRegister_AsRegister(self)->getExtendSize());
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* Register_getExtendType(PyObject* self, PyObject* noarg) {
178
        try {
179 1
          return PyLong_FromUint32(PyRegister_AsRegister(self)->getExtendType());
180
        }
181 0
        catch (const triton::exceptions::Exception& e) {
182 0
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
183
        }
184
      }
185

186

187 1
      static PyObject* Register_getId(PyObject* self, PyObject* noarg) {
188
        try {
189 1
          return PyLong_FromUint32(PyRegister_AsRegister(self)->getId());
190
        }
191 0
        catch (const triton::exceptions::Exception& e) {
192 0
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
193
        }
194
      }
195

196

197 1
      static PyObject* Register_getName(PyObject* self, PyObject* noarg) {
198
        try {
199 1
          return Py_BuildValue("s", PyRegister_AsRegister(self)->getName().c_str());
200
        }
201 0
        catch (const triton::exceptions::Exception& e) {
202 0
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
203
        }
204
      }
205

206

207 1
      static PyObject* Register_getShiftType(PyObject* self, PyObject* noarg) {
208
        try {
209 1
          return PyLong_FromUint32(PyRegister_AsRegister(self)->getShiftType());
210
        }
211 0
        catch (const triton::exceptions::Exception& e) {
212 0
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
213
        }
214
      }
215

216

217 1
      static PyObject* Register_getShiftImmediate(PyObject* self, PyObject* noarg) {
218
        try {
219 1
          return PyLong_FromUint64(PyRegister_AsRegister(self)->getShiftImmediate());
220
        }
221 0
        catch (const triton::exceptions::Exception& e) {
222 0
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
223
        }
224
      }
225

226

227 1
      static PyObject* Register_getShiftRegister(PyObject* self, PyObject* noarg) {
228
        try {
229 1
          return PyLong_FromUint64(PyRegister_AsRegister(self)->getShiftRegister());
230
        }
231 0
        catch (const triton::exceptions::Exception& e) {
232 0
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
233
        }
234
      }
235

236

237 1
      static PyObject* Register_getSize(PyObject* self, PyObject* noarg) {
238
        try {
239 1
          return PyLong_FromUint32(PyRegister_AsRegister(self)->getSize());
240
        }
241 0
        catch (const triton::exceptions::Exception& e) {
242 0
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
243
        }
244
      }
245

246

247 1
      static PyObject* Register_getType(PyObject* self, PyObject* noarg) {
248
        try {
249 1
          return PyLong_FromUint32(PyRegister_AsRegister(self)->getType());
250
        }
251 0
        catch (const triton::exceptions::Exception& e) {
252 0
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
253
        }
254
      }
255

256

257 1
      static PyObject* Register_isMutable(PyObject* self, PyObject* noarg) {
258
        try {
259 1
          if (PyRegister_AsRegister(self)->isMutable())
260 1
            Py_RETURN_TRUE;
261 1
          Py_RETURN_FALSE;
262
        }
263 0
        catch (const triton::exceptions::Exception& e) {
264 0
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
265
        }
266
      }
267

268

269 1
      static PyObject* Register_isOverlapWith(PyObject* self, PyObject* reg2) {
270
        try {
271
          triton::arch::Register* reg1;
272

273 1
          if (!PyRegister_Check(reg2))
274 0
            return PyErr_Format(PyExc_TypeError, "Register::isOverlapWith(): Expected a Register as argument.");
275

276 1
          reg1 = PyRegister_AsRegister(self);
277 1
          if (reg1->isOverlapWith(*PyRegister_AsRegister(reg2)))
278 1
            Py_RETURN_TRUE;
279 1
          Py_RETURN_FALSE;
280
        }
281 0
        catch (const triton::exceptions::Exception& e) {
282 0
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
283
        }
284
      }
285

286

287
      #if !defined(IS_PY3_8) || !IS_PY3_8
288 0
      static int Register_print(PyObject* self, void* io, int s) {
289 0
        std::cout << PyRegister_AsRegister(self);
290 0
        return 0;
291
      }
292
      #endif
293

294

295 0
      static long Register_hash(PyObject* self) {
296 0
        return static_cast<long>(PyRegister_AsRegister(self)->getId());
297
      }
298

299

300 1
      static PyObject* Register_str(PyObject* self) {
301
        try {
302 1
          std::stringstream str;
303 1
          str << PyRegister_AsRegister(self);
304 1
          return PyStr_FromFormat("%s", str.str().c_str());
305
        }
306 0
        catch (const triton::exceptions::Exception& e) {
307 0
          return PyErr_Format(PyExc_TypeError, "%s", e.what());
308
        }
309
      }
310

311

312 1
      static PyObject* Register_richcompare(PyObject* self, PyObject* other, int op) {
313 1
        PyObject* result    = nullptr;
314 1
        triton::uint32 id1  = 0;
315 1
        triton::uint32 id2  = 0;
316

317 1
        if (!PyRegister_Check(other)) {
318
          result = Py_NotImplemented;
319
        }
320

321
        else {
322 1
          id1 = PyRegister_AsRegister(self)->getId();
323 1
          id2 = PyRegister_AsRegister(other)->getId();
324

325 1
          switch (op) {
326
            case Py_LT:
327 0
                result = (id1 <  id2) ? Py_True : Py_False;
328
                break;
329
            case Py_LE:
330 0
                result = (id1 <= id2) ? Py_True : Py_False;
331
                break;
332
            case Py_EQ:
333 1
                result = (id1 == id2) ? Py_True : Py_False;
334
                break;
335
            case Py_NE:
336 0
                result = (id1 != id2) ? Py_True : Py_False;
337
                break;
338
            case Py_GT:
339 0
                result = (id1 >  id2) ? Py_True : Py_False;
340
                break;
341
            case Py_GE:
342 0
                result = (id1 >= id2) ? Py_True : Py_False;
343
                break;
344
          }
345
        }
346

347 1
        Py_INCREF(result);
348 1
        return result;
349
      }
350

351

352
      //! Register methods.
353
      PyMethodDef Register_callbacks[] = {
354
        {"getBitSize",        Register_getBitSize,        METH_NOARGS,    ""},
355
        {"getBitvector",      Register_getBitvector,      METH_NOARGS,    ""},
356
        {"getExtendSize",     Register_getExtendSize,     METH_NOARGS,    ""},
357
        {"getExtendType",     Register_getExtendType,     METH_NOARGS,    ""},
358
        {"getId",             Register_getId,             METH_NOARGS,    ""},
359
        {"getName",           Register_getName,           METH_NOARGS,    ""},
360
        {"getShiftType",      Register_getShiftType,      METH_NOARGS,    ""},
361
        {"getShiftImmediate", Register_getShiftImmediate, METH_NOARGS,    ""},
362
        {"getShiftRegister",  Register_getShiftRegister,  METH_NOARGS,    ""},
363
        {"getSize",           Register_getSize,           METH_NOARGS,    ""},
364
        {"getType",           Register_getType,           METH_NOARGS,    ""},
365
        {"isMutable",         Register_isMutable,         METH_NOARGS,    ""},
366
        {"isOverlapWith",     Register_isOverlapWith,     METH_O,         ""},
367
        {nullptr,             nullptr,                    0,              nullptr}
368
      };
369

370

371
      PyTypeObject Register_Type = {
372
        PyVarObject_HEAD_INIT(&PyType_Type, 0)
373
        "Register",                                 /* tp_name */
374
        sizeof(Register_Object),                    /* tp_basicsize */
375
        0,                                          /* tp_itemsize */
376
        (destructor)Register_dealloc,               /* tp_dealloc */
377
        #if IS_PY3_8
378
        0,                                          /* tp_vectorcall_offset */
379
        #else
380
        (printfunc)Register_print,                  /* tp_print */
381
        #endif
382
        0,                                          /* tp_getattr */
383
        0,                                          /* tp_setattr */
384
        0,                                          /* tp_compare */
385
        (reprfunc)Register_str,                     /* tp_repr */
386
        0,                                          /* tp_as_number */
387
        0,                                          /* tp_as_sequence */
388
        0,                                          /* tp_as_mapping */
389
        (hashfunc)Register_hash,                    /* tp_hash */
390
        0,                                          /* tp_call */
391
        (reprfunc)Register_str,                     /* tp_str */
392
        0,                                          /* tp_getattro */
393
        0,                                          /* tp_setattro */
394
        0,                                          /* tp_as_buffer */
395
        Py_TPFLAGS_DEFAULT,                         /* tp_flags */
396
        "Register objects",                         /* tp_doc */
397
        0,                                          /* tp_traverse */
398
        0,                                          /* tp_clear */
399
        (richcmpfunc)Register_richcompare,          /* tp_richcompare */
400
        0,                                          /* tp_weaklistoffset */
401
        0,                                          /* tp_iter */
402
        0,                                          /* tp_iternext */
403
        Register_callbacks,                         /* tp_methods */
404
        0,                                          /* tp_members */
405
        0,                                          /* tp_getset */
406
        0,                                          /* tp_base */
407
        0,                                          /* tp_dict */
408
        0,                                          /* tp_descr_get */
409
        0,                                          /* tp_descr_set */
410
        0,                                          /* tp_dictoffset */
411
        0,                                          /* tp_init */
412
        0,                                          /* tp_alloc */
413
        0,                                          /* tp_new */
414
        0,                                          /* tp_free */
415
        0,                                          /* tp_is_gc */
416
        0,                                          /* tp_bases */
417
        0,                                          /* tp_mro */
418
        0,                                          /* tp_cache */
419
        0,                                          /* tp_subclasses */
420
        0,                                          /* tp_weaklist */
421
        0,                                          /* tp_del */
422
        #if IS_PY3
423
          0,                                        /* tp_version_tag */
424
          0,                                        /* tp_finalize */
425
          #if IS_PY3_8
426
            0,                                      /* tp_vectorcall */
427
            #if !IS_PY3_9
428
              0,                                    /* bpo-37250: kept for backwards compatibility in CPython 3.8 only */
429
            #endif
430
          #endif
431
        #else
432
          0                                         /* tp_version_tag */
433
        #endif
434
      };
435

436

437 1
      PyObject* PyRegister(const triton::arch::Register& reg) {
438
        Register_Object* object;
439

440 1
        PyType_Ready(&Register_Type);
441 1
        object = PyObject_NEW(Register_Object, &Register_Type);
442 1
        if (object != NULL)
443 1
          object->reg = new triton::arch::Register(reg);
444

445 1
        return (PyObject*)object;
446
      }
447

448
    }; /* python namespace */
449
  }; /* bindings namespace */
450 1
}; /* triton namespace */

Read our documentation on viewing source code .

Loading