libTriton  version 0.7 build 1407
main.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 */
10 #include <triton/api.hpp>
11 
12 #include <csignal>
13 #include <cstring>
14 #include <iostream>
15 #include <stdexcept>
16 #include <string>
17 
18 #include <pin.H>
19 
20 /* Pintool */
21 #include "api.hpp"
22 #include "bindings.hpp"
23 #include "context.hpp"
24 #include "snapshot.hpp"
25 #include "trigger.hpp"
26 #include "utils.hpp"
27 
28 
29 
194 namespace tracer {
195  namespace pintool {
196 
198  KNOB<std::string> KnobPythonModule(KNOB_MODE_WRITEONCE, "pintool", "script", "", "Python script");
199 
202 
205 
206 
207 
208  /* Switch lock */
209  static void toggleWrapper(bool flag) {
210  PIN_LockClient();
212  PIN_UnlockClient();
213  }
214 
215 
216  /* Callback before instruction processing */
217  static void callbackBefore(triton::arch::Instruction* tritonInst, triton::uint8* addr, triton::uint32 size, CONTEXT* ctx, THREADID threadId) {
218  /* Some configurations must be applied before processing */
219  tracer::pintool::callbacks::preProcessing(tritonInst, threadId);
220 
222  /* Analysis locked */
223  return;
224 
225  /* Mutex */
226  PIN_LockClient();
227 
228  /* Update CTX */
230 
231  /* Setup Triton information */
232  tritonInst->clear();
233  tritonInst->setOpcode(addr, size);
234  tritonInst->setAddress(reinterpret_cast<triton::__uint>(addr));
235  tritonInst->setThreadId(reinterpret_cast<triton::uint32>(threadId));
236 
237  /* Disassemble the instruction */
238  tracer::pintool::api.disassembly(*tritonInst);
239 
240  /* Execute the Python callback before the IR processing */
243  else
245 
246  /* Check if we must execute a new context */
248  tritonInst->clear();
250  }
251 
252  /* Synchronize gliches between Pintool and libTriton */
254 
255  /* Process the IR and spread taint only if one of both engines are enabled */
256  if (tracer::pintool::api.isTaintEngineEnabled() || tracer::pintool::api.isSymbolicEngineEnabled())
258 
259  /* Execute the Python callback */
262 
263  /* Check if we must restore the snapshot */
264  if (tracer::pintool::snapshot.mustBeRestored() == true) {
265  tritonInst->clear();
267  }
268 
269  /* Some configurations must be applied after processing */
270  tracer::pintool::callbacks::postProcessing(tritonInst, threadId);
271 
272  /* Mutex */
273  PIN_UnlockClient();
274  }
275 
276 
277  /* Callback after instruction processing */
278  static void callbackAfter(triton::arch::Instruction* tritonInst, CONTEXT* ctx, THREADID threadId) {
280  /* Analysis locked */
281  return;
282 
283  /* Mutex */
284  PIN_LockClient();
285 
286  /* Update CTX */
288 
289  /* Execute the Python callback */
291 
292  /* Some configurations must be applied after processing */
293  tracer::pintool::callbacks::postProcessing(tritonInst, threadId);
294 
295  /* Clear Instruction information because of the Pin's cache */
296  tritonInst->clear();
297 
298  /* Check if we must execute a new context */
301 
302  /* Check if we must restore the snapshot */
303  if (tracer::pintool::snapshot.mustBeRestored() == true)
305 
306  /* Mutex */
307  PIN_UnlockClient();
308  }
309 
310 
311  /* Save the memory access into the Triton instruction */
312  static void saveMemoryAccess(triton::arch::Instruction* tritonInst, triton::__uint addr, triton::uint32 size) {
313  /* Mutex */
314  PIN_LockClient();
317  /* Mutex */
318  PIN_UnlockClient();
319  }
320 
321 
322  /* Callback to save bytes for the snapshot engine */
323  static void callbackSnapshot(triton::__uint mem, triton::uint32 writeSize) {
324  if (!tracer::pintool::analysisTrigger.getState())
325  /* Analysis locked */
326  return;
327 
328  /* If the snapshot is not enable we don't save the memory */
329  if (tracer::pintool::snapshot.isLocked())
330  return;
331 
332  /* Mutex */
333  PIN_LockClient();
334 
335  for (triton::uint32 i = 0; i < writeSize ; i++)
336  tracer::pintool::snapshot.addModification(mem+i, *(reinterpret_cast<triton::uint8*>(mem+i)));
337 
338  /* Mutex */
339  PIN_UnlockClient();
340  }
341 
342 
343  /* Callback at a routine entry */
344  static void callbackRoutineEntry(CONTEXT* ctx, THREADID threadId, PyObject* callback) {
346  /* Analysis locked */
347  return;
348 
349  /* Mutex lock */
350  PIN_LockClient();
351 
352  /* Update CTX */
354 
355  /* Execute the Python callback */
356  tracer::pintool::callbacks::routine(threadId, callback);
357 
358  /* Mutex unlock */
359  PIN_UnlockClient();
360  }
361 
362 
363  /* Callback at a routine exit */
364  static void callbackRoutineExit(CONTEXT* ctx, THREADID threadId, PyObject* callback) {
366  /* Analysis locked */
367  return;
368 
369  /* Mutex lock */
370  PIN_LockClient();
371 
372  /* Update CTX */
374 
375  /* Execute the Python callback */
376  tracer::pintool::callbacks::routine(threadId, callback);
377 
378  /* Mutex unlock */
379  PIN_UnlockClient();
380  }
381 
382 
383  /* Callback at the end of the execution */
384  static void callbackFini(int, VOID *) {
385  /* Execute the Python callback */
387  }
388 
389 
390  /* Callback at a syscall entry */
391  static void callbackSyscallEntry(unsigned int threadId, CONTEXT* ctx, SYSCALL_STANDARD std, void* v) {
393  /* Analysis locked */
394  return;
395 
396  /* Mutex */
397  PIN_LockClient();
398 
399  /* Update CTX */
401 
402  /* Execute the Python callback */
404 
405  /* Mutex */
406  PIN_UnlockClient();
407  }
408 
409 
410  /* Callback at the syscall exit */
411  static void callbackSyscallExit(unsigned int threadId, CONTEXT* ctx, SYSCALL_STANDARD std, void* v) {
413  /* Analysis locked */
414  return;
415 
416  /* Mutex */
417  PIN_LockClient();
418 
419  /* Update CTX */
421 
422  /* Execute the Python callback */
424 
425  /* Mutex */
426  PIN_UnlockClient();
427  }
428 
429 
430  /*
431  * Callback when an image is loaded.
432  * This callback must be called even outside the range analysis.
433  */
434  static void callbackImageLoad(IMG img) {
435  /* Mutex */
436  PIN_LockClient();
437 
438  /* Collect image information */
439  std::string imagePath = IMG_Name(img);
440  triton::__uint imageBase = IMG_LowAddress(img);
441  triton::__uint imageSize = (IMG_HighAddress(img) + 1) - imageBase;
442 
443  /* Execute the Python callback */
444  tracer::pintool::callbacks::imageLoad(imagePath, imageBase, imageSize);
445 
446  /* Mutex */
447  PIN_UnlockClient();
448  }
449 
450 
451  /* Callback when a signals occurs */
452  static bool callbackSignals(unsigned int threadId, int sig, CONTEXT* ctx, bool hasHandler, const EXCEPTION_INFO* pExceptInfo, void* v) {
453  /* Mutex */
454  PIN_LockClient();
455 
456  /* Update CTX */
458 
459  /* Execute the Python callback */
461 
462  /* Mutex */
463  PIN_UnlockClient();
464 
465  /*
466  * We must exit. If you don't want to exit,
467  * you must use the restoreSnapshot() function.
468  */
469  exit(0);
470 
471  return true;
472  }
473 
474 
475  /* Image instrumentation */
476  static void IMG_Instrumentation(IMG img, void *v) {
477  /* Lock / Unlock the Analysis from a Entry point */
480  /* IMG_LoadOffset(img) + IMG_Entry(img) for PIE binaries (see #524) */
481  tracer::pintool::options::startAnalysisFromAddress.insert(IMG_LoadOffset(img) + IMG_Entry(img));
482  }
483 
484  /* Lock / Unlock the Analysis from a symbol */
486 
487  RTN targetRTN = RTN_FindByName(img, tracer::pintool::options::startAnalysisFromSymbol);
488  if (RTN_Valid(targetRTN)) {
489  RTN_Open(targetRTN);
490 
491  RTN_InsertCall(targetRTN,
492  IPOINT_BEFORE,
493  (AFUNPTR) toggleWrapper,
494  IARG_BOOL, true,
495  IARG_END);
496 
497  RTN_InsertCall(targetRTN,
498  IPOINT_AFTER,
499  (AFUNPTR) toggleWrapper,
500  IARG_BOOL, false,
501  IARG_END);
502 
503  RTN_Close(targetRTN);
504  }
505  }
506 
507  /* Callback on routine entry */
508  std::map<const char *, PyObject *>::iterator it;
510  RTN targetRTN = RTN_FindByName(img, it->first);
511  if (RTN_Valid(targetRTN)){
512  RTN_Open(targetRTN);
513  RTN_InsertCall(targetRTN, IPOINT_BEFORE, (AFUNPTR)callbackRoutineEntry, IARG_CONTEXT, IARG_THREAD_ID, IARG_PTR, it->second, IARG_END);
514  RTN_Close(targetRTN);
515  }
516  }
517 
518  /* Callback on routine exit */
520  RTN targetRTN = RTN_FindByName(img, it->first);
521  if (RTN_Valid(targetRTN)){
522  RTN_Open(targetRTN);
523  RTN_InsertCall(targetRTN, IPOINT_AFTER, (AFUNPTR)callbackRoutineExit, IARG_CONTEXT, IARG_THREAD_ID, IARG_PTR, it->second, IARG_END);
524  RTN_Close(targetRTN);
525  }
526  }
527 
528  /*
529  * Callback when a new image is loaded.
530  * This callback must be called even outside the range analysis.
531  */
532  if (IMG_Valid(img))
533  tracer::pintool::callbackImageLoad(img);
534  }
535 
536 
537  /* Check if the analysis must be unlocked */
538  static bool checkUnlockAnalysis(triton::__uint address) {
540  return false;
541 
542  /* Unlock the analysis at the entry point from symbol */
544  if ((RTN_FindNameByAddress(address) == tracer::pintool::options::startAnalysisFromSymbol)) {
546  tracer::pintool::toggleWrapper(true);
547  return true;
548  }
549  }
550 
551  /* Unlock the analysis at the entry point from address */
554  tracer::pintool::toggleWrapper(true);
555  return true;
556  }
557 
558  /* Unlock the analysis at the entry point from offset */
561  tracer::pintool::toggleWrapper(true);
562  return true;
563  }
564  return false;
565  }
566 
567 
568  /* Check if the instruction is blacklisted */
569  static bool instructionBlacklisted(triton::__uint address) {
570  std::list<const char *>::iterator it;
572  if (strstr(tracer::pintool::getImageName(address).c_str(), *it))
573  return true;
574  }
575  return false;
576  }
577 
578 
579  /* Check if the instruction is whitelisted */
580  static bool instructionWhitelisted(triton::__uint address) {
581  std::list<const char *>::iterator it;
582 
583  /* If there is no whitelist -> jit everything */
585  return true;
586 
588  if (strstr(tracer::pintool::getImageName(address).c_str(), *it))
589  return true;
590  }
591 
592  return false;
593  }
594 
595 
596  /* Trace instrumentation */
597  static void TRACE_Instrumentation(TRACE trace, VOID *v) {
598 
599  for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)) {
600  for (INS ins = BBL_InsHead(bbl); INS_Valid(ins); ins = INS_Next(ins)) {
601 
602  /* Check if the analysis me be unlocked */
603  tracer::pintool::checkUnlockAnalysis(INS_Address(ins));
604 
605  if (!tracer::pintool::analysisTrigger.getState())
606  /* Analysis locked */
607  continue;
608 
609  if (tracer::pintool::instructionBlacklisted(INS_Address(ins)) == true || tracer::pintool::instructionWhitelisted(INS_Address(ins)) == false)
610  /* Insruction blacklisted */
611  continue;
612 
613  /* Prepare the Triton's instruction */
615 
616  /* Save memory read1 informations */
617  if (INS_IsMemoryRead(ins)) {
618  INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)saveMemoryAccess,
619  IARG_PTR, tritonInst,
620  IARG_MEMORYREAD_EA,
621  IARG_MEMORYREAD_SIZE,
622  IARG_END);
623  }
624 
625  /* Save memory read2 informations */
626  if (INS_HasMemoryRead2(ins)) {
627  INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)saveMemoryAccess,
628  IARG_PTR, tritonInst,
629  IARG_MEMORYREAD2_EA,
630  IARG_MEMORYREAD_SIZE,
631  IARG_END);
632  }
633 
634  /* Callback before */
635  INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)callbackBefore,
636  IARG_PTR, tritonInst,
637  IARG_INST_PTR,
638  IARG_UINT32, INS_Size(ins),
639  IARG_CONTEXT,
640  IARG_THREAD_ID,
641  IARG_END);
642 
643  /* Callback after */
644  /* Syscall after context must be catcher with INSERT_POINT.SYSCALL_EXIT */
645  if (INS_IsSyscall(ins) == false) {
646  IPOINT where = IPOINT_AFTER;
647  if (INS_HasFallThrough(ins) == false)
648  where = IPOINT_TAKEN_BRANCH;
649  INS_InsertCall(ins, where, (AFUNPTR)callbackAfter, IARG_PTR, tritonInst, IARG_CONTEXT, IARG_THREAD_ID, IARG_END);
650  }
651 
652  /* I/O memory monitoring for snapshot */
653  if (INS_OperandCount(ins) > 1 && INS_MemoryOperandIsWritten(ins, 0)) {
654  INS_InsertCall(
655  ins, IPOINT_BEFORE, (AFUNPTR)callbackSnapshot,
656  IARG_MEMORYOP_EA, 0,
657  IARG_UINT32, INS_MemoryWriteSize(ins),
658  IARG_END);
659  }
660 
661  }
662  }
663  }
664 
665 
666  /* Usage function */
667  static triton::sint32 Usage() {
668  std::cerr << KNOB_BASE::StringKnobSummary() << std::endl;
669  return -1;
670  }
671 
672 
674  int main(int argc, char *argv[]) {
675  PIN_InitSymbols();
676  PIN_SetSyntaxIntel();
677  if(PIN_Init(argc, argv))
678  return Usage();
679 
680  /* Init the Triton module */
682 
683  /* Define Triton architecure */
684  if (sizeof(void*) == QWORD_SIZE)
686  else
688 
689  /* During the execution provide concrete values only if Triton needs them - cf #376, #632 and #645 */
692 
693  /* Image callback */
694  IMG_AddInstrumentFunction(IMG_Instrumentation, nullptr);
695 
696  /* Instruction callback */
697  TRACE_AddInstrumentFunction(TRACE_Instrumentation, nullptr);
698 
699  /* End instrumentation callback */
700  PIN_AddFiniFunction(callbackFini, nullptr);
701 
702  /* Syscall entry callback */
703  PIN_AddSyscallEntryFunction(callbackSyscallEntry, nullptr);
704 
705  /* Syscall exit callback */
706  PIN_AddSyscallExitFunction(callbackSyscallExit, nullptr);
707 
708  /* Signals callback */
709  PIN_InterceptSignal(SIGHUP, callbackSignals, nullptr);
710  PIN_InterceptSignal(SIGINT, callbackSignals, nullptr);
711  PIN_InterceptSignal(SIGQUIT, callbackSignals, nullptr);
712  PIN_InterceptSignal(SIGILL, callbackSignals, nullptr);
713  PIN_InterceptSignal(SIGABRT, callbackSignals, nullptr);
714  PIN_InterceptSignal(SIGFPE, callbackSignals, nullptr);
715  PIN_InterceptSignal(SIGKILL, callbackSignals, nullptr);
716  PIN_InterceptSignal(SIGSEGV, callbackSignals, nullptr);
717  PIN_InterceptSignal(SIGPIPE, callbackSignals, nullptr);
718  PIN_InterceptSignal(SIGALRM, callbackSignals, nullptr);
719  PIN_InterceptSignal(SIGTERM, callbackSignals, nullptr);
720  PIN_InterceptSignal(SIGBUS, callbackSignals, nullptr);
721 
722  /* Exec the Pin's python bindings */
723  tracer::pintool::initBindings(argc, argv);
725 
726  return 0;
727  }
728 
729  };
730 };
731 
732 
734 int main(int argc, char *argv[]) {
735  return tracer::pintool::main(argc, argv);
736 }
737 
void restoreSnapshot(CONTEXT *ctx)
Restores a snapshot.
Definition: snapshot.cpp:66
PyObject * callbackAfter
Callback called after the instruction processing.
Definition: init.cpp:122
PyMODINIT_FUNC inittriton(void)
Entry point python bindings.
Definition: init.cpp:24
This class is used when to represent an instruction.
Definition: instruction.hpp:47
int main(int argc, char *argv[])
The pintool&#39;s entry point.
Definition: main.cpp:674
void preProcessing(triton::arch::Instruction *inst, triton::uint32 threadId)
Pre processing configuration.
Definition: callbacks.cpp:202
Snapshot snapshot
Snapshot engine.
Definition: main.cpp:204
PyObject * callbackSyscallEntry
Callback called before the syscall processing.
Definition: init.cpp:128
void beforeIRProc(triton::arch::Instruction *inst)
Callback called before the IR processing.
Definition: callbacks.cpp:75
PyObject * callbackSyscallExit
Callback called after the syscall processing.
Definition: init.cpp:129
void routine(triton::uint32 threadId, PyObject *callback)
Callback called before and after routine processing.
Definition: callbacks.cpp:114
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_EXPORT void clear(void)
Clears all instruction information.
void synchronizeContext(void)
Synchronize weird behavior from Pin to libTriton.
Definition: context.cpp:481
void before(triton::arch::Instruction *inst)
Callback called before the instruction processing.
Definition: callbacks.cpp:53
TRITON_EXPORT void setAddress(triton::uint64 addr)
Sets the address of the instruction.
void syscallExit(triton::uint32 threadId, triton::uint32 std)
Callback called after the syscall processing.
Definition: callbacks.cpp:163
triton::__uint getInsOffset(triton::__uint address)
Returns the instruction offset from a given address.
Definition: utils.cpp:59
triton::uint32 targetThreadId
TID focused during the JIT.
Definition: init.cpp:140
std::list< const char * > imageBlacklist
An image black list.
Definition: init.cpp:132
void fini(void)
Callback called at the end of the execution.
Definition: callbacks.cpp:97
std::map< const char *, PyObject * > callbackRoutineExit
Callback callled after routine processing.
Definition: init.cpp:135
void signals(triton::uint32 threadId, triton::sint32 sig)
Callback called when a signal occurs.
Definition: callbacks.cpp:125
void initBindings(int argc, char *argv[])
The initialization of the Pin&#39;s Python env.
Definition: init.cpp:144
std::set< triton::__uint > startAnalysisFromAddress
Start analysis from a symbol.
Definition: init.cpp:136
void after(triton::arch::Instruction *inst)
Callback called after the instruction processing.
Definition: callbacks.cpp:31
TRITON_EXPORT void disassembly(triton::arch::Instruction &inst) const
[architecture api] - Disassembles the instruction and setup operands. You must define an architecture...
Definition: api.cpp:421
CONTEXT * lastContext
The last Pin CONTEXT known.
Definition: context.cpp:29
This class is used to represent a memory access.
TRITON_EXPORT bool buildSemantics(triton::arch::Instruction &inst)
[IR builder api] - Builds the instruction semantics. Returns true if the instruction is supported...
Definition: api.cpp:504
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
TRITON_EXPORT void setConcreteMemoryValue(triton::uint64 addr, triton::uint8 value)
[architecture api] - Sets the concrete value of a memory cell.
Definition: api.cpp:379
#define QWORD_SIZE
Definition: cpuSize.hpp:33
std::int32_t sint32
signed 32-bits
Definition: tritonTypes.hpp:52
bool mustBeExecuted
True if the context must be executed.
Definition: context.cpp:30
TRITON_EXPORT void setThreadId(triton::uint32 tid)
Sets the thread id of the instruction.
Definition: instruction.cpp:87
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
void syscallEntry(triton::uint32 threadId, triton::uint32 std)
Callback called before the syscall processing.
Definition: callbacks.cpp:144
TRITON_EXPORT void setArchitecture(triton::arch::architecture_e arch)
[architecture api] - Initializes an architecture.
Definition: api.cpp:267
void needConcreteRegisterValue(triton::API &api, const triton::arch::Register &reg)
Callback to provide concrete register values only if Triton needs them - cf #376. ...
Definition: context.cpp:469
TRITON_EXPORT void addCallback(triton::callbacks::getConcreteMemoryValueCallback cb)
[callbacks api] - Adds a GET_CONCRETE_MEMORY_VALUE callback (LOAD).
Definition: api.cpp:531
std::uint8_t uint8
unisgned 8-bits
Definition: tritonTypes.hpp:25
bool startAnalysisFromEntry
Start analysis from the entry point.
Definition: init.cpp:130
void needConcreteMemoryValue(triton::API &api, const triton::arch::MemoryAccess &mem)
Callback to provide concrete memory values only if Triton needs them - cf #632.
Definition: context.cpp:475
PyObject * callbackSignals
Callback called when a signal occurs.
Definition: init.cpp:127
PyObject * callbackFini
Callback called at the end of the execution.
Definition: init.cpp:125
the snapshot class.
Definition: snapshot.hpp:41
void imageLoad(std::string imagePath, triton::__uint imageBase, triton::__uint imageSize)
Callback called when an image is loaded.
Definition: callbacks.cpp:182
boost::multiprecision::uint512_t uint512
unsigned 512-bits
Definition: tritonTypes.hpp:43
char * startAnalysisFromSymbol
Start analysis from a symbol.
Definition: init.cpp:131
triton::API api
Global triton API for pintools.
Definition: api.cpp:16
KNOB< std::string > KnobPythonModule(KNOB_MODE_WRITEONCE, "pintool", "script", "", "Python script")
Pin options: -script.
int main(int argc, char *argv[])
namespace trampoline
Definition: main.cpp:734
unsigned long long __uint
unsigned long long if the arch is 64-bits.
Definition: tritonTypes.hpp:71
void postProcessing(triton::arch::Instruction *inst, triton::uint32 threadId)
Post processing configuration.
Definition: callbacks.cpp:221
TRITON_EXPORT void setOpcode(const triton::uint8 *opcode, triton::uint32 size)
Sets the opcode of the instruction.
void update(bool flag)
Sets the state to flag.
Definition: trigger.cpp:39
The Tracer namespace.
Definition: api.cpp:12
Trigger analysisTrigger
Lock / Unlock InsertCall.
Definition: main.cpp:201
bool execScript(const char *fileName)
The python script which will be executed by Pin.
Definition: init.cpp:207
void executeContext(void)
Executes the new context.
Definition: context.cpp:461