static VOID OnException(THREADID threadIndex, CONTEXT_CHANGE_REASON reason, const CONTEXT *ctxtFrom, CONTEXT *ctxtTo, INT32 info, VOID *v) { if (!toolIsReadyForException && reason == CONTEXT_CHANGE_REASON_EXCEPTION) { fprintf (out, "See exception %d : info 0x%x from 0x%0x but this is not the exception we want to replay\n", exceptionCount, info, PIN_GetContextReg(ctxtFrom, REG_INST_PTR)); return; } if (!foundReplayException) { fprintf (out, "Failed to instrument ReplayException!\n"); } if (reason == CONTEXT_CHANGE_REASON_EXCEPTION) { if (exceptionCount++ == 0) { PIN_SaveContext (ctxtFrom, &savedFromContext); PIN_SaveContext (ctxtTo, &savedToContext); savedReason = info; } fprintf (out, "See exception %d : info 0x%x from 0x%0x\n", exceptionCount, info, PIN_GetContextReg(ctxtFrom, REG_INST_PTR)); fflush(out); if (exceptionCount == 2) { // Check that the second exception is the same as the first, at least to a first approximation. if (info == savedReason && PIN_GetContextReg(ctxtFrom, REG_INST_PTR) == PIN_GetContextReg(&savedFromContext, REG_INST_PTR)) { fprintf (out, "Second exception looks like a replay, good!\n"); fflush(out); exit(0); } else { fprintf (out, "Second exception does not look like a replay, BAD!\n"); fflush(out); exit(1); } } } }
/* Enable the snapshot engine. */ void Snapshot::takeSnapshot(CONTEXT *ctx) { /* 1 - Unlock the engine */ this->locked = false; /* 2 - Save current symbolic engine state */ this->snapshotSymEngine = new triton::engines::symbolic::SymbolicEngine(*triton::api.getSymbolicEngine()); /* 3 - Save current taint engine state */ this->snapshotTaintEngine = new triton::engines::taint::TaintEngine(*triton::api.getTaintEngine()); /* 4 - Save current set of nodes */ this->nodesList = triton::api.getAllocatedAstNodes(); /* 5 - Save current map of variables */ this->variablesMap = triton::api.getAstVariableNodes(); /* 6 - Save the Triton CPU state */ #if defined(__x86_64__) || defined(_M_X64) this->cpu = new triton::arch::x86::x8664Cpu(*reinterpret_cast<triton::arch::x86::x8664Cpu*>(triton::api.getCpu())); #endif #if defined(__i386) || defined(_M_IX86) this->cpu = new triton::arch::x86::x86Cpu(*reinterpret_cast<triton::arch::x86::x86Cpu*>(triton::api.getCpu())); #endif /* 7 - Save Pin registers context */ PIN_SaveContext(ctx, &this->pinCtx); }
int REPLACE_Replaced(CONTEXT *context, THREADID tid, AFUNPTR func) { int ret; printf("Calling replaced Replaced()\n"); CONTEXT writableContext, *ctxt; if (KnobUseIargConstContext) { // need to copy the ctxt into a writable context PIN_SaveContext(context, &writableContext); ctxt = &writableContext; } else { ctxt = context; } PIN_SetContextReg(ctxt, scratchReg, 1); printf("REPLACE_Replaced: REG_INST_G0=0x%x\n", PIN_GetContextReg(ctxt, scratchReg)); PIN_CallApplicationFunction(ctxt, tid, CALLINGSTD_DEFAULT, func, PIN_PARG(int), &ret, PIN_PARG_END()); printf("REPLACE_Replaced: REG_INST_G0=0x%x\n", PIN_GetContextReg(ctxt, scratchReg)); printf("Returning from replaced Replaced()\n"); return ret; }
static VOID printRegisterDiffs(THREADID tid, CONTEXT *ctx, UINT32 where) { 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<sizeof(checkedRegisters)/sizeof(checkedRegisters[0]); i++) { REG r = checkedRegisters[i].regnum; ADDRINT newValue = PIN_GetContextReg(ctx, r); if (PIN_GetContextReg(savedCtx, r) != newValue) { if (where != 0) { out << "*** Instrumentation (" << dec << where << ") caused a change "; } out << dec << seqNo << ": " << checkedRegisters[i].name << " = " << hex << UINT32(newValue) << endl; PIN_SetContextReg(savedCtx, r, newValue); } } } }
static BOOL DebugInterpreter(THREADID, CONTEXT *ctxt, const string &cmd, string *, VOID *) { if (cmd == "checkpoint") { PIN_SaveContext(ctxt, &Registers); isCheckpointing = TRUE; return TRUE; } if (cmd == "restore") { PIN_SaveContext(&Registers, ctxt); MemLog.Restore(); return TRUE; } return FALSE; }
VOID VerifyContext( ADDRINT pcval, CONTEXT * context) { PIN_SaveContext(context, &contextAtVerify); BOOL hadError = FALSE; if (!CompareContext (&contextAtVerify,&contextAtRecordFastCall)) { fprintf (log_inl,"contextAtRecordFastCall ERROR\n"); hadError = TRUE; } if (!CompareContext (&contextAtVerify,&contextAtRecordNonFastCall)) { fprintf (log_inl,"contextAtRecordNonFastCall ERROR\n"); hadError = TRUE; } if (hadError) { string s = disassemble ((pcval),(pcval)+15); fprintf (log_inl," %s\n", s.c_str()); exit (-1); } }
VOID RecordContext( UINT32 dummy1, UINT32 dummy2, UINT32 dummy3, UINT32 dummy4, CONTEXT * context) { PIN_SaveContext (context, &contextAtRecordNonFastCall); }
/* Restore the snapshot. */ void Snapshot::restoreSnapshot(CONTEXT *ctx) { if (this->mustBeRestore == false) return; /* 1 - Restore all memory modification. */ for(auto i = this->memory.begin(); i != this->memory.end(); ++i){ *(reinterpret_cast<char*>(i->first)) = i->second; } this->memory.clear(); /* 2 - Delete unused expressions */ auto currentExpressions = triton::api.getSymbolicExpressions(); auto snapshotExpressions = this->snapshotSymEngine->getSymbolicExpressions(); triton::__uint currentSize = currentExpressions.size(); triton::__uint snapshotSize = snapshotExpressions.size(); for (auto i = currentExpressions.begin(); i != currentExpressions.end(); ++i) { if (snapshotExpressions.find(i->first) == snapshotExpressions.end()) delete currentExpressions[i->first]; } /* 3 - Delete unused variables */ auto currentSymbolicVars = triton::api.getSymbolicVariables(); auto snapshotSymbolicVars = this->snapshotSymEngine->getSymbolicVariables(); currentSize = currentSymbolicVars.size(); snapshotSize = snapshotSymbolicVars.size(); for (auto i = currentSymbolicVars.begin(); i != currentSymbolicVars.end(); ++i) { if (snapshotSymbolicVars.find(i->first) == snapshotSymbolicVars.end()) delete currentSymbolicVars[i->first]; } /* 4 - Restore current symbolic engine state */ *triton::api.getSymbolicEngine() = *this->snapshotSymEngine; /* 5 - Restore current taint engine state */ *triton::api.getTaintEngine() = *this->snapshotTaintEngine; /* 6 - Restore current AST node state */ triton::api.setAllocatedAstNodes(this->nodesList); /* 7 - Restore current variables map state */ triton::api.setAstVariableNodes(this->variablesMap); /* 8 - Restore the Triton CPU state */ #if defined(__x86_64__) || defined(_M_X64) *reinterpret_cast<triton::arch::x86::x8664Cpu*>(triton::api.getCpu()) = *this->cpu; #endif #if defined(__i386) || defined(_M_IX86) *reinterpret_cast<triton::arch::x86::x86Cpu*>(triton::api.getCpu()) = *this->cpu; #endif /* 9 - Restore Pin registers context */ PIN_SaveContext(&this->pinCtx, ctx); this->mustBeRestore = false; PIN_UnlockClient(); PIN_ExecuteAt(ctx); }
VOID VerifyFpContext(ADDRINT pcval, CONTEXT * context) { //printf ("fpContextFromXsave %x FPSTATE_SIZE %d FPSTATE_ALIGNMENT %d\n", fpContextFromXsave, FPSTATE_SIZE, FPSTATE_ALIGNMENT); //fflush (stdout); Do_Xsave (fpContextFromXsave); //printf ("fpContextFromFxsave %x\n", fpContextFromFxsave); //fflush (stdout); Do_Fxsave (fpContextFromFxsave); PIN_SaveContext(context, &contextFromPin); FPSTATE *fpContextFromPin = reinterpret_cast<FPSTATE *> (( reinterpret_cast<ADDRINT>(fpContextSpaceForFpConextFromPin) + (FPSTATE_ALIGNMENT - 1)) & (-1*FPSTATE_ALIGNMENT)); //printf ("fpContextFromPin %x\n", fpContextFromPin); //fflush (stdout); PIN_GetContextFPState(&contextFromPin, fpContextFromPin); BOOL hadError = FALSE; if (!CompareFpContext (fpContextFromPin, fpContextFromXsave, TRUE)) { fprintf (log_inl, "***ERROR in xsave fp context\n"); printf ("***ERROR in xsave fp context see file %s\n", KnobOutputFile.Value().c_str()); fflush (stdout); string s = disassemble ((pcval),(pcval)+15); fprintf (log_inl," %s\n", s.c_str()); exit (-1); } if (!CompareFpContext (fpContextFromPin, fpContextFromFxsave, FALSE)) { fprintf (log_inl, "***ERROR in fxsave fp context\n"); printf ("***ERROR in fxsave fp context see file %s\n", KnobOutputFile.Value().c_str()); fflush (stdout); string s = disassemble ((pcval),(pcval)+15); fprintf (log_inl," %s\n", s.c_str()); exit (-1); } //printf ("verify success\n"); //fflush (stdout); }
/* Enable the snapshot engine. */ void SnapshotEngine::takeSnapshot(const SymbolicEngine ¤tSymEngine, const TaintEngine ¤tTaintEngine, CONTEXT *ctx) { /* 1 - Unlock the engine */ this->locked = UNLOCKED; /* 2 - Save current symbolic engine state */ this->snapshotSymEngine = new SymbolicEngine(currentSymEngine); /* 3 - Save current taint engine state */ this->snapshotTaintEngine = new TaintEngine(currentTaintEngine); /* 4 - Save Pin registers context */ PIN_SaveContext(ctx, &this->pinCtx); }
VOID ReceiveContext (CONTEXT *ctxt) { if (KnobGetIntContext || KnobGetPartOfIntContext) { GetIntRegsFromContext(ctxt); } if (KnobGetFpContext) { GetFpContextFromContext(ctxt); } if (!(KnobOnStackContextOnly || KnobGetSpillAreaContextOnly || !KnobCompareContexts)) { PIN_SaveContext(ctxt, &contextAtReceive); } }
/* Restore the snapshot. */ void SnapshotEngine::restoreSnapshot(SymbolicEngine *currentSymEngine, TaintEngine *currentTaintEngine, CONTEXT *ctx) { if (this->mustBeRestore == false) return; /* 1 - Restore all memory modification. */ list< std::pair<uint64, char> >::iterator i; for(i = this->memory.begin(); i != this->memory.end(); ++i){ *(reinterpret_cast<char*>(i->first)) = i->second; } this->memory.clear(); /* 2.1 - Delete unused expressions */ std::vector<SymbolicExpression *> currentExpressions = currentSymEngine->getExpressions(); uint64 currentSize = currentExpressions.size(); uint64 snapshotSize = this->snapshotSymEngine->getExpressions().size(); for (uint64 index = snapshotSize; index < currentSize; index++) { delete currentExpressions[index]; } /* 2.2 - Delete unused variables */ std::vector<SymbolicVariable *> currentSymbolicVars = currentSymEngine->getSymVars(); currentSize = currentSymbolicVars.size(); snapshotSize = this->snapshotSymEngine->getSymVars().size(); for (uint64 index = snapshotSize; index < currentSize; index++) { delete currentSymbolicVars[index]; } /* 2.3 - Restore current symbolic engine state */ *currentSymEngine = *this->snapshotSymEngine; /* 3 - Restore current taint engine state */ *currentTaintEngine = *this->snapshotTaintEngine; /* 4 - Delete unused AST nodes */ smt2lib::freeUnusedNodes(this->nodesList); /* 5 - Restore Pin registers context */ PIN_SaveContext(&this->pinCtx, ctx); this->mustBeRestore = false; PIN_UnlockClient(); PIN_ExecuteAt(ctx); }
/* Restore the snapshot. */ void SnapshotEngine::restoreSnapshot(SymbolicEngine *currentSymEngine, TaintEngine *currentTaintEngine, CONTEXT *ctx) { /* 1 - Restore all memory modification. */ list< std::pair<uint64_t, char> >::iterator i; for(i = this->memory.begin(); i != this->memory.end(); ++i){ *(reinterpret_cast<char*>(i->first)) = i->second; } this->memory.clear(); /* 2 - Restore current symbolic engine state */ *currentSymEngine = *this->snapshotSymEngine; /* 3 - Restore current taint engine state */ *currentTaintEngine = *this->snapshotTaintEngine; /* 4 - Restore Pin registers context */ PIN_SaveContext(&this->pinCtx, ctx); PIN_ExecuteAt(ctx); }
// This function is called whenever Pin wants to report a breakpoint event to the // debugger. // static BOOL InterceptBreakpoint(THREADID tid, DEBUGGING_EVENT eventType, CONTEXT *ctxt, VOID *) { if (eventType != DEBUGGING_EVENT_BREAKPOINT) { std::cout << "FAILURE: Wrong event type in InterceptBreakpoint()" << std::endl; std::exit(1); } ADDRINT pc = PIN_GetContextReg(ctxt, REG_INST_PTR); RTN rtn = RTN_FindByAddress(pc); // When the application triggers the breakpoint in Breakpoint1(), squash the breakpoint // and roll the application back to the Checkpoint() call. The application will NOT stop // at the breakpoint, and it will immediately resume from Checkpoint(). // if (rtn != RTN_Invalid() && RTN_Name(rtn) == "Breakpoint1") { std::cout << "Intercepting breakpoint #1 at 0x" << std::hex << pc << std::endl; PIN_SaveContext(&SavedContext, ctxt); PIN_SetContextReg(ctxt, REG_GAX, 1); MemLog.Restore(); IsCheckpointing = FALSE; return FALSE; } // When the application triggers the breakpoint in Breakpoint2(), do not squash the // breakpoint, but change the return value from Breakpoint2(). The application will stop // in the debugger, and the debugger should see the modified return value. // if (rtn != RTN_Invalid() && (RTN_Name(rtn) == "Breakpoint2" || RTN_Name(rtn) == "Breakpoint2Label")) { std::cout << "Intercepting breakpoint #2 at 0x" << std::hex << pc << std::endl; std::cout << "RTN=" << RTN_Name(rtn) << std::endl; PIN_SetContextReg(ctxt, REG_GAX, 1); return TRUE; } std::cout << "Skipping breakpoint at 0x" << std::hex << pc << ", RTN=" << RTN_Name(rtn) << std::endl; return TRUE; }
static VOID OnSignal(THREADID, CONTEXT_CHANGE_REASON reason, const CONTEXT *, CONTEXT *to, INT32 sig, VOID *) { if (reason == CONTEXT_CHANGE_REASON_SIGRETURN) return; SignalCount++; switch (SignalCount) { case 1: std::cout << "Notified of real signal, recording" << std::endl; PIN_SaveContext(to, &RecordedContext); RecordedSignal = sig; break; case 2: std::cout << "Notified of first replayed signal" << std::endl; if (reason != CONTEXT_CHANGE_REASON_SIGNAL) { std::cout << "Wrong 'reason' in signal notification, expected " << static_cast<int>(CONTEXT_CHANGE_REASON_SIGNAL) << " (CONTEXT_CHANGE_REASON_SIGNAL), but got " << reason << std::endl; std::exit(1); } break; case 3: std::cout << "Notified of second replayed signal" << std::endl; if (reason != CONTEXT_CHANGE_REASON_FATALSIGNAL) { std::cout << "Wrong 'reason' in signal notification" << std::endl; std::exit(1); } break; default: std::cout << "Notified of too many signals" << std::endl; std::exit(1); } }
VOID REPLACE_ReplacedXmmRegs(CONTEXT *context, THREADID tid, AFUNPTR originalFunction) { printf ("TOOL in REPLACE_ReplacedXmmRegs\n"); fflush (stdout); CONTEXT writableContext, *ctxt; if (KnobUseIargConstContext) { // need to copy the ctxt into a writable context PIN_SaveContext(context, &writableContext); ctxt = &writableContext; } else { ctxt = context; } /* set the xmm regs in the ctxt which is used to execute the originalFunction (via PIN_CallApplicationFunction) */ CHAR fpContextSpaceForFpConextFromPin[FPSTATE_SIZE]; FPSTATE *fpContextFromPin = reinterpret_cast<FPSTATE *>(fpContextSpaceForFpConextFromPin); PIN_GetContextFPState(ctxt, fpContextFromPin); for (int i=0; i<NUM_XMM_REGS; i++) { fpContextFromPin->fxsave_legacy._xmms[i]._vec32[0] = 0xacdcacdc; fpContextFromPin->fxsave_legacy._xmms[i]._vec32[1] = 0xacdcacdc; fpContextFromPin->fxsave_legacy._xmms[i]._vec32[2] = 0xacdcacdc; fpContextFromPin->fxsave_legacy._xmms[i]._vec32[3] = 0xacdcacdc; } PIN_SetContextFPState(ctxt, fpContextFromPin); // verify the xmm regs were set in the ctxt CHAR fpContextSpaceForFpConextFromPin2[FPSTATE_SIZE]; FPSTATE *fpContextFromPin2 = reinterpret_cast<FPSTATE *>(fpContextSpaceForFpConextFromPin2); PIN_GetContextFPState(ctxt, fpContextFromPin2); for (int i=0; i<NUM_XMM_REGS; i++) { if ((fpContextFromPin->fxsave_legacy._xmms[i]._vec64[0] !=fpContextFromPin2->fxsave_legacy._xmms[i]._vec64[0]) || (fpContextFromPin->fxsave_legacy._xmms[i]._vec64[1] !=fpContextFromPin2->fxsave_legacy._xmms[i]._vec64[1])) { printf("TOOL ERROR at xmm[%d] (%lx %lx %lx %lx) (%lx %lx %lx %lx)\n", i, (unsigned long)fpContextFromPin->fxsave_legacy._xmms[i]._vec32[0], (unsigned long)fpContextFromPin->fxsave_legacy._xmms[i]._vec32[1], (unsigned long)fpContextFromPin->fxsave_legacy._xmms[i]._vec32[2], (unsigned long)fpContextFromPin->fxsave_legacy._xmms[i]._vec32[3], (unsigned long)fpContextFromPin2->fxsave_legacy._xmms[i]._vec32[0], (unsigned long)fpContextFromPin2->fxsave_legacy._xmms[i]._vec32[1], (unsigned long)fpContextFromPin2->fxsave_legacy._xmms[i]._vec32[2], (unsigned long)fpContextFromPin2->fxsave_legacy._xmms[i]._vec32[3]); exit (-1); } } // call the originalFunction function with the xmm regs set from above printf("TOOL Calling replaced ReplacedXmmRegs()\n"); fflush (stdout); PIN_CallApplicationFunction(ctxt, tid, CALLINGSTD_DEFAULT, originalFunction, PIN_PARG_END()); printf("TOOL Returned from replaced ReplacedXmmRegs()\n"); fflush (stdout); if (executeAtAddr != 0) { // set xmm regs to other values for (int i=0; i<NUM_XMM_REGS; i++) { fpContextFromPin->fxsave_legacy._xmms[i]._vec32[0] = 0xdeadbeef; fpContextFromPin->fxsave_legacy._xmms[i]._vec32[1] = 0xdeadbeef; fpContextFromPin->fxsave_legacy._xmms[i]._vec32[2] = 0xdeadbeef; fpContextFromPin->fxsave_legacy._xmms[i]._vec32[3] = 0xdeadbeef; } PIN_SetContextFPState(ctxt, fpContextFromPin); // execute the application function ExecuteAtFunc with the xmm regs set PIN_SetContextReg(ctxt, REG_INST_PTR, executeAtAddr); printf("TOOL Calling ExecutedAtFunc\n"); fflush (stdout); PIN_ExecuteAt (ctxt); printf("TOOL returned from ExecutedAtFunc\n"); fflush (stdout); } }
static void OnCheckpoint(CONTEXT *ctxt) { PIN_SaveContext(ctxt, &SavedContext); IsCheckpointing = TRUE; }
VOID REPLACE_ReplacedX87Regs(CONTEXT *context, THREADID tid, AFUNPTR originalFunction) { printf ("TOOL in REPLACE_ReplacedX87Regs x87 regs are:\n"); fflush (stdout); CHAR fpContextSpaceForFpConextFromPin[FPSTATE_SIZE]; FPSTATE *fpContextFromPin = reinterpret_cast<FPSTATE *>(fpContextSpaceForFpConextFromPin); PIN_GetContextFPState(context, fpContextFromPin); // verfiy that x87 registers are as they were set by the app just before the call to // ReplacedX87Regs, which is replaced by this function /* app set the x87 fp regs just before the call to ReplacedX87Regs as follows _mxcsr 1f80 _st[0] 0 3fff 80000000 0 _st[1] 0 3fff 80000000 0 _st[2] 0 3fff 80000000 0 _st[3] 0 5a5a 5a5a5a5a 5a5a5a5a _st[4] 0 5a5a 5a5a5a5a 5a5a5a5a _st[5] 0 5a5a 5a5a5a5a 5a5a5a5a _st[6] 0 5a5a 5a5a5a5a 5a5a5a5a _st[7] 0 5a5a 5a5a5a5a 5a5a5a5a */ printf ("_mxcsr %x\n", fpContextFromPin->fxsave_legacy._mxcsr); if (fpContextFromPin->fxsave_legacy._mxcsr & 0x200) { printf ("***Error divide by zero should be masked\n"); exit (-1); } int i; for (i=0; i<3; i++) { RAW32 *ptr = reinterpret_cast<RAW32 *>(&fpContextFromPin->fxsave_legacy._sts[i]._raw); printf ("_st[%d] %x %x %x %x\n", i,ptr->_hi2,ptr->_hi1,ptr->_lo2,ptr->_lo1); if (ptr->_hi2 != 0 && ptr->_hi1 != 0x3fff && ptr->_lo2 != 0x80000000 && ptr->_lo1 != 0) { printf ("***Error in this _st\n"); exit(-1); } } for (; i< 8; i++) { RAW32 *ptr = reinterpret_cast<RAW32 *>(&fpContextFromPin->fxsave_legacy._sts[i]._raw); printf ("_st[%d] %x %x %x %x\n", i,ptr->_hi2,ptr->_hi1,ptr->_lo2,ptr->_lo1); if (ptr->_hi2 != 0 && ptr->_hi1 != 0x5a5a && ptr->_lo2 != 0x5a5a5a5a && ptr->_lo1 != 0x5a5a5a5a) { printf ("***Error in this _st\n"); exit(-1); } } CONTEXT writableContext, *ctxt; if (KnobUseIargConstContext) { // need to copy the ctxt into a writable context PIN_SaveContext(context, &writableContext); ctxt = &writableContext; } else { ctxt = context; } /* set the x87 regs in the ctxt which is used to execute the originalFunction (via PIN_CallApplicationFunction) */ PIN_GetContextFPState(ctxt, fpContextFromPin); for (i=0; i< 8; i++) { RAW32 *ptr = reinterpret_cast<RAW32 *>(&fpContextFromPin->fxsave_legacy._sts[i]._raw); ptr->_hi2=0xacdcacdc; ptr->_hi1=0xacdcacdc; ptr->_lo2=0xacdcacdc; ptr->_lo1=0xacdcacdc; } fpContextFromPin->fxsave_legacy._mxcsr |= (0x200); // mask divide by zero PIN_SetContextFPState(ctxt, fpContextFromPin); // verify the setting worked for (i=0; i<8; i++) { RAW32 *ptr = reinterpret_cast<RAW32 *>(&fpContextFromPin->fxsave_legacy._sts[i]._raw); ptr->_hi2=0x0; ptr->_hi1=0x0; ptr->_lo2=0x0; ptr->_lo1=0x0; } PIN_GetContextFPState(ctxt, fpContextFromPin); for (i=0; i<8; i++) { RAW32 *ptr = reinterpret_cast<RAW32 *>(&fpContextFromPin->fxsave_legacy._sts[i]._raw); if (ptr->_hi2 != 0xacdcacdc || ptr->_hi2 != 0xacdcacdc || ptr->_lo2!= 0xacdcacdc || ptr->_lo1!= 0xacdcacdc ) { printf ("TOOL error1 in setting fp context in REPLACE_ReplacedX87Regs\n"); exit (-1); } } // call the originalFunction function with the xmm regs set from above printf("TOOL Calling replaced ReplacedX87Regs()\n"); fflush (stdout); PIN_CallApplicationFunction(ctxt, tid, CALLINGSTD_DEFAULT, originalFunction, PIN_PARG_END()); printf("TOOL Returned from replaced ReplacedX87Regs()\n"); fflush (stdout); if (executeAtAddr != 0) { for (i=0; i< 8; i++) { RAW32 *ptr = reinterpret_cast<RAW32 *>(&fpContextFromPin->fxsave_legacy._sts[i]._raw); ptr->_hi2=0xcacdcacd; ptr->_hi1=0xcacdcacd; ptr->_lo2=0xcacdcacd; ptr->_lo1=0xcacdcacd; } PIN_SetContextFPState(ctxt, fpContextFromPin); // verify the setting worked for (i=0; i<8; i++) { RAW32 *ptr = reinterpret_cast<RAW32 *>(&fpContextFromPin->fxsave_legacy._sts[i]._raw); ptr->_hi2=0x0; ptr->_hi1=0x0; ptr->_lo2=0x0; ptr->_lo1=0x0; } PIN_GetContextFPState(ctxt, fpContextFromPin); for (i=0; i<8; i++) { RAW32 *ptr = reinterpret_cast<RAW32 *>(&fpContextFromPin->fxsave_legacy._sts[i]._raw); if (ptr->_hi2 != 0xcacdcacd || ptr->_hi2 != 0xcacdcacd || ptr->_lo2!= 0xcacdcacd || ptr->_lo1!= 0xcacdcacd ) { printf ("TOOL error2 in setting fp context in REPLACE_ReplacedX87Regs\n"); exit (-1); } } // execute the application function ExecuteAtFunc with the xmm regs set PIN_SetContextReg(ctxt, REG_INST_PTR, executeAtAddr); printf("TOOL Calling ExecutedAtFunc\n"); fflush (stdout); PIN_ExecuteAt (ctxt); printf("TOOL returned from ExecutedAtFunc\n"); fflush (stdout); } }
VOID VerifyFpContext(ADDRINT pcval, CONTEXT * context) { //printf ("fpContextFromXsave %x FPSTATE_SIZE %d FPSTATE_ALIGNMENT %d\n", fpContextFromXsave, FPSTATE_SIZE, FPSTATE_ALIGNMENT); //fflush (stdout); Do_Xsave (fpContextFromXsave); //printf ("fpContextFromFxsave %x\n", fpContextFromFxsave); //fflush (stdout); Do_Fxsave (fpContextFromFxsave); PIN_SaveContext(context, &contextFromPin); FPSTATE *fpContextFromPin = reinterpret_cast<FPSTATE *> (( reinterpret_cast<ADDRINT>(fpContextSpaceForFpConextFromPin) + (FPSTATE_ALIGNMENT - 1)) & (-1*FPSTATE_ALIGNMENT)); unsigned char * ptr = (reinterpret_cast< unsigned char *>(fpContextFromPin))+ sizeof (FXSAVE); // set values after fxsave part of fp context - to verify that the deprecated call to PIN_GetContextFPState does NOT change these memset (ptr, 0xa5, sizeof(FPSTATE) - sizeof (FXSAVE)); PIN_GetContextFPState(&contextFromPin, reinterpret_cast<void *>(fpContextFromPin)); for (int i=0; i<sizeof(FPSTATE) - sizeof (FXSAVE); i++,ptr++) { if (*ptr != 0xa5) { printf ("**** ERROR: value set after FXSAVE part in deprecated PIN_GetContextFPState *ptr = %x (i %d)\n", *ptr, i); exit (-1); } } PIN_GetContextFPState(&contextFromPin, fpContextFromPin); ptr = (reinterpret_cast< unsigned char *>(fpContextFromPin))+ sizeof (FXSAVE); FPSTATE *fpContextFromPin1 = reinterpret_cast<FPSTATE *> (( reinterpret_cast<ADDRINT>(fpContextSpaceForFpConextFromPin1) + (FPSTATE_ALIGNMENT - 1)) & (-1*FPSTATE_ALIGNMENT)); PIN_GetContextFPState(&contextFromPin, fpContextFromPin1); // set values after fxsave part of fp context - to verify that the deprecated call to PIN_SetContextFPState does NOT change these unsigned char * ptr1 = (reinterpret_cast< unsigned char *>(fpContextFromPin1)) + sizeof (FXSAVE); memset (ptr1, 0xa5, sizeof(FPSTATE) - sizeof (FXSAVE)); PIN_SetContextFPState(&contextFromPin, reinterpret_cast<const void *>(fpContextFromPin1)); PIN_GetContextFPState(&contextFromPin, fpContextFromPin1); if (memcmp (ptr1, ptr, sizeof(FPSTATE) - sizeof (FXSAVE)) != 0) { printf ("**** ERROR: value set after FXSAVE part in deprecated PIN_SetContextFPState\n"); exit (-1); } if (!CompareFpContext (fpContextFromPin, fpContextFromFxsave, FALSE)) { fprintf (log_inl, "***ERROR in fxsave fp context\n"); printf ("***ERROR in fxsave fp context see file %s\n", KnobOutputFile.Value().c_str()); fflush (stdout); string s = disassemble ((pcval),(pcval)+15); fprintf (log_inl," %s\n", s.c_str()); exit (-1); } }
VOID PIN_FAST_ANALYSIS_CALL RecordContextFastCall( CONTEXT * context) { PIN_SaveContext (context, &contextAtRecordFastCall); }