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); } }
// 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, ®sIn, ®sOut,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); } } } }