Ejemplo n.º 1
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();
}
Ejemplo n.º 2
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();
}
Ejemplo n.º 3
0
void convert_load_addr(INS ins, void*  v) {
    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(convert),
                       IARG_MEMORYREAD_EA,
                       IARG_END);
    }
}
Ejemplo n.º 4
0
void SEMAPHORE::cXADD(INS &ins)
{
    // pointeur vers fonction à appeler
    void (*callback)() = nullptr;

    // XADD : opérande 0 est soit mémoire, soit registre, opérande 1 tjs registre
    REG regSrc = INS_OperandReg(ins, 1);
    UINT32 regSrcSize = getRegSize(regSrc);

    if (!regSrcSize) return;    // registre non géré en marquage
    else if (INS_OperandIsMemory(ins, 0)) // XADD_M (opérande 0 = mémoire)
    {
        switch (regSrcSize) 
        {	
        case 1:	callback = (AFUNPTR) sXADD_M<8>;  break;
        case 2:	callback = (AFUNPTR) sXADD_M<16>;  break;
        case 4:	callback = (AFUNPTR) sXADD_M<32>;  break;
        #if TARGET_IA32E
        case 8: callback = (AFUNPTR) sXADD_M<64>;  break;
        #endif
        }
        INS_InsertCall (ins, IPOINT_BEFORE, callback,
            IARG_THREAD_ID,
            IARG_UINT32,    regSrc,
            IARG_REG_VALUE, regSrc,
            IARG_MEMORYWRITE_EA, 
            IARG_INST_PTR, IARG_END); 
    }
    else  // XADD_R (opérande 0 = registre)
    {
        REG regDest = INS_OperandReg(ins, 0);
        switch (getRegSize(regDest)) 
        {	
        case 1:	callback = (AFUNPTR) sXADD_R<8>;  break;
        case 2:	callback = (AFUNPTR) sXADD_R<16>;  break;
        case 4:	callback = (AFUNPTR) sXADD_R<32>;  break;
        #if TARGET_IA32E
        case 8: callback = (AFUNPTR) sXADD_R<64>;  break;
        #endif
        }
        INS_InsertCall (ins, IPOINT_BEFORE, callback,
            IARG_THREAD_ID,
            IARG_UINT32,    regSrc,
            IARG_REG_VALUE, regSrc,
            IARG_UINT32,    regDest,
            IARG_REG_VALUE, regDest,
            IARG_INST_PTR, IARG_END); 
    }
} // cXADD
void processMemoryWriteInstruction(INS ins, const char* imageName)
{
	UINT32 memoryOperandCount = INS_MemoryOperandCount(ins);
	for (UINT32 i = 0; i < memoryOperandCount; ++i)
	{
		if (INS_MemoryOperandIsWritten(ins, i) && INS_OperandIsMemory(ins, i))
		{
			INS_InsertPredicatedCall(ins, IPOINT_BEFORE, (AFUNPTR) Write,
			                         IARG_THREAD_ID, IARG_MEMORYOP_EA, i, IARG_REG_VALUE,
			                         REG_STACK_PTR, //pass current stack ptr
			                         IARG_PTR, imageName, IARG_INST_PTR, IARG_MEMORYWRITE_SIZE,
			                         IARG_CALL_ORDER, CALL_ORDER_FIRST + 30, IARG_END);
		}
	}
}
Ejemplo n.º 6
0
void taint_ins(INS ins, void *v)
{
    uint32_t opcode = INS_Opcode(ins);
    uint32_t opcount = INS_OperandCount(ins);

    // the generic stuff only supports up to 5 operands
    if(opcount < 6 && taint_handler_count[opcode] != 0) {
        // first we have to build up the flags, which is kind of expensive.
        uint32_t flags = 0;

        for (uint32_t i = 0; i < opcount; i++) {
            uint32_t op_flag = 0;
            if(INS_OperandIsMemory(ins, i) != 0) {
                op_flag |= T_MEM;
            }
            if(INS_OperandIsAddressGenerator(ins, i) != 0) {
                op_flag |= T_ADR;
            }
            if(INS_OperandIsReg(ins, i) != 0) {
                op_flag |= T_REG;
            }
            if(INS_OperandIsImmediate(ins, i) != 0) {
                op_flag |= T_IMM;
            }
            if(INS_OperandRead(ins, i) != 0) {
                op_flag |= T_RD;
            }
            if(INS_OperandWritten(ins, i) != 0) {
                op_flag |= T_WR;
            }
            flags |= op_flag << (6 * i);
        }

        for (uint32_t i = 0; i < taint_handler_count[opcode]; i++) {
            if(taint_handler_flag[opcode][i] == flags) {
                taint_prop_handle(ins, taint_handler_fn[opcode][i],
                    taint_handler_args[opcode][i]);
                return;
            }
        }
    }
}
Ejemplo n.º 7
0
VOID EmulateLoad(INS ins, VOID* v)
{
    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);
        
        INS_Delete(ins);
    }
}
Ejemplo n.º 8
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;
    }
}
Ejemplo n.º 9
0
VOID Instruction(INS ins, VOID *v)
{
    INT32 count = INS_OperandCount(ins);
    
    for (INT32 i = 0; i < 5; i++)
    {
        if (i >= count)
        {
            dis << "        ";
            continue;
        }
        
        else if (INS_OperandIsAddressGenerator(ins, i))
            dis << "AGN";
        else if (INS_OperandIsMemory(ins, i))
        {
            dis << "MEM";
            dis << " " << REG_StringShort(INS_OperandMemoryBaseReg(ins, i));
        }
        else if (INS_OperandIsReg(ins, i))
            dis << "REG";
        else if (INS_OperandIsImmediate(ins, i))
            dis << "IMM";
        else if (INS_OperandIsDisplacement(ins, i))
            dis << "DSP";
        else
            dis << "XXX";

        if (INS_OperandIsImplicit(ins, i))
            dis << ":IMP ";
        else
            dis << "     ";
                
        
    }

    dis << INS_Disassemble(ins) << endl;
}
Ejemplo n.º 10
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);
    }
}
Ejemplo n.º 11
0
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);
        }

    }
}
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);
}
Ejemplo n.º 13
0
VOID Emulate2Address(OPCODE opcode,
                     INS ins,
                     ADDRINT (*OpRM)(ADDRINT,ADDRINT*),
                     ADDRINT (*OpRV)(ADDRINT,ADDRINT),
                     VOID (*OpMV)(ADDRINT*,ADDRINT))
{
    if (INS_Opcode(ins) != opcode)
        return;
    if (INS_OperandIsMemory(ins, 0)
        // This will filter out segment overrides
        && INS_IsMemoryWrite(ins))
    {
        if (INS_OperandIsReg(ins, 1)
            && REG_is_gr(INS_OperandReg(ins, 1)))
        {
            // Source register, dst memory
            INS_InsertCall(ins,
                           IPOINT_BEFORE,
                           AFUNPTR(OpMV),
                           IARG_MEMORYWRITE_EA,
                           IARG_REG_VALUE,
                           INS_OperandReg(ins, 1),
                           IARG_END);
            INS_Delete(ins);
        }
        else
        {
            ASSERTX(!INS_OperandIsMemory(ins, 1));
        }
    }
    else if (INS_OperandIsReg(ins, 0))
    {
    	REG dst = INS_OperandReg(ins, 0);
    	if ((dst == REG_SEG_GS) || (dst == REG_SEG_FS))
    		return;
        if (INS_OperandIsReg(ins, 1))
        {
            // Source register, dst register
            INS_InsertCall(ins,
                           IPOINT_BEFORE,
                           AFUNPTR(OpRV),
                           IARG_REG_VALUE,
                           INS_OperandReg(ins, 0),
                           IARG_REG_VALUE,
                           INS_OperandReg(ins, 1),
                           IARG_RETURN_REGS,
                           INS_OperandReg(ins, 0),
                           IARG_END);
            INS_Delete(ins);
        }
        else if (INS_OperandIsMemory(ins, 1)
                 // This will filter out segment overrides
                 && INS_IsMemoryRead(ins))
        {
            // Source register, dst register
            INS_InsertCall(ins,
                           IPOINT_BEFORE,
                           AFUNPTR(OpRM),
                           IARG_REG_VALUE,
                           INS_OperandReg(ins, 0),
                           IARG_MEMORYREAD_EA,
                           IARG_RETURN_REGS,
                           INS_OperandReg(ins, 0),
                           IARG_END);
           INS_Delete(ins);
        }
    }
    
#if 0
    if (KnobCount == icount)
        fprintf(stderr,"Last one %s\n",INS_Disassemble(ins).c_str());
    else if (icount > KnobCount)
        return;
    icount++;
#endif

}
Ejemplo n.º 14
0
VOID Instruction(INS ins, VOID *v)
{
    
    if (INS_IsMemoryRead(ins) && !instrumentedReadFromIpWithNoOffset)
    {
        
        BOOL readsFromIpWithNoOffset = FALSE;
        for (UINT32 i = 0; i < INS_OperandCount(ins); i++)
        {
            if (!INS_OperandIsMemory(ins, i))
                continue;
        

            if (INS_OperandMemoryBaseReg(ins, i) == REG_INST_PTR && INS_OperandMemoryDisplacement(ins, i)==0)
            {
                readsFromIpWithNoOffset = TRUE;
                break;
            }
        }
        if (!readsFromIpWithNoOffset)
        {
            return;
        }
        instrumentedReadFromIpWithNoOffset = TRUE; // only instrument one of these
        printf ("Instrumenting [ip] read   %p   %s\n", INS_Address(ins), INS_Disassemble(ins).c_str());
        globalIpOfReadRecordedAtInstrumentationTime = INS_Address(ins);
        globalReadInsSize = INS_Size(ins);
        fflush (stdout);
        INS_InsertCall(ins,IPOINT_BEFORE, 
                       (AFUNPTR)IpReadBefore,
                       IARG_INST_PTR,
                       IARG_MEMORYREAD_EA,
                       IARG_REG_VALUE, REG_INST_PTR,
                       IARG_END);
		INS_InsertCall(ins,IPOINT_AFTER, 
                       (AFUNPTR)IpReadAfter,
                       IARG_REG_VALUE, REG_INST_PTR,
                       IARG_END);
    }
    else if (INS_IsMemoryWrite(ins) && !instrumentedWriteFromIpWithNoOffset)
    {
        /*
        const xed_decoded_inst_t* xedd = INS_XedDec(ins);
        
        xed_reg_enum_t breg1 = xed_decoded_inst_get_base_reg(xedd,0);
        if (breg1== XED_REG_RIP) 
        {
            readsFromIpWithNoOffset = TRUE;
        }
        */
        BOOL writesFromIpWithNoOffset = FALSE;
        for (UINT32 i = 0; i < INS_OperandCount(ins); i++)
        {
            if (!INS_OperandIsMemory(ins, i))
                continue;
        

            if (INS_OperandMemoryBaseReg(ins, i) == REG_INST_PTR && INS_OperandMemoryDisplacement(ins, i)==0)
            {
                writesFromIpWithNoOffset = TRUE;
                break;
            }
        }
        if (!writesFromIpWithNoOffset)
        {
            return;
        }
        instrumentedReadFromIpWithNoOffset = TRUE; // only instrument one of these
        printf ("Instrumenting [ip] write  %p   %s\n", INS_Address(ins), INS_Disassemble(ins).c_str());
        globalIpOfWriteRecordedAtInstrumentationTime = INS_Address(ins);
        globalWriteInsSize = INS_Size(ins);
        fflush (stdout);
        INS_InsertCall(ins,IPOINT_BEFORE, 
                       (AFUNPTR)IpWriteBefore,
                       IARG_INST_PTR,
                       IARG_MEMORYWRITE_EA,
                       IARG_REG_VALUE, REG_INST_PTR,
                       IARG_END);
		INS_InsertCall(ins,IPOINT_AFTER, 
                       (AFUNPTR)IpWriteAfter,
                       IARG_REG_VALUE, REG_INST_PTR,
                       IARG_END);
    }
    

}
Ejemplo n.º 15
0
VOID Instruction(INS ins, VOID *v){
	/**
 	 * INS_InsertCall(INS ins, IPOINT action, AFUNPTR funptr, ...)
 	 *
 	 * insert a call to 'docount' relative to instruction 'ins'
 	 *
 	 * ins: instruction to instrument
 	 * action: specifies before/after, etc. IPOINT_BEFORE is always valid for all instructions.
 	 * funptr: insert a call to funptr.
 	 * ...: list of arguments to pass funptr, terminated with IARG_END
 	 */ 
	//INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)stat_ins, IARG_END);
	InsCount ++;

	//string ins_cat = CATEGORY_StringShort(INS_Category(ins));
	int num_ops = INS_OperandCount(ins);                                //total #operands
    int memOperands = INS_MemoryOperandCount(ins);                      //#mem_operands
    
    string op_string = "";                                              //string to record all operands
    stringstream sstm;                                                  //string stream

    int num_mems = 0;
	for(int ii=0; ii<num_ops; ii++){                                    //iterate each operand
        if(INS_OperandIsImmediate(ins, ii)){                            //immediate
            auto value = INS_OperandImmediate(ins, ii);
            sstm.str("");                                               //empty
            sstm << "$" << value;
            op_string += " " + sstm.str();
        } else if(INS_OperandIsReg(ins, ii)){                           //register
           auto reg = REG_StringShort(INS_OperandReg(ins, ii)); 
           sstm.str("");
           sstm << "%" << reg;
           op_string += " " + sstm.str();
        } else if(INS_OperandIsMemory(ins, ii) && memOperands>0){       //memory
            string mem_type = "memXX";
            if(INS_MemoryOperandIsRead(ins, num_mems)) {
                mem_type = "memR";
            } else if(INS_MemoryOperandIsWritten(ins, num_mems)) {
                mem_type = "memW";
            }

            if(INS_MemoryOperandIsRead(ins, num_mems) && INS_MemoryOperandIsWritten(ins, num_mems)) {
                mem_type = "memRW";
            }

            ++ num_mems;
            op_string += " " + mem_type;
        //true if this operand is a memory reference,
        //Note: this does not include LEA operands.
        } else if(INS_OperandIsMemory(ins, ii) && memOperands==0){      //NOP
            assert(INS_IsNop(ins));
        } else {
            //TRUE if memory operand uses predefined base register and this register can not be changed 
            //Example: movs ds:(esi), es:(edi) There are two fixed operands
            string other_type = "";
            if(INS_OperandIsFixedMemop(ins, ii))
                other_type = "FM";
            //true if this operand is a displacement (e.g. branch offset)
            else if(INS_OperandIsBranchDisplacement(ins, ii))
                other_type = "BD";
            //true if this operand is implied by the opcode (e.g. the stack write in a push instruction)
            else if(INS_OperandIsImplicit(ins, ii))
                other_type = "IM";
            else {
                assert(INS_IsLea(ins));
                other_type = "lea";
            }
            op_string += " " + other_type;
        }
    }

    assert(num_mems == memOperands);
    assert(num_ops <= 6);

    //record ins
    INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)record_ins,
            IARG_THREAD_ID,
            IARG_UINT32,
            INS_Opcode(ins),
            IARG_UINT32, num_ops,
            IARG_PTR, new string(op_string),
            IARG_END);

    if (INS_IsXchg(ins) && INS_OperandReg(ins, 0)==REG_BX && INS_OperandReg(ins, 1)==REG_BX)
    {
        //INS_InsertPredictedCall() is used to call analysis functions.
        //This API function prevents pollution of the memory analysis by calling an analysis function only if a particular
        //instruction is actualy executed, i.e., only if the instruction is executed.
        INS_InsertPredicatedCall(ins, IPOINT_BEFORE, (AFUNPTR)handleHook, IARG_THREAD_ID, IARG_REG_VALUE, REG_GAX,
        #ifdef TARGET_IA32
        IARG_REG_VALUE, REG_GDX,
        #else
        IARG_REG_VALUE, REG_GBX,
        #endif
        IARG_REG_VALUE, REG_GCX, IARG_END);
    }
}
Ejemplo n.º 16
0
VOID instruction(INS ins, void *v) 
{

    UINT32 numOperands = INS_OperandCount(ins);
    int numOpMems = 0;
    for (unsigned int i = 0; i < numOperands; i++) {
        //check number of reads and writes
        if (INS_OperandIsMemory(ins, i))
            numOpMems++;
    }

    if (numOpMems > 2) {
        std::cout << "number of operands = " << numOpMems << std::endl;
    }

    const ADDRINT iaddr = INS_Address(ins);

    UINT32 idx;
   struct PC item;
   item.refs = 0;
   item.miss = 0;
   item.pc = iaddr;
   iCachePC.push_back(item);
   idx = iCachePC.size() - 1;


    INS_InsertPredicatedCall(
            ins, IPOINT_BEFORE, (AFUNPTR) iCacheCount,
            IARG_ADDRINT,
            iaddr,
            IARG_UINT32,
            idx,
            IARG_END);

    if (INS_IsMemoryRead(ins)) {
        struct PC readItem;
        readItem.refs = 0;
        readItem.miss = 0;
        readItem.pc = iaddr;
        readItem.isLoad = 1;
        dCachePC.push_back(readItem);
        UINT32 idx2 = dCachePC.size()-1;
        INS_InsertPredicatedCall(
                ins, IPOINT_BEFORE, (AFUNPTR) dCacheCount,
                IARG_ADDRINT,
                iaddr,
                IARG_MEMORYREAD_EA,
                IARG_MEMORYREAD_SIZE,
                IARG_UINT32,
                idx2,
                IARG_UINT32,
                1,
                IARG_UINT32,
                0,
                IARG_END);

        if (INS_HasMemoryRead2(ins)) {
            INS_InsertPredicatedCall(
                    ins, IPOINT_BEFORE, (AFUNPTR) dCacheCount,
                    IARG_ADDRINT,
                    iaddr,
                    IARG_MEMORYREAD2_EA,
                    IARG_MEMORYREAD_SIZE,
                    IARG_UINT32,
                    idx2,
                    IARG_UINT32,
                    1,
                    IARG_UINT32,
                    1,
                    IARG_END);
        }

    }
    if (INS_IsMemoryWrite(ins)) {
        struct PC writeItem;
        writeItem.refs = 0;
        writeItem.miss = 0;
        writeItem.pc = iaddr;
        writeItem.isLoad = 0;
        dCachePC.push_back(writeItem);
        UINT32 idx2 = dCachePC.size()-1;

         INS_InsertPredicatedCall(
                ins, IPOINT_BEFORE, (AFUNPTR) dCacheCount,
                IARG_ADDRINT,
                iaddr,
                IARG_MEMORYWRITE_EA,
                IARG_MEMORYWRITE_SIZE,
                IARG_UINT32,
                idx2,
                IARG_UINT32,
                0,
                IARG_UINT32,
                0,
                IARG_END);
    }

}
Ejemplo n.º 17
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);
}
Ejemplo n.º 18
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++;

    if (INS_Opcode(ins) == XED_ICLASS_PUSH)
    {
        if (INS_OperandIsImmediate(ins, 0))
        {
            ADDRINT value = INS_OperandImmediate(ins, 0);
            INS_InsertCall(ins, IPOINT_BEFORE,
                AFUNPTR(EmuPushValue),
                IARG_REG_VALUE, REG_STACK_PTR,
                IARG_ADDRINT, value,
                IARG_RETURN_REGS, REG_STACK_PTR, IARG_END);

            INS_Delete(ins);
        }
        else if(INS_OperandIsReg(ins, 0))
        {
            REG reg = INS_OperandReg(ins, 0);
            INS_InsertCall(ins, IPOINT_BEFORE,
                AFUNPTR(EmuPushValue),
                IARG_REG_VALUE, REG_STACK_PTR,
                IARG_REG_VALUE, reg,
                IARG_RETURN_REGS, REG_STACK_PTR, IARG_END);

            INS_Delete(ins);
        }
        else if(INS_OperandIsMemory(ins, 0))
        {
            INS_InsertCall(ins, IPOINT_BEFORE,
                AFUNPTR(EmuPushMem),
                IARG_REG_VALUE, REG_STACK_PTR,
                IARG_MEMORYREAD_EA,
                IARG_RETURN_REGS, REG_STACK_PTR, IARG_END);

            INS_Delete(ins);
        }
        else
        {
            fprintf(stderr, "EmuPush: unsupported operand type (%p:'%s')\n", 
                Addrint2VoidStar(INS_Address(ins)), INS_Disassemble(ins).c_str());
        }
    } 
    else if (INS_Opcode(ins) == XED_ICLASS_POP)
    {
        if(INS_OperandIsReg(ins, 0))
        {
            INS_InsertCall(ins, IPOINT_BEFORE,
                AFUNPTR(EmuPopReg),
                IARG_REG_VALUE, REG_STACK_PTR,
                IARG_REG_REFERENCE, INS_OperandReg(ins, 0),
                IARG_RETURN_REGS, REG_STACK_PTR, IARG_END);

            INS_Delete(ins);
        }
        else if(INS_OperandIsMemory(ins, 0))
        {
            INS_InsertCall(ins, IPOINT_BEFORE,
                AFUNPTR(EmuPopMem),
                IARG_REG_VALUE, REG_STACK_PTR,
                IARG_MEMORYWRITE_EA,
                IARG_RETURN_REGS, REG_STACK_PTR, IARG_END);

            INS_Delete(ins);
        }
        else
        {
            fprintf(stderr, "EmuPop: unsupported operand type (%p:'%s')\n", 
                Addrint2VoidStar(INS_Address(ins)), INS_Disassemble(ins).c_str());
        }
    }
    else if (INS_Opcode(ins) == XED_ICLASS_LEAVE)
    {
        INS_InsertCall(ins, IPOINT_BEFORE,
            AFUNPTR(EmuLeave),
            IARG_REG_VALUE, REG_STACK_PTR,
            IARG_REG_REFERENCE, REG_GBP,
            IARG_RETURN_REGS, REG_STACK_PTR, IARG_END);

        INS_Delete(ins);
    }
    else if (INS_IsCall(ins))
    {
        INS_InsertCall(ins, IPOINT_BEFORE,
            AFUNPTR(EmuCall),
            IARG_ADDRINT, INS_NextAddress(ins),
            IARG_BRANCH_TARGET_ADDR,
            IARG_REG_REFERENCE, REG_STACK_PTR,
            IARG_RETURN_REGS, scratchReg, IARG_END);

        INS_InsertIndirectJump(ins, IPOINT_AFTER, scratchReg);

        INS_Delete(ins);
    }
    else if (INS_IsRet(ins))
    {
        UINT64 imm = 0;
        if (INS_OperandCount(ins) > 0 && INS_OperandIsImmediate(ins, 0))
        {
            imm = INS_OperandImmediate(ins, 0);
        }

        INS_InsertCall(ins, IPOINT_BEFORE,
            AFUNPTR(EmuRet),
            IARG_CALL_ORDER, CALL_ORDER_FIRST,
            IARG_REG_REFERENCE, REG_STACK_PTR,
            IARG_ADDRINT, (ADDRINT)imm,
            IARG_RETURN_REGS, scratchReg, IARG_END);

        INS_InsertIndirectJump(ins, IPOINT_AFTER, scratchReg);

        INS_Delete(ins);
    }
    else if (INS_IsIndirectBranchOrCall(ins))
    {
        // This is not a call (it was checked before) so this is indirect jump
        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);
    }
}