static void InstrumentIns(INS ins, VOID *)
{
    for (UINT32 memIndex = 0;  memIndex < INS_MemoryOperandCount(ins);  memIndex++)
    {
        REG scratchReg = GetScratchReg(memIndex);
        INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(GetMemAddress),
            IARG_MEMORYOP_EA, memIndex,
            IARG_RETURN_REGS, scratchReg,
            IARG_END);
        INS_RewriteMemoryOperand(ins, memIndex, scratchReg); 
    }
}
// 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);
    }
}
Exemple #3
0
// This function is called before every instruction is executed
VOID instrument_routine(RTN rtn, void *ip)
{
    string name = RTN_Name(rtn);
    if(name == "ivan")
    {
        RTN_Open(rtn);
        for (INS ins = RTN_InsHead(rtn); INS_Valid(ins); ins = INS_Next(ins))
        {
            int opCount = INS_OperandCount(ins);

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


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

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

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

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

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

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

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

                            INS_RewriteMemoryOperand(ins, i, scratchReg);
                        }

                    }
                }
            }
        }
        RTN_Close(rtn);
    }
}
void PINshield::avoidEvasion(INS ins){
	
	ADDRINT curEip = INS_Address(ins);
	ProcInfo *pInfo = ProcInfo::getInstance();
	Config *config = Config::getInstance();
	FilterHandler *filterHandler = FilterHandler::getInstance();
	//Filter instructions inside a known library (only graphic dll)
	if(filterHandler->isFilteredLibraryInstruction(curEip)){
		return;
	}
	// Pattern matching in order to avoid the dead path of obsidium
	if(strcmp( (INS_Disassemble(ins).c_str() ),"xor eax, dword ptr [edx+ecx*8+0x4]") == 0){
		MYTEST("Obsidium_evasion");
		REGSET regsIn;
		REGSET_AddAll(regsIn);
		REGSET regsOut;
		REGSET_AddAll(regsOut);
		if(INS_HasFallThrough(ins)){
			INS_InsertCall(ins,IPOINT_AFTER,(AFUNPTR)KillObsidiumDeadPath, IARG_PARTIAL_CONTEXT, &regsIn, &regsOut,IARG_END); 
		}
		}
	// 1 - single instruction detection
	if(config->ANTIEVASION_MODE_INS_PATCHING && this->evasionPatcher.patchDispatcher(ins, curEip)){
		return;
	}
	// 2 - memory read 
	// Checking if there is a read at addresses that the application shouldn't be aware of
	if(config->ANTIEVASION_MODE_SREAD){
		for (UINT32 op = 0; op<INS_MemoryOperandCount(ins); op++) {
			if (INS_MemoryOperandIsRead(ins,op)) {
				//if first read initialize the FakeReadHandler		
				if(firstRead == 0){
					fakeMemH.initFakeMemory();
					firstRead=1;
				}			
				REG scratchReg = GetScratchReg(op);		
				INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(handleRead),
					IARG_INST_PTR,
					IARG_MEMORYOP_EA, op,
					IARG_PTR, &fakeMemH,
					IARG_RETURN_REGS, scratchReg,
					IARG_END);			
				INS_RewriteMemoryOperand(ins, op, scratchReg); 
			}
		}
	}
	//3. memory write filter
	if(config->ANTIEVASION_MODE_SWRITE){	
		for (UINT32 op = 0; op<INS_MemoryOperandCount(ins); op++) {
			if(INS_MemoryOperandIsWritten(ins,op) && INS_IsMov(ins)){
				REG writeReg = GetScratchReg(op);			
				INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(handleWrite),
					IARG_INST_PTR,
					IARG_MEMORYOP_EA, op,
					IARG_PTR, &fakeWriteH,
					IARG_RETURN_REGS, writeReg, // this is an output param
					IARG_END);	
				INS_RewriteMemoryOperand(ins, op, writeReg); 		
			}	
		}	
	}
}