static BOOL DebugInterpreter(THREADID tid, CONTEXT *ctxt, const string &cmd, string *result, VOID *) { TINFO_MAP::iterator it = ThreadInfos.find(tid); if (it == ThreadInfos.end()) return FALSE; TINFO *tinfo = it->second; std::string line = TrimWhitespace(cmd); *result = ""; if (line == "help") { result->append("mappings -- Mappings.\n"); return TRUE; } else if(line == "mappings") { tinfo->_os.str(""); tinfo->_os << "{"; //open JSON for( IMG img= APP_ImgHead(); IMG_Valid(img); img = IMG_Next(img) ) { const string& name = LEVEL_PINCLIENT::IMG_Name(img); tinfo->_os <<"\""<< name << "\":{"; //open img ADDRINT address = LEVEL_PINCLIENT::IMG_LowAddress(img); tinfo->_os << "\"start\":" << address << ","; address = LEVEL_PINCLIENT::IMG_HighAddress(img); tinfo->_os << "\"end\":" << address << ","; tinfo->_os << "\"sections\":" << "{"; //open sections for( SEC sec = IMG_SecHead(img); SEC_Valid(sec); sec = SEC_Next(sec)) { const string& name = LEVEL_PINCLIENT::SEC_Name(sec); if(name != "") { tinfo->_os << "\"" << name <<"\":{"; //open section ADDRINT address = LEVEL_PINCLIENT::SEC_Address(sec); tinfo->_os << "\"start\":" << address << ","; USIZE size = LEVEL_PINCLIENT::SEC_Size(sec); if(SEC_Valid(SEC_Next(sec))) { tinfo->_os << "\"size\":" << size << "},"; //close section }else { tinfo->_os << "\"size\":" << size << "}}"; //close section and sections } } } if(IMG_Valid(IMG_Next(img))) { tinfo->_os << "},"; //close img }else { tinfo->_os << "}}"; //close img and json } } *result = tinfo->_os.str(); return TRUE; } return FALSE; /* Unknown command */ }
BaseIRBuilder::BaseIRBuilder(__uint address, const std::string &dis) { RTN rtn; SEC sec; IMG img; this->address = address; this->branchTaken = false; this->branchTargetAddress = 0; this->disas = dis; this->needSetup = false; this->nextAddress = 0; this->imageName = "unknown"; this->sectionName = "unknown"; rtn = RTN_FindByAddress(address); if (RTN_Valid(rtn)) { sec = RTN_Sec(rtn); if (SEC_Valid(sec)) { this->sectionName = SEC_Name(sec); img = SEC_Img(sec); if (IMG_Valid(img)) { this->baseAddress = IMG_LowAddress(img); this->imageName = IMG_Name(img); } } } this->offset = this->address - this->baseAddress; this->routineName = RTN_FindNameByAddress(address); if (this->routineName.empty()) this->routineName = "unknown"; }
VOID MemWrite(THREADID tid, ADDRINT ea, ADDRINT eip ) { IMG imgR; string retName = "ANON", rR = "unknown"; thread_data_t *tdata = get_tls(tid); list<ADDRINT>::const_iterator sp_iter; for (sp_iter = tdata->data_sp.begin(); sp_iter != tdata->data_sp.end(); sp_iter++) { if ( *sp_iter == ea ) break; } if ( sp_iter != tdata->data_sp.end() ) { PIN_LockClient(); imgR = IMG_FindByAddress((ADDRINT)eip); PIN_UnlockClient(); if ( IMG_Valid(imgR) ) { retName = IMG_Name(imgR); } rR = RTN_FindNameByAddress((ADDRINT)eip); OutFile[tid] << tid << hex << "return address overwrite!!! " << ea << " " << eip << " " << retName << " " << rR << endl; } }
static void Instruction(INS ins, void *v) { INS_InsertPredicatedCall( ins, IPOINT_BEFORE, (AFUNPTR)do_count, IARG_END); // Filters out non memory reference instructions. if (!INS_IsMemoryRead(ins) && !INS_IsMemoryWrite(ins)) return; // Filters out references to stack. if (INS_IsStackRead(ins) || INS_IsStackWrite(ins)) return; // Filters out instructions out of main executable. IMG img = IMG_FindByAddress(INS_Address(ins)); if (!IMG_Valid(img) || !IMG_IsMainExecutable(img)) return; unsigned i; unsigned int mem_op = INS_MemoryOperandCount(ins); for (i = 0; i < mem_op; i++) { INS_InsertPredicatedCall( ins, IPOINT_BEFORE, (AFUNPTR)check_addr, IARG_INST_PTR, IARG_MEMORYOP_EA, i, IARG_END); } }
VOID Image(IMG img, VOID *v){ char szFilePath[260]; unsigned long index; GetLock(&lock, 1); if (process_start != 0){ ReleaseLock(&lock); return; } if (IMG_Valid(img)){ memset(szFilePath, 0, sizeof(szFilePath)); strncpy(szFilePath, IMG_Name(img).c_str(), sizeof(szFilePath)-1); index = 0; while (szFilePath[index] != 0){ szFilePath[index] = tolower(szFilePath[index]); index++; } if (strstr(szFilePath, KnobProcessToTrace.Value().c_str())){ process_start = IMG_LowAddress(img); process_end = IMG_HighAddress(img); } } ReleaseLock(&lock); }
/* Image instrumentation */ static void IMG_Instrumentation(IMG img, void *v) { /* Lock / Unlock the Analysis from a Entry point */ if (tracer::pintool::options::startAnalysisFromEntry) { tracer::pintool::options::startAnalysisFromEntry = false; /* IMG_LoadOffset(img) + IMG_Entry(img) for PIE binaries (see #524) */ tracer::pintool::options::startAnalysisFromAddress.insert(IMG_LoadOffset(img) + IMG_Entry(img)); } /* Lock / Unlock the Analysis from a symbol */ if (tracer::pintool::options::startAnalysisFromSymbol != nullptr){ RTN targetRTN = RTN_FindByName(img, tracer::pintool::options::startAnalysisFromSymbol); if (RTN_Valid(targetRTN)) { RTN_Open(targetRTN); RTN_InsertCall(targetRTN, IPOINT_BEFORE, (AFUNPTR) toggleWrapper, IARG_BOOL, true, IARG_END); RTN_InsertCall(targetRTN, IPOINT_AFTER, (AFUNPTR) toggleWrapper, IARG_BOOL, false, IARG_END); RTN_Close(targetRTN); } } /* Callback on routine entry */ std::map<const char *, PyObject *>::iterator it; for (it = tracer::pintool::options::callbackRoutineEntry.begin(); it != tracer::pintool::options::callbackRoutineEntry.end(); it++) { RTN targetRTN = RTN_FindByName(img, it->first); if (RTN_Valid(targetRTN)){ RTN_Open(targetRTN); RTN_InsertCall(targetRTN, IPOINT_BEFORE, (AFUNPTR)callbackRoutineEntry, IARG_CONTEXT, IARG_THREAD_ID, IARG_PTR, it->second, IARG_END); RTN_Close(targetRTN); } } /* Callback on routine exit */ for (it = tracer::pintool::options::callbackRoutineExit.begin(); it != tracer::pintool::options::callbackRoutineExit.end(); it++) { RTN targetRTN = RTN_FindByName(img, it->first); if (RTN_Valid(targetRTN)){ RTN_Open(targetRTN); RTN_InsertCall(targetRTN, IPOINT_AFTER, (AFUNPTR)callbackRoutineExit, IARG_CONTEXT, IARG_THREAD_ID, IARG_PTR, it->second, IARG_END); RTN_Close(targetRTN); } } /* * Callback when a new image is loaded. * This callback must be called even outside the range analysis. */ if (IMG_Valid(img)) tracer::pintool::callbackImageLoad(img); }
/* * process_loaded_image: Called every time when new image is loaded. */ static VOID process_loaded_image(IMG image, VOID *value) { if ( !IMG_Valid(image) || foundFunc) return; DoReplacementFunc( image, "StdCallFunctionToBeReplacedByPin"); }
static void reportError(ADDRINT addr) { fprintf (stderr, "BAD Fetch from 0x%08x\n", addr); for (IMG img= APP_ImgHead(); IMG_Valid(img); img = IMG_Next(img)) { fprintf (stderr, "%-30s: 0x%08x:0x%08x\n", IMG_Name(img).c_str(), IMG_LowAddress(img),IMG_HighAddress(img)); } exit (-1); }
static IMG FindNamedImg(const string& imgName) { // Visit every loaded image for (IMG img= APP_ImgTail(); IMG_Valid(img); img = IMG_Prev(img)) { if (IMG_Name(img) == imgName) return img; } return IMG_Invalid(); }
bool Profiler::HandleIgnoreInstCount(IMG img) { if (knob_->ValueBool("ignore_ic_pthread")) { if (!IMG_Valid(img)) return false; Image *image = sinfo_->FindImage(IMG_Name(img)); DEBUG_ASSERT(image); if (image->IsPthread()) return true; } return false; }
// Print the list of images currently loaded, with some information about each. static VOID PrintImageList() { for (IMG img= APP_ImgHead(); IMG_Valid(img); img = IMG_Next(img)) { ADDRESS_RANGE range = FindImageTextMargin(img); fprintf (trace, " L %-40s %2d [0x%llx:0x%llx] offset 0x%llx %4d RTNs\n", IMG_Name(img).c_str(), (int)IMG_Id(img), (unsigned long long)range._low, (unsigned long long)range._high, (unsigned long long)IMG_LoadOffset(img), CountImageRtns (img)); } }
static void InstrumentRtn(RTN rtn, VOID *) { ADDRINT a = RTN_Address(rtn); IMG img = IMG_FindByAddress(a); if (IMG_Valid(img) && IMG_IsMainExecutable(img)) { RTN_Open(rtn); RTN_InsertCall(rtn, IPOINT_BEFORE, AFUNPTR(FunctionHook), IARG_ADDRINT, a, IARG_END); RTN_Close(rtn); } }
// Print the list of images currently loaded, with some information about each. static VOID PrintImageList() { for (IMG img= APP_ImgHead(); IMG_Valid(img); img = IMG_Next(img)) { int nSecs; int nRtns; CountImageSecsAndRtns (img, &nSecs, &nRtns); fprintf (trace, " L %-40s %2d [0x%lx:0x%lx] offset 0x%lx %2d SECs %4d RTNs\n", IMG_Name(img).c_str(), IMG_Id(img), (unsigned long)IMG_LowAddress(img), (unsigned long)IMG_HighAddress(img), (unsigned long)IMG_LoadOffset(img), nSecs, nRtns); } }
bool Profiler::HandleIgnoreMemAccess(IMG img) { if (!IMG_Valid(img)) return true; Image *image = sinfo_->FindImage(IMG_Name(img)); DEBUG_ASSERT(image); if (image->IsPthread()) return true; if (knob_->ValueBool("ignore_lib")) { if (image->IsCommonLib()) return true; } return false; }
static BOOL traceFromExecutable(TRACE trace) { RTN rtn = TRACE_Rtn(trace); if (!RTN_Valid(rtn)) return FALSE; SEC sec = RTN_Sec(rtn); if (!SEC_Valid(sec)) return FALSE; IMG img = SEC_Img(sec); if (!IMG_Valid(img)) return FALSE; return IMG_IsMainExecutable(img); }
static VOID Instruction(INS ins, VOID *v) { IMG img = IMG_FindByAddress(INS_Address(ins)); if (IMG_Valid(img)) { numTimesImgFoundInInstrumentation++; } else { numTimesImgNotFoundInInstrumentation++; } INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)AnalysisFindImg, IARG_INST_PTR, IARG_END); }
static VOID AnalysisFindImg (ADDRINT ip) { PIN_LockClient(); IMG img = IMG_FindByAddress(ip); PIN_UnlockClient(); if (IMG_Valid(img)) { numTimesImgFoundInAnalysis++; } else { numTimesImgNotFoundInAnalysis++; } }
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 ""; }
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; }
VOID instrumentTrace(TRACE trace, VOID *v) { IMG img = IMG_FindByAddress(TRACE_Address(trace)); if (!IMG_Valid(img) || !IMG_IsMainExecutable(img)) return; const char* imageName = IMG_Name(img).c_str(); for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)) { for (INS ins = BBL_InsHead(bbl); INS_Valid(ins); ins = INS_Next(ins)) { processMemoryWriteInstruction(ins, imageName); processMemoryReadInstruction(ins, imageName); } } }
/** * Given an address, this function determines the name of the loaded module the * address belongs to. If the address does not belong to any module, the empty * string is returned. **/ std::string getModule(ADDRINT address) { // To find the module name of an address, iterate over all sections of all // modules until a section is found that contains the address. for(IMG img=APP_ImgHead(); IMG_Valid(img); img = IMG_Next(img)) { for(SEC sec=IMG_SecHead(img); SEC_Valid(sec); sec = SEC_Next(sec)) { if (address >= SEC_Address(sec) && address < SEC_Address(sec) + SEC_Size(sec)) { return extractFilename(IMG_Name(img)); } } } return ""; }
/** * Determines whether a given address belongs to a known module or not. **/ bool isUnknownAddress(ADDRINT address) { // An address belongs to a known module, if the address belongs to any // section of any module in the target address space. for(IMG img=APP_ImgHead(); IMG_Valid(img); img = IMG_Next(img)) { for(SEC sec=IMG_SecHead(img); SEC_Valid(sec); sec = SEC_Next(sec)) { if (address >= SEC_Address(sec) && address < SEC_Address(sec) + SEC_Size(sec)) { return false; } } } return true; }
static VOID tpss_on_module_loading(IMG img, VOID *data) { unsigned long origAttrs = 0; if (IMG_Valid(img)) { if (IMG_IsMainExecutable(img)) { g_tpss_entry_point = (void(*)())RTN_ReplaceProbed( RTN_FindByAddress(IMG_Entry(img)), (AFUNPTR)tpss_mainStartup); } else { tpss_instrument_module(img, data); } } }
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); } }
VOID PIN_FAST_ANALYSIS_CALL LogBBL(ADDRINT addr) { PIN_LockClient(); IMG img = IMG_FindByAddress(addr); PIN_UnlockClient(); if (IMG_Valid(img)){ std::set<ADDRINT> *s = bbls[IMG_Name(img)]; if (s == NULL){ s = new std::set<ADDRINT> (); bbls[IMG_Name(img)] = s; } s->insert(addr - IMG_LowAddress(img)); } }
int main(INT32 argc, CHAR **argv) { PIN_InitSymbols(); if (PIN_Init(argc,argv)) return 1; IMG img = IMG_Open(KnobInputFile); if (!IMG_Valid(img)) { std::cout << "Could not open " << KnobInputFile.Value() << endl; return 1; } RTN_FindNameByAddress(0x123); PIN_LockClient(); PIN_UnlockClient(); IMG_Close(img); return 0; }
int main(INT32 argc, CHAR **argv) { PIN_InitSymbols(); if( PIN_Init(argc,argv) ) { return Usage(); } IMG img = IMG_Open(KnobInputFile); if (!IMG_Valid(img)) { std::cout << "Could not open " << KnobInputFile.Value() << endl; exit(1); } std::cout << hex; rtnInternalRangeList.clear(); for (SEC sec = IMG_SecHead(img); SEC_Valid(sec); sec = SEC_Next(sec)) { std::cout << "Section: " << setw(8) << SEC_Address(sec) << " " << SEC_Name(sec) << endl; for (RTN rtn = SEC_RtnHead(sec); RTN_Valid(rtn); rtn = RTN_Next(rtn)) { std::cout << " Rtn: " << setw(8) << hex << RTN_Address(rtn) << " " << RTN_Name(rtn) << endl; string path; INT32 line; PIN_GetSourceLocation(RTN_Address(rtn), NULL, &line, &path); if (path != "") { std::cout << "File " << path << " Line " << line << endl; } RTN_Open(rtn); if (!INS_Valid(RTN_InsHead(rtn))) { RTN_Close(rtn); continue; } RTN_INTERNAL_RANGE rtnInternalRange; rtnInternalRange.start = INS_Address(RTN_InsHead(rtn)); rtnInternalRange.end = INS_Address(RTN_InsHead(rtn)) + INS_Size(RTN_InsHead(rtn)); INS lastIns = INS_Invalid(); for (INS ins = RTN_InsHead(rtn); INS_Valid(ins); ins = INS_Next(ins)) { std::cout << " " << setw(8) << hex << INS_Address(ins) << " " << INS_Disassemble(ins) << endl; if (INS_Valid(lastIns)) { if ((INS_Address(lastIns) + INS_Size(lastIns)) == INS_Address(ins)) { rtnInternalRange.end = INS_Address(ins)+INS_Size(ins); } else { rtnInternalRangeList.push_back(rtnInternalRange); std::cout << " rtnInternalRangeList.push_back " << setw(8) << hex << rtnInternalRange.start << " " << setw(8) << hex << rtnInternalRange.end << endl; // make sure this ins has not already appeared in this RTN for (vector<RTN_INTERNAL_RANGE>::iterator ri = rtnInternalRangeList.begin(); ri != rtnInternalRangeList.end(); ri++) { if ((INS_Address(ins) >= ri->start) && (INS_Address(ins)<ri->end)) { std::cout << "***Error - above instruction already appeared in this RTN\n"; std::cout << " in rtnInternalRangeList " << setw(8) << hex << ri->start << " " << setw(8) << hex << ri->end << endl; exit (1); } } rtnInternalRange.start = INS_Address(ins); rtnInternalRange.end = INS_Address(ins) + INS_Size(ins); } } lastIns = ins; } RTN_Close(rtn); rtnInternalRangeList.clear(); } } IMG_Close(img); }
// Replay the image log. // We run this before the each instruction of the code as an analysis routine. // So we eat up the image loads one instruction at a time! // We can also call it before PIN_StartProgram, to check that queuing // the replay calls up works. // static void ReplayImageEntry() { if (feof(imgLog)) return; char tag = fgetc(imgLog); switch (tag) { case 'L': { string imageName; ADDRINT startAddr; ADDRINT offset; USIZE size; BOOL mainExe; vector<RTN_INFO> rtns; ParseImageLoadLine(imageName, &startAddr, &size, &offset, &mainExe, &rtns); if (KnobVerbose) fprintf (stderr, "Replaying load for %s, address: %llx offset: %llx, size: %lx\n", imageName.c_str(), (unsigned long long)startAddr, (unsigned long long)offset, (long)size); // Create a temporary IMG object IMG img = IMG_CreateAt(imageName.c_str(), startAddr, size, offset, mainExe); ASSERT(IMG_Valid(img), "IMG_CreateAt for " + imageName + " is invalid"); // Populate the IMG object with recorded RTNs PIN_LockClient(); for (vector<RTN_INFO>::iterator it = rtns.begin(); it < rtns.end(); it++) { RTN rtn = RTN_CreateAt(it->startAddr, it->name); ASSERT(RTN_Valid(rtn), "Failed to create RTN " + it->name + " at address " + hexstr(it->startAddr)); } // And, finally, inform Pin that it is all there, which will invoke // image load callbacks. IMG_ReplayImageLoad(img); PIN_UnlockClient(); break; } case 'U': { string imageName; ParseImageUnloadLine(imageName); IMG img = FindNamedImg(imageName); if (KnobVerbose) fprintf (stderr, "Replaying unload for %s\n", imageName.c_str()); // And, finally, inform Pin that it has gone, which will invoke // image unload callbacks. PIN_LockClient(); PIN_ReplayImageUnload(img); PIN_UnlockClient(); break; } default: fprintf (trace, "Unexpected line in log file starting with '%c'\n", tag); exit(1); } }
// ------------------------------------------------------------- // STool_LibraryNameByID // ------------------------------------------------------------- // Return pointer to the name of the library with the given ID, // or <unknown_library>, if the ID is invalid. // Note: the user should *not* deallocate the returned pointer const char* STool_LibraryNameByID(UINT32 libID) { IMG img = IMG_FindImgById(libID); if( IMG_Valid(img) && strlen(IMG_Name(img).c_str()) > 0 ) return IMG_Name(img).c_str(); else return "<unknown_library>"; }
// 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; } }