VOID Instruction(INS ins, void *v) { if( INS_IsRet(ins) ) { INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) inc_return, IARG_BRANCH_TAKEN, IARG_END); } else if( INS_IsSyscall(ins) ) { INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) inc_syscall, IARG_BRANCH_TAKEN, IARG_END); } else if (INS_IsDirectBranchOrCall(ins)) { if( INS_IsCall(ins) ) INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) inc_call, IARG_BRANCH_TAKEN, IARG_END); else INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) inc_branch, IARG_BRANCH_TAKEN, IARG_END); } else if( INS_IsIndirectBranchOrCall(ins) ) { if( INS_IsCall(ins) ) INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) inc_call_indirect, IARG_BRANCH_TAKEN, IARG_END); else INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) inc_branch_indirect, IARG_BRANCH_TAKEN, IARG_END); } }
VOID Instruction(INS ins, VOID *v) { //if (RTN_Valid(INS_Rtn(ins)) && RTN_Name(INS_Rtn(ins)) == "__SEH_epilog4") { // cerr << "image " << IMG_Name(SEC_Img(RTN_Sec(INS_Rtn(ins)))) << endl; //} if ( leaflag && INS_IsLea(ins) ) { INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(LeaAdd), IARG_THREAD_ID, IARG_REG_VALUE, REG_STACK_PTR, IARG_INST_PTR, IARG_REG_VALUE, REG_GBP, IARG_END); } if ( INS_IsBranch(ins) && !(INS_IsCall(ins)) && !(INS_IsRet(ins)) ) { INS_InsertCall(ins, IPOINT_TAKEN_BRANCH, AFUNPTR(Branch), IARG_THREAD_ID, IARG_REG_VALUE, REG_STACK_PTR, IARG_BRANCH_TARGET_ADDR, IARG_INST_PTR, IARG_END); } else if (INS_IsRet(ins)) { INS prev = INS_Prev(ins); //cout<< "CALL TO RET" << endl; INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(Ret), IARG_THREAD_ID, IARG_REG_VALUE, REG_STACK_PTR, IARG_BRANCH_TARGET_ADDR, IARG_INST_PTR, IARG_UINT32, (INS_Valid(prev) && INS_Opcode(prev) == XED_CATEGORY_PUSH), IARG_END); } else if (INS_IsCall(ins)) { //cout << "CALL TO CALL" << endl; INS_InsertCall(ins, IPOINT_TAKEN_BRANCH, AFUNPTR(Call), IARG_THREAD_ID, IARG_REG_VALUE, REG_STACK_PTR, IARG_BRANCH_TARGET_ADDR, IARG_INST_PTR, IARG_END); } else if (INS_IsMemoryWrite(ins)) { //cout<< "CALL TO MEWRITE" << endl; INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(MemWrite), IARG_THREAD_ID, IARG_MEMORYWRITE_EA, IARG_END); } }
VOID Instruction(INS ins, VOID *v) { if (!init) Commence(); if (INS_IsCall(ins)) { if (INS_IsDirectCall(ins)) { ADDRINT addr = INS_DirectBranchOrCallTargetAddress(ins); FID fid = fn_lookup_by_address(addr); INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) fn_call, IARG_CONST_CONTEXT, IARG_UINT32, fid, IARG_BOOL, false, IARG_END); } else { INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) fn_icall, IARG_CONST_CONTEXT, IARG_BRANCH_TARGET_ADDR, IARG_BOOL, false, IARG_END); } } if (INS_IsIndirectBranchOrCall(ins)) { if (!INS_IsCall(ins)) { INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) fn_icall, IARG_CONST_CONTEXT, IARG_BRANCH_TARGET_ADDR, IARG_BOOL, true, IARG_END); } } if (INS_IsRet(ins)) { INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) fn_ret, IARG_CONST_CONTEXT, IARG_END); } return; }
VOID Trace(TRACE trace, VOID *v) { for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)) { INS tail = BBL_InsTail(bbl); if( INS_IsCall(tail) ) { INS_InsertCall(tail, IPOINT_BEFORE, AFUNPTR(do_call_indirect), IARG_BRANCH_TARGET_ADDR, IARG_BRANCH_TAKEN, IARG_END); } else { // sometimes code is not in an image RTN rtn = TRACE_Rtn(trace); // also track stup jumps into share libraries if( RTN_Valid(rtn) && !INS_IsDirectBranchOrCall(tail) && ".plt" == SEC_Name( RTN_Sec( rtn ) )) { INS_InsertCall(tail, IPOINT_BEFORE, AFUNPTR(do_call_indirect), IARG_BRANCH_TARGET_ADDR, IARG_BRANCH_TAKEN, IARG_END); } } } }
/** * Converts a PIN instruction object into a disassembled string. **/ std::string dumpInstruction(INS ins) { std::stringstream ss; ADDRINT address = INS_Address(ins); // Generate address and module information ss << "0x" << setfill('0') << setw(8) << uppercase << hex << address << "::" << getModule(address) << " "; // Generate instruction byte encoding for (int i=0;i<INS_Size(ins);i++) { ss << setfill('0') << setw(2) << (((unsigned int) *(unsigned char*)(address + i)) & 0xFF) << " "; } for (int i=INS_Size(ins);i<8;i++) { ss << " "; } // Generate diassembled string ss << INS_Disassemble(ins); // Look up call information for direct calls if (INS_IsCall(ins) && INS_IsDirectBranchOrCall(ins)) { ss << " -> " << RTN_FindNameByAddress(INS_DirectBranchOrCallTargetAddress(ins)); } return ss.str(); }
/* Instrumentation of each instruction * that uses a memory operand */ VOID Instruction(INS ins, VOID *v) { trace_enter(); if (!INS_IsStackRead(ins)) { for (UINT32 memopIdx = 0; memopIdx < INS_MemoryOperandCount(ins); memopIdx++) { if (INS_MemoryOperandIsWritten(ins, memopIdx)) { INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) update_stack_heap_region, IARG_CONST_CONTEXT, IARG_MEMORYOP_EA, memopIdx, IARG_END); UINT32 opIdx = INS_MemoryOperandIndexToOperandIndex(ins, memopIdx); REG base_reg = INS_OperandMemoryBaseReg(ins, opIdx); if (base_reg != REG_INVALID()) { INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) check_parameter_out, IARG_REG_VALUE, base_reg, IARG_END); } } } } if (INS_IsCall(ins)) { if (INS_IsDirectCall(ins)) { ADDRINT addr = INS_DirectBranchOrCallTargetAddress(ins); FID fid = fn_lookup_by_address(addr); INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) fn_call, IARG_CONST_CONTEXT, IARG_UINT32, fid, IARG_END); } else { INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) fn_indirect_call, IARG_CONST_CONTEXT, IARG_BRANCH_TARGET_ADDR, IARG_END); } } if (INS_IsRet(ins)) { INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) fn_ret, IARG_CONST_CONTEXT, IARG_END); } trace_leave(); }
void InstructionTrace(INS ins, void* v) { // check if we just received a snapshot request bool snapshotStatus = CheckSnapshotEvent(); if (snapshotStatus) { // We just detected a monitoring change! Take a memory snapshot now TakeSnapshot(); // reset the event DisableSnapshotEvent(); } // check the monitoring event if we should still be monitoring or not bool monitoringStatus = CheckMonitoringEvent(); if (!monitoringStatus) { return; } instruction_trace trace; trace.tid = PIN_GetTid(); trace.address = INS_Address(ins); memset(trace.library_name, 0, 260); std::string libraryName; if (CHECK_LIBRARY_NAMES && GetLibraryName(trace.address, libraryName)) { snprintf(trace.library_name, sizeof(trace.library_name), "%s", libraryName.c_str()); } if (INS_IsCall(ins) == true) { trace.execution_depth = executionDepth++; } else if (INS_IsRet(ins) == true) { trace.execution_depth = executionDepth--; } else trace.execution_depth = executionDepth; trace.instruction_count = instructionCount++; #ifdef TARGET_WINDOWS trace.execution_time = WINDOWS::GetTickCount(); #else timeval time; gettimeofday(&time, NULL); unsigned long millis = (time.tv_sec * 1000) + (time.tv_usec / 1000); trace.execution_time = millis; #endif LogStruct(trace); }
VOID Instruction(INS ins, void *v) { // The subcases of direct branch and indirect branch are // broken into "call" or "not call". Call is for a subroutine // These are left as subcases in case the programmer wants // to extend the statistics to see how sub cases of branches behave if( INS_IsRet(ins) ) { INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) br_predict, IARG_INST_PTR, IARG_BRANCH_TAKEN, IARG_END); } else if( INS_IsSyscall(ins) ) { INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) br_predict, IARG_INST_PTR, IARG_BRANCH_TAKEN, IARG_END); } else if (INS_IsDirectBranchOrCall(ins)) { if( INS_IsCall(ins) ) { INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) br_predict, IARG_INST_PTR, IARG_BRANCH_TAKEN, IARG_END); } else { INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) br_predict, IARG_INST_PTR, IARG_BRANCH_TAKEN, IARG_END); } } else if( INS_IsIndirectBranchOrCall(ins) ) { if( INS_IsCall(ins) ) { INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) br_predict, IARG_INST_PTR, IARG_BRANCH_TAKEN, IARG_END); } else { INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) br_predict, IARG_INST_PTR, IARG_BRANCH_TAKEN, IARG_END); } } }
// determines whether or not the instruction is a call VOID Instruction(INS ins, VOID *v) { if (INS_IsCall(ins)) { INS_InsertPredicatedCall( ins, IPOINT_BEFORE, (AFUNPTR)RecordCall, IARG_INST_PTR, IARG_BRANCH_TARGET_ADDR, IARG_END); } }
void trace (TRACE trace, void *v) { for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)) { INS tail = BBL_InsTail(bbl); if (INS_IsRet(tail)) { INS_InsertCall(tail, IPOINT_BEFORE, AFUNPTR(before_return), IARG_THREAD_ID, IARG_REG_VALUE, REG_ESP, IARG_END); } else if (INS_IsCall(tail)) { INS_InsertCall(tail, IPOINT_BEFORE, AFUNPTR(before_call), IARG_THREAD_ID, IARG_REG_VALUE, REG_ESP, IARG_ADDRINT, INS_NextAddress(tail), IARG_BRANCH_TARGET_ADDR, IARG_END); } } }
//-------------------------------------------------------------------------------------- VOID Trace(TRACE TraceInfo, VOID *v) { // Visit every basic block in the trace for (BBL Bbl = TRACE_BblHead(TraceInfo); BBL_Valid(Bbl); Bbl = BBL_Next(Bbl)) { // Forward pass over all instructions in bbl for (INS Ins = BBL_InsHead(Bbl); INS_Valid(Ins); Ins = INS_Next(Ins)) { // check for the CALL if (INS_IsCall(Ins)) { INS_InsertCall( Ins, IPOINT_BEFORE, (AFUNPTR)InstCallHandler, IARG_INST_PTR, IARG_BRANCH_TARGET_ADDR, IARG_END ); } // check for the RET if (INS_IsRet(Ins)) { INS_InsertCall( Ins, IPOINT_BEFORE, (AFUNPTR)InstRetHandler, IARG_INST_PTR, IARG_END ); } } // Insert a call to CountBbl() before every basic bloc, passing the number of instructions BBL_InsertCall( Bbl, IPOINT_BEFORE, (AFUNPTR)CountBbl, IARG_INST_PTR, (UINT32)IARG_UINT32, BBL_Size(Bbl), IARG_UINT32, BBL_NumIns(Bbl), 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++; // 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); } }
VOID Instruction(INS ins, VOID *v) { ADDRINT nextIns; if (INS_IsRet(ins)) { INS prev = INS_Prev(ins); INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(Ret), IARG_THREAD_ID, IARG_REG_VALUE, REG_STACK_PTR, IARG_BRANCH_TARGET_ADDR, IARG_INST_PTR, IARG_UINT32, (INS_Valid(prev) && INS_Opcode(prev) == XED_CATEGORY_PUSH), IARG_END); } else if (INS_IsCall(ins)) { nextIns = INS_NextAddress(ins); INS_InsertCall(ins, IPOINT_TAKEN_BRANCH, AFUNPTR(Call), IARG_THREAD_ID, IARG_REG_VALUE, REG_STACK_PTR, IARG_BRANCH_TARGET_ADDR, IARG_INST_PTR, IARG_ADDRINT, nextIns, IARG_END); } else if (INS_IsMemoryWrite(ins)) { INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(MemWrite), IARG_THREAD_ID, IARG_MEMORYWRITE_EA, IARG_INST_PTR, IARG_END); } }
VOID Ins(INS ins, VOID *v) { if (!INS_IsCall(ins)) return; if (foobarAddress != 0 && INS_IsDirectBranchOrCall(ins) && INS_DirectBranchOrCallTargetAddress(ins) == foobarAddress) { TraceFile << "Instrument call to foobar" << endl; INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(FoobarArgs), IARG_G_ARG0_CALLER, IARG_G_ARG1_CALLER, IARG_END); } static BOOL first = true; if (!first) return; first = false; INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(CallArgs), IARG_G_ARG0_CALLER, IARG_END); }
VOID Trace(TRACE trace, VOID *v) { const BOOL print_args = KnobPrintArgs.Value(); for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)) { INS tail = BBL_InsTail(bbl); if( INS_IsCall(tail) ) { if( INS_IsDirectBranchOrCall(tail) ) { const ADDRINT target = INS_DirectBranchOrCallTargetAddress(tail); if( print_args ) { INS_InsertPredicatedCall(tail, IPOINT_BEFORE, AFUNPTR(do_call_args), IARG_PTR, Target2String(target), IARG_G_ARG0_CALLER, IARG_END); } else { INS_InsertPredicatedCall(tail, IPOINT_BEFORE, AFUNPTR(do_call), IARG_PTR, Target2String(target), IARG_END); } } else { if( print_args ) { INS_InsertCall(tail, IPOINT_BEFORE, AFUNPTR(do_call_args_indirect), IARG_BRANCH_TARGET_ADDR, IARG_BRANCH_TAKEN, IARG_G_ARG0_CALLER, IARG_END); } else { INS_InsertCall(tail, IPOINT_BEFORE, AFUNPTR(do_call_indirect), IARG_BRANCH_TARGET_ADDR, IARG_BRANCH_TAKEN, IARG_END); } } } else { // sometimes code is not in an image RTN rtn = TRACE_Rtn(trace); // also track stup jumps into share libraries if( RTN_Valid(rtn) && !INS_IsDirectBranchOrCall(tail) && ".plt" == SEC_Name( RTN_Sec( rtn ) )) { if( print_args ) { INS_InsertCall(tail, IPOINT_BEFORE, AFUNPTR(do_call_args_indirect), IARG_BRANCH_TARGET_ADDR, IARG_BRANCH_TAKEN, IARG_G_ARG0_CALLER, IARG_END); } else { INS_InsertCall(tail, IPOINT_BEFORE, AFUNPTR(do_call_indirect), IARG_BRANCH_TARGET_ADDR, IARG_BRANCH_TAKEN, IARG_END); } } } } }
// ------------------------------------------------------------- // Trace instrumentation function // ------------------------------------------------------------- void I_Trace(TRACE trace, void *v) { BOOL isPLT = IsPLT(TRACE_Rtn(trace)); #if DEBUG_INS printf("-- Instrumenting trace %X of function %s\n", TRACE_Address(trace), RTN_Valid(TRACE_Rtn(trace)) ? RTN_Name(TRACE_Rtn(trace)).c_str() : "<unknown_routine>"); #endif // scan BBLs within the current trace for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)) { // instrument memory reads and writes for(INS ins = BBL_InsHead(bbl); INS_Valid(ins); ins = INS_Next(ins)) Instruction(ins); INS tail = BBL_InsTail(bbl); // skip system calls if ( INS_IsSyscall(tail) ) continue; // instrument .plt stub calls if ( isPLT ) { #if DEBUG_INS printf(" > .plt stub call\n"); #endif if (gSetup.callingSite) { if (gSetup.memBuf) INS_InsertCall(tail, IPOINT_BEFORE, (AFUNPTR)A_ProcessIndirectCallCSBuf, IARG_FAST_ANALYSIS_CALL, IARG_INST_PTR, IARG_BRANCH_TARGET_ADDR, IARG_REG_VALUE, REG_STACK_PTR, IARG_THREAD_ID, IARG_CONTEXT, IARG_END); else INS_InsertCall(tail, IPOINT_BEFORE, (AFUNPTR)A_ProcessIndirectCallCS, IARG_FAST_ANALYSIS_CALL, IARG_INST_PTR, IARG_BRANCH_TARGET_ADDR, IARG_REG_VALUE, REG_STACK_PTR, IARG_THREAD_ID, IARG_END); } else { if (gSetup.memBuf) INS_InsertCall(tail, IPOINT_BEFORE, (AFUNPTR)A_ProcessIndirectCallBuf, IARG_FAST_ANALYSIS_CALL, IARG_BRANCH_TARGET_ADDR, IARG_REG_VALUE, REG_STACK_PTR, IARG_THREAD_ID, IARG_CONTEXT, IARG_END); else INS_InsertCall(tail, IPOINT_BEFORE, (AFUNPTR)A_ProcessIndirectCall, IARG_FAST_ANALYSIS_CALL, IARG_BRANCH_TARGET_ADDR, IARG_REG_VALUE, REG_STACK_PTR, IARG_THREAD_ID, IARG_END); } continue; } // instrument all calls and returns if ( INS_IsCall(tail) ) { // direct call if( INS_IsDirectBranchOrCall(tail) ) { // get target address ADDRINT target = Target2FunAddr(INS_DirectBranchOrCallTargetAddress(tail)); #if DEBUG_INS printf(" > Direct call to %s\n", Target2RtnName(target).c_str()); #endif // instrument direct call: target address determined here if (gSetup.callingSite) { if (gSetup.memBuf) INS_InsertPredicatedCall(tail, IPOINT_BEFORE, (AFUNPTR)A_ProcessDirectCallCSBuf, IARG_FAST_ANALYSIS_CALL, IARG_INST_PTR, IARG_ADDRINT, target, IARG_REG_VALUE, REG_STACK_PTR, IARG_THREAD_ID, IARG_CONTEXT, IARG_END); else INS_InsertPredicatedCall(tail, IPOINT_BEFORE, (AFUNPTR)A_ProcessDirectCallCS, IARG_FAST_ANALYSIS_CALL, IARG_INST_PTR, IARG_ADDRINT, target, IARG_REG_VALUE, REG_STACK_PTR, IARG_THREAD_ID, IARG_END); } else { if (gSetup.memBuf) INS_InsertPredicatedCall(tail, IPOINT_BEFORE, (AFUNPTR)A_ProcessDirectCallBuf, IARG_FAST_ANALYSIS_CALL, IARG_ADDRINT, target, IARG_REG_VALUE, REG_STACK_PTR, IARG_THREAD_ID, IARG_CONTEXT, IARG_END); else INS_InsertPredicatedCall(tail, IPOINT_BEFORE, (AFUNPTR)A_ProcessDirectCall, IARG_FAST_ANALYSIS_CALL, IARG_ADDRINT, target, IARG_REG_VALUE, REG_STACK_PTR, IARG_THREAD_ID, IARG_END); } } // indirect call: target address determined at call time else { #if DEBUG_INS printf(" > Indirect call\n"); #endif // instrument indirect call if (gSetup.callingSite) { if (gSetup.memBuf) INS_InsertPredicatedCall(tail, IPOINT_BEFORE, (AFUNPTR)A_ProcessIndirectCallCSBuf, IARG_FAST_ANALYSIS_CALL, IARG_INST_PTR, IARG_BRANCH_TARGET_ADDR, IARG_REG_VALUE, REG_STACK_PTR, IARG_THREAD_ID, IARG_CONTEXT, IARG_END); else INS_InsertPredicatedCall(tail, IPOINT_BEFORE, (AFUNPTR)A_ProcessIndirectCallCS, IARG_FAST_ANALYSIS_CALL, IARG_INST_PTR, IARG_BRANCH_TARGET_ADDR, IARG_REG_VALUE, REG_STACK_PTR, IARG_THREAD_ID, IARG_END); } else { if (gSetup.memBuf) INS_InsertPredicatedCall(tail, IPOINT_BEFORE, (AFUNPTR)A_ProcessIndirectCallBuf, IARG_FAST_ANALYSIS_CALL, IARG_BRANCH_TARGET_ADDR, IARG_REG_VALUE, REG_STACK_PTR, IARG_THREAD_ID, IARG_CONTEXT, IARG_END); else INS_InsertPredicatedCall(tail, IPOINT_BEFORE, (AFUNPTR)A_ProcessIndirectCall, IARG_FAST_ANALYSIS_CALL, IARG_BRANCH_TARGET_ADDR, IARG_REG_VALUE, REG_STACK_PTR, IARG_THREAD_ID, IARG_END); } } continue; } if ( INS_IsRet(tail) ) { #if DEBUG_INS printf(" > return\n"); #endif if (gSetup.memBuf) INS_InsertPredicatedCall(tail, IPOINT_BEFORE, (AFUNPTR)A_ProcessReturnBuf, IARG_FAST_ANALYSIS_CALL, IARG_REG_VALUE, REG_STACK_PTR, IARG_THREAD_ID, IARG_CONTEXT, IARG_END); else INS_InsertPredicatedCall(tail, IPOINT_BEFORE, (AFUNPTR)A_ProcessReturn, IARG_FAST_ANALYSIS_CALL, IARG_REG_VALUE, REG_STACK_PTR, IARG_THREAD_ID, IARG_END); } } }
// Pin calls this function before a code sequence is executed for the first time VOID TraceCalls(INS ins, VOID *v) { // If we don't have a proper config, we cannot instrument anything if (config == NULL) { return; } ADDRINT addr = INS_Address(ins); IMG img = IMG_FindByAddress(addr); // We are interested only calls from the JITted code. That code is not part of any valid image if (IMG_Valid(img) && img != config->img) { return; } // We don't know the origins of the calls (only the targets) so we need to instrument every call if (INS_IsCall(ins)) { bool ok = false; if (INS_RegRContain(ins, REG_EAX) || INS_RegRContain(ins, REG_EDX)) { ok = true; } else if (INS_IsDirectCall(ins)) { ADDRINT target_addr = INS_DirectBranchOrCallTargetAddress(ins); IMG target_img = IMG_FindByAddress(target_addr); if (!IMG_Valid(img) || img == config->img) { ok = true; } } if (ok) { // Select which call analysis function to use depending on whether we are in fast mode AFUNPTR analysisFunc = (AFUNPTR)MethodCallAnalysis; if (KnobFast.Value()) { analysisFunc = (AFUNPTR)MethodCallAnalysisFast; } ADDRINT ret_addr = INS_NextAddress(ins); INS_InsertIfCall(ins, IPOINT_BEFORE, (AFUNPTR)ShouldCallBeAnalyzed, IARG_FUNCARG_CALLSITE_REFERENCE, 0, IARG_ADDRINT, ret_addr, IARG_BRANCH_TARGET_ADDR, IARG_END); INS_InsertThenCall(ins, IPOINT_BEFORE, analysisFunc, IARG_FUNCARG_CALLSITE_REFERENCE, 0, IARG_ADDRINT, ret_addr, IARG_BRANCH_TARGET_ADDR, IARG_END); returnAddressToInstument[ret_addr] = true; return; } } if (returnAddressToInstument.find(addr) != returnAddressToInstument.end()) { // Select which call analysis function to use depending on whether we are in fast mode AFUNPTR analysisFuncIf = (AFUNPTR)ShouldReturnAddressBeAnalyzed; AFUNPTR analysisFuncThen = (AFUNPTR)ReturnValueAnalysis; if (KnobFast.Value()) { analysisFuncIf = (AFUNPTR)ShouldReturnAddressBeAnalyzedFast; analysisFuncThen = (AFUNPTR)ReturnValueAnalysisFast; } INS_InsertIfCall(ins, IPOINT_BEFORE, analysisFuncIf, IARG_ADDRINT, addr, IARG_END); INS_InsertThenCall(ins, IPOINT_BEFORE, analysisFuncThen, IARG_ADDRINT, addr, IARG_REG_VALUE, REG_EAX, IARG_FUNCARG_CALLSITE_REFERENCE, 0, IARG_END); return; } }
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 Trace(TRACE trace, VOID *v) { if(TAINT_Analysis_On&&TAINT_Instrumentation_On) { for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)) { if(bbl_taintedmem) BBL_InsertCall(bbl,IPOINT_BEFORE,(AFUNPTR)bblBegin,IARG_END); for (INS ins = BBL_InsHead(bbl); INS_Valid(ins); ins = INS_Next(ins)) { INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)checkEIP,IARG_INST_PTR,IARG_END); if(INS_IsCall(ins))//detect overflow of stack { INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)MemofRetAddr, IARG_MEMORYOP_EA, 0, IARG_END); } if ( INS_Opcode(ins) >= XED_ICLASS_MOV && INS_Opcode(ins) <= XED_ICLASS_MOVZX )//&& INS_Address(ins) == 0x7c80a2f0)//||INS_Address(ins)==0x7c80a2f3))//||( (INS_Opcode(ins) >= XED_ICLASS_POP) && (INS_Opcode(ins) <= XED_ICLASS_POPFQ))||((INS_Opcode(ins) >= XED_ICLASS_PUSH) && (INS_Opcode(ins) <= XED_ICLASS_PUSHFQ))||(INS_Opcode(ins) == XED_ICLASS_LEA)) { if (INS_has_immed(ins)) { if (INS_IsMemoryWrite(ins)) //immed -> mem { INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)ImmedCleanMem, IARG_MEMORYOP_EA, 0, IARG_END); } else //immed -> reg { REG insreg1 = INS_get_write_reg(ins); INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)ImmedCleanReg, IARG_ADDRINT, (ADDRINT)insreg1, IARG_END); } } else if (INS_IsMemoryRead(ins)) //mem -> reg { //in this case we call MemTaintReg to copy the taint if relevant REG insreg2 = INS_get_write_reg(ins); REG basereg2 = INS_get_mem_basereg(ins); REG indexreg2 = INS_get_mem_indexreg(ins); //ADDRINT insadd = INS_Address(ins); //string insdis = INS_Disassemble(ins); //out << "instruction 2 opcode " << INS_Opcode(ins)<<endl; INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)MemTaintReg, IARG_MEMORYOP_EA, 0, IARG_UINT32,INS_MemoryScale(ins), IARG_ADDRINT, (ADDRINT)basereg2, IARG_ADDRINT, (ADDRINT)indexreg2, IARG_ADDRINT, (ADDRINT)insreg2, IARG_UINT32, INS_Opcode(ins), IARG_INST_PTR, IARG_END); } else if (INS_IsMemoryWrite(ins)) //reg -> mem { //in this case we call RegTaintMem to copy the taint if relevant REG insreg3 = INS_get_read_reg(ins); REG basereg3 = INS_get_memwr_basereg(ins); REG indexreg3 = INS_get_memwr_indexreg(ins); //ADDRINT insadd = INS_Address(ins); //IARG_INST_PTR INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)RegTaintMem, IARG_ADDRINT,(ADDRINT)insreg3, IARG_UINT32,INS_MemoryScale(ins), IARG_ADDRINT, (ADDRINT)basereg3, IARG_ADDRINT, (ADDRINT)indexreg3, IARG_MEMORYOP_EA, 0, IARG_UINT32, INS_Opcode(ins), IARG_INST_PTR, IARG_END); } else if (INS_RegR(ins, 0) != REG_INVALID()) //reg -> reg { //in this case we call RegTaintReg REG Rreg = INS_get_read_reg(ins); REG Wreg = INS_get_write_reg(ins); //ADDRINT insadd = INS_Address(ins); INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)RegTaintReg, IARG_ADDRINT, (ADDRINT)Rreg, IARG_ADDRINT, (ADDRINT)Wreg, IARG_UINT32, INS_Opcode(ins), IARG_INST_PTR, IARG_END); } else //should never happen { out << "serious error?!\n" << endl; } } // IF opcode is a MOV /* if(bbl_taintedmem == 1&&INS_IsBranch(ins)) { out << BBL_Address(bbl) <<endl; out << INS_Address(ins)<<endl; out << INS_NextAddress(ins)<<endl; out << INS_DirectBranchOrCallTargetAddress(ins)<<endl; out << " taintBBL: "<<endl; out << INS_Disassemble(ins) <<endl; if(INS_NextAddress(ins)>=BBL_Address(bbl)&&INS_NextAddress(ins)<=INS_Address(ins)) { out << "find bbl loop"<<endl; //bblLoop = 1; } } */ if(bbl_taintedmem ==1 && ins==BBL_InsTail(bbl)) { // out <<"find tainted bbl " <<endl; // out <<"bbl start address: "<< BBL_Address(bbl) <<endl; // out <<"bbl size: "<<BBL_Size(bbl) << endl; // out <<"bbl head: "<< INS_Disassemble(BBL_InsHead(bbl))<<endl; // out <<"bbl tail: "<< INS_Disassemble(ins) <<endl; if(INS_DirectBranchOrCallTargetAddress(ins)>=BBL_Address(bbl)&&INS_DirectBranchOrCallTargetAddress(ins)<=INS_Address(ins)) { out<<endl<<"this tainted bbl is a loop"<<endl; //BBL_InsertCall(bbl,IPOINT_AFTER,(AFUNPTR)loopBblEnd,IARG_END); } } }// For INS } // For BBL }//for enable DTA } // VOID Trace
VOID record_calls(INS ins, VOID *v) { if (record) { fprintf(file,"%lx\n",INS_Address(ins)); record = 0; } if (INS_IsCall(ins)) record = 1; }
VOID trace_instrument(TRACE trace, VOID *v){ for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)){ /* iterate over all basic blocks */ string codelet_string = ""; // this writes disassembly char codelet_buffer[65536*2]; int cbs = 0; INS head = BBL_InsHead(bbl); INS tail = BBL_InsTail(bbl); ADDRINT stage_entry = INS_Address( head ); ADDRINT target = 0; if (INS_IsCall(tail)){ if( INS_IsDirectBranchOrCall(tail)){ target = INS_DirectBranchOrCallTargetAddress(tail);}} INS cur ; int branch_id = slp_count; /* If compression is turned off (default), only output the addresses of * the BBL once */ if (!KnobNoCompress){ /* Instrument the head instruction right before it is called, but also * before we instrument the instructions in the basic block */ string msg_pre = "\n@@BBL(" + decstr( branch_id ) + ") STAGE " + Target2String(stage_entry)->c_str() + "\n" ; INS_InsertCall(head, IPOINT_BEFORE, AFUNPTR(string_report), IARG_PTR, new string(msg_pre), IARG_END); } /* Walk the list of instructions inside the BBL. Disassemble each, and add * it to the codelet string. Also, instrument each instruction at the * point before it is called with the do_count function. */ for ( cur = head; INS_Valid( cur ); cur = INS_Next(cur ) ){ cbs += sprintf( codelet_buffer + cbs , "\n\t@%llx\t%s", INS_Address( cur ), INS_Disassemble( cur ).c_str() ); INS_InsertCall(cur, IPOINT_BEFORE, (AFUNPTR)do_count, IARG_ADDRINT, INS_Address( cur ), IARG_END); } /* Finish off the codelet assembly string with an out message and * address ranges of the BBL */ cbs += sprintf( codelet_buffer + cbs , "\n\t}BBL.OUT [%d] %llx - %llx\n", branch_id, INS_Address( head ), INS_Address( tail )); /* If compression is turned on, output the codelet every single time we * hit the same block. */ if(KnobNoCompress){ INS_InsertCall(tail, IPOINT_BEFORE, AFUNPTR(string_report), IARG_PTR, new string(codelet_buffer), IARG_END); slp_count ++; } else{ /* add the mapped BBL to output */ TraceFile.write(codelet_buffer, cbs); /* Instrument the tail instruction by inserting just before it is called */ string msg_post = "+@@BBL(" + decstr( branch_id ) + ") ACHIEVE : GOTO " + Target2String(target)->c_str(); INS_InsertCall(tail, IPOINT_BEFORE, AFUNPTR(string_report), IARG_PTR, new string(msg_post), IARG_END); slp_count ++; } } }
instruction::instruction(const INS& ins) { this->address = INS_Address(ins); this->next_address = INS_NextAddress(ins); // this->opcode = INS_Mnemonic(ins); this->opcode_size = static_cast<uint8_t>(INS_Size(ins)); this->opcode_buffer = std::shared_ptr<uint8_t>(new uint8_t[this->opcode_size], std::default_delete<uint8_t[]>()); PIN_SafeCopy(opcode_buffer.get(), reinterpret_cast<const VOID*>(this->address), this->opcode_size); this->disassemble = INS_Disassemble(ins); // including image, routine auto img = IMG_FindByAddress(this->address); this->including_image = IMG_Valid(img) ? IMG_Name(img) : ""; // this->including_routine = RTN_FindNameByAddress(this->address); PIN_LockClient(); auto routine = RTN_FindByAddress(this->address); PIN_UnlockClient(); if (RTN_Valid(routine)) { auto routine_mangled_name = RTN_Name(routine); this->including_routine_name = PIN_UndecorateSymbolName(routine_mangled_name, UNDECORATION_NAME_ONLY); } else this->including_routine_name = ""; // has fall through this->has_fall_through = INS_HasFallThrough(ins); // is call, ret or syscall this->is_call = INS_IsCall(ins); this->is_branch = INS_IsBranch(ins); this->is_ret = INS_IsRet(ins); this->is_syscall = INS_IsSyscall(ins); this->category = static_cast<xed_category_enum_t>(INS_Category(ins)); this->iclass = static_cast<xed_iclass_enum_t>(INS_Opcode(ins)); // read registers auto read_reg_number = INS_MaxNumRRegs(ins); for (decltype(read_reg_number) reg_id = 0; reg_id < read_reg_number; ++reg_id) { this->src_registers.push_back(INS_RegR(ins, reg_id)); } // written registers auto written_reg_number = INS_MaxNumWRegs(ins); for (decltype(written_reg_number) reg_id = 0; reg_id < written_reg_number; ++reg_id) { this->dst_registers.push_back(INS_RegW(ins, reg_id)); } auto is_special_reg = [](const REG& reg) -> bool { return (reg >= REG_MM_BASE); }; this->is_special = std::any_of(std::begin(this->src_registers), std::end(this->src_registers), is_special_reg) || std::any_of(std::begin(this->dst_registers), std::end(this->dst_registers), is_special_reg) || (this->category == XED_CATEGORY_X87_ALU) || (this->iclass == XED_ICLASS_XEND) || (this->category == XED_CATEGORY_LOGICAL_FP) || (this->iclass == XED_ICLASS_PUSHA) || (this->iclass == XED_ICLASS_PUSHAD) || (this->iclass == XED_ICLASS_PUSHF) || (this->iclass == XED_ICLASS_PUSHFD) || (this->iclass == XED_ICLASS_PUSHFQ); // is memory read, write this->is_memory_read = INS_IsMemoryRead(ins); this->is_memory_write = INS_IsMemoryWrite(ins); this->is_memory_read2 = INS_HasMemoryRead2(ins); }
static void I_Trace(TRACE trace, void *v) { //FIXME if (PIN_IsSignalHandler()) {Sequence_ProcessSignalHandler(head)}; for(BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)) { INS tail = BBL_InsTail(bbl); // All memory reads/writes for( INS ins = BBL_InsHead(bbl); INS_Valid(ins); ins = INS_Next(ins) ) { if( INS_IsMemoryRead(ins) || INS_HasMemoryRead2(ins) || INS_IsMemoryWrite(ins) ) { INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)A_DoMem, IARG_BOOL, INS_IsMemoryWrite(ins), (INS_IsMemoryWrite(ins) ? IARG_MEMORYWRITE_EA : (INS_IsMemoryRead(ins) ? IARG_MEMORYREAD_EA : IARG_MEMORYREAD2_EA)), IARG_INST_PTR, IARG_END); } #if defined(TARGET_IA32) && defined (TARGET_WINDOWS) // on ia-32 windows need to identify // push // ret // in order to process callstack correctly if (ins != tail) { INS_InsertPredicatedCall(ins, IPOINT_BEFORE, (AFUNPTR)ProcessInst, IARG_INST_PTR, IARG_END); if (INS_Opcode(ins)==XED_ICLASS_PUSH) { RecordPush (ins); } } #endif } // All calls and returns if( INS_IsSyscall(tail) ) { INS_InsertPredicatedCall(tail, IPOINT_BEFORE, (AFUNPTR)A_ProcessSyscall, IARG_INST_PTR, IARG_SYSCALL_NUMBER, IARG_REG_VALUE, REG_STACK_PTR, IARG_SYSCALL_ARG0, IARG_END); } else { if( INS_IsCall(tail) ) { if( INS_IsDirectBranchOrCall(tail) ) { ADDRINT target = INS_DirectBranchOrCallTargetAddress(tail); INS_InsertPredicatedCall(tail, IPOINT_BEFORE, (AFUNPTR)A_ProcessDirectCall, IARG_INST_PTR, IARG_ADDRINT, target, IARG_REG_VALUE, REG_STACK_PTR, IARG_END); } else if( !IsPLT(trace) ) { INS_InsertPredicatedCall(tail, IPOINT_BEFORE, (AFUNPTR)A_ProcessIndirectCall, IARG_INST_PTR, IARG_BRANCH_TARGET_ADDR, IARG_REG_VALUE, REG_STACK_PTR, IARG_END); } } if( IsPLT(trace) ) { INS_InsertCall(tail, IPOINT_BEFORE, (AFUNPTR)A_ProcessStub, IARG_INST_PTR, IARG_BRANCH_TARGET_ADDR, IARG_REG_VALUE, REG_STACK_PTR, IARG_END); } if( INS_IsRet(tail) ) { INS_InsertPredicatedCall(tail, IPOINT_BEFORE, (AFUNPTR)A_ProcessReturn, IARG_INST_PTR, IARG_REG_VALUE, REG_STACK_PTR, IARG_END); } } } }
void log_ins(INS ins) { // dump the instruction INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) &execute_instruction, IARG_INST_PTR, IARG_PTR, strdup(INS_Disassemble(ins).c_str()), IARG_END); // reads memory (1) if(INS_IsMemoryRead(ins) != 0) { INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) &dump_read_memory, IARG_MEMORYREAD_EA, IARG_MEMORYREAD_SIZE, IARG_END); } // reads memory (2) if(INS_HasMemoryRead2(ins) != 0) { INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) &dump_read_memory, IARG_MEMORYREAD2_EA, IARG_MEMORYREAD_SIZE, IARG_END); } IPOINT after = IPOINT_AFTER; if(INS_IsCall(ins) != 0) { // TODO is this correct? after = IPOINT_TAKEN_BRANCH; } else if(INS_IsSyscall(ins) != 0) { // TODO support syscalls return; } else if(INS_HasFallThrough(ins) == 0 && (INS_IsBranch(ins) != 0 || INS_IsRet(ins) != 0)) { // TODO is this correct? after = IPOINT_TAKEN_BRANCH; } // dump written memory if(INS_IsMemoryWrite(ins) != 0) { INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) &dump_written_memory_before, IARG_MEMORYWRITE_EA, IARG_MEMORYWRITE_SIZE, IARG_END); INS_InsertCall(ins, after, (AFUNPTR) &dump_written_memory_after, IARG_END); } // dump all affected registers for (UINT32 i = 0; i < INS_OperandCount(ins); i++) { if(INS_OperandIsMemory(ins, i) != 0) { if(INS_OperandMemoryBaseReg(ins, i) != REG_INVALID()) { REG base_reg = INS_OperandMemoryBaseReg(ins, i); if(g_reg_index[base_reg] != 0) { INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) &dump_reg_before, IARG_UINT32, g_reg_index[base_reg]-1, IARG_REG_VALUE, INS_OperandMemoryBaseReg(ins, i), IARG_END); INS_InsertCall(ins, after, (AFUNPTR) &dump_reg_r_after, IARG_UINT32, g_reg_index[base_reg]-1, IARG_END); } } if(INS_OperandMemoryIndexReg(ins, i) != REG_INVALID()) { REG index_reg = INS_OperandMemoryIndexReg(ins, i); if(g_reg_index[index_reg] != 0) { INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) &dump_reg_before, IARG_UINT32, g_reg_index[index_reg]-1, IARG_REG_VALUE, INS_OperandMemoryIndexReg(ins, i), IARG_END); INS_InsertCall(ins, after, (AFUNPTR) &dump_reg_r_after, IARG_UINT32, g_reg_index[index_reg]-1, IARG_END); } } } if(INS_OperandIsReg(ins, i) != 0) { REG reg_index = REG_FullRegName(INS_OperandReg(ins, i)); if(INS_OperandReadAndWritten(ins, i) != 0) { if(g_reg_index[reg_index] != 0) { INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) &dump_reg_before, IARG_UINT32, g_reg_index[reg_index]-1, IARG_REG_VALUE, reg_index, IARG_END); INS_InsertCall(ins, after, (AFUNPTR) &dump_reg_rw_after, IARG_UINT32, g_reg_index[reg_index]-1, IARG_REG_VALUE, reg_index, IARG_END); } } else if(INS_OperandRead(ins, i) != 0) { if(g_reg_index[reg_index] != 0) { INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) &dump_reg_before, IARG_UINT32, g_reg_index[reg_index]-1, IARG_REG_VALUE, reg_index, IARG_END); INS_InsertCall(ins, after, (AFUNPTR) &dump_reg_r_after, IARG_UINT32, g_reg_index[reg_index]-1, IARG_END); } } else if(INS_OperandWritten(ins, i) != 0) { if(g_reg_index[reg_index] != 0) { INS_InsertCall(ins, after, (AFUNPTR) &dump_reg_w_after, IARG_UINT32, g_reg_index[reg_index]-1, IARG_REG_VALUE, reg_index, IARG_END); } } } } INS_InsertCall(ins, after, (AFUNPTR) &print_newline, IARG_END); }
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); } }