// Grab some detailed information about the image, the number of SECs and RTNs static VOID CountImageSecsAndRtns (IMG img, int *nSecs, int *nRtns) { int numSecs = 0; int numRtns = 0; for (SEC sec = IMG_SecHead(img); SEC_Valid(sec); sec = SEC_Next(sec)) { numSecs++; for (RTN rtn=SEC_RtnHead(sec); RTN_Valid(rtn); rtn = RTN_Next(rtn)) { numRtns++; } } *nSecs = numSecs; *nRtns = numRtns; }
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); for (INS ins = RTN_InsHead(rtn); INS_Valid(ins); ins = INS_Next(ins)) { sandbox.RecordIns(ins); } 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 instrumentation1", IARG_CALL_ORDER, CALL_ORDER_FIRST+3, IARG_END); INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(Emit), IARG_PTR, "RTN instrumentation2", IARG_CALL_ORDER, CALL_ORDER_FIRST+3, IARG_END); RTN_Close(rtn); }
static VOID ImageLoadCallback(IMG img, VOID *v) { if (threadFunction == 0) { if (KnobVerbose) cerr << "Looking for doNothing in " << IMG_Name(img) << "\n"; RTN rtn = RTN_FindByName (img, "doNothing"); if (RTN_Valid(rtn)) { threadFunction = RTN_Address(rtn); if (KnobVerbose) cerr << "'doNothing' at " << hex << threadFunction << dec << "\n"; } } }
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)) { INS ins = BBL_InsHead(TRACE_BblHead(trace)); INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(Emit), IARG_PTR, "Trace instrumentation", IARG_CALL_ORDER, CALL_ORDER_FIRST+2, IARG_END); printf("Trace Instrumenting %s\n", watch_rtn); } }
// Called every time a new image is loaded // Look for routines that we want to probe VOID ImageLoad(IMG img, VOID *v) { const ANNOTATION *ann = 0; USIZE num = 0; printf("Processing %s\n", IMG_Name(img).c_str()); for (SEC sec = IMG_SecHead(img); SEC_Valid(sec); sec = SEC_Next(sec)) { if (SEC_Name(sec) == "MyAnnot") { ann = reinterpret_cast<const ANNOTATION*>(SEC_Data(sec)); num = SEC_Size(sec) / sizeof(ANNOTATION); } } if (ann) { printf("Found annotations: \n"); for (UINT32 i = 0; i < num; i++) { ADDRINT addr = ann[i].addr; ADDRINT val = ann[i].value; printf("\t%p %p\t", Addrint2VoidStar(addr), Addrint2VoidStar(val)); if (PIN_IsSafeForProbedInsertion(addr)) { PIN_InsertCallProbed(addr, AFUNPTR(Notification), IARG_ADDRINT, val, IARG_END); printf(" - OK\n"); } else { printf(" - Failed\n"); } } // Set the write line function, from the image of the annotations (i.e. the main executable). RTN writeRtn = RTN_FindByName(img, "write_line"); if (RTN_Valid(writeRtn)) { writeFun = (void (*)(char *))RTN_Funptr(writeRtn); } } printf("Completed %s\n", IMG_Name(img).c_str()); }
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); } } }
// This routine is executed for each image. VOID ImageLoad(IMG img, VOID *) { RTN rtn = RTN_FindByName(img, "pthread_mutex_lock"); if ( RTN_Valid( rtn )) { RTN_Open(rtn); RTN_InsertCall(rtn, IPOINT_BEFORE, AFUNPTR(BeforeLock), IARG_THREAD_ID, IARG_END); RTN_InsertCall(rtn, IPOINT_AFTER, AFUNPTR(AfterLock), IARG_THREAD_ID, IARG_END); RTN_Close(rtn); } }
static VOID Image(IMG img, VOID *v) { RTN rtn = RTN_FindByName(img, watch_rtn); if (!RTN_Valid(rtn)) { return; } printf("Image 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, "IMG instrumentation", IARG_CALL_ORDER, CALL_ORDER_FIRST, IARG_END); RTN_Close(rtn); }
triton::__uint getBaseAddress(triton::__uint address) { RTN rtn; SEC sec; IMG img; PIN_LockClient(); rtn = RTN_FindByAddress(address); PIN_UnlockClient(); if (RTN_Valid(rtn)) { sec = RTN_Sec(rtn); if (SEC_Valid(sec)) { img = SEC_Img(sec); if (IMG_Valid(img)) { return IMG_LowAddress(img); } } } return 0; }
std::string getImageName(triton::__uint address) { RTN rtn; SEC sec; IMG img; PIN_LockClient(); rtn = RTN_FindByAddress(address); PIN_UnlockClient(); if (RTN_Valid(rtn)) { sec = RTN_Sec(rtn); if (SEC_Valid(sec)) { img = SEC_Img(sec); if (IMG_Valid(img)) { return IMG_Name(img); } } } return ""; }
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 instrumentation1", IARG_CALL_ORDER, CALL_ORDER_FIRST+1, IARG_END); INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(Emit), IARG_PTR, "Ins instrumentation2", IARG_CALL_ORDER, CALL_ORDER_FIRST, IARG_END); printf("Ins Instrumenting %s\n", watch_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)); } }
// 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 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)); } }
// Pin calls this function every time a new instruction is encountered VOID Instruction(INS ins, VOID *v) { RTN rtn = INS_Rtn(ins); if (!RTN_Valid(rtn)) { ++insNoRtnDiscoveredCount; INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)InsNoRtnCount, IARG_END); } else if (RTN_IsDynamic(rtn)) { ++insDynamicDiscoveredCount; INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)InsDynamicCount, IARG_END); } else { ++insNativeDiscoveredCount; INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)InsNativeCount, IARG_END); } }
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); } }
/*! * Test SafeCopy in the image instrumentation callback */ VOID ImageLoad(IMG img, VOID *v) { #if defined(TARGET_WINDOWS) // Pin on Windows inserts a probe that intercepts APCs at KiApcUserDispatcher RTN rtn = RTN_FindByName(img, "KiUserApcDispatcher"); if (RTN_Valid(rtn)) { probeAddr = (VOID *)RTN_Address(rtn); } #endif static BOOL first = TRUE; if (first) { first = FALSE; out << "Test SafeCopy in the image instrumentation callback." << endl << flush; SafeCopyTest(); } }
const string& Target2LibName(ADDRINT target) { PIN_LockClient(); const RTN rtn = RTN_FindByAddress(target); static const string _invalid_rtn("[Unknown image]"); string name; if( RTN_Valid(rtn) ) { name = IMG_Name(SEC_Img(RTN_Sec(rtn))); } else { name = _invalid_rtn; } PIN_UnlockClient(); return *new string(name); }
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); } } } } }
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; } } }
static VOID imageLoad(IMG img, VOID *v) { // Just instrument the main image. if (!IMG_IsMainExecutable(img)) 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)) { RTN_Open(rtn); for (INS ins=RTN_InsHead(rtn); INS_Valid(ins); ins=INS_Next(ins)) { INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)incCount, IARG_END); } RTN_Close(rtn); } } }
VOID ImageLoad(IMG img, VOID *v) { if (IMG_IsMainExecutable(img)) { std::cout << "Processing image " << IMG_Name( img ) << std::endl; RTN rtn = RTN_FindByName( img, "Add2" ); if (RTN_Valid( rtn )) { pf_Add = (AFUNPTR)RTN_Address( rtn ); fprintf( out, "address of application function = 0x%x\n", pf_Add ); fflush(out); } else std::cout << "Cannot find Add2" << std::endl; } }
VOID Trace(TRACE trace, VOID *v) { const RTN rtn = TRACE_Rtn(trace); if (! RTN_Valid(rtn)) return; const SEC sec = RTN_Sec(rtn); ASSERTX(SEC_Valid(sec)); const IMG img = SEC_Img(sec); ASSERTX(IMG_Valid(img)); if ( KnobNoSharedLibs.Value() && IMG_Type(img) == IMG_TYPE_SHAREDLIB) return; for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)) { // Record the registers into a dummy buffer so we can count them #define MAX_STATS_PER_BLOCK (128*1024) UINT16 buffer[MAX_STATS_PER_BLOCK]; INT32 count = RecordRegisters(bbl, buffer, MAX_STATS_PER_BLOCK); ASSERTX(count < MAX_STATS_PER_BLOCK); // Summarize the stats for the bbl in a 0 terminated list // This is done at instrumentation time UINT16 * stats = new UINT16[count]; memcpy(stats, buffer, count * sizeof(UINT16)); // Insert instrumentation to count the number of times the bbl is executed BBLSTATS * bblstats = new BBLSTATS(stats); INS_InsertCall(BBL_InsHead(bbl), IPOINT_BEFORE, AFUNPTR(docount), IARG_PTR, bblstats->_counter, IARG_THREAD_ID, IARG_END); // Remember the counter and stats so we can compute a summary at the end statsList.push_back(bblstats); } }
static VOID tpss_instrument_module(IMG img, VOID *data) { SYM sym; std::string::size_type pos; const char *module_name = tpss_extract_mod_name_with_ext(IMG_Name(img).c_str()); if (strcmp(module_name, "kernel32.dll") == 0) { for (sym = IMG_RegsymHead(img); SYM_Valid(sym) == TRUE; sym = SYM_Next(sym)) { /* in case of availablity of symbols for system libraries PIN can provide * decorated names so we need to undecorate it first */ std::string uname(SYM_Name(sym).c_str()); pos = uname.find("@"); if (pos != std::string::npos) { uname = uname.substr(0, pos); if (uname[0] == '_') { uname = uname.substr(1, std::string::npos); } } if (strcmp("LoadLibraryW", uname.c_str()) == 0) { RTN routine = RTN_FindByName(img, "LoadLibraryW"); if (RTN_Valid(routine)) { g_LoadLibraryW_ptr = RTN_ReplaceProbed(routine, (AFUNPTR)(tpss_LoadLibraryW_ver0)); } } } free((void *)(module_name)); } }
// 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); } } } }
// Count the number of RTN objects inside an IMG static int CountImageRtns(IMG img) { int numRtns = 0; 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; } numRtns++; } } return numRtns; }
void InsertProbe( IMG img, char * funcName) { /* 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"); } } } */ RTN allocRtn = RTN_FindByName(img, funcName); if (RTN_Valid(allocRtn) && RTN_IsSafeForProbedReplacement(allocRtn)) { fprintf (fp, "RTN_ReplaceSignatureProbed on %s\n", funcName); PROTO protoHeapAlloc = PROTO_Allocate( PIN_PARG(void *), CALLINGSTD_STDCALL, "protoHeapAlloc", PIN_PARG(WINDOWS::HANDLE), PIN_PARG(WINDOWS::DWORD),PIN_PARG(WINDOWS::DWORD), PIN_PARG_END() ); RTN_ReplaceSignatureProbed(allocRtn, AFUNPTR(ReplacementFunc), IARG_PROTOTYPE, protoHeapAlloc, IARG_ORIG_FUNCPTR, IARG_FUNCARG_ENTRYPOINT_VALUE, 0, IARG_FUNCARG_ENTRYPOINT_VALUE, 1, IARG_FUNCARG_ENTRYPOINT_VALUE, 2, IARG_CONTEXT, IARG_RETURN_IP, IARG_END); PROTO_Free( protoHeapAlloc ); }
static VOID on_module_loading(IMG img, VOID *data) { if (IMG_IsMainExecutable(img)) { RTN routine = RTN_FindByName(img, "foo"); if (!RTN_Valid(routine)) { routine = RTN_FindByName(img, "_foo"); } if (RTN_Valid(routine)) { PROTO foo_proto = PROTO_Allocate( PIN_PARG(int), CALLINGSTD_DEFAULT, "foo", PIN_PARG_END() ); AFUNPTR foo_ptr = RTN_ReplaceSignatureProbed(routine, (AFUNPTR)foo_rep, IARG_PROTOTYPE, foo_proto, IARG_ORIG_FUNCPTR, IARG_RETURN_IP, IARG_END); ASSERTX(foo_ptr != 0); } } }
void inst_func_summary(IMG img) { for (int i=0; i< sizeof(summary_table)/sizeof(summary_table[0]);i++) { if(IMG_Name(img).find(summary_table[i].lib_name)!=string::npos) { RTN summary_func; out<<"find summary dll"<<endl; summary_func = RTN_FindByName(img, summary_table[i].func_name.c_str());//summary_table[i].func_name); if (RTN_Valid(summary_func)) { RTN_Open(summary_func); out << "function summary: "<<endl; out << " Image: " << IMG_Name(img).c_str() << " Func: " << summary_table[i].func_name << endl; RTN_InsertCall(summary_func, IPOINT_BEFORE, (AFUNPTR)funcbegin, IARG_ADDRINT,& (summary_table[i]),IARG_REG_VALUE, REG_STACK_PTR ,IARG_RETURN_REGS, REG_INST_G0,IARG_END); RTN_InsertCall(summary_func, IPOINT_AFTER, (AFUNPTR)funcend, IARG_ADDRINT,& (summary_table[i]),IARG_FUNCRET_EXITPOINT_VALUE ,IARG_RETURN_REGS, REG_INST_G0,IARG_END); RTN_Close(summary_func); } } } }