static VOID Trace(TRACE trace, VOID *v) { RTN rtn = TRACE_Rtn(trace); ADDRINT version = TRACE_Version(trace); // If we are not in watch_rtn, switch back to base version if (!RTN_Valid(rtn) || RTN_Name(rtn) != watch_rtn) { if (version != VERSION_BASE) BBL_SetTargetVersion(TRACE_BblHead(trace), VERSION_BASE); return; } if (TRACE_Address(trace) == RTN_Address(rtn)) { INS ins = BBL_InsHead(TRACE_BblHead(trace)); if (version == VERSION_BASE) { // version_reg is used to select the version, use the first // argument of watch_rtn to set it INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(select_version), IARG_FUNCARG_ENTRYPOINT_VALUE, 0, IARG_RETURN_REGS, version_reg, IARG_END); // IF we are in the base version, decide if we should go to the // other versions // Note that the version instrumentation will occur before any // following instrumentation done on this ins INS_InsertVersionCase(ins, version_reg, 10, VERSION_1, IARG_END); INS_InsertVersionCase(ins, version_reg, 20, VERSION_2, IARG_END); printf ("Instrumentation at %p\n", reinterpret_cast<void *>(INS_Address(ins))); } } INS ins = BBL_InsHead(TRACE_BblHead(trace)); for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)) { // Instrumentation depends on version // These instrumentations occur after the preceeding version instrumentation // (i.e. the instrumentation inserted by the above INS_InsertVersionCase calls switch(version) { case VERSION_BASE: INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(Emit), IARG_PTR, "version base", IARG_END); break; case VERSION_1: INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(Emit), IARG_PTR, "version 1", IARG_END); break; case VERSION_2: INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(Emit), IARG_PTR, "version 2", IARG_END); break; default: assert(0); break; } } }
void Instruction(INS ins, VOID *v) { RTN rtn = INS_Rtn(ins); if (RTN_Valid(rtn) && ((RTN_Name(rtn) == "SegAccessRtn") || (RTN_Name(rtn) == "SegAccessStrRtn"))) { REG segReg = INS_SegmentRegPrefix(ins); if ((segReg != REG_SEG_GS) && (segReg != REG_SEG_FS)) return; REG baseReg = (segReg == REG_SEG_GS)? REG_SEG_GS_BASE : REG_SEG_FS_BASE; if (INS_RewriteMemoryAddressingToBaseRegisterOnly(ins, MEMORY_TYPE_READ, REG_INST_G0)) { INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(ProcessAddress), IARG_REG_VALUE, baseReg, IARG_MEMORYREAD_EA, IARG_INST_PTR, IARG_RETURN_REGS, REG_INST_G0, IARG_END); } if (INS_RewriteMemoryAddressingToBaseRegisterOnly(ins, MEMORY_TYPE_WRITE, REG_INST_G1)) { INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(ProcessAddress), IARG_REG_VALUE, baseReg, IARG_MEMORYWRITE_EA, IARG_INST_PTR, IARG_RETURN_REGS, REG_INST_G1, IARG_END); } if (INS_RewriteMemoryAddressingToBaseRegisterOnly(ins, MEMORY_TYPE_READ2, REG_INST_G2)) { INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(ProcessAddress), IARG_REG_VALUE, baseReg, IARG_MEMORYREAD2_EA, IARG_INST_PTR, IARG_RETURN_REGS, REG_INST_G2, IARG_END); } } }
static void InstrumentIns(INS ins, VOID *) { RTN rtn = INS_Rtn(ins); if (RTN_Valid(rtn) && RTN_Name(rtn) == "DoWorkInstrumentedWithPin") { FoundDoWork = true; INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(UseLocksWorker), IARG_END); } }
void DoReplacementFunc( IMG img, char * funcName) { RTN rtnToReplace; //printf ("Image %s\n", IMG_Name(img).c_str()); for (SEC sec = IMG_SecHead(img); SEC_Valid(sec); sec = SEC_Next(sec)) { for (RTN rtn = SEC_RtnHead(sec); RTN_Valid(rtn); rtn = RTN_Next(rtn)) { //printf (" Rtn: %s %s\n", RTN_Name(rtn).c_str(), funcName); if (strstr( RTN_Name(rtn).c_str(), funcName)) { printf (" found\n"); foundFunc = true; rtnToReplace = rtn; break; } } if (foundFunc) { break; } } if (!foundFunc) { return; } printf ( "Found %s %x\n", funcName, RTN_Address(rtnToReplace)); if (RTN_IsSafeForProbedReplacement(rtnToReplace)) { printf ( "RTN_ReplaceSignatureProbed on %s\n", funcName); foundFunc = true; PROTO protoOfFastCallFunction1ToBeReplacedByPin = PROTO_Allocate( PIN_PARG(void *), CALLINGSTD_REGPARMS, "protoOfFastCallFunction1ToBeReplacedByPin", PIN_PARG(char), PIN_PARG(int), PIN_PARG(char), PIN_PARG(int), PIN_PARG_END() ); RTN_ReplaceSignatureProbed(rtnToReplace, AFUNPTR(ReplacementFunc), IARG_PROTOTYPE, protoOfFastCallFunction1ToBeReplacedByPin, IARG_ORIG_FUNCPTR, IARG_FUNCARG_ENTRYPOINT_VALUE, 0, IARG_FUNCARG_ENTRYPOINT_VALUE, 1, IARG_FUNCARG_ENTRYPOINT_VALUE, 2, IARG_FUNCARG_ENTRYPOINT_VALUE, 3, IARG_END); PROTO_Free( protoOfFastCallFunction1ToBeReplacedByPin ); } }
VOID Image(IMG img, VOID *v) { if(IMG_IsMainExecutable(img)) { for (SEC sec = IMG_SecHead(img); SEC_Valid(sec); sec = SEC_Next(sec)) { for (RTN rtn = SEC_RtnHead(sec); RTN_Valid(rtn); rtn = RTN_Next(rtn)) { if (RTN_Name(rtn) == "_NotifyPinAfterMmap" || RTN_Name(rtn) == "NotifyPinAfterMmap") { RTN_Open(rtn); RTN_InsertCall(rtn, IPOINT_BEFORE, (AFUNPTR)MmapAfter, IARG_FUNCARG_ENTRYPOINT_VALUE, 0, IARG_END); RTN_Close(rtn); } } } } }
// When the application executes the Checkpoint() function, we take a snapshot of the // registers and start recording changes to memory. This allows us to roll the application // back to the Checkpoint() call later. // static void InstrumentRtn(RTN rtn, VOID *) { if (RTN_Name(rtn) == "Checkpoint") { RTN_Open(rtn); RTN_InsertCall(rtn, IPOINT_AFTER, AFUNPTR(OnCheckpoint), IARG_CONTEXT, IARG_END); FoundCheckpoint = TRUE; RTN_Close(rtn); } }
std::string getRoutineName(triton::__uint address) { RTN rtn; PIN_LockClient(); rtn = RTN_FindByAddress(address); PIN_UnlockClient(); if (RTN_Valid(rtn)) { return RTN_Name(rtn); } return ""; }
static VOID InstrumentRtn(RTN rtn, VOID *) { if (RTN_Name(rtn) == "One") { RTN_Open(rtn); RTN_InsertCall(rtn, IPOINT_BEFORE, AFUNPTR(AtOne), IARG_END); FoundOneRtn = TRUE; RTN_Close(rtn); } }
static void OnRtn(RTN rtn, VOID *) { // We want to stop at a debugger breakpoint at the "Inner" function. // if (RTN_Name(rtn) == "Inner") { RTN_Open(rtn); RTN_InsertCall(rtn, IPOINT_BEFORE, AFUNPTR(DoBreakpoint), IARG_CONTEXT, IARG_THREAD_ID, IARG_END); RTN_Close(rtn); } }
VOID Rtn(RTN rtn, VOID * v) { string name = RTN_Name(rtn); if (name == "test1") { RTN_Open(rtn); for (INS ins = RTN_InsHead(rtn); INS_Valid(ins); ins = INS_Next(ins)) { CountsUpdate(ins); } RTN_Close(rtn); } }
// When an image is loaded, check for a MyAlloc function VOID Image(IMG img, VOID *v) { //fprintf(stderr, "Loading %s\n",IMG_name(img)); for (SEC sec = IMG_SecHead(img); SEC_Valid(sec); sec = SEC_Next(sec)) { //fprintf(stderr, " sec %s\n", SEC_name(sec).c_str()); for (RTN rtn = SEC_RtnHead(sec); RTN_Valid(rtn); rtn = RTN_Next(rtn)) { //fprintf(stderr, " rtn %s\n", RTN_name(rtn).c_str()); // Swizzle the return value of MyAlloc #if defined(TARGET_MAC) if (RTN_Name(rtn) == "_MyAlloc") #else if (RTN_Name(rtn) == "MyAlloc") #endif { RTN_Open(rtn); fprintf(stderr, "Adding swizzle to %s\n", "MyAlloc"); RTN_InsertCall(rtn, IPOINT_AFTER, AFUNPTR(Swizzle), IARG_REG_VALUE, REG_GAX, IARG_RETURN_REGS, REG_GAX, IARG_END); RTN_Close(rtn); } #if defined(TARGET_MAC) if (RTN_Name(rtn) == "_MyFree") #else if (RTN_Name(rtn) == "MyFree") #endif { RTN_Open(rtn); fprintf(stderr, "Adding unswizzle to %s\n", "MyFree"); RTN_InsertCall(rtn, IPOINT_BEFORE, AFUNPTR(SwizzleArg), IARG_FUNCARG_ENTRYPOINT_REFERENCE, 0, IARG_END); RTN_Close(rtn); } } } }
// This function is called whenever Pin wants to report a breakpoint event to the // debugger. // static BOOL InterceptBreakpoint(THREADID tid, DEBUGGING_EVENT eventType, CONTEXT *ctxt, VOID *) { if (eventType != DEBUGGING_EVENT_BREAKPOINT) { std::cout << "FAILURE: Wrong event type in InterceptBreakpoint()" << std::endl; std::exit(1); } ADDRINT pc = PIN_GetContextReg(ctxt, REG_INST_PTR); RTN rtn = RTN_FindByAddress(pc); // When the application triggers the breakpoint in Breakpoint1(), squash the breakpoint // and roll the application back to the Checkpoint() call. The application will NOT stop // at the breakpoint, and it will immediately resume from Checkpoint(). // if (rtn != RTN_Invalid() && RTN_Name(rtn) == "Breakpoint1") { std::cout << "Intercepting breakpoint #1 at 0x" << std::hex << pc << std::endl; PIN_SaveContext(&SavedContext, ctxt); PIN_SetContextReg(ctxt, REG_GAX, 1); MemLog.Restore(); IsCheckpointing = FALSE; return FALSE; } // When the application triggers the breakpoint in Breakpoint2(), do not squash the // breakpoint, but change the return value from Breakpoint2(). The application will stop // in the debugger, and the debugger should see the modified return value. // if (rtn != RTN_Invalid() && (RTN_Name(rtn) == "Breakpoint2" || RTN_Name(rtn) == "Breakpoint2Label")) { std::cout << "Intercepting breakpoint #2 at 0x" << std::hex << pc << std::endl; std::cout << "RTN=" << RTN_Name(rtn) << std::endl; PIN_SetContextReg(ctxt, REG_GAX, 1); return TRUE; } std::cout << "Skipping breakpoint at 0x" << std::hex << pc << ", RTN=" << RTN_Name(rtn) << std::endl; return TRUE; }
static VOID Rtn(RTN rtn, VOID *v) { if (!RTN_Valid(rtn) || RTN_Name(rtn) != watch_rtn) { return; } printf("Rtn Instrumenting %s\n", watch_rtn, reinterpret_cast<void *>(RTN_Address(rtn))); RTN_Open(rtn); RTN_InsertCall(rtn, IPOINT_BEFORE, AFUNPTR(Emit), IARG_PTR, "RTN instrumentation", IARG_CALL_ORDER, CALL_ORDER_FIRST+1, IARG_END); RTN_Close(rtn); }
VOID Routine(RTN rtn, void *v) { #ifdef USER_PROFILE // control the simulation string szFunc = RTN_Name(rtn); if(szFunc == "main") { RTN_Open(rtn); RTN_InsertCall(rtn, IPOINT_BEFORE, (AFUNPTR)SetSimu, IARG_END); RTN_InsertCall(rtn, IPOINT_AFTER, (AFUNPTR)UnsetSimu, IARG_END); RTN_Close(rtn); } #endif }
VOID Image(IMG img, VOID * v) { if (strstr (IMG_Name(img).c_str(), "flags_at_analysis_app")==NULL) { return; } for (SEC sec = IMG_SecHead(img); SEC_Valid(sec); sec = SEC_Next(sec)) { for (RTN rtn = SEC_RtnHead(sec); RTN_Valid(rtn); rtn = RTN_Next(rtn)) { // Prepare for processing of RTN, an RTN is not broken up into BBLs, // it is merely a sequence of INSs RTN_Open(rtn); for (INS ins = RTN_InsHead(rtn); INS_Valid(ins); ins = INS_Next(ins)) { if (INS_Opcode(ins)==XED_ICLASS_POPF || INS_Opcode(ins)==XED_ICLASS_POPFD || INS_Opcode(ins)==XED_ICLASS_POPFQ) { // popf is the marker printf ("found popf in rtn %s\n", RTN_Name(rtn).c_str()); if (!INS_Valid(INS_Next(ins)) || !INS_Valid(INS_Next(INS_Next(ins)))) { printf ("wrong popf marker found\n"); exit (-1); } printf ("next ins should be cmp al, 0x81 it is %s\n", INS_Disassemble(INS_Next(ins)).c_str()); printf ("next ins should be xor ecx, ecx it is %s\n", INS_Disassemble(INS_Next(INS_Next(ins))).c_str()); // Insert analysis calls to read the value of the flags register just after the cmp al, 0x81 - the OF flag should be set INS_InsertIfCall(INS_Next(INS_Next(ins)), IPOINT_BEFORE, (AFUNPTR)IfReturnTrue, IARG_INST_PTR, IARG_END); INS_InsertThenCall(INS_Next(INS_Next(ins)), IPOINT_BEFORE, (AFUNPTR)ThenFunc, IARG_REG_VALUE, REG_GFLAGS, IARG_END); INS_InsertCall(INS_Next(INS_Next(ins)), IPOINT_BEFORE, (AFUNPTR)AnalysisFunc, IARG_REG_VALUE, REG_GFLAGS, IARG_END); } } // to preserve space, release data associated with RTN after we have processed it RTN_Close(rtn); } } }
VOID Image(IMG img, void *v) { for (SEC sec = IMG_SecHead(img); SEC_Valid(sec); sec = SEC_Next(sec)) { for (RTN rtn = SEC_RtnHead(sec); RTN_Valid(rtn); rtn = RTN_Next(rtn)) { RTN_Open(rtn); RTN_InsertCall( rtn, IPOINT_BEFORE, AFUNPTR(AtRtn1), IARG_PTR, RTN_Name(rtn).c_str(), IARG_TSC, IARG_INST_PTR , IARG_END); RTN_InsertCall( rtn, IPOINT_BEFORE, AFUNPTR(AtRtn2), IARG_FAST_ANALYSIS_CALL, IARG_PTR, RTN_Name(rtn).c_str(), IARG_TSC, IARG_INST_PTR , IARG_END); RTN_Close(rtn); } } }
static VOID Rtn(RTN rtn, VOID *v) { if (!RTN_Valid(rtn) || RTN_Name(rtn) != watch_rtn) { return; } printf("Rtn Instrumenting %s\n", watch_rtn); RTN_Open(rtn); INS ins = RTN_InsHeadOnly(rtn); ASSERTX (INS_Valid(ins)); INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(Emit), IARG_PTR, "RTN instrumentation", IARG_CALL_ORDER, CALL_ORDER_FIRST+1, IARG_END); RTN_Close(rtn); }
static VOID Ins(INS ins, VOID *v) { RTN rtn = INS_Rtn(ins); if (!RTN_Valid(rtn) || RTN_Name(rtn) != watch_rtn) { return; } if (INS_Address(ins) == RTN_Address(rtn)) { INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(Emit), IARG_PTR, "Ins instrumentation", IARG_CALL_ORDER, CALL_ORDER_FIRST+3, IARG_END); printf("Ins Instrumenting %s\n", watch_rtn, reinterpret_cast<void *>(RTN_Address(rtn))); } }
static VOID Trace(TRACE trace, VOID *v) { RTN rtn = TRACE_Rtn(trace); if (!RTN_Valid(rtn) || RTN_Name(rtn) != watch_rtn) { return; } if (TRACE_Address(trace) == RTN_Address(rtn)) { BBL_InsertCall(TRACE_BblHead(trace), IPOINT_BEFORE, AFUNPTR(Emit), IARG_PTR, "Trace_BBL instrumentation", IARG_CALL_ORDER, CALL_ORDER_FIRST+2, IARG_END); printf("Trace Instrumenting %s\n", watch_rtn); } }
// Insert a call to an analysis routine that sets the scratch xmm registers, the call is inserted just after the // movdqa instruction of DoXmm (see xmm-asm-*.s) static VOID InstrumentRoutine(RTN rtn, VOID *) { if (RTN_Name(rtn) == "DoXmm") { RTN_Open(rtn); for (INS ins = RTN_InsHead(rtn); INS_Valid(ins); ins = INS_Next(ins)) { if (INS_Opcode(ins)==XED_ICLASS_MOVDQA) { fprintf (fp, "instrumenting ins %p %s\n", (void *)INS_Address(ins), INS_Disassemble(ins).c_str()); instrumented = TRUE; INS_InsertCall(ins, IPOINT_AFTER, (AFUNPTR)SetXmmScratchesFun, IARG_PTR, xmmInitVals, IARG_END); } } RTN_Close(rtn); } }
// Prints all RTNs in a given IMG to the trace file. // We use that file later on to see if the record and replay went the same static VOID PrintRTNs(IMG img) { for (SEC sec = IMG_SecHead(img); SEC_Valid(sec); sec = SEC_Next(sec)) { if (SEC_Type(sec) != SEC_TYPE_EXEC) { continue; } for (RTN rtn=SEC_RtnHead(sec); RTN_Valid(rtn); rtn = RTN_Next(rtn)) { if (RTN_IsArtificial(rtn)) { continue; } fprintf(trace, "Function '%s' loaded at %llx\n", RTN_Name(rtn).c_str(), (unsigned long long)RTN_Address(rtn)); } } }
static VOID Trace(TRACE trace, VOID *v) { RTN rtn = TRACE_Rtn(trace); if (!RTN_Valid(rtn) || RTN_Name(rtn) != watch_rtn) { return; } if (TRACE_Address(trace) == RTN_Address(rtn)) { // Pin does not support issuing an RTN_Replace from the TRACE instrumentation callback // This will cause Pin to terminate with an error RTN_Replace(rtn, AFUNPTR(WatchRtnReplacement)); } }
VOID Routine(RTN rtn, VOID *v) { string name = RTN_Name(rtn); if (name == "OpenProcess") { RTN_Open(rtn); RTN_InsertCall(rtn, IPOINT_AFTER, (AFUNPTR)killOpenProcess, IARG_ADDRINT, "OpenProcess", IARG_FUNCARG_ENTRYPOINT_VALUE, 1, IARG_FUNCRET_EXITPOINT_VALUE, IARG_FUNCRET_EXITPOINT_REFERENCE, IARG_END); RTN_Close(rtn); } if (name == "GetProcAddress") { RTN_Open(rtn); // call killRegOpenKey after RegOpenKeyExW is called RTN_InsertCall(rtn, IPOINT_AFTER, (AFUNPTR)killIsDebuggerPresent, IARG_ADDRINT, "GetProcAddress", IARG_FUNCARG_ENTRYPOINT_VALUE, 1, IARG_FUNCRET_EXITPOINT_VALUE, IARG_FUNCRET_EXITPOINT_REFERENCE, IARG_END); RTN_Close(rtn); } if (name == "RegOpenKeyExW"){ RTN_Open(rtn); // call killRegOpenKey after RegOpenKeyExW is called RTN_InsertCall(rtn, IPOINT_AFTER, (AFUNPTR)killRegOpenKey, IARG_ADDRINT, "RegOpenKeyExW", IARG_FUNCARG_ENTRYPOINT_VALUE, 1, IARG_FUNCRET_EXITPOINT_VALUE, IARG_FUNCRET_EXITPOINT_REFERENCE, IARG_END); RTN_Close(rtn); } }
VOID Routine(RTN rtn, void * v) { RTN_Open(rtn); if(strcmp(RTN_Name(rtn).c_str(),"memcpy")==0) { if(SYM_IFunc(RTN_Sym(rtn))) { cout << "Found IFUNC memcpy"<< endl; RTN_InsertCall(rtn, IPOINT_BEFORE, AFUNPTR(IfuncMemcpy), IARG_END); } else { cout << "Found non IFUNC memcpy"<< endl; RTN_InsertCall(rtn, IPOINT_BEFORE, AFUNPTR(Memcpy), IARG_FUNCARG_ENTRYPOINT_VALUE, 0, IARG_FUNCARG_ENTRYPOINT_VALUE, 1, IARG_FUNCARG_ENTRYPOINT_VALUE, 2 , IARG_END); } } RTN_Close(rtn); }
static VOID Trace(TRACE trace, VOID *v) { RTN rtn = TRACE_Rtn(trace); if (!RTN_Valid(rtn) || RTN_Name(rtn) != watch_rtn) { return; } if (TRACE_Address(trace) == RTN_Address(rtn)) { // Pin does not support issuing an RTN_InsertCall from the TRACE instrumentation callback // This will cause Pin to terminate with an error RTN_Open(rtn); RTN_InsertCall(rtn, IPOINT_BEFORE, AFUNPTR(Emit), IARG_PTR, "Ins instrumentation1", IARG_END); RTN_Close(rtn); } }
static VOID Instruction(INS ins, VOID *v) { RTN rtn = INS_Rtn(ins); if (!RTN_Valid(rtn) || RTN_Name(rtn) != watch_rtn) { return; } if (INS_Address(ins) == RTN_Address(rtn)) { // Pin does not support issuing an RTN_Replace from the INS instrumentation callback // This will cause Pin to terminate with an error RTN_Replace(rtn, AFUNPTR(WatchRtnReplacement)); } }
VOID Routine(RTN rtn, VOID *v) { // Allocate a counter for this routine RTN_COUNT * rc = new RTN_COUNT; // The RTN goes away when the image is unloaded, so save it now // because we need it in the fini rc->_name = RTN_Name(rtn); rc->_image = StripPath(IMG_Name(SEC_Img(RTN_Sec(rtn))).c_str()); rc->_address = RTN_Address(rtn); rc->_next = RtnList; RtnList = rc; if(!startSymbolAddress && rc->_name == start_symbol) { startSymbolAddress = rc->_address; } if(!stopSymbolAddress && rc->_name == stop_symbol) { stopSymbolAddress = rc->_address; } RTN_Open(rtn); if (rc->_address == startSymbolAddress || rc->_address == stopSymbolAddress) { if (rc->_address == startSymbolAddress) { RTN_InsertCall(rtn, IPOINT_BEFORE, (AFUNPTR)startRoutineEnter, IARG_FAST_ANALYSIS_CALL, IARG_PTR, reinterpret_cast<UINT64*>(rc), IARG_THREAD_ID, IARG_END); LOG("Instrumented start symbol\n"); } else { RTN_InsertCall(rtn, IPOINT_BEFORE, (AFUNPTR)stopRoutineEnter, IARG_FAST_ANALYSIS_CALL, IARG_PTR, reinterpret_cast<UINT64*>(rc), IARG_THREAD_ID, IARG_END); LOG("Instrumented stop symbol\n"); } }else { RTN_InsertCall(rtn, IPOINT_BEFORE, (AFUNPTR)routineEnter, IARG_FAST_ANALYSIS_CALL, IARG_PTR, reinterpret_cast<UINT64*>(rc), IARG_THREAD_ID, IARG_END); } RTN_InsertCall(rtn, IPOINT_AFTER, (AFUNPTR)routineExit, IARG_FAST_ANALYSIS_CALL, IARG_PTR, reinterpret_cast<UINT64*>(rc), IARG_THREAD_ID, IARG_END); RTN_Close(rtn); }
static VOID Trace(TRACE trace, VOID *v) { RTN rtn = TRACE_Rtn(trace); ADDRINT version = TRACE_Version(trace); // If we are not in watch_rtn, switch back to base version if (!RTN_Valid(rtn) || RTN_Name(rtn) != watch_rtn) { if (version != VERSION_BASE) BBL_SetTargetVersion(TRACE_BblHead(trace), VERSION_BASE); return; } INS ins = BBL_InsHead(TRACE_BblHead(trace)); for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)) { // Instrumentation depends on version // These instrumentations occur after the following version instrumentation // (i.e. the instrumentation inserted by the below INS_InsertVersionCase calls // from within the image load callback - because image load callback // instrumentation occurs before trace and before instruction callback instrumentation switch(version) { case VERSION_BASE: INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(Emit), IARG_PTR, "version base", IARG_END); break; case VERSION_1: INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(Emit), IARG_PTR, "version 1", IARG_END); break; case VERSION_2: INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(Emit), IARG_PTR, "version 2", IARG_END); break; default: assert(0); break; } } }
// WSASendTo HOOK Untested, I think. I forget :/. VOID HookWSASendTo( const IMG img, AFUNPTR replacement, const char *functionName ) { std::cerr << "Found " << functionName << "..." << endl; RTN rtn = RTN_FindByName(img, functionName ); PROTO proto = PROTO_Allocate( PIN_PARG(WINDOWS::INT), // retval CALLINGSTD_STDCALL, functionName, PIN_PARG(WINDOWS::SOCKET), // s, PIN_PARG(WINDOWS::LPWSABUF), // lpBuffers, PIN_PARG(WINDOWS::DWORD), // dwBufferCount PIN_PARG(WINDOWS::LPDWORD), // lpNumberOfBytesSend PIN_PARG(WINDOWS::DWORD), // dwFlags PIN_PARG(WINDOWS::SOCKADDR *), // lpTo, PIN_PARG(WINDOWS::INT), // iToLen, PIN_PARG(WINDOWS::LPWSAOVERLAPPED), // lpOverlapped PIN_PARG(WINDOWS::LPWSAOVERLAPPED_COMPLETION_ROUTINE), // lpCompletionRoutine PIN_PARG_END() ); RTN_ReplaceSignature(rtn, replacement, IARG_PROTOTYPE, proto, IARG_ORIG_FUNCPTR, IARG_FUNCARG_ENTRYPOINT_VALUE, 0, IARG_FUNCARG_ENTRYPOINT_VALUE, 1, IARG_FUNCARG_ENTRYPOINT_VALUE, 2, IARG_FUNCARG_ENTRYPOINT_VALUE, 3, IARG_FUNCARG_ENTRYPOINT_VALUE, 4, IARG_FUNCARG_ENTRYPOINT_VALUE, 5, IARG_FUNCARG_ENTRYPOINT_VALUE, 6, IARG_FUNCARG_ENTRYPOINT_VALUE, 7, IARG_FUNCARG_ENTRYPOINT_VALUE, 8, IARG_CONTEXT, IARG_PTR, functionName, IARG_END ); std::cerr << "Replaced " << RTN_Name( rtn ) << endl; PROTO_Free(proto); }
VOID Routine(RTN rtn, VOID *v) { std::string name = PIN_UndecorateSymbolName(RTN_Name(rtn).c_str(), UNDECORATION_NAME_ONLY); std::vector<std::string>::iterator it; for (it = userFuncs.begin(); it != userFuncs.end(); ++it) { std::string userFunc = *it; if (name.find(userFunc) == std::string::npos) continue; RTN_Open(rtn); // For each instruction of the routine for (INS ins = RTN_InsHead(rtn); INS_Valid(ins); ins = INS_Next(ins)) { UINT32 memOperands = INS_MemoryOperandCount(ins); // Iterate over each memory operand of the instruction. for (UINT32 memOp = 0; memOp < memOperands; memOp++) { if (INS_IsStackRead(ins) || INS_IsStackWrite(ins)) break; if (INS_MemoryOperandIsRead(ins, memOp)) { INS_InsertPredicatedCall( ins, IPOINT_BEFORE, (AFUNPTR)RecordMemRead, IARG_INST_PTR, IARG_MEMORYOP_EA, memOp, IARG_THREAD_ID, IARG_END); } if (INS_MemoryOperandIsWritten(ins, memOp)) { INS_InsertPredicatedCall( ins, IPOINT_BEFORE, (AFUNPTR)RecordMemWrite, IARG_INST_PTR, IARG_MEMORYOP_EA, memOp, IARG_THREAD_ID, IARG_END); } } } RTN_Close(rtn); } }