/* * Copyright 2002-2019 Intel Corporation. * * This software is provided to you as Sample Source Code as defined in the accompanying * End User License Agreement for the Intel(R) Software Development Products ("Agreement") * section 1.L. * * This software and the related documents are provided as is, with no express or implied * warranties, other than those that are expressly stated in the License. */ /* * Rewrite all memory operands, though we don't actually change the addresses they access. */ #include #include #include #include #include "pin.H" using std::hex; using std::ofstream; using std::dec; using std::string; using std::endl; KNOB KnobTrace(KNOB_MODE_WRITEONCE, "pintool", "t", "0", "trace rewrites"); KNOB KnobOne(KNOB_MODE_WRITEONCE, "pintool", "1", "0", "Don't rewrite the first memory operand"); KNOB KnobTwo(KNOB_MODE_WRITEONCE, "pintool", "2", "0", "Don't rewrite the second memory operand"); KNOB KnobOutput(KNOB_MODE_WRITEONCE,"pintool", "o", "rewritememop1.out", "Name for log file"); KNOB KnobUseIargConstContext(KNOB_MODE_WRITEONCE, "pintool", "const_context", "0", "use IARG_CONST_CONTEXT"); static ofstream out; static UINT64 rewritten = 0; static UINT64 afterBranch = 0; static BOOL rewriteOp[32]; #define STRINGIZE(v) #v #define REGENTRY(n) { REG_##n, STRINGIZE(n) } /* ===================================================================== */ /* Tracing code. It prints each instruction, and, after it, the register state * changes it made. */ /* Information for each thread. */ class threadState { public: UINT32 iCount; CONTEXT context; }; static threadState threadStates[32]; /************************************************************************/ /* We simply allocate space for the dis-assembled instruction strings and * let them leak. */ static char const * formatInstruction(INS ins) { ADDRINT ip = INS_Address(ins); string formatted = hexstr(ip) + " " + INS_Disassemble(ins); char * res = new char [formatted.length()+1]; strcpy (res, formatted.c_str()); return res; } // This function is called before every instruction is executed // and prints the pre-formatted dis-assembled instruction static VOID printInstruction(THREADID thread, ADDRINT disas) { threadState * s = &threadStates[thread]; UINT32 seqNo = ++s->iCount; out << dec << seqNo << ":" << ((const char *)Addrint2VoidStar(disas)) << endl; } // Table of registers to check and display static const struct { REG regnum; const char * name; } checkedRegisters[] = #if defined(TARGET_IA32E) { REGENTRY(RFLAGS), REGENTRY(RAX), REGENTRY(RBX), REGENTRY(RCX), REGENTRY(RDX), REGENTRY(RBP), REGENTRY(RSP), REGENTRY(RDI), REGENTRY(RSI), REGENTRY(R8), REGENTRY(R9), REGENTRY(R10), REGENTRY(R11), REGENTRY(R12), REGENTRY(R13), REGENTRY(R14), REGENTRY(R15) }; #elif defined(TARGET_IA32) { REGENTRY(EFLAGS), REGENTRY(EAX), REGENTRY(EBX), REGENTRY(ECX), REGENTRY(EDX), REGENTRY(EBP), REGENTRY(ESP), REGENTRY(EDI), REGENTRY(ESI), }; #else # error Unknown processor #endif static VOID printRegisterDiffs(THREADID tid, CONTEXT *ctx) { threadState * s = &threadStates[tid]; UINT32 seqNo = s->iCount; CONTEXT * savedCtx = &s->context; // Save the context if this was the first instruction if (seqNo == 0) PIN_SaveContext(ctx, savedCtx); else { for (UINT32 i=0; i