Example #1
0
INT32 RecordRegisters(BBL bbl, 
                      UINT16 * stats, 
                      UINT32 max_stats)
{
    UINT32 count = 0;
    
    for (INS ins = BBL_InsHead(bbl); INS_Valid(ins); ins = INS_Next(ins))
    {
        if (count >= max_stats)
        {
            cerr << "Too many stats in this block" << endl;
            exit(1);
        }
        bool rmem = INS_IsMemoryRead(ins) || INS_HasMemoryRead2(ins);
        bool wmem = INS_IsMemoryWrite(ins);
        bool rw_mem = rmem & wmem;
        if (rw_mem)
            stats[count++] = PATTERN_MEM_RW;
        else if (rmem)
            stats[count++] = PATTERN_MEM_R;
        else if (wmem)
            stats[count++] = PATTERN_MEM_W;
        else if (INS_SegmentRegPrefix(ins) != REG_INVALID())
            stats[count++] = PATTERN_NO_MEM_LIES;
        else 
            stats[count++] = PATTERN_NO_MEM;
    }

    stats[count++] = 0;
    
    return count;
}
Example #2
0
File: type.cpp Project: Frky/scat
/*  Instrumentation of each instruction
 *  that uses a memory operand
 */
VOID Instruction(INS ins, VOID *v) {
    trace_enter();

    if (!INS_IsStackRead(ins)) {
        for (UINT32 memopIdx = 0; memopIdx < INS_MemoryOperandCount(ins); memopIdx++) {
            if (INS_MemoryOperandIsWritten(ins, memopIdx)) {
                INS_InsertCall(ins,
                                IPOINT_BEFORE,
                                (AFUNPTR) update_stack_heap_region,
                                IARG_CONST_CONTEXT,
                                IARG_MEMORYOP_EA, memopIdx,
                                IARG_END);

                UINT32 opIdx = INS_MemoryOperandIndexToOperandIndex(ins, memopIdx);
                REG base_reg = INS_OperandMemoryBaseReg(ins, opIdx);
                if (base_reg != REG_INVALID()) {
                    INS_InsertCall(ins,
                                    IPOINT_BEFORE,
                                    (AFUNPTR) check_parameter_out,
                                    IARG_REG_VALUE, base_reg,
                                    IARG_END);
                }
            }
        }
    }

    if (INS_IsCall(ins)) {
        if (INS_IsDirectCall(ins)) {
            ADDRINT addr = INS_DirectBranchOrCallTargetAddress(ins);
            FID fid = fn_lookup_by_address(addr);

            INS_InsertCall(ins,
                        IPOINT_BEFORE,
                        (AFUNPTR) fn_call,
                        IARG_CONST_CONTEXT,
                        IARG_UINT32, fid,
                        IARG_END);
        }
        else {
            INS_InsertCall(ins,
                        IPOINT_BEFORE,
                        (AFUNPTR) fn_indirect_call,
                        IARG_CONST_CONTEXT,
                        IARG_BRANCH_TARGET_ADDR,
                        IARG_END);
        }
    }

    if (INS_IsRet(ins)) {
        INS_InsertCall(ins,
                    IPOINT_BEFORE,
                    (AFUNPTR) fn_ret,
                    IARG_CONST_CONTEXT,
                    IARG_END);
    }

    trace_leave();
}
Example #3
0
REG INS_get_memwr_basereg(INS ins)
{
	for (unsigned int i = 0; i < INS_OperandCount(ins); i++)
	{
        if (INS_OperandIsMemory(ins, i) && INS_OperandWritten(ins, i))
        {
            return REG_FullRegName(INS_OperandMemoryBaseReg(ins, i));
        }
    }
    
    return REG_INVALID();
}
Example #4
0
REG INS_get_mem_indexreg(INS ins)
{
	for (unsigned int i = 0; i < INS_OperandCount(ins); i++)
	{
        if (INS_OperandIsMemory(ins, i) && INS_OperandRead(ins, i))
        {
            return REG_FullRegName(INS_OperandMemoryIndexReg(ins, i));
        }
    }
    
    return REG_INVALID();
}
Example #5
0
// returns the full name of the first register operand read
REG INS_get_read_reg(INS ins)
{
    for (unsigned int i = 0; i < INS_OperandCount(ins); i++)
    {
        if (INS_OperandIsReg(ins, i) && INS_OperandRead(ins, i))
        {
            return REG_FullRegName(INS_OperandReg(ins, i));
        }
    }
    
    return REG_INVALID();
}
Example #6
0
VOID RewriteBases(INS ins, BOOL * live)
{
    for (UINT32 i = 0; i < INS_OperandCount(ins); i++)
    {
        if (!INS_OperandIsMemory(ins, i))
            continue;
        
        if (INS_OperandMemoryIndexReg(ins, i) != REG_INVALID())
        {
            CheckEffectiveAddress(ins);
            return;
        }
            
        REG baseReg = INS_OperandMemoryBaseReg(ins, i);

        // If no basereg is used, then it must be an absolute address
        if (baseReg == REG_INVALID())
            continue;

        // No need to rewrite stack references
        if (baseReg == REG_ESP)
            continue;
        
        // If we reach this point, we have an instruction that
        // must be rewritten, but if the memory operand is
        // implicit, we can't rewrite the base register
        if (INS_OperandIsImplicit(ins, i))
        {
            CheckEffectiveAddress(ins);
            return;
        }
        
        REG shadowReg = ShadowReg(baseReg);
        INS_OperandMemorySetBaseReg(ins, i, shadowReg);

        // Remember to write the shadow register
        live[RegIndex(baseReg)] = true;
    }
}
Example #7
0
/**
* This function is called
**/
void traceInst(INS ins, VOID*)
{
    ADDRINT address = INS_Address(ins);

    std::string mod_name = getModule( address );
    RegList regs;

    for ( UINT32 i = 0; i < INS_OperandCount(ins); i++ )
    {
        if ( INS_OperandIsReg(ins, i) )
        {
            REG x = INS_OperandReg(ins, i);
            if ( x != REG_INVALID() )
                regs.push_back( x );
        }
    }

    if (isUnknownAddress(address))
    {
        // The address is an address that does not belong to any loaded module.
        // This is potential shellcode. For these instructions a callback
        // function is inserted that dumps information to the trace file when
        // the instruction is actually executed.

        INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(dump_shellcode),
                       IARG_PTR, new std::string(dumpInstruction(ins)),
                       IARG_PTR, &regs,
                       IARG_CONTEXT, IARG_END
            );
    }
    else
    {
        if ( !modlist.empty() && (modlist.find(mod_name) == modlist.end()) ) // not concerned
            return;

        // The address is a legit address, meaning it is probably not part of
        // any shellcode. In this case we just log the instruction to dump it
        // later to show when control flow was transfered from legit code to
        // shellcode.

        legitInstructions.push_back(dumpInstruction(ins));

        if (legitInstructions.size() > KnobMaxLegitInsLogSize.Value())
        {
            // Log only up to KnobMaxLegitInsLogSize.Value() instructions or the whole
            // program before the shellcode will be dumped.

            legitInstructions.pop_front();
        }
    }
}
Example #8
0
VOID Instruction(INS ins, VOID *v)
{
    REG basereg = INS_dec(ins)->basereg;
        
    if (basereg == REG_INVALID())
        return;
        
    // Not allowed to change esp
    if (basereg == REG_ESP)
        return;
        
    INS_InsertCall(ins, IPOINT_BEFORE,
                   (AFUNPTR)SwizzleAddress, IARG_REG_VALUE, basereg, IARG_RETURN_REGS, basereg, IARG_END);
}
Example #9
0
int main(int argc, char **argv)
{
    const int nScratch = REG_INST_TOOL_LAST-REG_INST_TOOL_FIRST+1;
    int seen[nScratch];
    bool failed = false;

    PIN_Init(argc, argv);

    for (int i=0; i<nScratch; i++)
        seen[i] = 0;

    // Claim all the registers we expect to be able to claim
    for (int i=0; i<nScratch; i++)
    {
        REG scratch = PIN_ClaimToolRegister();
        if (scratch < REG_INST_TOOL_FIRST ||
            scratch > REG_INST_TOOL_LAST)
        {
            printf ("Failed: got a non-scratch register (%d)\n", int(scratch));
            failed = true;
        }
        seen[scratch-REG_INST_TOOL_FIRST]++;
    }

    // Check that we fail when we try to allocate an extra one.
    if (PIN_ClaimToolRegister() != REG_INVALID())
    {
        printf ("Failed: got register when we shouldn't have\n");
        failed = true;
    }

    // Check that we got each register once
    for (int i=0; i<nScratch; i++)
    {
        if (seen[i] != 1)
        {
            printf ("Failed: saw REG_INST_G%d %d times\n", i, seen[i]);
            failed = true;
        }
    }

    if (!failed)
        printf ("Passed\n");
    
    // No need to run the code...
    exit(failed ? 1 : 0);
}
Example #10
0
VOID CountsUpdate(INS ins)
{
    if (INS_FullRegRContain(ins, REG_EAX)) fullRegRContainCount++;
    if (INS_IsInterrupt(ins)) interruptCount++;
    if (INS_IsRDTSC(ins)) rdtscCount++;
    if (INS_IsSysret(ins)) sysretCount++;
    if (INS_IsXchg(ins)) xchgCount++;

    if (INS_IsDirectFarJump(ins)) {
        directFarJumpCount++;

        UINT32 displacement; UINT16 segment;
        INS_GetFarPointer(ins, segment, displacement);
        TEST(segment == 0xabcd && displacement == 0x14, "INS_GetFarPointer failed");
    }
    if (INS_MemoryIndexReg(ins) != REG_INVALID()) memoryIndexRegCount++;
}
Example #11
0
REG GetScratchReg(UINT32 index)
{
    static std::vector<REG> regs;

    while (index >= regs.size())
    {
        REG reg = PIN_ClaimToolRegister();
        if (reg == REG_INVALID())
        {
            std::cerr << "*** Ran out of tool registers" << std::endl;
            PIN_ExitProcess(1);
            /* does not return */
        }
        regs.push_back(reg);
    }

    return regs[index];
}
Example #12
0
File: type.cpp Project: Frky/scat
REG param_reg(unsigned int pid) {
    switch (pid) {
    case 0:
        return REG_RAX;
    case 1:
        return REG_RDI;
    case 2:
        return REG_RSI;
    case 3:
        return REG_RDX;
    case 4:
        return REG_RCX;
    case 5:
        return REG_R8;
    case 6:
        return REG_R9;
    default:
        return REG_INVALID();
    }
}
Example #13
0
/*
* initialize thread contexts
*
* spill a tool register for the thread
* contexts and register a thread start callback
*
* returns: 0 on success, 1 on error
*/
static inline int
thread_ctx_init(void)
{
	/* claim a tool register; optimized branch */
	if (unlikely(
		(thread_ctx_ptr = PIN_ClaimToolRegister()) == REG_INVALID())) {
			/* error message */
			LOG(string(__FUNCTION__) + ": register claim failed\n");

			/* failed */
			return 1;
	}

	/* 
	* thread start/stop hooks;
	* keep track of the threads and allocate/free space for the
	* per-thread logistics (i.e., syscall context, VCPU, etc)
	*/
	PIN_AddThreadStartFunction(thread_alloc, NULL);
	PIN_AddThreadFiniFunction(thread_free, NULL);

	/* success */
	return 0;
}
Example #14
0
int main(int argc, char * argv[])
{
    PIN_Init(argc, argv);
    PIN_InitSymbols();

    RegThreadInfo = PIN_ClaimToolRegister();
    if (RegThreadInfo == REG_INVALID())
    {
        std::cout << "Out of tool registers" << std::endl;
        PIN_ExitProcess(1);
    }

    // Get the test type and initialize the corresponding lock variable.
    //
    TestType = GetTestType(KnobTest.Value());
    switch (TestType)
    {
    case TEST_NONE:
        std::cout << "Must specify a test to run with the '-test' knob" << std::endl;
        PIN_ExitProcess(1);
        break;
    case TEST_INVALID:
        std::cout << "Invalid test name: " << KnobTest.Value() << std::endl;
        PIN_ExitProcess(1);
        break;
    case TEST_LOCK_INTEGRITY:
    case TEST_LOCK_STRESS:
        PIN_InitLock(&Lock);
        break;
    case TEST_MUTEX_INTEGRITY:
    case TEST_MUTEX_STRESS:
    case TEST_MUTEX_TRYSTRESS:
        PIN_MutexInit(&Mutex);
        break;
    case TEST_WRITER_INTEGRITY:
    case TEST_WRITER_STRESS:
    case TEST_WRITER_TRYSTRESS:
    case TEST_READER_STRESS:
    case TEST_READER_TRYSTRESS:
    case TEST_RW_INTEGRITY:
    case TEST_RW_STRESS:
    case TEST_RW_TRYSTRESS:
        PIN_RWMutexInit(&RWMutex);
        break;
    case TEST_SEMAPHORE:
        PIN_SemaphoreInit(&Sem1);
        PIN_SemaphoreInit(&Sem2);
        PIN_SemaphoreSet(&Sem1);
        PIN_MutexInit(&Mutex);
        break;
    case TEST_TRYLOCKS:
        PIN_MutexInit(&Mutex);
        PIN_RWMutexInit(&RWMutex);
        PIN_SemaphoreInit(&Sem1);
        break;
    default:
        ASSERTX(0);
    }

    PIN_AddThreadStartFunction(OnThreadStart, 0);
    PIN_AddThreadFiniFunction(OnThreadFini, 0);
    RTN_AddInstrumentFunction(InstrumentRtn, 0);
    PIN_AddFiniFunction(OnExit, 0);
    PIN_StartProgram();
    return 0;
}
VOID HandleAccess (INS ins, BOOL isRead)
{
    UINT32 operandCount = INS_OperandCount (ins);
    UINT32 i, displacement=0, scale=0;
    REG baseReg = REG_INVALID(), indexReg = REG_INVALID();
    BOOL instrumented = FALSE;
   
    
    for (i=0; i<operandCount; i++)
    {
        if ( 
            ((INS_OperandIsMemory (ins, i) && isRead && INS_OperandRead (ins, i)) || 
             (INS_OperandIsMemory (ins, i) && !isRead && INS_OperandWritten (ins, i)))
           )
        {
            displacement  = INS_OperandMemoryDisplacement (ins, i);
            baseReg = INS_OperandMemoryBaseReg (ins, i);
            indexReg = INS_OperandMemoryIndexReg (ins, i);
            scale = INS_OperandMemoryScale (ins, i);
            break;
        }
    }
    if (baseReg != REG_INVALID())
    {
        if (indexReg != REG_INVALID())
        {
            if (isRead)
            {
                INS_InsertPredicatedCall(
                    ins, IPOINT_BEFORE, (AFUNPTR)AnalyzeMemAccessBaseIndexDispl,
                    IARG_INST_PTR,
                    IARG_MEMORYREAD_EA,
                    IARG_UINT32, BASE_INDEX_DISPLACEMENT_ADDRESSING_READ_TYPE,
                    IARG_REG_VALUE, baseReg,
                    IARG_REG_VALUE, indexReg,
                    IARG_UINT32, scale,
                    IARG_UINT32, displacement,
                    IARG_THREAD_ID,
                    IARG_END);
            }
            else
            {
                INS_InsertPredicatedCall(
                    ins, IPOINT_BEFORE, (AFUNPTR)AnalyzeMemAccessBaseIndexDispl,
                    IARG_INST_PTR,
                    IARG_MEMORYWRITE_EA,
                    IARG_UINT32, BASE_INDEX_DISPLACEMENT_ADDRESSING_WRITE_TYPE,
                    IARG_REG_VALUE, baseReg,
                    IARG_REG_VALUE, indexReg,
                    IARG_UINT32, scale,
                    IARG_UINT32, displacement,
                    IARG_THREAD_ID,
                    IARG_END);

            }
            instrumented = TRUE;
        }
        else
        {
            if (isRead)
            {
                INS_InsertPredicatedCall(
                    ins, IPOINT_BEFORE, (AFUNPTR)AnalyzeMemAccessBaseDispl,
                    IARG_INST_PTR,
                    IARG_MEMORYREAD_EA,
                    IARG_UINT32, BASE_DISPLACEMENT_ADDRESSING_READ_TYPE,
                    IARG_REG_VALUE, baseReg,
                    IARG_UINT32, displacement,
                    IARG_THREAD_ID,
                    IARG_END);
            }
            else
            {
                INS_InsertPredicatedCall(
                    ins, IPOINT_BEFORE, (AFUNPTR)AnalyzeMemAccessBaseDispl,
                    IARG_INST_PTR,
                    IARG_MEMORYWRITE_EA,
                    IARG_UINT32, BASE_DISPLACEMENT_ADDRESSING_WRITE_TYPE,
                    IARG_REG_VALUE, baseReg,
                    IARG_UINT32, displacement,
                    IARG_THREAD_ID,
                    IARG_END);
            }
            instrumented = TRUE;
        }
    }
    
    else 
    {
        if (isRead)
        {
            INS_InsertPredicatedCall(
                ins, IPOINT_BEFORE, (AFUNPTR)AnalyzeMemAccessDispl,
                IARG_INST_PTR,
                IARG_MEMORYREAD_EA,
                IARG_UINT32, DISPLACEMENT_ONLY_ADDRESSING_READ_TYPE,
                IARG_UINT32, displacement,
                IARG_THREAD_ID,
                IARG_END);
        }
        else
        {
            INS_InsertPredicatedCall(
                ins, IPOINT_BEFORE, (AFUNPTR)AnalyzeMemAccessDispl,
                IARG_INST_PTR,
                IARG_MEMORYWRITE_EA,
                IARG_UINT32, DISPLACEMENT_ONLY_ADDRESSING_WRITE_TYPE,
                IARG_UINT32, displacement,
                IARG_THREAD_ID,
                IARG_END);
        }
        instrumented = TRUE;
    }
    ASSERTX (instrumented);
    // must delete this INS - since it's memory address is 16bit, cannot be sure
    // it accesses valid memory - so we are only testing the IARG_MEMORY(READ/WRITE)_EA
    // on these instructions
    INS_Delete(ins);
}
Example #16
0
// This function represents the case of a register copied to memory
void RegTaintMem(ADDRINT reg_r, UINT32 mem_scale, ADDRINT reg_base, ADDRINT reg_index, ADDRINT mem_w, UINT32 op,ADDRINT inst_addr)
{
	
    if (TaintedRegs[reg_r]) 
    {
	
		bbl_taintedmem = 1;
		
        TDS *tds_temp = new TDS;
        
		tds_temp->offset = TaintedRegs[reg_r]->offset;
		tds_temp->var_length = TaintedRegs[reg_r]->var_length;
		
		switch(mem_scale)
		{
		case 1:
			tds_temp->var_type = type_BYTE;
			break;
		case 2:
			tds_temp->var_type = type_WORD;
			break;
		case 4:
			tds_temp->var_type = type_DWORD;
			break;
		default:
			tds_temp->var_type = type_unknown;
			break;
		}

        tds_temp->memaddr = mem_w;
		tds_temp->opcode = op;
		tds_temp->source = TaintedRegs[reg_r];
		tds_temp->pointer = TaintedRegs[reg_r]->pointer;
        
		TaintedAddrs[mem_w] = tds_temp;

		if(reg_base!=REG_INVALID())
		{
			pointer[reg_base][reg_index].pointer=1;
			pointer[reg_base][reg_index].pointaddr=mem_w;
			pointer[reg_base][reg_index].var_type = tds_temp->var_type;
		}

		out << " reg point this tainted mem: "<<reg_base<<" && "<<reg_index<<" type: "<<tds_temp->var_type<<endl;

		out << endl;
		out << "register to memory " << inst_addr <<endl;
		if ( op >= XED_ICLASS_MOV && op <= XED_ICLASS_MOVZX)
		{
			out << "MOV " <<" scale: "<<mem_scale<<endl;
			if( mem_w == memRetStack )
			{
				out <<"detect overwriting of function's retaddr at stack!"<<endl;
				out <<"retaddress in stack at: "<<mem_w<<endl;
			}
		}

		out << "T " << mem_w << " source " << TaintedRegs[reg_r]->memaddr<<endl;

       
		
		// for (TDS * t=TaintedAddrs[mem_w];t;t=t->source)
		 //out << "trace " << t->memaddr << endl;
	}
    else //reg not tainted --> mem not tainted
    {
        if (TaintedAddrs.count(mem_w)) // if mem is already not tainted nothing to do
        {
            TaintedAddrs.erase(mem_w);
            out << "U by clean memory addr " << mem_w << endl;
        }
    }
}
Example #17
0
// this function represents the case of a memory copied to register
void MemTaintReg(ADDRINT mem_r, UINT32 mem_scale, ADDRINT reg_base, ADDRINT reg_index, ADDRINT reg_w, UINT32 op, ADDRINT inst_addr)//ADDRINT insad)
{

//	out<<"reg_w:"<<reg_w<<endl;
    if (TaintedAddrs.count(mem_r)) //count is either 0 or 1 for set
    {
		TDS *tds_temp = new TDS;

        tds_temp->offset = TaintedAddrs[mem_r]->offset;
		tds_temp->var_length = TaintedAddrs[mem_r]->var_length;
        tds_temp->memaddr = reg_w;
		tds_temp->opcode = op;
		tds_temp->source = TaintedAddrs[mem_r];
		tds_temp->pointer = TaintedAddrs[mem_r]->pointer;

		switch(mem_scale)
		{
		case 1:
			tds_temp->var_type = type_BYTE;
			break;
		case 2:
			tds_temp->var_type = type_WORD;
			break;
		case 4:
			tds_temp->var_type = type_DWORD;
			break;
		default:
			tds_temp->var_type = type_unknown;
			break;
		}

        TaintedRegs[reg_w] = tds_temp; 
	
		if(reg_index!=REG_INVALID())
		{
			
			if(TaintedRegs[reg_index])
			{
				out<<endl<<" tainted reg point this tainted mem: "<<reg_index<<" && "<<reg_base<<" type: "<<tds_temp->var_type<<endl;
				TaintedRegs[reg_index]->pointer=1;
			}
			else if(TaintedRegs[reg_base])
			{
				out<<endl<<" tainted reg point this tainted mem: "<<reg_index<<" && "<<reg_base<<" type: "<<tds_temp->var_type<<endl;
				TaintedRegs[reg_base]->pointer=1;
			}
			else
				out<<endl<<" untainted reg point this tainted mem: "<<reg_index<<" && "<<reg_base<<" type: "<<tds_temp->var_type<<endl;
		}
		else if(reg_base!=REG_INVALID())
		{
			if(TaintedRegs[reg_base])
			{
				out<<endl<<"a tainted reg point this tainted mem: "<<reg_base<<" type: "<<tds_temp->var_type<<endl;
				TaintedRegs[reg_base]->pointer=1;
			}
			else
				out<<endl<<"a untainted reg point this tainted mem: "<<reg_base<<" type: "<<tds_temp->var_type<<endl;
		}

		pointer[reg_base][reg_index].pointer=1;
		pointer[reg_base][reg_index].pointaddr=mem_r;
		pointer[reg_base][reg_index].var_type=tds_temp->var_type;

		out << endl;
		out <<  "memory to register " <<inst_addr<<endl;
		if ( op >= XED_ICLASS_MOV && op <= XED_ICLASS_MOVZX)
			out << "MOV " <<" scale: "<<mem_scale<<endl;
		out << "T " << reg_w << " source " << TaintedAddrs[mem_r]->memaddr <<endl;

    }
	else if(TaintedRegs[reg_index])//first taint index reg
	{

		out << endl;
		out <<"tainted index-register point to this untainted mem "<<inst_addr<<endl;
		//RegTaintMem(reg_index,mem_scale,reg_base,reg_index,mem_r,0,inst_addr);
		TaintedRegPointMem(reg_base,reg_index,mem_r,mem_scale,1);

		TaintedRegs[reg_index]->pointer=1;//after taint mem,set pointer of reg,because can't propagate this attribute to mem
			


		TDS *tds_temp = new TDS;

	    tds_temp->offset = TaintedAddrs[mem_r]->offset;
		tds_temp->var_length = TaintedAddrs[mem_r]->var_length;
		tds_temp->memaddr = reg_w;
		tds_temp->opcode = op;
		tds_temp->source = TaintedRegs[mem_r];
		tds_temp->pointer = TaintedRegs[mem_r]->pointer;

		switch(mem_scale)
		{
		case 1:
			tds_temp->var_type = type_BYTE;
			break;
		case 2:
			tds_temp->var_type = type_WORD;
			break;
		case 4:
			tds_temp->var_type = type_DWORD;
			break;
		default:
			tds_temp->var_type = type_unknown;
			break;
		}

		TaintedRegs[reg_w] = tds_temp;

		if ( op >= XED_ICLASS_MOV && op <= XED_ICLASS_MOVZX)
				out << "MOV " <<" scale: "<<mem_scale<<endl;
		out << "T " << reg_w << " source " << TaintedRegs[mem_r]->memaddr<<endl;

		TaintedAddrs.erase(mem_r);//clean [base+index] after move
	}
	else if(TaintedRegs[reg_base]&&reg_index!=REG_INVALID())//second taint base reg if index reg exist
	{
		out << endl;
		out <<"tainted base-register point to this untainted mem " <<inst_addr<<endl;	
		//RegTaintMem(reg_base,mem_scale,reg_base,reg_index,mem_r,0,inst_addr);
		TaintedRegPointMem(reg_base,reg_index,mem_r,mem_scale,0);//reg_base is the index reg!!!


		TaintedRegs[reg_base]->pointer=1;//after taint mem,set pointer of reg,because can't propagate this attribute to mem

		TDS *tds_temp = new TDS;
		tds_temp->offset = TaintedAddrs[mem_r]->offset;
		tds_temp->var_length = TaintedAddrs[mem_r]->var_length;
		tds_temp->memaddr = reg_w;
		tds_temp->opcode = op;
		tds_temp->source = TaintedAddrs[mem_r];
		tds_temp->pointer = TaintedAddrs[mem_r]->pointer;

		switch(mem_scale)
		{
		case 1:
			tds_temp->var_type = type_BYTE;
			break;
		case 2:
			tds_temp->var_type = type_WORD;
			break;
		case 4:
			tds_temp->var_type = type_DWORD;
			break;
		default:
			tds_temp->var_type = type_unknown;
			break;
		}

		TaintedRegs[reg_w] = tds_temp;

		if ( op >= XED_ICLASS_MOV && op <= XED_ICLASS_MOVZX)
				out << "MOV " <<" scale: "<<mem_scale<<endl;

		out << "T " << reg_w << " source " << TaintedAddrs[mem_r]->memaddr<<endl;

		TaintedAddrs.erase(mem_r);//clean [base+index] after move

	}
	else 
	{
		TaintedRegs[reg_w] = NULL;
	}
}
Example #18
0
VOID Trace(TRACE trace, VOID *v)
{
	if(TAINT_Analysis_On&&TAINT_Instrumentation_On)
	{
  for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl))
  {
	  if(bbl_taintedmem)
	  BBL_InsertCall(bbl,IPOINT_BEFORE,(AFUNPTR)bblBegin,IARG_END);

	  
    for (INS ins = BBL_InsHead(bbl); INS_Valid(ins); ins = INS_Next(ins))
    {
		INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)checkEIP,IARG_INST_PTR,IARG_END);
	
		if(INS_IsCall(ins))//detect overflow of stack
		{
			INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)MemofRetAddr,
                                            IARG_MEMORYOP_EA, 0,
                                            IARG_END);
		}
        if ( INS_Opcode(ins) >= XED_ICLASS_MOV && INS_Opcode(ins) <= XED_ICLASS_MOVZX )//&& INS_Address(ins) == 0x7c80a2f0)//||INS_Address(ins)==0x7c80a2f3))//||( (INS_Opcode(ins) >= XED_ICLASS_POP) && (INS_Opcode(ins) <= XED_ICLASS_POPFQ))||((INS_Opcode(ins) >= XED_ICLASS_PUSH) && (INS_Opcode(ins) <= XED_ICLASS_PUSHFQ))||(INS_Opcode(ins) == XED_ICLASS_LEA))
        {
		
            if (INS_has_immed(ins))
            {
                if (INS_IsMemoryWrite(ins)) //immed -> mem
                {
                    INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)ImmedCleanMem,
                                            IARG_MEMORYOP_EA, 0,
                                            IARG_END);
                }
                else						//immed -> reg
                {
                    REG insreg1 = INS_get_write_reg(ins);
                    INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)ImmedCleanReg,
                                            IARG_ADDRINT, (ADDRINT)insreg1,
                                            IARG_END);
                }
            }
            else if (INS_IsMemoryRead(ins)) //mem -> reg 
            {
                //in this case we call MemTaintReg to copy the taint if relevant
                REG insreg2 = INS_get_write_reg(ins);
				REG basereg2 = INS_get_mem_basereg(ins);
				REG indexreg2 = INS_get_mem_indexreg(ins);

				//ADDRINT insadd = INS_Address(ins);
				//string insdis = INS_Disassemble(ins);
				//out <<  "instruction 2 opcode " << INS_Opcode(ins)<<endl;
					INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)MemTaintReg,
                                        IARG_MEMORYOP_EA, 0,
										IARG_UINT32,INS_MemoryScale(ins),
										IARG_ADDRINT, (ADDRINT)basereg2,
										IARG_ADDRINT, (ADDRINT)indexreg2,
                                        IARG_ADDRINT, (ADDRINT)insreg2,										
										IARG_UINT32, INS_Opcode(ins),
										IARG_INST_PTR,
                                        IARG_END);


            }
            else if (INS_IsMemoryWrite(ins)) //reg -> mem 
            {
                //in this case we call RegTaintMem to copy the taint if relevant
                REG insreg3 = INS_get_read_reg(ins);
				REG basereg3 = INS_get_memwr_basereg(ins);
				REG indexreg3 = INS_get_memwr_indexreg(ins);
				//ADDRINT insadd = INS_Address(ins);
				//IARG_INST_PTR


                INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)RegTaintMem,
                                        IARG_ADDRINT,(ADDRINT)insreg3,
										IARG_UINT32,INS_MemoryScale(ins),
										IARG_ADDRINT, (ADDRINT)basereg3,
                                        IARG_ADDRINT, (ADDRINT)indexreg3,	
										IARG_MEMORYOP_EA, 0,
										IARG_UINT32, INS_Opcode(ins),
										IARG_INST_PTR,
										IARG_END);
            }
            else if (INS_RegR(ins, 0) != REG_INVALID()) //reg -> reg
            {
                //in this case we call RegTaintReg
                REG Rreg = INS_get_read_reg(ins); 
                REG Wreg = INS_get_write_reg(ins);
				//ADDRINT insadd = INS_Address(ins);
                INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)RegTaintReg,
                                        IARG_ADDRINT, (ADDRINT)Rreg,
                                        IARG_ADDRINT, (ADDRINT)Wreg,
										IARG_UINT32, INS_Opcode(ins),
										IARG_INST_PTR,
										IARG_END);
            }
            else	//should never happen
            {
                out << "serious error?!\n" << endl;
            }		
		} // IF opcode is a MOV
		/*
		if(bbl_taintedmem == 1&&INS_IsBranch(ins))
		{
			out << BBL_Address(bbl) <<endl;
			out << INS_Address(ins)<<endl;
			out << INS_NextAddress(ins)<<endl;
			out << INS_DirectBranchOrCallTargetAddress(ins)<<endl;
			out << " taintBBL: "<<endl;
			out << INS_Disassemble(ins) <<endl;
			if(INS_NextAddress(ins)>=BBL_Address(bbl)&&INS_NextAddress(ins)<=INS_Address(ins))
			{
				out << "find bbl loop"<<endl;
				//bblLoop = 1;
			}
		}
		*/
		if(bbl_taintedmem ==1 && ins==BBL_InsTail(bbl))
		{
//			out <<"find tainted bbl " <<endl;
//			out <<"bbl start address: "<< BBL_Address(bbl) <<endl;
//			out <<"bbl size: "<<BBL_Size(bbl) << endl;
//			out <<"bbl head: "<< INS_Disassemble(BBL_InsHead(bbl))<<endl;
//			out <<"bbl tail: "<< INS_Disassemble(ins) <<endl;
			if(INS_DirectBranchOrCallTargetAddress(ins)>=BBL_Address(bbl)&&INS_DirectBranchOrCallTargetAddress(ins)<=INS_Address(ins))
			{
				out<<endl<<"this tainted bbl is a loop"<<endl;
				//BBL_InsertCall(bbl,IPOINT_AFTER,(AFUNPTR)loopBblEnd,IARG_END);
			}
		}
    }// For INS
  }  // For BBL
  }//for enable DTA
} // VOID Trace
VOID HandleAccess (INS ins, BOOL isRead, BOOL *hasSegmentedMemAccess)
{
    UINT32 operandCount = INS_OperandCount (ins);
    UINT32 i, displacement, scale;
    REG baseReg = REG_INVALID(), indexReg = REG_INVALID();
    *hasSegmentedMemAccess = FALSE;
    
    for (i=0; i<operandCount; i++)
    {
        if (INS_OperandIsMemory (ins, i) && 
            (INS_OperandMemorySegmentReg (ins, i) == TESTED_SEG_REG ) &&
            ((isRead && INS_OperandRead (ins, i)) || (!isRead && INS_OperandWritten (ins, i)))
           )
        {
            displacement  = INS_OperandMemoryDisplacement (ins, i);
            baseReg = INS_OperandMemoryBaseReg (ins, i);
            indexReg = INS_OperandMemoryIndexReg (ins, i);
            scale = INS_OperandMemoryScale (ins, i);
            *hasSegmentedMemAccess = TRUE;
            break;
        }
    }
    /*fprintf(trace, "  SegMemAccess-%s (hasSegmentedMemAccess %d) (operand %d) %p %s\n", 
           isRead?"READ":"WRITE", *hasSegmentedMemAccess, i, INS_Address(ins), INS_Disassemble(ins).c_str());*/
    if (baseReg != REG_INVALID())
    {
        if (indexReg != REG_INVALID())
        {
            if (isRead)
            {
                INS_InsertPredicatedCall(
                    ins, IPOINT_BEFORE, (AFUNPTR)AnalyzeSegmentedMemAccessBaseIndexDispl,
                    IARG_INST_PTR,
                    IARG_MEMORYREAD_EA,
                    IARG_UINT32, BASE_INDEX_DISPLACEMENT_ADDRESSING_READ_TYPE,
                    IARG_REG_VALUE, baseReg,
                    IARG_REG_VALUE, indexReg,
                    IARG_UINT32, scale,
                    IARG_UINT32, displacement,
                    IARG_THREAD_ID,
                    IARG_END);
            }
            else
            {
                INS_InsertPredicatedCall(
                    ins, IPOINT_BEFORE, (AFUNPTR)AnalyzeSegmentedMemAccessBaseIndexDispl,
                    IARG_INST_PTR,
                    IARG_MEMORYWRITE_EA,
                    IARG_UINT32, BASE_INDEX_DISPLACEMENT_ADDRESSING_WRITE_TYPE,
                    IARG_REG_VALUE, baseReg,
                    IARG_REG_VALUE, indexReg,
                    IARG_UINT32, scale,
                    IARG_UINT32, displacement,
                    IARG_THREAD_ID,
                    IARG_END);

            }
        }
        else
        {
            if (isRead)
            {
                INS_InsertPredicatedCall(
                    ins, IPOINT_BEFORE, (AFUNPTR)AnalyzeSegmentedMemAccessBaseDispl,
                    IARG_INST_PTR,
                    IARG_MEMORYREAD_EA,
                    IARG_UINT32, BASE_DISPLACEMENT_ADDRESSING_READ_TYPE,
                    IARG_REG_VALUE, baseReg,
                    IARG_UINT32, displacement,
                    IARG_THREAD_ID,
                    IARG_END);
            }
            else
            {
                INS_InsertPredicatedCall(
                    ins, IPOINT_BEFORE, (AFUNPTR)AnalyzeSegmentedMemAccessBaseDispl,
                    IARG_INST_PTR,
                    IARG_MEMORYWRITE_EA,
                    IARG_UINT32, BASE_DISPLACEMENT_ADDRESSING_WRITE_TYPE,
                    IARG_REG_VALUE, baseReg,
                    IARG_UINT32, displacement,
                    IARG_THREAD_ID,
                    IARG_END);
            }
        }
    }
    else if (indexReg != REG_INVALID())
    {
        if (isRead)
        {
            INS_InsertPredicatedCall(
                    ins, IPOINT_BEFORE, (AFUNPTR)AnalyzeSegmentedMemAccessIndexDispl,
                    IARG_INST_PTR,
                    IARG_MEMORYREAD_EA,
                    IARG_UINT32, INDEX_DISPLACEMENT_ADDRESSING_READ_TYPE,
                    IARG_REG_VALUE, indexReg,
                    IARG_UINT32, scale,
                    IARG_UINT32, displacement,
                    IARG_THREAD_ID,
                    IARG_END);
        }
        else
        {
            INS_InsertPredicatedCall(
                ins, IPOINT_BEFORE, (AFUNPTR)AnalyzeSegmentedMemAccessIndexDispl,
                IARG_INST_PTR,
                IARG_MEMORYWRITE_EA,
                IARG_UINT32, INDEX_DISPLACEMENT_ADDRESSING_WRITE_TYPE,
                IARG_REG_VALUE, indexReg,
                IARG_UINT32, scale,
                IARG_UINT32, displacement,
                IARG_THREAD_ID,
                IARG_END);
        }
        
    }
    else if (*hasSegmentedMemAccess)
    {
        if (isRead)
        {
            INS_InsertPredicatedCall(
                ins, IPOINT_BEFORE, (AFUNPTR)AnalyzeSegmentedMemAccessDispl,
                IARG_INST_PTR,
                IARG_MEMORYREAD_EA,
                IARG_UINT32, DISPLACEMENT_ONLY_ADDRESSING_READ_TYPE,
                IARG_UINT32, displacement,
                IARG_THREAD_ID,
                IARG_END);
        }
        else
        {
            INS_InsertPredicatedCall(
                ins, IPOINT_BEFORE, (AFUNPTR)AnalyzeSegmentedMemAccessDispl,
                IARG_INST_PTR,
                IARG_MEMORYWRITE_EA,
                IARG_UINT32, DISPLACEMENT_ONLY_ADDRESSING_WRITE_TYPE,
                IARG_UINT32, displacement,
                IARG_THREAD_ID,
                IARG_END);
        }

    }
}
Example #20
0
// CALLBACKS
void SEMAPHORE::cCMPXCHG(INS &ins)
{
    // CMPXCHG : d'abord une comparaison destination (R ou M) avec 
    // puis 1 MOV selon le resultat de la comparaison
    // Opérande 0 : ModRM:r/m (si reg : regDest)
    // Opérande 1 : reg (dénommé regSrc)
    // CMPXCHG compare opérande 0 avec AL/AX/EAX/RAX
    // Si égal,       ZF = 1 (comme une vraie comparaison) et opérande 1 -> opérande 0 
    // Si différent : ZF = 0 (comme une vraie comparaison) et opérande 0 -> AL/AX/EAX/RAX
    // Dans les arguments des callbacks, il vaut ajouter la valeur de AL/AX/EAX/RAX
    // Et celle du registre dest (cas RR) pour faire la comparaison.
    
    // opérande 1 : regSrc
    REG regSrc = INS_OperandReg(ins, 1);
    UINT32 regSrcSize = getRegSize(regSrc);
    if (!regSrcSize) return;	// registre non suivi
    
    // registre de comparasion avec la destination
    REG cmpReg = REG_INVALID(); // selon la taille, AL/AX/EAX/RAX

    // pointeur vers fonction à appeler
    void (*callback)() = nullptr;
    if (INS_IsMemoryRead(ins)) // CMPXCHG_RM (source 0 = mémoire)
    {
        switch (regSrcSize) 
        {	
        case 1:	callback = (AFUNPTR) sCMPXCHG_RM<8>;  cmpReg = REG_AL; break;
        case 2:	callback = (AFUNPTR) sCMPXCHG_RM<16>; cmpReg = REG_AX; break;
        case 4:	callback = (AFUNPTR) sCMPXCHG_RM<32>; cmpReg = REG_EAX; break;
        #if TARGET_IA32E
        case 8: callback = (AFUNPTR) sCMPXCHG_RM<64>; cmpReg = REG_RAX; break;
        #endif
        }
        INS_InsertCall (ins, IPOINT_BEFORE, callback,
            IARG_THREAD_ID,
            IARG_UINT32, regSrc, // pas besoin de la valeur du registre, le déplacement se fera octet par octet
            IARG_MEMORYREAD_EA, 
            IARG_UINT32,    cmpReg,
            IARG_REG_VALUE, cmpReg,
            IARG_INST_PTR, IARG_END);      
    }
    else // CMPXCHG_RR (source 0 = registre)
    {
        REG regDest = INS_OperandReg(ins, 0); // registre de destination (comparé à AL/AX/EAX/RAX)
        switch (getRegSize(regDest)) 
        {	
        case 0: return; // non suivi en instrumentation
        case 1:	callback = (AFUNPTR) sCMPXCHG_RR<8>;  cmpReg = REG_AL; break;
        case 2:	callback = (AFUNPTR) sCMPXCHG_RR<16>; cmpReg = REG_AX; break;
        case 4:	callback = (AFUNPTR) sCMPXCHG_RR<32>; cmpReg = REG_EAX; break;
        #if TARGET_IA32E
        case 8: callback = (AFUNPTR) sCMPXCHG_RR<64>; cmpReg = REG_RAX; break;
        #endif
        }
        INS_InsertCall (ins, IPOINT_BEFORE, callback,
            IARG_THREAD_ID,
            IARG_UINT32, regSrc, 
            IARG_UINT32, regDest, 
            IARG_REG_VALUE, regDest,// valeur indispendable pour comparaison à RAX
            IARG_UINT32,    cmpReg,
            IARG_REG_VALUE, cmpReg,
            IARG_INST_PTR, IARG_END);     
    }
} // cCMPXCHG
/* Unwind to previous to frame.  Returns 0 if successful, negative
 * number in case of an error. */
int 
unwind(struct unwind_frame_info *frame, int is_ehframe)
{
#define FRAME_REG(r, t) (((t *)frame)[reg_info[r].offs])
	const u32 *fde = NULL, *cie = NULL;
	const u8 *ptr = NULL, *end = NULL;
	unsigned long startLoc = 0, endLoc = 0, cfa;
	unsigned i;
	signed ptrType = -1;
	uleb128_t retAddrReg = 0;
//	struct unwind_table *table;
	void *unwind_table;
	struct local_unwind_table *table;
	struct unwind_state state;
	u64 reg_ptr = 0;


	if (UNW_PC(frame) == 0)
		return -EINVAL;

	if ((table = find_table(UNW_PC(frame)))) {
//		unsigned long tableSize = unwind_table_size;
		unsigned long tableSize = table->size;

		unwind_table = table->address;

		for (fde = unwind_table;
		     tableSize > sizeof(*fde) && tableSize - sizeof(*fde) >= *fde;
		     tableSize -= sizeof(*fde) + *fde,
		     fde += 1 + *fde / sizeof(*fde)) {
			if (!*fde || (*fde & (sizeof(*fde) - 1)))
				break;
			if (is_ehframe && !fde[1])
				continue; /* this is a CIE */
			else if (fde[1] == 0xffffffff)
				continue; /* this is a CIE */
			if ((fde[1] & (sizeof(*fde) - 1))
			    || fde[1] > (unsigned long)(fde + 1)
			                - (unsigned long)unwind_table)
				continue; /* this is not a valid FDE */
			if (is_ehframe)
				cie = fde + 1 - fde[1] / sizeof(*fde);
			else
				cie = unwind_table + fde[1];
			if (*cie <= sizeof(*cie) + 4
			    || *cie >= fde[1] - sizeof(*fde)
			    || (*cie & (sizeof(*cie) - 1))
			    || (cie[1] != 0xffffffff && cie[1])
			    || (ptrType = fde_pointer_type(cie)) < 0) {
				cie = NULL; /* this is not a (valid) CIE */
				continue;
			}
			ptr = (const u8 *)(fde + 2);
			startLoc = read_pointer(&ptr,
			                        (const u8 *)(fde + 1) + *fde,
			                        ptrType);
			endLoc = startLoc
			         + read_pointer(&ptr,
			                        (const u8 *)(fde + 1) + *fde,
			                        ptrType & DW_EH_PE_indirect
			                        ? ptrType
			                        : ptrType & (DW_EH_PE_FORM|DW_EH_PE_signed));
			if (UNW_PC(frame) >= startLoc && UNW_PC(frame) < endLoc)
				break;
			cie = NULL;
		}
	}
	if (cie != NULL) {
		memset(&state, 0, sizeof(state));
		state.cieEnd = ptr; /* keep here temporarily */
		ptr = (const u8 *)(cie + 2);
		end = (const u8 *)(cie + 1) + *cie;
		if ((state.version = *ptr) != 1)
			cie = NULL; /* unsupported version */
		else if (*++ptr) {
			/* check if augmentation size is first (and thus present) */
			if (*ptr == 'z') {
				/* check for ignorable (or already handled)
				 * nul-terminated augmentation string */
				while (++ptr < end && *ptr)
					if (strchr("LPR", *ptr) == NULL)
						break;
			}
			if (ptr >= end || *ptr)
				cie = NULL;
		}
		++ptr;
	}
	if (cie != NULL) {
		/* get code aligment factor */
		state.codeAlign = get_uleb128(&ptr, end);
		/* get data aligment factor */
		state.dataAlign = get_sleb128(&ptr, end);
		if (state.codeAlign == 0 || state.dataAlign == 0 || ptr >= end)
			cie = NULL;
		else {
			retAddrReg = state.version <= 1 ? *ptr++ : get_uleb128(&ptr, end);
			/* skip augmentation */
			if (((const char *)(cie + 2))[1] == 'z')
				ptr += get_uleb128(&ptr, end);
			if (ptr > end
			   || retAddrReg >= ARRAY_SIZE(reg_info)
			   || REG_INVALID(retAddrReg)
			   || reg_info[retAddrReg].width != sizeof(unsigned long))
				cie = NULL;
		}
	}
	if (cie != NULL) {
		state.cieStart = ptr;
		ptr = state.cieEnd;
		state.cieEnd = end;
		end = (const u8 *)(fde + 1) + *fde;
		/* skip augmentation */
		if (((const char *)(cie + 2))[1] == 'z') {
			uleb128_t augSize = get_uleb128(&ptr, end);

			if ((ptr += augSize) > end)
				fde = NULL;
		}
	}
	if (cie == NULL || fde == NULL)
		return -ENXIO;

	state.org = startLoc;
	memcpy(&state.cfa, &badCFA, sizeof(state.cfa));
	/* process instructions */
	if (!processCFI(ptr, end, UNW_PC(frame), ptrType, &state)
	   || state.loc > endLoc
	   || state.regs[retAddrReg].where == Nowhere
	   || state.cfa.reg >= ARRAY_SIZE(reg_info)
	   || reg_info[state.cfa.reg].width != sizeof(unsigned long)
	   || state.cfa.offs % sizeof(unsigned long)) {
		return -EIO;
		}
	/* update frame */
	cfa = FRAME_REG(state.cfa.reg, unsigned long) + state.cfa.offs;
	startLoc = min((unsigned long)UNW_SP(frame), cfa);
	endLoc = max((unsigned long)UNW_SP(frame), cfa);
	if (STACK_LIMIT(startLoc) != STACK_LIMIT(endLoc)) {
		startLoc = min(STACK_LIMIT(cfa), cfa);
		endLoc = max(STACK_LIMIT(cfa), cfa);
	}
#ifndef CONFIG_64BIT
# define CASES CASE(8); CASE(16); CASE(32)
#else
# define CASES CASE(8); CASE(16); CASE(32); CASE(64)
#endif
	for (i = 0; i < ARRAY_SIZE(state.regs); ++i) {
		if (REG_INVALID(i)) {
			if (state.regs[i].where == Nowhere)
				continue;
			return -EIO;
		}
		switch(state.regs[i].where) {
		default:
			break;
		case Register:
			if (state.regs[i].value >= ARRAY_SIZE(reg_info)
			   || REG_INVALID(state.regs[i].value)
			   || reg_info[i].width > reg_info[state.regs[i].value].width){
				return -EIO;
	}
			switch(reg_info[state.regs[i].value].width) {
#define CASE(n) \
			case sizeof(u##n): \
				state.regs[i].value = FRAME_REG(state.regs[i].value, \
				                                const u##n); \
				break
			CASES;
#undef CASE
			default:
				return -EIO;
			}
			break;
		}
	}
	for (i = 0; i < ARRAY_SIZE(state.regs); ++i) {
		if (REG_INVALID(i))
			continue;
		switch(state.regs[i].where) {
		case Nowhere:
			if (reg_info[i].width != sizeof(UNW_SP(frame))
			   || &FRAME_REG(i, __typeof__(UNW_SP(frame)))
			      != &UNW_SP(frame))
				continue;
			UNW_SP(frame) = cfa;
			break;
		case Register:
			switch(reg_info[i].width) {
#define CASE(n) case sizeof(u##n): \
				FRAME_REG(i, u##n) = state.regs[i].value; \
				break
			CASES;
#undef CASE
			default:
				return -EIO;
			}
			break;
		case Value:
			if (reg_info[i].width != sizeof(unsigned long)){
				return -EIO;}
			FRAME_REG(i, unsigned long) = cfa + state.regs[i].value
			                                    * state.dataAlign;
			break;
		case Memory: {
				unsigned long addr = cfa + state.regs[i].value
				                           * state.dataAlign;
				if ((state.regs[i].value * state.dataAlign)
				    % sizeof(unsigned long)
				    || addr < startLoc
				    || addr + sizeof(unsigned long) < addr
				    || addr + sizeof(unsigned long) > endLoc){
					return -EIO;}
				switch(reg_info[i].width) {
#define CASE(n)     case sizeof(u##n): \
					readmem(addr, KVADDR, &reg_ptr,sizeof(u##n), "register", RETURN_ON_ERROR|QUIET); \
					FRAME_REG(i, u##n) = (u##n)reg_ptr;\
					break
				CASES;
#undef CASE
				default:
					return -EIO;
				}
			}
			break;
		}
	}
	return 0;
#undef CASES
#undef FRAME_REG
}
Example #22
0
PyObject* Python_REG_INVALID(PyObject* self, PyObject* args) {
    return Py_BuildValue("L", REG_INVALID());
}
Example #23
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);
}
Example #24
0
VOID Instruction(INS ins, VOID *v)
{
  PIN_LockClient();
  IMG img = IMG_FindByAddress(INS_Address(ins));
  PIN_UnlockClient();
  
  if (IMG_Valid(img) && IMG_IsMainExecutable(img)){
    if (INS_IsCall(ins)){
      INS_InsertCall(
          ins, IPOINT_BEFORE, (AFUNPTR)PrologueAnalysis,
          IARG_ADDRINT, INS_Address(ins),
          IARG_ADDRINT, INS_NextAddress(ins),
          IARG_PTR, new string(INS_Disassemble(ins)),
          IARG_END);
    }
    else if (INS_IsRet(ins)){
      INS_InsertCall(
          ins, IPOINT_BEFORE, (AFUNPTR)EpilogueAnalysis,
          IARG_ADDRINT, INS_Address(ins),
          IARG_ADDRINT, INS_NextAddress(ins),
          IARG_PTR, new string(INS_Disassemble(ins)),
          IARG_END);
    }
    else if (INS_OperandCount(ins) > 1 && INS_MemoryOperandIsWritten(ins, 0)){
      INS_InsertCall(
          ins, IPOINT_BEFORE, (AFUNPTR)WriteMem,
          IARG_ADDRINT, INS_Address(ins),
          IARG_PTR, new string(INS_Disassemble(ins)),
          IARG_UINT32, INS_OperandCount(ins),
          IARG_UINT32, INS_OperandReg(ins, 1),
          IARG_MEMORYOP_EA, 0,
          IARG_END);
    }

    /* Value Set Analysis */
    if (INS_Opcode(ins) == XED_ICLASS_MOV &&
        INS_RegR(ins, 0) == REG_RBP && 
        INS_RegR(ins, 1) == REG_INVALID() && 
        INS_IsMemoryWrite(ins)){
      INS_InsertCall(
          ins, IPOINT_BEFORE, (AFUNPTR)ValueSetAnalysis,
          IARG_ADDRINT, INS_Address(ins),
          IARG_PTR, new string(INS_Disassemble(ins)),
          IARG_REG_VALUE, REG_RSP,
          IARG_REG_VALUE, REG_RBP,
          IARG_MEMORYOP_EA, 0,
          IARG_END);
    }

    /* Analyzes stack overflow */
    if (INS_MemoryOperandIsWritten(ins, 0)){
        INS_InsertCall(
            ins, IPOINT_BEFORE, (AFUNPTR)WriteMemAnalysis,
            IARG_ADDRINT, INS_Address(ins),
            IARG_PTR, new string(INS_Disassemble(ins)),
            IARG_MEMORYOP_EA, 0,
            IARG_END);
      }

    /* Timer Handler - And instruction counter */
    INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)timerHandler, 
      IARG_ADDRINT, INS_Address(INS_Prev(ins)),
      IARG_ADDRINT, INS_Address(ins),
      IARG_ADDRINT, INS_Address(INS_Next(ins)),
      IARG_PTR, new string(INS_Disassemble(ins)),
      IARG_END);

  }
}