// this function verifies that the xmm regs in the ctxtFrom are as they were set in the app just before the
// exception occurs. Then it sets the xmm regs in the ctxtTo to a different value, finally it causes the
// execution to continue in the application function DumpXmmRegsAtException
static void OnException(THREADID threadIndex,
                        CONTEXT_CHANGE_REASON reason,
                        const CONTEXT *ctxtFrom,
                        CONTEXT *ctxtTo,
                        INT32 info,
                        VOID *v)
{
    if (CONTEXT_CHANGE_REASON_SIGRETURN == reason || CONTEXT_CHANGE_REASON_APC == reason
            || CONTEXT_CHANGE_REASON_CALLBACK == reason || CONTEXT_CHANGE_REASON_FATALSIGNAL == reason
            || ctxtTo == NULL)
    {   // don't want to handle these
        return;
    }
    fprintf (stdout, "TOOL OnException callback\n");
    fflush (stdout);


    //PIN_SaveContext(ctxtFrom, ctxtTo);
    CheckAndSetFpContextXmmRegs(ctxtFrom, ctxtTo);



    // call the application function with the ctxtTo context
#ifdef TARGET_IA32E
    PIN_SetContextReg(ctxtTo, REG_RIP, dumpXmmRegsAtExceptionAddr);
    // take care of stack alignment since tool is redirecting execution flow to function
    ADDRINT curSp = PIN_GetContextReg(ctxtTo, REG_RSP);
    INT32 currentAlignment = curSp % 16;
    PIN_SetContextReg(ctxtTo, REG_RSP, curSp - GetStackAdjustmentForRedirectionToFunction(currentAlignment));
#else
    PIN_SetContextReg(ctxtTo, REG_EIP, dumpXmmRegsAtExceptionAddr);
#endif
}
static BOOL Intercept(THREADID tid, DEBUGGING_EVENT eventType, CONTEXT *ctxt, VOID *)
{
    if (eventType == DEBUGGING_EVENT_BREAKPOINT)
    {
        // When the child thread reaches the breakpoint in Breakpoint(), wait for the main
        // thread to reach the One() function.  If the main thread is not there yet, squash the
        // breakpoint and move the PC back to the start of the Breakpoint() function.  This will
        // delay a while and then re-trigger the breakpoint.
        //
        ADDRINT pc = PIN_GetContextReg(ctxt, REG_INST_PTR);
        if (pc == BreakpointLocation && !AllowBreakpoint)
        {
            PIN_SetContextReg(ctxt, REG_INST_PTR, BreakpointFunction);
            GetLock(&Lock, 1);
            std::cout << "Squashing breakpoint at 0x" << std::hex << pc << " on thread " << std::dec << tid << std::endl;
            ReleaseLock(&Lock);
            return FALSE;
        }

        GetLock(&Lock, 1);
        std::cout << "Stopping at breakpoint at 0x" << std::hex << pc << " on thread " << std::dec << tid << std::endl;
        ReleaseLock(&Lock);
        return TRUE;
    }

    if (eventType == DEBUGGING_EVENT_ASYNC_BREAK)
    {
        // When the child thread triggers the breakpoint, we should be at the One() function.
        // Change the PC to the Two() function, which is the point of this test.  We want to
        // make sure Pin properly handles the change of PC in this case.
        //
        ADDRINT pc = PIN_GetContextReg(ctxt, REG_INST_PTR);
        if (pc == OneFunction)
        {
            PIN_SetContextReg(ctxt, REG_INST_PTR, TwoFunction);
            GetLock(&Lock, 1);
            std::cout << "Changing ASYNC BREAK PC to Two() on thread " << std::dec << tid << std::endl;
            ReleaseLock(&Lock);
            return TRUE;
        }

        // If the PC is not at the One() function, the child thread has probably hit some breakpoint
        // other than the one at Breakpoint().  (E.g. an internal breakpoint set by GDB.)  Don't
        // change the PC in such a case.
        //
        GetLock(&Lock, 1);
        std::cout << "ASYNC_BREAK at 0x" << std::hex << pc << " on thread " << std::dec << tid << std::endl;
        ReleaseLock(&Lock);
        return TRUE;
    }

    GetLock(&Lock, 1);
    std::cout << "FAILURE: Unexpected debugging event type" << std::endl;
    ReleaseLock(&Lock);
    std::exit(1);
}
Example #3
0
static VOID SyscallEntry(THREADID threadIndex, CONTEXT *ctxt, SYSCALL_STANDARD std, VOID *v)
{
    if (PIN_GetSyscallNumber(ctxt, std) != SYS_sysarch)
        return;

    ADDRINT pc = PIN_GetContextReg(ctxt, REG_INST_PTR);
    ADDRINT op = PIN_GetSyscallArgument(ctxt, std, 0);
    ADDRINT addr = PIN_GetSyscallArgument(ctxt, std, 1);
    ADDRINT value = 0;

    if (op == AMD64_SET_FSBASE || op == AMD64_SET_GSBASE)
    {
        if (PIN_SafeCopy(&value, Addrint2VoidStar(addr), sizeof(ADDRINT)) != sizeof(ADDRINT))
        {
            Out << Header(threadIndex, pc) << "Failed to read actual TLS pointer" << endl;
        }
    }
    else
    {
        // Remember the location where to write the segment register in REG_INST_G0
        PIN_SetContextReg(ctxt, REG_INST_G0, addr);
        value = addr;
    }

    Out << Header(threadIndex, pc) << "sysarch(" << SysArchFunc(op) << ", 0x" << std::hex << value << ")" << std::endl;
}
Example #4
0
/*
 * thread start callback (analysis function)
 *
 * allocate space for the syscall context and VCPUs
 * (i.e., thread context), and set the TLS-like pointer
 * (i.e., thread_ctx_ptr) accordingly
 *
 * @tid:	thread id
 * @ctx:	CPU context
 * @flags:	OS specific flags for the new thread
 * @v:		callback value
 */
static void
thread_alloc(THREADID tid, CONTEXT *ctx, INT32 flags, VOID *v)
{
	/* thread context pointer (ptr) */
	thread_ctx_t *tctx = NULL;

	/* allocate space for the thread context; optimized branch */
	if (unlikely((tctx = (thread_ctx_t *)calloc(1,
					sizeof(thread_ctx_t))) == NULL)) {
		/* error message */
		LOG(string(__func__) + ": thread_ctx_t allocation failed (" +
				string(strerror(errno)) + ")\n");

		/* die */
		libdft_die();
	}

	/* save the address of the per-thread context to the spilled register */
	PIN_SetContextReg(ctx, thread_ctx_ptr, (ADDRINT)tctx);

    char fileName[256];
    sprintf(fileName, "C:\\itrace_thread%u.txt", tid);
    thread_local *t_local = new thread_local;
    t_local->insaddr = 0;
    t_local->logfile = fopen(fileName, "w");
    PIN_SetThreadData(trace_tls_key, t_local, tid);
}
Example #5
0
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;
}
VOID ThreadStart(THREADID tid, CONTEXT *ctxt, INT32 flags, VOID *v)
{
    // When the thread starts, zero the virtual register that holds the
    // dynamic instruction count.
    //
    PIN_SetContextReg(ctxt, ScratchReg, 0);
}
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);
            }
        }
    }
}
Example #8
0
static VOID cloneThread(CONTEXT * ctxt)
{
    // Should maybe use atomic increment here, but if we create a few bonus ones, it
    // doesn't really matter!
    UINT32 threadId = ++threadsCreated;

    if (threadId >= MAXTHREADS)
        return;

    CONTEXT localContext;

    if (!ctxt)
    {
        ctxt = &localContext;
        PIN_SetContextReg(ctxt, REG_GFLAGS, 0);
    }

    if (!PIN_SpawnApplicationThread(ctxt))
    {
        cerr << "PIN_SpawnApplicationThread failed\n";
        PIN_ExitProcess(-1);
    }
    if (KnobVerbose)
        cerr << "Spawned a new thread (" << threadId << ")\n";
}
/*
 * Pin calls this function to set the value of an emulated register.
 */
static VOID SetReg(unsigned toolRegId, THREADID tid, CONTEXT *ctxt, const VOID *data, VOID *)
{
    PrintEmulated();

    switch (toolRegId)
    {
    case EMULATED_REG_RCX:
      {
        const ADDRINT *val = static_cast<const ADDRINT *>(data);
        PIN_SetContextReg(ctxt, REG_RCX, *val);
        break;
      }
    case EMULATED_REG_RSP:
      {
        const ADDRINT *val = static_cast<const ADDRINT *>(data);
        PIN_SetContextReg(ctxt, REG_RSP, *val);
        break;
      }
    case EMULATED_REG_FPSW:
      {
        const UINT32 *val = static_cast<const UINT32 *>(data);
        PIN_SetContextReg(ctxt, REG_FPSW, static_cast<ADDRINT>(*val));
        break;
      }
    case EMULATED_REG_ST0:
      {
        FPSTATE fpstate;
        PIN_GetContextFPState(ctxt, &fpstate);
        std::memcpy(&fpstate.fxsave_legacy._sts[0], data, 10);
        PIN_SetContextFPState(ctxt, &fpstate);
        break;
      }
    case EMULATED_REG_XMM0:
      {
        FPSTATE fpstate;
        PIN_GetContextFPState(ctxt, &fpstate);
        std::memcpy(&fpstate.fxsave_legacy._xmms[0], data, 16);
        PIN_SetContextFPState(ctxt, &fpstate);
        break;
      }
    default:
      {
        ASSERTX(0);
        break;
      }
    }
}
Example #10
0
// There is no verification on the validity of the ID.
void PINContextHandler::setRegisterValue(uint64 TritRegID, uint64 value) const
{
  REG reg = safecast(PINConverter::convertTritonReg2DBIReg(TritRegID));

  if (!REG_valid(reg) || (TritRegID >= ID_XMM0 && TritRegID <= ID_XMM15))
    throw std::runtime_error("Error: setRegisterValue() - Invalid PIN register id.");

  PIN_SetContextReg(this->_ctx, reg, value);
  PIN_ExecuteAt(this->_ctx);
}
static bool OnCommand(THREADID, CONTEXT *ctxt, const std::string &cmd, std::string *reply, VOID *)
{
    if (cmd == "clear-sp")
    {
        PIN_SetContextReg(ctxt, REG_STACK_PTR, 0);
        *reply = "Changed $SP to 0\n";
        return true;
    }
    return false;
}
Example #12
0
unsigned int PinExecutionContext::setRegisterValue(enum eRegister reg, unsigned long value) {
	REG 		pin_register;
	unsigned int 	result;

	result = mapRegisterToPin(reg, &pin_register);
	if (result == 0) {
		PIN_SetContextReg(pin_context, pin_register, (ADDRINT) value);
		return 0;
	} else {
		return result;
	}
}
Example #13
0
// 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;
}
Example #14
0
static bool PostPatchTimeoutSyscall(uint32_t tid, CONTEXT* ctxt, SYSCALL_STANDARD std, int syscall, ADDRINT prevIp, ADDRINT timeoutArgVal) {
    assert(inFakeTimeoutMode[tid]);
    int res = (int)PIN_GetSyscallNumber(ctxt, std);

    // Decide if it timed out
    bool timedOut;
    if (syscall == SYS_futex) {
        timedOut = (res == -ETIMEDOUT);
    } else {
        timedOut = (res == 0);
    }

    bool isSleeping = zinfo->sched->isSleeping(procIdx, tid);

    // Decide whether to retry
    bool retrySyscall;
    if (!timedOut) {
        if (isSleeping) zinfo->sched->notifySleepEnd(procIdx, tid);
        retrySyscall = false;
    } else {
        retrySyscall = isSleeping;
    }

    if (retrySyscall && zinfo->procArray[procIdx]->isInFastForward()) {
        warn("[%d] Fast-forwarding started, not retrying timeout syscall (%s)", tid, GetSyscallName(syscall));
        retrySyscall = false;
        assert(isSleeping);
        zinfo->sched->notifySleepEnd(procIdx, tid);
    }

    if (retrySyscall) {
        // ADDRINT curIp = PIN_GetContextReg(ctxt, REG_INST_PTR);
        //info("[%d] post-patch, retrying, IP: 0x%lx -> 0x%lx", tid, curIp, prevIp);
        PIN_SetContextReg(ctxt, REG_INST_PTR, prevIp);
        PIN_SetSyscallNumber(ctxt, std, syscall);
    } else {
        // Restore timeout arg
        PIN_SetSyscallArgument(ctxt, std, getTimeoutArg(syscall), timeoutArgVal);
        inFakeTimeoutMode[tid] = false;

        // Restore arg? I don't think we need this!
        /*if (syscall == SYS_futex) {
            PIN_SetSyscallNumber(ctxt, std, -ETIMEDOUT);
        } else {
            assert(syscall == SYS_epoll_wait || syscall == SYS_epoll_pwait || syscall == SYS_poll);
            PIN_SetSyscallNumber(ctxt, std, 0); //no events returned
        }*/
    }

    //info("[%d] post-patch %s (%d), timedOut %d, sleeping (orig) %d, retrying %d, orig res %d, patched res %d", tid, GetSyscallName(syscall), syscall, timedOut, isSleeping, retrySyscall, res, (int)PIN_GetSyscallNumber(ctxt, std));
    return retrySyscall;
}
// check if the address that has to be executed has been written by anoter instruction in the trace (polymorphic code)
// if this is true we have to break the trace and recompile it from the current eip address
VOID checkIfWrittenAddress(ADDRINT eip, CONTEXT * ctxt, UINT32 ins_size, void *pcpatchesH){
	PolymorphicCodeHandlerModule *pcpatches = (PolymorphicCodeHandlerModule *)pcpatchesH;
	//we have to check if the wriotten address is between the eip and eip + inst_size because 
	// sometime can happen that only part of the original instruction is written
	// ES : push 0x20 -> push 0x30 (only the operand is written)
	if(pcpatches->getFirstWrittenAddressInMesmory() >= eip && pcpatches->getFirstWrittenAddressInMesmory() <= eip + ins_size){
		PIN_SetContextReg(ctxt, REG_EIP, eip);
		//reset the address
		pcpatches->setFirstWrittenAddressInMesmory(0x0);
		// break the terace
		PIN_ExecuteAt(ctxt);
	}
}
Example #16
0
static VOID OnThreadStart(THREADID tid, CONTEXT *ctxt, INT32, VOID *)
{
    // Skip root thread.
    //
    if (tid == 0)
        return;

    // Give each worker thread a unique, contiguous ID.
    //
    static unsigned workerCount = 0;
    THREAD_INFO *info = new THREAD_INFO(workerCount++);
    PIN_SetContextReg(ctxt, RegThreadInfo, reinterpret_cast<ADDRINT>(info));
}
Example #17
0
static VOID SyscallExit(THREADID threadIndex, CONTEXT *ctxt, SYSCALL_STANDARD std, VOID *v)
{
    ADDRINT addr = PIN_GetContextReg(ctxt, REG_INST_G0);
    if (!addr)
        return;

    // Reset REG_INST_G0
    PIN_SetContextReg(ctxt, REG_INST_G0, 0);

    ADDRINT pc = PIN_GetContextReg(ctxt, REG_INST_PTR);
    ADDRINT ret = PIN_GetSyscallReturn(ctxt, std);
    ADDRINT value = 0;
    if (ret == (ADDRINT)-1 || PIN_SafeCopy(&value, Addrint2VoidStar(addr), sizeof(ADDRINT)) != sizeof(ADDRINT))
    {
        Out << Header(threadIndex, pc) << "Failed to read actual TLS pointer" << endl;
    }
    Out << Header(threadIndex, pc) << "sysarch returned: " << ", 0x" << std::hex << value << "" << std::endl;
}
Example #18
0
static VOID ThreadCreateCallback(THREADID tid, CONTEXT * ctxt, INT32 flags, VOID * v)
{
    if (KnobVerbose)
        cerr << "Thread create callback for " << tid << "\n";

    // First thread is static, we don't want to mangle it, but we do create a new thread
    // from the callback.
    if (KnobFromCallback)
    {
        ADDRINT * stack = new ADDRINT [1024];
        CONTEXT context;
        
        ctxt = &context;

        if (!threadFunction)
        {
            cerr << "Cannot find 'doNothing()' in application\n";
            PIN_ExitProcess(-1);
        }

        // Fill in sensible values for critical registers.
        PIN_SetContextReg(ctxt, REG_STACK_PTR,ADDRINT (&stack[1023]));
        PIN_SetContextReg(ctxt, REG_INST_PTR, threadFunction);
        PIN_SetContextReg(ctxt, REG_GFLAGS, 0);

        cloneThread(ctxt);
    }

    if (tid >= (MAXTHREADS-1))
    {
        cerr << "Created all threads OK\n";
        PIN_ExitProcess(0);
    }

    // First thread is created statically, we don't want to mess with it.
    if (tid == 0 || KnobFromCallback)
        return;

    if (!threadFunction)
    {
        cerr << "Cannot find 'doNothing()' in application\n";
        PIN_ExitProcess(-1);
    }

    ADDRINT * stack = new ADDRINT [1024];

    // Fill in sensible values for critical registers.
    PIN_SetContextReg(ctxt, REG_STACK_PTR,ADDRINT (&stack[1023]));
    PIN_SetContextReg(ctxt, REG_INST_PTR, ADDRINT (&threadFunction));
    PIN_SetContextReg(ctxt, REG_GFLAGS, 0);
}
Example #19
0
/*
* thread start callback (analysis function)
*
* allocate space for the syscall context and VCPUs
* (i.e., thread context), and set the TLS-like pointer
* (i.e., thread_ctx_ptr) accordingly
*
* @tid:	thread id
* @ctx:	CPU context
* @flags:	OS specific flags for the new thread
* @v:		callback value
*/
static void
thread_alloc(THREADID tid, CONTEXT *ctx, INT32 flags, VOID *v)
{
	/* thread context pointer (ptr) */
	thread_ctx_t *tctx = NULL;

	/* allocate space for the thread context; optimized branch */
	if (unlikely((tctx = (thread_ctx_t *)calloc(1,
		sizeof(thread_ctx_t))) == NULL)) { 
			/* error message */
			LOG(string(__FUNCTION__) + ": thread_ctx_t allocation failed (" +
				string(strerror(errno)) + ")\n");

			/* die */
			libdft_die();
	}

	/* save the address of the per-thread context to the spilled register */
	PIN_SetContextReg(ctx, thread_ctx_ptr, (ADDRINT)tctx);
}
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);
    }
}
Example #21
0
static VOID OnThreadStart(THREADID tid, CONTEXT *ctxt, INT32, VOID *)
{
    TINFO *tinfo = new TINFO(PIN_GetContextReg(ctxt, REG_STACK_PTR));
    ThreadInfos.insert(std::make_pair(tid, tinfo));
    PIN_SetContextReg(ctxt, RegTinfo, reinterpret_cast<ADDRINT>(tinfo));
}
Example #22
0
// In order to avoid obsidium to take the path of the 'or byte ptr [esp+0x1],0x1' 
VOID KillObsidiumDeadPath(CONTEXT *ctxt){
	PIN_SetContextReg(ctxt,REG_EAX,0x7);
}
Example #23
0
VOID OnThread(THREADID threadIndex, CONTEXT *ctxt, INT32 flags, VOID *v)
{
    PIN_SetContextReg(ctxt, scratchReg, 0);
}
Example #24
0
VOID ThreadStart(THREADID tid, CONTEXT *ctxt, int flags, VOID *v)
{
    for (UINT32 r = 0;  r <= 9;  r++)
        PIN_SetContextReg(ctxt, REG(REG_INST_G0 + r), BaseValue + tid + r);
}
VOID AnalysisFunc(CONTEXT *context)
{
    PIN_SetContextReg(context, REG_GAX, 0);
}
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);
    }
}