// 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; } } }
// Insert a direct branch over the first mov immediate static VOID insertJump (RTN rtn) { for (INS ins = RTN_InsHead(rtn); INS_Valid(ins); ins = INS_Next(ins)) { if (INS_IsMov(ins) && INS_HasImmediateOperand(ins)) { INS_InsertDirectJump(ins, IPOINT_BEFORE, INS_Address(ins) + INS_Size(ins)); instrumentationCount++; return; } } }
// Insert an indirect branch over the first mov immediate static VOID insertIndirectJump (RTN rtn) { for (INS ins = RTN_InsHead(rtn); INS_Valid(ins); ins = INS_Next(ins)) { if (INS_IsMov(ins) && INS_HasImmediateOperand(ins)) { INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(returnValue), IARG_ADDRINT, INS_Address(ins) + INS_Size(ins), IARG_RETURN_REGS, scratchReg, IARG_END); INS_InsertIndirectJump(ins, IPOINT_BEFORE, scratchReg); instrumentationCount++; return; } } }
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); } } } }