Пример #1
0
VOID InstrumentDivide(INS ins, VOID* v)
{
    cout << "instruction:"<<INS_Mnemonic(ins)<<endl;
    if ((INS_Mnemonic(ins) == "DIV") &&
        (INS_OperandIsReg(ins, 0)))
    {
        INS_InsertCall(ins,
                       IPOINT_BEFORE,
                       AFUNPTR(EmulateIntDivide),
                       IARG_REG_REFERENCE, REG_GDX,
                       IARG_REG_REFERENCE, REG_GAX,
                       IARG_REG_VALUE, REG(INS_OperandReg(ins, 0)),
                       IARG_CONTEXT,
                       IARG_THREAD_ID,
                       IARG_END);
        INS_Delete(ins);
    }
    if ((INS_Mnemonic(ins) == "DIV") &&
        (!INS_OperandIsReg(ins, 0)))
    {
        INS_InsertCall(ins,
                    IPOINT_BEFORE,
                    AFUNPTR(EmulateMemDivide),
                    IARG_REG_REFERENCE, REG_GDX,
                    IARG_REG_REFERENCE, REG_GAX,
                    IARG_MEMORYREAD_EA,
                    IARG_MEMORYREAD_SIZE,
                    IARG_CONTEXT,
                    IARG_THREAD_ID,
                    IARG_END);
        INS_Delete(ins);
   }
        
}
Пример #2
0
VOID delete_int3(INS ins, VOID* v)
{
    if (INS_Opcode(ins) == XED_ICLASS_INT3)
    {
        INS_Delete(ins);
    }
}
// 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_CONTEXT,
                       IARG_MULTI_MEMORYACCESS_EA,
                       IARG_REG_REFERENCE, ymmDest,
                       IARG_REG_REFERENCE, ymmMask,
                       IARG_END);

        INS_InsertFillBuffer(ins, IPOINT_BEFORE, bufId,
                             IARG_MULTI_MEMORYACCESS_EA, 0, IARG_END);

        INS_Delete(ins);
    }
}
// Delete the first mov immediate
static VOID deleteMov (RTN rtn)
{
    for (INS ins = RTN_InsHead(rtn); INS_Valid(ins); ins = INS_Next(ins))
    {
        if (INS_IsMov(ins) && INS_HasImmediateOperand(ins))
        {
            INS_Delete(ins);
            instrumentationCount++;
            return;
        }
    }
}
Пример #5
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);
    }
}
Пример #6
0
VOID FirstInCC(TRACE trace, VOID * v)
{
    if (!test)
        return;
    test = false;

    BBL bbl = TRACE_BblHead(trace);
    while (!BBL_Valid(bbl))
        bbl = BBL_Next(bbl);
    
    INS_Delete(BBL_InsHead(bbl));

    TEST(!TRACE_Original(trace), "TRACE_Original failed");

}
Пример #7
0
VOID EmulateLoad(INS ins, VOID* v)
{
    if (INS_Opcode(ins) == XEDICLASS_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);
    }
}
Пример #8
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);
        }
                
        for (UINT32 memIndex = 0;  
            memIndex < INS_MemoryOperandCount(ins);//each access is 1 MemoryOperand  	                                    
            memIndex++)
        {
                INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(EmuGatherMemOp),
                            IARG_UINT32, memIndex,
                            IARG_MEMORYOP_EA, memIndex,
                            IARG_MEMORYOP_MASKED_ON, memIndex,
                            IARG_UINT32, INS_MemoryOperandSize(ins, memIndex),
                            IARG_UINT32, INS_MemoryOperandIsRead(ins, memIndex),
                            IARG_REG_REFERENCE, ymmDest,
                            IARG_BOOL, REG_is_ymm(INS_OperandReg(ins, 0)),
                            IARG_END);
                REG scratchReg = GetScratchReg(memIndex);
                INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(ManipulateMemAddress),
                               IARG_MEMORYOP_EA, memIndex,
                               IARG_RETURN_REGS, scratchReg,
                               IARG_END);
                INS_RewriteMemoryOperand(ins, memIndex, scratchReg); 
        }

        INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)EmuGatherFinal,
                        IARG_REG_REFERENCE, ymmDest,
                        IARG_REG_REFERENCE, ymmMask,
                        IARG_END);
        INS_Delete(ins);
    }
}
Пример #9
0
// Pin calls this function every time a new instruction is encountered
VOID Instruction(INS ins, VOID *v)
{
	//get the address of the current instruction
	ADDRINT address = INS_Address(ins);
	//get the string rapresentation of the address
	string addr = StringFromAddrint(address);
	//if we reach the address of the conditional jump (discover by hand with immunity)
	//we substitute this instruction with an uncoditional jump in order o force the execution path
	if(addr.compare("0x00411a10") == 0){
		//get the jmp target address
		ADDRINT tgt = INS_DirectBranchOrCallTargetAddress(ins);
		string addr2 = StringFromAddrint(tgt);
		//insert the incoditional jmp
		INS_InsertDirectJump(ins, IPOINT_BEFORE, tgt); 
		//fprintf(file, "%s\n", addr2.c_str()); 
		//remove the conditional jmp instruction
		INS_Delete(ins);
	}
	

}
Пример #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);
    }
}
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);
}
Пример #12
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

}
Пример #13
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);
    }
}