Пример #1
0
static VOID MemoryTrace(TRACE trace, INS ins)
{
	if (!KnobTraceMemory)
		return;

	if (INS_IsMemoryRead(ins) ||
	    INS_HasMemoryRead2(ins) ||
	    INS_IsMemoryWrite(ins)
	   ) {
		INS_InsertCall(ins, IPOINT_BEFORE,
				AFUNPTR(EmitMemory),
				IARG_THREAD_ID,
				IARG_INST_PTR,
				IARG_BOOL, INS_IsMemoryWrite(ins),
				(INS_IsMemoryWrite(ins) ?
				 	IARG_MEMORYWRITE_EA :
				 INS_IsMemoryRead(ins) ?
				 	IARG_MEMORYREAD_EA : IARG_MEMORYREAD2_EA),
				IARG_END
			      );
	}
}
static VOID Trace(TRACE trace, VOID *v)
{
    RTN rtn = TRACE_Rtn(trace);
    
    if (!RTN_Valid(rtn) || RTN_Name(rtn) != watch_rtn)
    {
        return;
    }

    if (TRACE_Address(trace) == RTN_Address(rtn)) 
    {
        INS ins = BBL_InsHead(TRACE_BblHead(trace));
        INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(Emit),
                             IARG_PTR, "Trace instrumentation3", IARG_END);
        BBL_InsertCall(TRACE_BblHead(trace), IPOINT_BEFORE, AFUNPTR(Emit),
                             IARG_PTR, "Trace instrumentation2", IARG_END);
        TRACE_InsertCall(trace, IPOINT_BEFORE, AFUNPTR(Emit),
                             IARG_PTR, "Trace instrumentation1", IARG_END);
        
        printf("Trace Instrumenting %s\n", watch_rtn);
    }
}
Пример #3
0
VOID Ins( INS ins, VOID *v )
{
    if (KnobDetach > 0 && scount > KnobDetach)
        return;

    if (KnobLog)
    {
        void *addr = Addrint2VoidStar(INS_Address(ins));
        string disasm = INS_Disassemble(ins);
        PrintIns(addr, disasm.c_str());
    }

    scount++;

    // call and return need also stack manipulation (see emu_stack.cpp)
    // conditional jumps need handling the condition (not supported yet)
    if (INS_IsCall(ins) || INS_IsRet(ins) || INS_Category(ins) == XED_CATEGORY_COND_BR)
        return;

    if (INS_IsIndirectBranchOrCall(ins))
    {
        INS_InsertCall(ins, IPOINT_BEFORE,
            AFUNPTR(EmuIndJmp),
            IARG_BRANCH_TARGET_ADDR,
            IARG_RETURN_REGS, scratchReg, IARG_END);

        INS_InsertIndirectJump(ins, IPOINT_AFTER, scratchReg);

        INS_Delete(ins);
    }
    else if (INS_IsDirectBranchOrCall(ins))
    {
        ADDRINT tgt = INS_DirectBranchOrCallTargetAddress(ins);

        INS_InsertDirectJump(ins, IPOINT_AFTER, tgt);

        INS_Delete(ins);
    }
}
Пример #4
0
VOID Instruction(INS ins, VOID *v)
{
    INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(incinst), IARG_END);
    INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(andinst), IARG_END);

    static bool first = true;
    if (first)
    {
        data[16] = 1;
        INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(cmov_test), IARG_PTR, &cmov_data, IARG_END);
        INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(leainst), IARG_PTR, data, IARG_END);
        INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(CheckData), IARG_END);

        INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(leaindex), IARG_REG_VALUE, REG_STACK_PTR, IARG_PTR, &res, IARG_END);
#if defined(TARGET_IA32E)
        INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(leaindex), IARG_REG_VALUE, REG_R9, IARG_PTR, &res, IARG_END);
#endif
    }

    first = false;
}
Пример #5
0
VOID EmulateLoad(INS ins, VOID* v)
{
    // Find the instructions that move a value from memory to a register
    if (INS_Opcode(ins) == XED_ICLASS_MOV &&
        INS_IsMemoryRead(ins) && 
        INS_OperandIsReg(ins, 0) &&
        INS_OperandIsMemory(ins, 1))
    {
        // op0 <- *op1
        INS_InsertCall(ins,
                       IPOINT_BEFORE,
                       AFUNPTR(DoLoad),
                       IARG_UINT32,
                       REG(INS_OperandReg(ins, 0)),
                       IARG_MEMORYREAD_EA,
                       IARG_RETURN_REGS,
                       INS_OperandReg(ins, 0),
                       IARG_END);

        // Delete the instruction
        INS_Delete(ins);
    }
}
Пример #6
0
// Pin calls this function every time a new instruction is encountered
VOID Instruction(INS ins, VOID *v)
{
    if (INS_IsVgather(ins))
    {
        REG ymmDest = INS_OperandReg(ins, 0), ymmMask = INS_OperandReg(ins, 2);
        if (!REG_is_ymm(ymmDest))
        {
            ymmDest = (REG)(ymmDest - REG_XMM0 + REG_YMM0);
        }
        if (!REG_is_ymm(ymmMask))
        {
            ymmMask = (REG)(ymmMask - REG_XMM0 + REG_YMM0);
        }
                
        INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)EmuGather, 
                        IARG_MULTI_MEMORYACCESS_EA,
                        IARG_REG_REFERENCE, ymmDest,
                        IARG_REG_REFERENCE, ymmMask,
                        IARG_END);

        INS_Delete(ins);
    }
}
Пример #7
0
VOID Trace(TRACE trace, VOID *v)
{
    const RTN rtn = TRACE_Rtn(trace);
    
    if (! RTN_Valid(rtn))
        return;
    
    const SEC sec = RTN_Sec(rtn);
    ASSERTX(SEC_Valid(sec));
    
    const IMG img = SEC_Img(sec);
    ASSERTX(IMG_Valid(img));
    
    if ( KnobNoSharedLibs.Value() && IMG_Type(img) == IMG_TYPE_SHAREDLIB)
        return;
    
    for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl))
    {
        // Record the registers into a dummy buffer so we can count them
        UINT16 buffer[128 * 1024];
        INT32 count = RecordRegisters(bbl, buffer);
        ASSERTX(count < 128 * 1024);
        
        // Summarize the stats for the bbl in a 0 terminated list
        // This is done at instrumentation time
        UINT16 * stats = new UINT16[count];

        RecordRegisters(bbl, stats);

        // Insert instrumentation to count the number of times the bbl is executed
        BBLSTATS * bblstats = new BBLSTATS(stats);
        INS_InsertCall(BBL_InsHead(bbl), IPOINT_BEFORE, AFUNPTR(docount), IARG_PTR, &(bblstats->_counter), IARG_END);

        // Remember the counter and stats so we can compute a summary at the end
        statsList.push_back(bblstats);
    }
}
Пример #8
0
LOCALFUN VOID Instruction(INS ins, VOID *v)
{
    // all instruction fetches access I-cache
    INS_InsertCall(
        ins, IPOINT_BEFORE, (AFUNPTR)InsRef,
        IARG_INST_PTR,
        IARG_END);

    if (INS_IsMemoryRead(ins))
    {
        const UINT32 size = INS_MemoryReadSize(ins);
        const AFUNPTR countFun = (size <= 4 ? (AFUNPTR) MemRefSingle : (AFUNPTR) MemRefMulti);

        // only predicated-on memory instructions access D-cache
        INS_InsertPredicatedCall(
            ins, IPOINT_BEFORE, countFun,
            IARG_MEMORYREAD_EA,
            IARG_MEMORYREAD_SIZE,
            IARG_UINT32, CACHE_BASE::ACCESS_TYPE_LOAD,
            IARG_END);
    }

    if (INS_IsMemoryWrite(ins))
    {
        const UINT32 size = INS_MemoryWriteSize(ins);
        const AFUNPTR countFun = (size <= 4 ? (AFUNPTR) MemRefSingle : (AFUNPTR) MemRefMulti);

        // only predicated-on memory instructions access D-cache
        INS_InsertPredicatedCall(
            ins, IPOINT_BEFORE, countFun,
            IARG_MEMORYWRITE_EA,
            IARG_MEMORYWRITE_SIZE,
            IARG_UINT32, CACHE_BASE::ACCESS_TYPE_STORE,
            IARG_END);
    }
}
Пример #9
0
// Insert instrumentation to count memory operations
// The optimisations here are similar to those above.
static VOID insertRepMemoryCountInstrumentation(INS ins, UINT32 opIdx)
{
    const opInfo * op = &opcodes[opIdx];

    if (takesConditionalRep(opIdx))
    {
        INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)addMemops,
                       IARG_UINT32, opIdx,
                       IARG_EXECUTING,
                       IARG_UINT32, op->reads,
                       IARG_UINT32, op->writes,
                       IARG_END);
    }
    else
    {
        INS_InsertIfCall(ins, IPOINT_BEFORE, (AFUNPTR)returnArg, IARG_FIRST_REP_ITERATION, IARG_END);
        INS_InsertThenCall(ins, IPOINT_BEFORE, (AFUNPTR)addMemops,
                           IARG_UINT32, opIdx,
                           IARG_REG_VALUE, INS_RepCountRegister(ins),
                           IARG_UINT32, op->reads,
                           IARG_UINT32, op->writes,
                           IARG_END);
    }
}
Пример #10
0
VOID Instruction(INS ins, void *v)
{

// The subcases of direct branch and indirect branch are
// broken into "call" or "not call".  Call is for a subroutine
// These are left as subcases in case the programmer wants
// to extend the statistics to see how sub cases of branches behave

    if( INS_IsRet(ins) )
    {
        INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) br_predict, 
            IARG_INST_PTR, IARG_BRANCH_TAKEN,  IARG_END);
    }
    else if( INS_IsSyscall(ins) )
    {
        INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) br_predict, 
            IARG_INST_PTR, IARG_BRANCH_TAKEN,  IARG_END);
    }
    else if (INS_IsDirectBranchOrCall(ins))
    {
        if( INS_IsCall(ins) ) {
            INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) br_predict, 
                IARG_INST_PTR, IARG_BRANCH_TAKEN,  IARG_END);
        }
        else {
            INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) br_predict, 
                IARG_INST_PTR, IARG_BRANCH_TAKEN,  IARG_END);
        }
    }
    else if( INS_IsIndirectBranchOrCall(ins) )
    {
        if( INS_IsCall(ins) ) {
            INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) br_predict, 
                IARG_INST_PTR, IARG_BRANCH_TAKEN,  IARG_END);
    }
        else {
            INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) br_predict, 
                IARG_INST_PTR, IARG_BRANCH_TAKEN,  IARG_END);
        }
    }

}
Пример #11
0
VOID Instruction(INS ins, VOID *v)
{
    if (KnobCompareContexts)
    {
        INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) ReceiveContext,  IARG_CONTEXT, IARG_END);
        INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) VerifyContext,   IARG_CONST_CONTEXT, IARG_END);
        if (KnobCompareReverseContexts)
        {
            INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) ReceiveContext,  IARG_CONST_CONTEXT, IARG_END);
            INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) VerifyContext,   IARG_CONTEXT, IARG_END);
        }
    }
    else if (KnobOnStackContextOnly)
    {
        INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) ReceiveContext,  IARG_CONTEXT, IARG_END);
    }
    else if (KnobGetSpillAreaContextOnly)
    {
        INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) ReceiveContext,  IARG_CONST_CONTEXT, IARG_END);
    }
}
// Pin calls this function every time a new instruction is encountered
VOID Instruction(INS ins, VOID *v)
{
    
    INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)ReadWriteFlags_asm, IARG_END);
}
Пример #13
0
VOID Instruction(INS ins, VOID *v)
{
    INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)setdf, IARG_FAST_ANALYSIS_CALL, IARG_END);
}
Пример #14
0
VOID Trace(TRACE trace, VOID *v)
{
    const BOOL print_args = KnobPrintArgs.Value();
    
        
    for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl))
    {
        INS tail = BBL_InsTail(bbl);
        
        if( INS_IsCall(tail) )
        {
            if( INS_IsDirectBranchOrCall(tail) )
            {
                const ADDRINT target = INS_DirectBranchOrCallTargetAddress(tail);
                if( print_args )
                {
                    INS_InsertPredicatedCall(tail, IPOINT_BEFORE, AFUNPTR(do_call_args),
                                             IARG_PTR, Target2String(target), IARG_G_ARG0_CALLER, IARG_END);
                }
                else
                {
                    INS_InsertPredicatedCall(tail, IPOINT_BEFORE, AFUNPTR(do_call),
                                             IARG_PTR, Target2String(target), IARG_END);
                }
                
            }
            else
            {
                if( print_args )
                {
                    INS_InsertCall(tail, IPOINT_BEFORE, AFUNPTR(do_call_args_indirect),
                                   IARG_BRANCH_TARGET_ADDR, IARG_BRANCH_TAKEN,  IARG_G_ARG0_CALLER, IARG_END);
                }
                else
                {
                    INS_InsertCall(tail, IPOINT_BEFORE, AFUNPTR(do_call_indirect),
                                   IARG_BRANCH_TARGET_ADDR, IARG_BRANCH_TAKEN, IARG_END);
                }
                
                
            }
        }
        else
        {
            // sometimes code is not in an image
            RTN rtn = TRACE_Rtn(trace);
            
            // also track stup jumps into share libraries
            if( RTN_Valid(rtn) && !INS_IsDirectBranchOrCall(tail) && ".plt" == SEC_Name( RTN_Sec( rtn ) ))
            {
                if( print_args )
                {
                    INS_InsertCall(tail, IPOINT_BEFORE, AFUNPTR(do_call_args_indirect),
                                   IARG_BRANCH_TARGET_ADDR, IARG_BRANCH_TAKEN,  IARG_G_ARG0_CALLER, IARG_END);
                }
                else
                {
                    INS_InsertCall(tail, IPOINT_BEFORE, AFUNPTR(do_call_indirect),
                                   IARG_BRANCH_TARGET_ADDR, IARG_BRANCH_TAKEN, IARG_END);

                }
            }
        }
        
    }
}
Пример #15
0
void log_ins(INS ins)
{
    // dump the instruction
    INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) &execute_instruction,
        IARG_INST_PTR, IARG_PTR, strdup(INS_Disassemble(ins).c_str()),
        IARG_END);

    // reads memory (1)
    if(INS_IsMemoryRead(ins) != 0) {
        INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) &dump_read_memory,
            IARG_MEMORYREAD_EA, IARG_MEMORYREAD_SIZE, IARG_END);
    }

    // reads memory (2)
    if(INS_HasMemoryRead2(ins) != 0) {
        INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) &dump_read_memory,
            IARG_MEMORYREAD2_EA, IARG_MEMORYREAD_SIZE, IARG_END);
    }

    IPOINT after = IPOINT_AFTER;
    if(INS_IsCall(ins) != 0) {
        // TODO is this correct?
        after = IPOINT_TAKEN_BRANCH;
    }
    else if(INS_IsSyscall(ins) != 0) {
        // TODO support syscalls
        return;
    }
    else if(INS_HasFallThrough(ins) == 0 && (INS_IsBranch(ins) != 0 ||
            INS_IsRet(ins) != 0)) {
        // TODO is this correct?
        after = IPOINT_TAKEN_BRANCH;
    }

    // dump written memory
    if(INS_IsMemoryWrite(ins) != 0) {
        INS_InsertCall(ins, IPOINT_BEFORE,
            (AFUNPTR) &dump_written_memory_before, IARG_MEMORYWRITE_EA,
            IARG_MEMORYWRITE_SIZE, IARG_END);

        INS_InsertCall(ins, after, (AFUNPTR) &dump_written_memory_after,
            IARG_END);
    }

    // dump all affected registers
    for (UINT32 i = 0; i < INS_OperandCount(ins); i++) {
        if(INS_OperandIsMemory(ins, i) != 0) {
            if(INS_OperandMemoryBaseReg(ins, i) != REG_INVALID()) {
                REG base_reg = INS_OperandMemoryBaseReg(ins, i);

                if(g_reg_index[base_reg] != 0) {
                    INS_InsertCall(ins, IPOINT_BEFORE,
                        (AFUNPTR) &dump_reg_before,
                        IARG_UINT32, g_reg_index[base_reg]-1,
                        IARG_REG_VALUE, INS_OperandMemoryBaseReg(ins, i),
                        IARG_END);

                    INS_InsertCall(ins, after,
                        (AFUNPTR) &dump_reg_r_after,
                        IARG_UINT32, g_reg_index[base_reg]-1, IARG_END);
                }
            }
            if(INS_OperandMemoryIndexReg(ins, i) != REG_INVALID()) {
                REG index_reg = INS_OperandMemoryIndexReg(ins, i);

                if(g_reg_index[index_reg] != 0) {
                    INS_InsertCall(ins, IPOINT_BEFORE,
                        (AFUNPTR) &dump_reg_before,
                        IARG_UINT32, g_reg_index[index_reg]-1,
                        IARG_REG_VALUE, INS_OperandMemoryIndexReg(ins, i),
                        IARG_END);

                    INS_InsertCall(ins, after,
                        (AFUNPTR) &dump_reg_r_after,
                        IARG_UINT32, g_reg_index[index_reg]-1, IARG_END);
                }
            }
        }
        if(INS_OperandIsReg(ins, i) != 0) {
            REG reg_index = REG_FullRegName(INS_OperandReg(ins, i));

            if(INS_OperandReadAndWritten(ins, i) != 0) {
                if(g_reg_index[reg_index] != 0) {
                    INS_InsertCall(ins, IPOINT_BEFORE,
                        (AFUNPTR) &dump_reg_before,
                        IARG_UINT32, g_reg_index[reg_index]-1,
                        IARG_REG_VALUE, reg_index, IARG_END);

                    INS_InsertCall(ins, after, (AFUNPTR) &dump_reg_rw_after,
                        IARG_UINT32, g_reg_index[reg_index]-1,
                        IARG_REG_VALUE, reg_index, IARG_END);
                }
            }
            else if(INS_OperandRead(ins, i) != 0) {
                if(g_reg_index[reg_index] != 0) {
                    INS_InsertCall(ins, IPOINT_BEFORE,
                        (AFUNPTR) &dump_reg_before,
                        IARG_UINT32, g_reg_index[reg_index]-1,
                        IARG_REG_VALUE, reg_index, IARG_END);

                    INS_InsertCall(ins, after, (AFUNPTR) &dump_reg_r_after,
                        IARG_UINT32, g_reg_index[reg_index]-1, IARG_END);
                }
            }
            else if(INS_OperandWritten(ins, i) != 0) {
                if(g_reg_index[reg_index] != 0) {
                    INS_InsertCall(ins, after, (AFUNPTR) &dump_reg_w_after,
                        IARG_UINT32, g_reg_index[reg_index]-1,
                        IARG_REG_VALUE, reg_index, IARG_END);
                }
            }
        }
    }

    INS_InsertCall(ins, after, (AFUNPTR) &print_newline, IARG_END);
}
Пример #16
0
 void Insert(INT32 frameSize)
 {
     INS_InsertCall(_ins, IPOINT_BEFORE, _afunptr, IARG_FAST_ANALYSIS_CALL, IARG_REG_VALUE, scratch_reg0, IARG_ADDRINT, ADDRINT(_offset - frameSize), _itype, IARG_END);
 }
Пример #17
0
static VOID Trace(TRACE trace, VOID *v)
{
    RTN rtn = TRACE_Rtn(trace);
    
    ADDRINT version = TRACE_Version(trace);
    // If we are not in watch_rtn, switch back to base version
    if (!RTN_Valid(rtn) || RTN_Name(rtn) != watch_rtn)
    {
        if (version != VERSION_BASE)
            BBL_SetTargetVersion(TRACE_BblHead(trace), VERSION_BASE);
        return;
    }

    if (TRACE_Address(trace) == RTN_Address(rtn)) {
        INS ins = BBL_InsHead(TRACE_BblHead(trace));
        if (version == VERSION_BASE) 
        {
            // version_reg is used to select the version, use the first
            // argument of watch_rtn to set it
            INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(select_version),
                           IARG_FUNCARG_ENTRYPOINT_VALUE, 0,
                           IARG_RETURN_REGS, version_reg,
                           IARG_CALL_ORDER, CALL_ORDER_FIRST,
                           IARG_END);
        }
    }

    INS ins = BBL_InsHead(TRACE_BblHead(trace));
    for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)) 
    {
        // Instrumentation depends on version
        // These instrumentations occur after the following version instrumentation
        // (i.e. the instrumentation inserted by the below INS_InsertVersionCase calls)
        // This is due to the use of IARG_CALL_ORDER, CALL_ORDER_FIRST in the below
        // INS_InsertVersionCase calls.
        switch(version) {
          case VERSION_BASE:
            INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(Emit),
                             IARG_PTR, "version base", IARG_END);
            break;
          case VERSION_1:
            INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(Emit),
                             IARG_PTR, "version 1", IARG_END);
            break;
          case VERSION_2:
            INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(Emit),
                             IARG_PTR, "version 2", IARG_END);
            break;
          default:
            assert(0);
            break;
        }
    }

    // If we are at the entry point, select the version
    if (TRACE_Address(trace) == RTN_Address(rtn)) {
        INS ins = BBL_InsHead(TRACE_BblHead(trace));

        // IF we are in the base version, decide if we should go to the
        // other versions
        if (version == VERSION_BASE) 
        {
            INS_InsertVersionCase(ins, version_reg, 10, VERSION_1, IARG_CALL_ORDER, CALL_ORDER_FIRST, IARG_END);
            INS_InsertVersionCase(ins, version_reg, 20, VERSION_2, IARG_CALL_ORDER, CALL_ORDER_FIRST, IARG_END);
            printf ("Instrumentation at %p\n", reinterpret_cast<void *>(INS_Address(ins)));
        }
    }
}
Пример #18
0
// -------------------------------------------------------------
// Trace instrumentation function
// -------------------------------------------------------------
void I_Trace(TRACE trace, void *v) {

    BOOL isPLT = IsPLT(TRACE_Rtn(trace));

    #if DEBUG_INS    
    printf("-- Instrumenting trace %X of function %s\n", 
        TRACE_Address(trace), RTN_Valid(TRACE_Rtn(trace)) ? RTN_Name(TRACE_Rtn(trace)).c_str() : "<unknown_routine>");
    #endif

    // scan BBLs within the current trace
    for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)) {

    	// instrument memory reads and writes
    	for(INS ins = BBL_InsHead(bbl); INS_Valid(ins); ins = INS_Next(ins))
    	    Instruction(ins);

        INS tail = BBL_InsTail(bbl);

        // skip system calls
        if ( INS_IsSyscall(tail) ) continue;
        
        // instrument .plt stub calls
        if ( isPLT ) {

            #if DEBUG_INS
            printf("   > .plt stub call\n");
            #endif

            if (gSetup.callingSite) {
                if (gSetup.memBuf)
                    INS_InsertCall(tail, IPOINT_BEFORE, 
                                (AFUNPTR)A_ProcessIndirectCallCSBuf,
                                IARG_FAST_ANALYSIS_CALL,
                                IARG_INST_PTR,
                                IARG_BRANCH_TARGET_ADDR,
                                IARG_REG_VALUE, REG_STACK_PTR,
                                IARG_THREAD_ID,
                                IARG_CONTEXT,
                                IARG_END);
                else
                    INS_InsertCall(tail, IPOINT_BEFORE, 
                                (AFUNPTR)A_ProcessIndirectCallCS,
                                IARG_FAST_ANALYSIS_CALL,
                                IARG_INST_PTR,
                                IARG_BRANCH_TARGET_ADDR,
                                IARG_REG_VALUE, REG_STACK_PTR,
                                IARG_THREAD_ID,
                                IARG_END);
            }
            else {
                if (gSetup.memBuf)
                    INS_InsertCall(tail, IPOINT_BEFORE, 
                                (AFUNPTR)A_ProcessIndirectCallBuf,
                                IARG_FAST_ANALYSIS_CALL,
                                IARG_BRANCH_TARGET_ADDR,
                                IARG_REG_VALUE, REG_STACK_PTR,
                                IARG_THREAD_ID,
                                IARG_CONTEXT,
                                IARG_END);
                else
                    INS_InsertCall(tail, IPOINT_BEFORE, 
                                (AFUNPTR)A_ProcessIndirectCall,
                                IARG_FAST_ANALYSIS_CALL,
                                IARG_BRANCH_TARGET_ADDR,
                                IARG_REG_VALUE, REG_STACK_PTR,
                                IARG_THREAD_ID,
                                IARG_END);
            }
            continue;
        }

        // instrument all calls and returns
        if ( INS_IsCall(tail) ) {
        
            // direct call
            if( INS_IsDirectBranchOrCall(tail) ) {

                // get target address
                ADDRINT target = Target2FunAddr(INS_DirectBranchOrCallTargetAddress(tail));

                #if DEBUG_INS
                printf("   > Direct call to %s\n", Target2RtnName(target).c_str());
                #endif

                // instrument direct call: target address determined here
                if (gSetup.callingSite) {
                    if (gSetup.memBuf)
                        INS_InsertPredicatedCall(tail, IPOINT_BEFORE,
                                              (AFUNPTR)A_ProcessDirectCallCSBuf,
                                              IARG_FAST_ANALYSIS_CALL,
                                              IARG_INST_PTR,
                                              IARG_ADDRINT, target,
                                              IARG_REG_VALUE, REG_STACK_PTR,
                                              IARG_THREAD_ID,
                                              IARG_CONTEXT,
                                              IARG_END);
                    else
                        INS_InsertPredicatedCall(tail, IPOINT_BEFORE,
                                              (AFUNPTR)A_ProcessDirectCallCS,
                                              IARG_FAST_ANALYSIS_CALL,
                                              IARG_INST_PTR,
                                              IARG_ADDRINT, target,
                                              IARG_REG_VALUE, REG_STACK_PTR,
                                              IARG_THREAD_ID,
                                              IARG_END);
                }
                else {
                    if (gSetup.memBuf)
                        INS_InsertPredicatedCall(tail, IPOINT_BEFORE,
                                              (AFUNPTR)A_ProcessDirectCallBuf,
                                              IARG_FAST_ANALYSIS_CALL,
                                              IARG_ADDRINT, target,
                                              IARG_REG_VALUE, REG_STACK_PTR,
                                              IARG_THREAD_ID,
                                              IARG_CONTEXT,
                                              IARG_END);
                    else
                        INS_InsertPredicatedCall(tail, IPOINT_BEFORE,
                                              (AFUNPTR)A_ProcessDirectCall,
                                              IARG_FAST_ANALYSIS_CALL,
                                              IARG_ADDRINT, target,
                                              IARG_REG_VALUE, REG_STACK_PTR,
                                              IARG_THREAD_ID,
                                              IARG_END);
                }
            }

            // indirect call: target address determined at call time
            else {

                #if DEBUG_INS
                printf("   > Indirect call\n");
                #endif

                // instrument indirect call
                if (gSetup.callingSite) {
                    if (gSetup.memBuf)
                        INS_InsertPredicatedCall(tail, IPOINT_BEFORE,
                                              (AFUNPTR)A_ProcessIndirectCallCSBuf,
                                              IARG_FAST_ANALYSIS_CALL,
                                              IARG_INST_PTR,
                                              IARG_BRANCH_TARGET_ADDR,
                                              IARG_REG_VALUE, REG_STACK_PTR,
                                              IARG_THREAD_ID,
                                              IARG_CONTEXT,
                                              IARG_END);
                    else
                        INS_InsertPredicatedCall(tail, IPOINT_BEFORE,
                                              (AFUNPTR)A_ProcessIndirectCallCS,
                                              IARG_FAST_ANALYSIS_CALL,
                                              IARG_INST_PTR,
                                              IARG_BRANCH_TARGET_ADDR,
                                              IARG_REG_VALUE, REG_STACK_PTR,
                                              IARG_THREAD_ID,
                                              IARG_END);
                }
                else {
                    if (gSetup.memBuf)
                        INS_InsertPredicatedCall(tail, IPOINT_BEFORE,
                                              (AFUNPTR)A_ProcessIndirectCallBuf,
                                              IARG_FAST_ANALYSIS_CALL,
                                              IARG_BRANCH_TARGET_ADDR,
                                              IARG_REG_VALUE, REG_STACK_PTR,
                                              IARG_THREAD_ID,
                                              IARG_CONTEXT,
                                              IARG_END);
                    else
                        INS_InsertPredicatedCall(tail, IPOINT_BEFORE,
                                              (AFUNPTR)A_ProcessIndirectCall,
                                              IARG_FAST_ANALYSIS_CALL,
                                              IARG_BRANCH_TARGET_ADDR,
                                              IARG_REG_VALUE, REG_STACK_PTR,
                                              IARG_THREAD_ID,
                                              IARG_END);
                }
            }

            continue;
        }
        
        if ( INS_IsRet(tail) ) {

            #if DEBUG_INS
            printf("   > return\n");
            #endif

            if (gSetup.memBuf)
                INS_InsertPredicatedCall(tail, IPOINT_BEFORE,
                                     (AFUNPTR)A_ProcessReturnBuf,
                                     IARG_FAST_ANALYSIS_CALL,
                                     IARG_REG_VALUE, REG_STACK_PTR,
                                     IARG_THREAD_ID,
                                     IARG_CONTEXT,
                                     IARG_END);
            else
                INS_InsertPredicatedCall(tail, IPOINT_BEFORE,
                                     (AFUNPTR)A_ProcessReturn,
                                     IARG_FAST_ANALYSIS_CALL,
                                     IARG_REG_VALUE, REG_STACK_PTR,
                                     IARG_THREAD_ID,
                                     IARG_END);
        }
    }
}
VOID Instruction(INS ins, VOID *v)
{
  	INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)AnalysisFunc, IARG_CONST_CONTEXT, IARG_END);
}
Пример #20
0
VOID Ins(INS ins, VOID * v)
{
    INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(DoExit), IARG_END);
    INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(NeverCalled), IARG_ADDRINT, 0, IARG_END);
}
static VOID InstrumentInstruction (INS ins, void *)
{
    INS_InsertCall (ins, IPOINT_BEFORE, (AFUNPTR)ReplayImageEntry, IARG_END);
}
Пример #22
0
// This function is called before every instruction is executed
VOID instrument_routine(RTN rtn, void *ip)
{
    string name = RTN_Name(rtn);
    if(name == "ivan")
    {
        RTN_Open(rtn);
        for (INS ins = RTN_InsHead(rtn); INS_Valid(ins); ins = INS_Next(ins))
        {
            int opCount = INS_OperandCount(ins);

            int opcode = INS_Opcode(ins);
            if(INS_IsMemoryRead(ins))
            {


                for(int i = 0; i< opCount; i++)
                {
                    if(INS_MemoryOperandIsRead(ins,i))
                    {
                        /*
                           INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)RecordMemRead,IARG_PTR,ins,
                           IARG_INST_PTR,
                           IARG_MEMORYOP_EA, i,
                           IARG_END);
                           */

                        cout<<"opcode:"<<INS_Opcode(ins)<<", mnemonic: "<<INS_Mnemonic(ins)<<endl;
                        if(INS_Opcode(ins)!= XED_ICLASS_RET_NEAR)
                        {
                            REG scratchReg = GetScratchReg(i);
                            INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(GetMemAddress),
                                           IARG_MEMORYOP_EA, i, IARG_RETURN_REGS, scratchReg, IARG_END);

                            INS_RewriteMemoryOperand(ins, i, scratchReg);
                        }
                    }
                }
            }

            if(INS_IsMemoryWrite(ins))
            {
                for(int i = 0; i< opCount; i++)
                {
                    /*
                    if(INS_OperandIsImmediate(ins,i))
                    {
                    	cout<<"immediate "<<INS_OperandImmediate(ins,i)<<endl;
                    }
                    */
                    if(INS_MemoryOperandIsWritten(ins,i) && INS_HasFallThrough(ins))
                    {

                        /*
                        INS_InsertCall(
                                ins, IPOINT_BEFORE, (AFUNPTR)RecordMemWrite,
                                IARG_INST_PTR,
                                IARG_MEMORYOP_EA, i,
                                IARG_END);

                        INS_InsertCall(
                                ins, IPOINT_AFTER, (AFUNPTR)RecordMemWrite,
                                IARG_INST_PTR,
                                IARG_MEMORYOP_EA, i,
                                IARG_END);
                                */

                        if(opcode != XED_ICLASS_PUSH)
                        {
                            REG scratchReg = GetScratchReg(i);
                            INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(GetMemAddress),
                                           IARG_MEMORYOP_EA, i, IARG_RETURN_REGS, scratchReg, IARG_END);

                            INS_RewriteMemoryOperand(ins, i, scratchReg);
                        }

                    }
                }
            }
        }
        RTN_Close(rtn);
    }
}
Пример #23
0
VOID Instruction(INS ins, VOID *v)
{
    INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)use_xed, 
                   IARG_INST_PTR,
                   IARG_END);
}
Пример #24
0
VOID Instruction(INS ins, VOID *v)
{
    
    INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(ZeroOutScratches), IARG_END);
       
}
Пример #25
0
VOID Instruction(INS ins, VOID *v)
{
  	INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)AnalysisFunc, IARG_REG_REFERENCE, REG_ST0, IARG_END);  
}
Пример #26
0
VOID instrument_reg(INS ins, ins_buffer_entry* e){


	UINT32 i, maxNumRegsProd, maxNumRegsCons, regReadCnt, regWriteCnt, opCnt, regOpCnt;
	REG reg;

	if(!e->setRead){

		maxNumRegsCons = INS_MaxNumRRegs(ins); // maximum number of register consumations (reads)

		regReadCnt = 0;
		for(i = 0; i < maxNumRegsCons; i++){ // finding all register operands which are read
			reg = INS_RegR(ins,i);
			//assert(((UINT32)reg) < MAX_NUM_REGS);
			/* only consider valid general-purpose registers (any bit-width) and floating-point registers,
			 * i.e. exlude branch, segment and pin registers, among others */
			if(REG_valid(reg) && (REG_is_fr(reg) || REG_is_mm(reg) || REG_is_xmm(reg) || REG_is_gr(reg) || REG_is_gr8(reg) || REG_is_gr16(reg) || REG_is_gr32(reg) || REG_is_gr64(reg))){
				regReadCnt++;
			}
		}

		e->regReadCnt = regReadCnt;
		e->regsRead = (REG*) checked_malloc(regReadCnt*sizeof(REG));

		regReadCnt = 0;
		for(i = 0; i < maxNumRegsCons; i++){ // finding all register operands which are read
			reg = INS_RegR(ins,i);
			//assert(((UINT32)reg) < MAX_NUM_REGS);
			/* only consider valid general-purpose registers (any bit-width) and floating-point registers,
			 * i.e. exlude branch, segment and pin registers, among others */
			if(REG_valid(reg) && (REG_is_fr(reg) || REG_is_mm(reg) || REG_is_xmm(reg) || REG_is_gr(reg) || REG_is_gr8(reg) || REG_is_gr16(reg) || REG_is_gr32(reg) || REG_is_gr64(reg))){
				e->regsRead[regReadCnt++] = reg;
			}
		}
		e->setRead = true;
	}
	if(!e->setWritten){

		maxNumRegsProd = INS_MaxNumWRegs(ins);

		regWriteCnt = 0;
		for(i=0; i < maxNumRegsProd; i++){

			reg = INS_RegW(ins, i);
			//assert(((UINT32)reg) < MAX_NUM_REGS);
			/* only consider valid general-purpose registers (any bit-width) and floating-point registers,
			 * i.e. exlude branch, segment and pin registers, among others */
			if(REG_valid(reg) && (REG_is_fr(reg) || REG_is_mm(reg) || REG_is_xmm(reg) || REG_is_gr(reg) || REG_is_gr8(reg) || REG_is_gr16(reg) || REG_is_gr32(reg) || REG_is_gr64(reg))){
				regWriteCnt++;
			}
		}

		e->regWriteCnt = regWriteCnt;
		e->regsWritten = (REG*)checked_malloc(regWriteCnt*sizeof(REG));

		regWriteCnt = 0;
		for(i=0; i < maxNumRegsProd; i++){

			reg = INS_RegW(ins, i);
			//assert(((UINT32)reg) < MAX_NUM_REGS);
			/* only consider valid general-purpose registers (any bit-width) and floating-point registers,
			 * i.e. exlude branch, segment and pin registers, among others */
			if(REG_valid(reg) && (REG_is_fr(reg) || REG_is_mm(reg) || REG_is_xmm(reg) || REG_is_gr(reg) || REG_is_gr8(reg) || REG_is_gr16(reg) || REG_is_gr32(reg) || REG_is_gr64(reg))){
				e->regsWritten[regWriteCnt++] = reg;
			}
		}


		e->setWritten = true;
	}

	if(!e->setRegOpCnt){
		regOpCnt = 0;
		opCnt = INS_OperandCount(ins);
		for(i = 0; i < opCnt; i++){
			if(INS_OperandIsReg(ins,i))
				regOpCnt++;
		}
		/*if(regOpCnt >= MAX_NUM_OPER){
			cerr << "BOOM! -> MAX_NUM_OPER is exceeded! (" << regOpCnt << ")" << endl;
			exit(1);
		}*/
		e->regOpCnt = regOpCnt;
		e->setRegOpCnt = true;
	}

	if(interval_size == -1){
		INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)reg_instr_full, IARG_PTR, (void*)e, IARG_END);
	}
	else{
		INS_InsertIfCall(ins, IPOINT_BEFORE, (AFUNPTR)reg_instr_intervals, IARG_PTR, (void*)e, IARG_END);
		/* only called if interval is full */
		INS_InsertThenCall(ins, IPOINT_BEFORE, (AFUNPTR)reg_instr_interval, IARG_END);
	}
}
Пример #27
0
VOID Instruction(INS ins, VOID *v)
{
    INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)docount, IARG_END);
}
    static void rewrite_instruction(INS ins, bool is_read, sse_aligner_t* pthis) 
    {
        // Avoid aligning trivially aligned stuff
        const xed_decoded_inst_t* xedd = INS_XedDec(ins);
        if (xed_decoded_inst_get_memory_operand_length(xedd,0) 
              > sizeof (sse_aligned_buffer_t))
        {
            return;
        }

        //fprintf(stderr,"Rewriting %p\n",(void*)INS_Address(ins));

        if (pthis->verbose)
            *(pthis->out) << "REWRITE "
                          << string(is_read ? "LOAD :" : "STORE:")
                          << std::setw(16)
                          << std::hex 
                          << INS_Address(ins) 
                          << std::dec 
                          << " "
                          << INS_Disassemble(ins) << std::endl;

        if (is_read)
        {
            // Loads -- we change the load to use G0 as the base register and
            // then add a "before" function that sets G0 and copies the data to
            // an aligned bufffer.
            INS_InsertCall(ins, IPOINT_BEFORE,
                           AFUNPTR(copy_to_aligned_load_buffer_and_return_pointer),
                           IARG_MEMORYREAD_EA,
                           IARG_MEMORYREAD_SIZE,
                           IARG_INST_PTR,
                           IARG_THREAD_ID,
                           IARG_PTR, pthis,
                           IARG_RETURN_REGS, REG_INST_G0, 
                           IARG_END);
        }
        else
        {
            // Stores -- we change the store to use G0 as a base register and
            // then add a "before" function to set G0 and an "after" function
            // that copies the data from the aligned buffer to where it was
            // supposed to go.
            // Since we can't ask for the MEMORYWRITE_EA at IPOINT_AFTER, we save
            // that in REG_INST_G1 at IPOINT_BEFORE and then use it at IPOINT_AFTER.
            INS_InsertCall(ins, IPOINT_BEFORE,
                           AFUNPTR(return_pointer_to_aligned_store_buffer),
                           IARG_MEMORYWRITE_EA,
                           IARG_INST_PTR,
                           IARG_THREAD_ID,
                           IARG_PTR, pthis,
                           IARG_REG_REFERENCE, REG_INST_G1,
                           IARG_RETURN_REGS, REG_INST_G0,
                           IARG_END);
            INS_InsertCall(ins, IPOINT_AFTER,
                           AFUNPTR(copy_from_aligned_store_buffer),
                           IARG_REG_VALUE, REG_INST_G1,                           
                           IARG_MEMORYWRITE_SIZE,
                           IARG_INST_PTR,
                           IARG_THREAD_ID,
                           IARG_PTR, pthis,
                           IARG_END);
        }

        // Rewrite the memory operand (we assume there's only one) to use the address in REG_INST_G0
        INS_RewriteMemoryOperand (ins, 0, REG_INST_G0);
    }
Пример #29
0
VOID InsertCall(INS ins, IPOINT action, func_type funptr, param_types... param_values) 
{ INS_InsertCall(ins, action, (AFUNPTR)funptr, param_values..., IARG_END); }
Пример #30
0
/* ===================================================================== */
VOID Image(IMG img, VOID *v){

  for (UINT16 i = 0; i < n_excluded_lib_names; i++)
  {
    if (IMG_Name(img).find(excluded_lib_names[i]) != string::npos){
      cout << "Excluded module: " << IMG_Name(img) << endl;
      return;
    }
  }

	for (SEC sec = IMG_SecHead(img); SEC_Valid(sec); sec = SEC_Next(sec)){
    for (RTN rtn = SEC_RtnHead(sec); RTN_Valid(rtn); rtn = RTN_Next(rtn)) {
      RTN_Open(rtn);
      for (INS ins = RTN_InsHead(rtn); INS_Valid(ins); ins = INS_Next(ins)) {
        // Avoid instrumenting the instrumentation
        if (!INS_IsOriginal(ins))
          continue;
				
        if(!SeqProgram) {
				  if ((INS_IsMemoryWrite(ins) || INS_IsMemoryRead(ins)) && INS_HasFallThrough(ins)) {		
				  	if (INS_IsMemoryWrite(ins) && INS_IsMemoryRead(ins) &&
                INS_HasMemoryRead2(ins)) {
              INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)ProcessInst, IARG_THREAD_ID,
                            IARG_MEMORYWRITE_EA,
                            IARG_MEMORYREAD_EA,
                            IARG_MEMORYREAD2_EA,
                            IARG_INST_PTR,
                            IARG_END); 
            }					
				  	else if (INS_IsMemoryWrite(ins) && INS_IsMemoryRead(ins) &&
          	          !INS_HasMemoryRead2(ins)) {
				  		INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)ProcessInst, IARG_THREAD_ID,
                            IARG_MEMORYWRITE_EA,
                            IARG_MEMORYREAD_EA,
                            IARG_ADDRINT, 0,
                            IARG_INST_PTR,
                            IARG_END);		
				  		
				  	}
				  	else if (INS_IsMemoryWrite(ins) && !INS_IsMemoryRead(ins)) {
				  		INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)ProcessInst, IARG_THREAD_ID,
                            IARG_MEMORYWRITE_EA,
                            IARG_ADDRINT, 0,
                            IARG_ADDRINT, 0,
                            IARG_INST_PTR,
                            IARG_END);		
				  	}
				  	else if (!INS_IsMemoryWrite(ins) && INS_IsMemoryRead(ins) &&
                    INS_HasMemoryRead2(ins)) {
				  		INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)ProcessInst, IARG_THREAD_ID,
                 						IARG_ADDRINT, 0,
                            IARG_MEMORYREAD_EA,
                            IARG_MEMORYREAD2_EA,
                            IARG_INST_PTR,
                            IARG_END);
				  	}
				  	else if (!INS_IsMemoryWrite(ins) && INS_IsMemoryRead(ins) &&
                    !INS_HasMemoryRead2(ins)) {
				  		INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)ProcessInst, IARG_THREAD_ID,
                 						IARG_ADDRINT, 0,
                            IARG_MEMORYREAD_EA,
                            IARG_ADDRINT,0,
                            IARG_INST_PTR,
                            IARG_END);	
				  	}
				  	else { //not a memory opeartion     
              ASSERTX(0);
				  	}
				  }
        }
        else {
          if(INS_IsBranch(ins)){
            INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)ProcessBranch, 
              IARG_BRANCH_TAKEN, IARG_INST_PTR, IARG_END);
          }
        }
			}
			RTN_Close(rtn);
		}
	}

  
}