// Pin calls this function every time a new instruction is encountered VOID Instruction(INS ins, VOID *v) { string *disptr = new string(INS_Disassemble(ins)); // reads if (INS_IsMemoryRead(ins)) { INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)readMemoryFunc, IARG_FAST_ANALYSIS_CALL, IARG_MEMORYREAD_EA, IARG_MEMORYREAD_PTR, IARG_THREAD_ID, IARG_PTR, disptr, IARG_INST_PTR, IARG_END); } // writes if (INS_IsMemoryWrite(ins)) { INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)writeMemoryFunc, IARG_FAST_ANALYSIS_CALL, IARG_THREAD_ID, IARG_MEMORYWRITE_EA, IARG_MEMORYWRITE_PTR , IARG_INST_PTR, IARG_PTR, disptr, IARG_END); } UINT32 memOperands = INS_MemoryOperandCount(ins); if (!INS_IsVgather(ins) && memOperands) { // OPs for (UINT32 memOp = 0; memOp < memOperands; memOp++) { if (INS_MemoryOperandIsRead(ins, memOp) || INS_MemoryOperandIsWritten(ins, memOp)) { INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)opMemoryFunc, IARG_FAST_ANALYSIS_CALL, IARG_MEMORYOP_EA, memOp, IARG_MEMORYOP_PTR, memOp, IARG_INST_PTR , IARG_PTR, disptr, IARG_END); } } } // READ2 if (INS_HasMemoryRead2(ins)) { INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)read2MemoryFunc, IARG_FAST_ANALYSIS_CALL, IARG_MEMORYREAD_EA, IARG_MEMORYREAD_PTR, IARG_MEMORYREAD2_EA, IARG_MEMORYREAD2_PTR, IARG_THREAD_ID, IARG_PTR, disptr, IARG_CONTEXT, IARG_INST_PTR, IARG_END); } }
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); } }
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 }
VOID Instruction(INS ins, VOID *v) { PIN_LockClient(); IMG img = IMG_FindByAddress(INS_Address(ins)); PIN_UnlockClient(); if (IMG_Valid(img) && IMG_IsMainExecutable(img)){ if (INS_IsCall(ins)){ INS_InsertCall( ins, IPOINT_BEFORE, (AFUNPTR)PrologueAnalysis, IARG_ADDRINT, INS_Address(ins), IARG_ADDRINT, INS_NextAddress(ins), IARG_PTR, new string(INS_Disassemble(ins)), IARG_END); } else if (INS_IsRet(ins)){ INS_InsertCall( ins, IPOINT_BEFORE, (AFUNPTR)EpilogueAnalysis, IARG_ADDRINT, INS_Address(ins), IARG_ADDRINT, INS_NextAddress(ins), IARG_PTR, new string(INS_Disassemble(ins)), IARG_END); } else if (INS_OperandCount(ins) > 1 && INS_MemoryOperandIsWritten(ins, 0)){ INS_InsertCall( ins, IPOINT_BEFORE, (AFUNPTR)WriteMem, IARG_ADDRINT, INS_Address(ins), IARG_PTR, new string(INS_Disassemble(ins)), IARG_UINT32, INS_OperandCount(ins), IARG_UINT32, INS_OperandReg(ins, 1), IARG_MEMORYOP_EA, 0, IARG_END); } /* Value Set Analysis */ if (INS_Opcode(ins) == XED_ICLASS_MOV && INS_RegR(ins, 0) == REG_RBP && INS_RegR(ins, 1) == REG_INVALID() && INS_IsMemoryWrite(ins)){ INS_InsertCall( ins, IPOINT_BEFORE, (AFUNPTR)ValueSetAnalysis, IARG_ADDRINT, INS_Address(ins), IARG_PTR, new string(INS_Disassemble(ins)), IARG_REG_VALUE, REG_RSP, IARG_REG_VALUE, REG_RBP, IARG_MEMORYOP_EA, 0, IARG_END); } /* Analyzes stack overflow */ if (INS_MemoryOperandIsWritten(ins, 0)){ INS_InsertCall( ins, IPOINT_BEFORE, (AFUNPTR)WriteMemAnalysis, IARG_ADDRINT, INS_Address(ins), IARG_PTR, new string(INS_Disassemble(ins)), IARG_MEMORYOP_EA, 0, IARG_END); } /* Timer Handler - And instruction counter */ INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)timerHandler, IARG_ADDRINT, INS_Address(INS_Prev(ins)), IARG_ADDRINT, INS_Address(ins), IARG_ADDRINT, INS_Address(INS_Next(ins)), IARG_PTR, new string(INS_Disassemble(ins)), IARG_END); } }