libTriton  version 0.6 build 1389
bindings.cpp
Go to the documentation of this file.
1 /*
3 ** Copyright (C) - Triton
4 **
5 ** This program is under the terms of the BSD License.
6 */
7 
8 /* libTriton */
9 #include <triton/pythonUtils.hpp>
10 #include <triton/pythonObjects.hpp>
11 #include <triton/tritonTypes.hpp>
12 
13 #include <pin.H>
14 
15 /* pintool */
16 #include "api.hpp"
17 #include "bindings.hpp"
18 #include "context.hpp"
19 #include "snapshot.hpp"
20 
21 
22 
158 namespace tracer {
159  namespace pintool {
160 
161  static PyObject* pintool_checkReadAccess(PyObject* self, PyObject* addr) {
162  if (!PyLong_Check(addr) && !PyInt_Check(addr))
163  return PyErr_Format(PyExc_TypeError, "tracer::pintool::checkReadAccess(): Expected an address (integer) as argument.");
164 
165  if (PIN_CheckReadAccess(reinterpret_cast<void*>(triton::bindings::python::PyLong_AsUint(addr))) == true)
166  Py_RETURN_TRUE;
167 
168  Py_RETURN_FALSE;
169  }
170 
171 
172  static PyObject* pintool_checkWriteAccess(PyObject* self, PyObject* addr) {
173  if (!PyLong_Check(addr) && !PyInt_Check(addr))
174  return PyErr_Format(PyExc_TypeError, "tracer::pintool::checkWriteAccess(): Expected an address (integer) as argument.");
175 
176  if (PIN_CheckWriteAccess(reinterpret_cast<void*>(triton::bindings::python::PyLong_AsUint(addr))) == true)
177  Py_RETURN_TRUE;
178 
179  Py_RETURN_FALSE;
180  }
181 
182 
183  static PyObject* pintool_detachProcess(PyObject* self, PyObject* noarg) {
184  PIN_Detach();
186  Py_INCREF(Py_None);
187  return Py_None;
188  }
189 
190 
191  static PyObject* pintool_disableSnapshot(PyObject* self, PyObject* noarg) {
193  Py_INCREF(Py_None);
194  return Py_None;
195  }
196 
197 
198  static PyObject* pintool_getCurrentMemoryValue(PyObject* self, PyObject* args) {
199  PyObject* mem = nullptr;
200  PyObject* size = nullptr;
201 
202  /* Extract arguments */
203  PyArg_ParseTuple(args, "|OO", &mem, &size);
204 
205  if (mem != nullptr && (PyMemoryAccess_Check(mem) || PyInt_Check(mem) || PyLong_Check(mem))) {
206 
207  if (size != nullptr && (!PyInt_Check(size) && !PyLong_Check(size)))
208  return PyErr_Format(PyExc_TypeError, "tracer::pintool::getCurrentMemoryValue(): The size must be an integer.");
209 
210  try {
211  if (PyMemoryAccess_Check(mem))
213  else if (size != nullptr) {
215  }
216  else
218  }
219  catch (const std::exception& e) {
220  return PyErr_Format(PyExc_TypeError, "%s", e.what());
221  }
222 
223  }
224 
225  return PyErr_Format(PyExc_TypeError, "tracer::pintool::getCurrentMemoryValue(): Expected a Memory as first argument.");
226  }
227 
228 
229  static PyObject* pintool_getCurrentRegisterValue(PyObject* self, PyObject* reg) {
230  if (!PyRegister_Check(reg))
231  return PyErr_Format(PyExc_TypeError, "tracer::pintool::getCurrentRegisterValue(): Expected a REG as argument.");
232  try {
234  }
235  catch (const std::exception& e) {
236  return PyErr_Format(PyExc_TypeError, "%s", e.what());
237  }
238  }
239 
240 
241  static PyObject* pintool_getImageName(PyObject* self, PyObject* addr) {
242  if (!PyLong_Check(addr) && !PyInt_Check(addr))
243  return PyErr_Format(PyExc_TypeError, "tracer::pintool::getImageName(): Expected an address (integer) as argument.");
244 
246  return PyString_FromFormat("%s", imageName.c_str());;
247  }
248 
249 
250  static PyObject* pintool_getRoutineName(PyObject* self, PyObject* addr) {
251  if (!PyLong_Check(addr) && !PyInt_Check(addr))
252  return PyErr_Format(PyExc_TypeError, "tracer::pintool::getImageName(): Expected an address (integer) as argument.");
253 
255  return PyString_FromFormat("%s", routineName.c_str());;
256  }
257 
258 
259  static PyObject* pintool_getSyscallArgument(PyObject* self, PyObject* args) {
260  PyObject* num = nullptr;
261  PyObject* std = nullptr;
262  triton::__uint ret;
263 
264  /* Extract arguments */
265  PyArg_ParseTuple(args, "|OO", &std, &num);
266 
267  if (std == nullptr || (!PyLong_Check(std) && !PyInt_Check(std)))
268  return PyErr_Format(PyExc_TypeError, "tracer::pintool::getSyscallArgument(): Expected an id (integer) as first argument.");
269 
270  if (num == nullptr || (!PyLong_Check(num) && !PyInt_Check(num)))
271  return PyErr_Format(PyExc_TypeError, "tracer::pintool::getSyscallArgument(): Expected an id (integer) as second argument.");
272 
273  LEVEL_CORE::SYSCALL_STANDARD standard = static_cast<LEVEL_CORE::SYSCALL_STANDARD>(triton::bindings::python::PyLong_AsUint32(std));
274  ret = PIN_GetSyscallArgument(tracer::pintool::context::lastContext, standard, triton::bindings::python::PyLong_AsUint32(num));
275 
277  }
278 
279 
280  static PyObject* pintool_getSyscallNumber(PyObject* self, PyObject* std) {
281  triton::uint32 syscallNumber;
282 
283  if (!PyLong_Check(std) && !PyInt_Check(std))
284  return PyErr_Format(PyExc_TypeError, "tracer::pintool::getSyscallNumber(): Expected an id (integer) as argument.");
285 
286  LEVEL_CORE::SYSCALL_STANDARD standard = static_cast<LEVEL_CORE::SYSCALL_STANDARD>(triton::bindings::python::PyLong_AsUint32(std));
287  syscallNumber = PIN_GetSyscallNumber(tracer::pintool::context::lastContext, standard);
288 
289  return triton::bindings::python::PyLong_FromUint32(syscallNumber);
290  }
291 
292 
293  static PyObject* pintool_getSyscallReturn(PyObject* self, PyObject* std) {
294  triton::__uint ret;
295 
296  if (!PyLong_Check(std) && !PyInt_Check(std))
297  return PyErr_Format(PyExc_TypeError, "tracer::pintool::getSyscallReturn(): Expected an id (integer) as argument.");
298 
299  LEVEL_CORE::SYSCALL_STANDARD standard = static_cast<LEVEL_CORE::SYSCALL_STANDARD>(triton::bindings::python::PyLong_AsUint32(std));
300  ret = PIN_GetSyscallReturn(tracer::pintool::context::lastContext, standard);
301 
303  }
304 
305 
306  static PyObject* pintool_getTritonContext(PyObject* self, PyObject* noarg) {
307  try {
309  }
310  catch (const std::exception& e) {
311  return PyErr_Format(PyExc_TypeError, "%s", e.what());
312  }
313  }
314 
315 
316  static PyObject* pintool_insertCall(PyObject* self, PyObject* args) {
317  PyObject* function = nullptr;
318  PyObject* flag = nullptr;
319  PyObject* routine = nullptr;
320 
321  /* Extract arguments */
322  PyArg_ParseTuple(args, "|OOO", &function, &flag, &routine);
323 
324  if (function == nullptr || !PyCallable_Check(function))
325  return PyErr_Format(PyExc_TypeError, "tracer::pintool::insertCall(): Expected a function callback as first argument.");
326 
327  /* Check if the second arg is an INSERT_POINT*/
328  if (flag == nullptr || (!PyLong_Check(flag) && !PyInt_Check(flag)))
329  return PyErr_Format(PyExc_TypeError, "tracer::pintool::insertCall(): Expected an INSERT_POINT (integer) as second argument.");
330 
333 
336 
339 
342 
345 
348 
351 
354 
356  if (routine == nullptr || !PyString_Check(routine))
357  return PyErr_Format(PyExc_TypeError, "tracer::pintool::insertCall(): Expected a routine name (string) as third argument.");
358  tracer::pintool::options::callbackRoutineEntry.insert(std::pair<const char*,PyObject*>(PyString_AsString(routine), function));
359  }
360 
362  if (routine == nullptr || !PyString_Check(routine))
363  return PyErr_Format(PyExc_TypeError, "tracer::pintool::insertCall(): Expected a routine name (string) as third argument.");
364  tracer::pintool::options::callbackRoutineExit.insert(std::pair<const char*,PyObject*>(PyString_AsString(routine), function));
365  }
366 
367  else
368  return PyErr_Format(PyExc_TypeError, "tracer::pintool::insertCall(): Expected an INSERT_POINT (integer) as second argument.");
369 
370  Py_INCREF(Py_None);
371  return Py_None;
372  }
373 
374 
375  static PyObject* pintool_isSnapshotEnabled(PyObject* self, PyObject* noarg) {
376  if (tracer::pintool::snapshot.isLocked() == false)
377  Py_RETURN_TRUE;
378  Py_RETURN_FALSE;
379  }
380 
381 
382  static PyObject* pintool_restoreSnapshot(PyObject* self, PyObject* noarg) {
384  Py_INCREF(Py_None);
385  return Py_None;
386  }
387 
388 
389  static PyObject* pintool_runProgram(PyObject* self, PyObject* noarg) {
390  /* Check if the architecture is definied */
391  if (tracer::pintool::api.getArchitecture() == triton::arch::ARCH_INVALID)
392  return PyErr_Format(PyExc_TypeError, "tracer::pintool::runProgram(): Architecture is not defined.");
393  /* Never returns - Rock 'n roll baby \o/ */
394  try {
395  PIN_StartProgram();
396  }
397  catch (const std::exception& e) {
398  return PyErr_Format(PyExc_TypeError, "%s", e.what());
399  }
400  Py_INCREF(Py_None);
401  return Py_None;
402  }
403 
404 
405  static PyObject* pintool_setCurrentMemoryValue(PyObject* self, PyObject* args) {
406  PyObject* mem = nullptr;
407  PyObject* value = nullptr;
408 
409  /* Extract arguments */
410  PyArg_ParseTuple(args, "|OO", &mem, &value);
411 
412  if (mem != nullptr && (PyMemoryAccess_Check(mem) || PyInt_Check(mem) || PyLong_Check(mem))) {
413 
414  if (value == nullptr || (!PyInt_Check(value) && !PyLong_Check(value)))
415  return PyErr_Format(PyExc_TypeError, "tracer::pintool::setCurrentMemoryValue(): Expected an integer value as second argument.");
416 
417  try {
418  if (PyMemoryAccess_Check(mem))
420  else if ((PyInt_Check(mem) || PyLong_Check(mem))) {
421  triton::uint8 v = (triton::bindings::python::PyLong_AsUint512(value) & 0xff).convert_to<triton::uint8>();
423  }
424  }
425  catch (const std::exception& e) {
426  return PyErr_Format(PyExc_TypeError, "%s", e.what());
427  }
428 
429  }
430  else
431  return PyErr_Format(PyExc_TypeError, "tracer::pintool::setCurrentMemoryValue(): Expected a Memory as first argument.");
432 
433  Py_INCREF(Py_None);
434  return Py_None;
435  }
436 
437 
438  static PyObject* pintool_setCurrentRegisterValue(PyObject* self, PyObject* args) {
439  PyObject* reg = nullptr;
440  PyObject* value = nullptr;
441 
442  /* Extract arguments */
443  PyArg_ParseTuple(args, "|OO", &reg, &value);
444 
445  if (reg != nullptr && PyRegister_Check(reg)) {
446  if (value == nullptr || (!PyInt_Check(value) && !PyLong_Check(value)))
447  return PyErr_Format(PyExc_TypeError, "tracer::pintool::setCurrentRegisterValue(): Expected an integer value as second argument.");
448 
449  try {
451  }
452  catch (const std::exception& e) {
453  return PyErr_Format(PyExc_TypeError, "%s", e.what());
454  }
455 
456  }
457  else
458  return PyErr_Format(PyExc_TypeError, "tracer::pintool::setCurrentRegisterValue(): Expected a REG as first argument.");
459 
460  Py_INCREF(Py_None);
461  return Py_None;
462  }
463 
464 
465  static PyObject* pintool_setupImageBlacklist(PyObject* self, PyObject* arg) {
466  /* Check if the arg is a list */
467  if (!PyList_Check(arg))
468  return PyErr_Format(PyExc_TypeError, "tracer::pintool::setupImageBlacklist(): Expected a list as first argument.");
469 
470  /* Check if the arg list contains only string item and insert them in the internal list */
471  for (Py_ssize_t i = 0; i < PyList_Size(arg); i++) {
472  PyObject* item = PyList_GetItem(arg, i);
473 
474  if (!PyString_Check(item))
475  return PyErr_Format(PyExc_TypeError, "tracer::pintool::setupImageBlacklist(): Each item of the list must be a string.");
476 
477  tracer::pintool::options::imageBlacklist.push_back(PyString_AsString(item));
478  }
479 
480  Py_INCREF(Py_None);
481  return Py_None;
482  }
483 
484 
485  static PyObject* pintool_setupImageWhitelist(PyObject* self, PyObject* arg) {
486  /* Check if the arg is a list */
487  if (!PyList_Check(arg))
488  return PyErr_Format(PyExc_TypeError, "tracer::pintool::setupImageWhitelist(): Expected a list as first argument.");
489 
490  /* Check if the arg list contains only string item and insert them in the internal list */
491  for (Py_ssize_t i = 0; i < PyList_Size(arg); i++) {
492  PyObject* item = PyList_GetItem(arg, i);
493 
494  if (!PyString_Check(item))
495  return PyErr_Format(PyExc_TypeError, "tracer::pintool::setupImageWhitelist(): Each item of the list must be a string.");
496 
497  tracer::pintool::options::imageWhitelist.push_back(PyString_AsString(item));
498  }
499 
500  Py_INCREF(Py_None);
501  return Py_None;
502  }
503 
504 
505  static PyObject* pintool_startAnalysisFromAddress(PyObject* self, PyObject* addr) {
506  if (!PyLong_Check(addr) && !PyInt_Check(addr))
507  return PyErr_Format(PyExc_TypeError, "tracer::pintool::startAnalysisFromAddress(): Expected an address (integer) as argument.");
508 
510  Py_INCREF(Py_None);
511  return Py_None;
512  }
513 
514 
515  static PyObject* pintool_startAnalysisFromEntry(PyObject* self, PyObject* noarg) {
517  Py_INCREF(Py_None);
518  return Py_None;
519  }
520 
521 
522  static PyObject* pintool_startAnalysisFromOffset(PyObject* self, PyObject* offset) {
523  if (!PyLong_Check(offset) && !PyInt_Check(offset))
524  return PyErr_Format(PyExc_TypeError, "tracer::pintool::startAnalysisFromOffset(): Expected an offset (integer) as argument.");
525 
527  Py_INCREF(Py_None);
528  return Py_None;
529  }
530 
531 
532  static PyObject* pintool_startAnalysisFromSymbol(PyObject* self, PyObject* name) {
533  if (!PyString_Check(name))
534  return PyErr_Format(PyExc_TypeError, "tracer::pintool::startAnalysisFromSymbol(): Expected a string as argument.");
535 
536  tracer::pintool::options::startAnalysisFromSymbol = PyString_AsString(name);
537  Py_INCREF(Py_None);
538  return Py_None;
539  }
540 
541 
542  static PyObject* pintool_stopAnalysisFromAddress(PyObject* self, PyObject* addr) {
543  if (!PyLong_Check(addr) && !PyInt_Check(addr))
544  return PyErr_Format(PyExc_TypeError, "tracer::pintool::stopAnalysisFromAddress(): Expected an address (integer) as argument.");
545 
547  Py_INCREF(Py_None);
548  return Py_None;
549  }
550 
551 
552  static PyObject* pintool_stopAnalysisFromOffset(PyObject* self, PyObject* offset) {
553  if (!PyLong_Check(offset) && !PyInt_Check(offset))
554  return PyErr_Format(PyExc_TypeError, "tracer::pintool::stopAnalysisFromOffset(): Expected an offset (integer) as argument.");
555 
557  Py_INCREF(Py_None);
558  return Py_None;
559  }
560 
561 
562  static PyObject* pintool_takeSnapshot(PyObject* self, PyObject* noarg) {
564  Py_INCREF(Py_None);
565  return Py_None;
566  }
567 
568 
569  PyMethodDef pintoolCallbacks[] = {
570  {"checkReadAccess", pintool_checkReadAccess, METH_O, ""},
571  {"checkWriteAccess", pintool_checkWriteAccess, METH_O, ""},
572  {"detachProcess", pintool_detachProcess, METH_NOARGS, ""},
573  {"disableSnapshot", pintool_disableSnapshot, METH_NOARGS, ""},
574  {"getCurrentMemoryValue", pintool_getCurrentMemoryValue, METH_VARARGS, ""},
575  {"getCurrentRegisterValue", pintool_getCurrentRegisterValue, METH_O, ""},
576  {"getImageName", pintool_getImageName, METH_O, ""},
577  {"getRoutineName", pintool_getRoutineName, METH_O, ""},
578  {"getSyscallArgument", pintool_getSyscallArgument, METH_VARARGS, ""},
579  {"getSyscallNumber", pintool_getSyscallNumber, METH_O, ""},
580  {"getSyscallReturn", pintool_getSyscallReturn, METH_O, ""},
581  {"getTritonContext", pintool_getTritonContext, METH_NOARGS, ""},
582  {"insertCall", pintool_insertCall, METH_VARARGS, ""},
583  {"isSnapshotEnabled", pintool_isSnapshotEnabled, METH_NOARGS, ""},
584  {"restoreSnapshot", pintool_restoreSnapshot, METH_NOARGS, ""},
585  {"runProgram", pintool_runProgram, METH_NOARGS, ""},
586  {"setCurrentMemoryValue", pintool_setCurrentMemoryValue, METH_VARARGS, ""},
587  {"setCurrentRegisterValue", pintool_setCurrentRegisterValue, METH_VARARGS, ""},
588  {"setupImageBlacklist", pintool_setupImageBlacklist, METH_O, ""},
589  {"setupImageWhitelist", pintool_setupImageWhitelist, METH_O, ""},
590  {"startAnalysisFromAddress", pintool_startAnalysisFromAddress, METH_O, ""},
591  {"startAnalysisFromEntry", pintool_startAnalysisFromEntry, METH_NOARGS, ""},
592  {"startAnalysisFromOffset", pintool_startAnalysisFromOffset, METH_O, ""},
593  {"startAnalysisFromSymbol", pintool_startAnalysisFromSymbol, METH_O, ""},
594  {"stopAnalysisFromAddress", pintool_stopAnalysisFromAddress, METH_O, ""},
595  {"stopAnalysisFromOffset", pintool_stopAnalysisFromOffset, METH_O, ""},
596  {"takeSnapshot", pintool_takeSnapshot, METH_NOARGS, ""},
597  {nullptr, nullptr, 0, nullptr}
598  };
599 
600  };
601 };
602 
#define PyMemoryAccess_AsMemoryAccess(v)
PyObject * PyTritonContextRef(triton::API &api)
Creates a TritonContext python class which is a reference to another Context.
PyObject * callbackAfter
Callback called after the instruction processing.
Definition: init.cpp:122
After the instruction processing.
Definition: bindings.hpp:68
Snapshot snapshot
Snapshot engine.
Definition: main.cpp:204
PyObject * callbackSyscallEntry
Callback called before the syscall processing.
Definition: init.cpp:128
Before the syscall processing.
Definition: bindings.hpp:75
#define PyRegister_Check(v)
At the end of the execution.
Definition: bindings.hpp:71
PyObject * callbackSyscallExit
Callback called after the syscall processing.
Definition: init.cpp:129
void takeSnapshot(CONTEXT *ctx)
Takes a snapshot.
Definition: snapshot.cpp:39
When a signal occurs.
Definition: bindings.hpp:74
PyObject * callbackBeforeIRProc
Callback called before the IR processing.
Definition: init.cpp:124
void routine(triton::uint32 threadId, PyObject *callback)
Callback called before and after routine processing.
Definition: callbacks.cpp:114
void setRestore(bool flag)
Sets the restore flag.
Definition: snapshot.cpp:140
After the syscall processing.
Definition: bindings.hpp:76
#define PyRegister_AsRegister(v)
When an image is loaded.
Definition: bindings.hpp:77
PyMethodDef pintoolCallbacks[]
Python callbacks of the pintool module.
Definition: bindings.cpp:569
PyObject * callbackBefore
Callback called before the instruction processing.
Definition: init.cpp:123
std::list< const char * > imageWhitelist
An image white list.
Definition: init.cpp:133
std::map< const char *, PyObject * > callbackRoutineEntry
Callback called before routine processing.
Definition: init.cpp:134
triton::uint512 getCurrentRegisterValue(const triton::arch::Register &reg)
Returns the current register value from a Register.
Definition: context.cpp:33
triton::uint32 PyLong_AsUint32(PyObject *vv)
Returns a triton::uint32 from a pyObject.
Definition: utils.cpp:84
void setCurrentMemoryValue(const triton::arch::MemoryAccess &mem, triton::uint512 value)
Sets the current memory value from a MemoryAccess.
Definition: context.cpp:426
void disableSnapshot(void)
Disables the snapshot engine.
Definition: snapshot.cpp:104
std::list< const char * > imageBlacklist
An image black list.
Definition: init.cpp:132
std::map< const char *, PyObject * > callbackRoutineExit
Callback callled after routine processing.
Definition: init.cpp:135
std::set< triton::__uint > stopAnalysisFromAddress
Stop analysis from address.
Definition: init.cpp:138
std::set< triton::__uint > startAnalysisFromAddress
Start analysis from a symbol.
Definition: init.cpp:136
std::set< triton::__uint > stopAnalysisFromOffset
Stop analysis from an offset.
Definition: init.cpp:139
CONTEXT * lastContext
The last Pin CONTEXT known.
Definition: context.cpp:29
PyObject * callbackImageLoad
Callback called when an image is loaded.
Definition: init.cpp:126
std::string getImageName(triton::__uint address)
Returns the image name from a given address.
Definition: utils.cpp:39
std::set< triton::__uint > startAnalysisFromOffset
Start analysis from an offset.
Definition: init.cpp:137
#define PyMemoryAccess_Check(v)
void setCurrentRegisterValue(const triton::arch::Register &reg, triton::uint512 value)
Sets the current register value from a Register.
Definition: context.cpp:299
triton::uint512 getCurrentMemoryValue(const triton::arch::MemoryAccess &mem)
Returns the current memory value from a MemoryAccess.
Definition: context.cpp:262
std::uint32_t uint32
unisgned 32-bits
Definition: tritonTypes.hpp:31
Before the routine processing.
Definition: bindings.hpp:72
std::string getRoutineName(triton::__uint address)
Returns the routine name from a given address.
Definition: utils.cpp:67
PyObject * PyLong_FromUint32(triton::uint32 value)
Returns a pyObject from a triton::uint32.
Definition: utils.cpp:285
std::uint8_t uint8
unisgned 8-bits
Definition: tritonTypes.hpp:25
bool startAnalysisFromEntry
Start analysis from the entry point.
Definition: init.cpp:130
PyObject * callbackSignals
Callback called when a signal occurs.
Definition: init.cpp:127
Before the instruction processing.
Definition: bindings.hpp:69
PyObject * callbackFini
Callback called at the end of the execution.
Definition: init.cpp:125
char * startAnalysisFromSymbol
Start analysis from a symbol.
Definition: init.cpp:131
triton::API api
Global triton API for pintools.
Definition: api.cpp:16
unsigned long long __uint
unsigned long long if the arch is 64-bits.
Definition: tritonTypes.hpp:71
triton::uint512 PyLong_AsUint512(PyObject *vv)
Returns a triton::uint512 from a pyObject.
Definition: utils.cpp:204
PyObject * PyLong_FromUint512(triton::uint512 value)
Returns a pyObject from a triton::uint512.
Definition: utils.cpp:385
void update(bool flag)
Sets the state to flag.
Definition: trigger.cpp:39
The Tracer namespace.
Definition: api.cpp:12
After the routine processing.
Definition: bindings.hpp:73
Trigger analysisTrigger
Lock / Unlock InsertCall.
Definition: main.cpp:201
PyObject * PyLong_FromUint(triton::__uint value)
Returns a pyObject from a triton::__uint.
Definition: utils.cpp:235
triton::__uint PyLong_AsUint(PyObject *vv)
Returns a triton::__uint from a pyObject.
Definition: utils.cpp:24