void Instrumentcall (BPatch_image *appImage, BPatch_process *appProcess) { unsigned insertion = 0; unsigned i = 0; BPatch_Vector<BPatch_function *> *vfunctions = appImage->getProcedures (true); cout << vfunctions->size() << " functions found in binary " << endl; cout << "Parsing functions " << flush; while (i < vfunctions->size()) { char name[1024], sharedlibname[1024]; BPatch_function *f = (*vfunctions)[i]; (f->getModule())->getFullName (sharedlibname, 1024); f->getName (name, 1024); BPatch_Vector<BPatch_point *> *vpoints = f->findPoint (BPatch_subroutine); unsigned j = 0; while (j < vpoints->size()) { BPatch_function *called = ((*vpoints)[j])->getCalledFunction(); if (NULL != called) { char calledname[1024]; called->getName (calledname, 1024); if (strcmp (calledname, "functionB") == 0) { string s = "functionA"; BPatch_function *patch = getRoutine (s, appImage); if (patch != NULL) { bool replaced = appProcess->replaceFunctionCall (*((*vpoints)[j]), *patch); if (replaced) cout << "call to functionA has been successfully replaced by a call to functionB" << endl; else cout << "call to functionA failed to replace a call to functionB" << endl; insertion++; } } } j++; } i++; } cout << endl; cout << "insertion = " << insertion << endl; }
/* * BPatch_addressSpace::replaceFunctionCall * * Replace a function call with a call to a different function. Returns true * upon success, false upon failure. * * point The call site that is to be changed. * newFunc The function that the call site will now call. */ bool BPatch_addressSpace::replaceFunctionCall(BPatch_point &point, BPatch_function &newFunc) { char name[1024]; newFunc.getName(name, 1024); // Can't make changes to code when mutations are not active. if (!getMutationsActive()) return false; assert(point.point && newFunc.lowlevel_func()); /* PatchAPI stuffs */ AddressSpace* addr_space = point.getAS(); DynModifyCallCommand* rep_call = DynModifyCallCommand::create(addr_space, point.point->block(), newFunc.lowlevel_func(), point.point->func()); addr_space->patcher()->add(rep_call); /* End of PatchAPI */ if (pendingInsertions == NULL) { // Trigger it now bool tmp; finalizeInsertionSet(false, &tmp); } return true; }
void instrCodeNode::prepareCatchupInstr(pdvector<instReqNode *> &nodes_for_catchup) { if (instrCatchuped()) return; for (unsigned instIter = 0; instIter < V.instRequests.size(); instIter++) { instReqNode *curInstReq = V.instRequests[instIter]; //prepareCatchupInstr_debug(V.instRequests[instIter]); if (pd_debug_catchup) { char buf[2048]; BPatch_function *bpf = const_cast<BPatch_function *>(curInstReq->Point()->getFunction()); if (! bpf) { sprintf(buf, "<bad function> in instReq"); } else bpf->getName(buf, 2048); cerr << " looking at instReq [" << instIter << "], in func: " << buf <<endl; } BPatchSnippetHandle *sh = curInstReq->snippetHandle(); } // don't mark catchup as having completed because we don't want to mark // this until the processMetFocusNode has completed initiating catchup for // all of the threads }
static void printCallingSites (int id, int total, char *name, string sharedlibname, BPatch_Vector<BPatch_point *> *vpoints) { if (vpoints->size() > 0) { unsigned j = 0; cout << id << " of " << total << " - Calling sites for " << name << " within " << sharedlibname << " (num = " << vpoints->size() << "):" << endl; while (j < vpoints->size()) { BPatch_function *called = ((*vpoints)[j])->getCalledFunction(); if (NULL != called) { char calledname[1024]; called->getName (calledname, 1024); cout << j+1 << " Calling " << calledname; BPatch_procedureLocation loc = ((*vpoints)[j])->getPointType(); if (loc == BPatch_entry) cout << " (entry)" << endl; else if (loc == BPatch_exit) cout << " (exit)" << endl; else if (loc == BPatch_subroutine) cout << " (subroutine)" << endl; else cout << " (unknown point type)" << endl; } else { cout << j+1 << " Undetermined " << endl; } j++; } cout << endl; } }
// // findVariable // scp - a BPatch_point that defines the scope of the current search // name - name of the variable to find. // BPatch_variableExpr *BPatch_image::findVariableInScope(BPatch_point &scp, const char *name) { // Get the function to search for it's local variables. // XXX - should really use more detailed scoping info here - jkh 6/30/99 BPatch_function *func = const_cast<BPatch_function *> (scp.getFunction()); if (!func) { pdstring msg = pdstring("point passed to findVariable lacks a function\n address point type passed?"); showErrorCallback(100, msg); return NULL; } BPatch_localVar *lv = func->findLocalVar(name); if (!lv) { // look for it in the parameter scope now lv = func->findLocalParam(name); } if (lv) { // create a local expr with the correct frame offset or absolute // address if that is what is needed return new BPatch_variableExpr(proc, (void *) lv->getFrameOffset(), lv->getRegister(), lv->getType(), lv->getStorageClass(), &scp); } // finally check the global scope. // return findVariable(name); /* If we have something else to try, don't report errors on this failure. */ bool reportErrors = true; char mangledName[100]; func->getName( mangledName, 100 ); char * lastScoping = NULL; if( strrchr( mangledName, ':' ) != NULL ) { reportErrors = false; } BPatch_variableExpr * gsVar = findVariable( name, reportErrors ); if( gsVar == NULL ) { /* Try finding it with the function's scope prefixed. */ if( (lastScoping = strrchr( mangledName, ':' )) != NULL ) { * (lastScoping + sizeof(char)) = '\0'; char scopedName[200]; memmove( scopedName, mangledName, strlen( mangledName ) ); memmove( scopedName + strlen( mangledName ), name, strlen( name ) ); scopedName[ strlen( mangledName ) + strlen( name ) ] = '\0'; bperr( "Searching for scoped name '%s'\n", scopedName ); gsVar = findVariable( scopedName ); } } return gsVar; }
void instrumentModule(BPatch_module *module) { char funcname[BUFFER_STRING_LEN]; instrumentPLTSection(module); std::vector<BPatch_function *>* functions; functions = module->getProcedures(); for (unsigned i = 0; i < functions->size(); i++) { BPatch_function *function = functions->at(i); function->getName(funcname, BUFFER_STRING_LEN); instrumentFunction(function); } }
static void ShowFunctions (BPatch_image *appImage) { BPatch_Vector<BPatch_function *> *vfunctions = appImage->getProcedures (false); cout << PACKAGE_NAME << ": " << vfunctions->size() << " functions found in binary " << endl; unsigned i = 0; while (i < vfunctions->size()) { char name[1024]; BPatch_function *f = (*vfunctions)[i]; f->getName (name, 1024); if (VerboseLevel) { char mname[1024], tname[1024], modname[1024]; f->getMangledName (mname, 1024); f->getTypedName (tname, 1024); f->getModuleName (modname, 1024); cout << " * " << i+1 << " of " << vfunctions->size() << ", Name: " << name << endl << " Mangled Name: " << mname << endl << " Typed Name : " << tname << endl << " Module name : " << modname << endl << " Base address: " << f->getBaseAddr() << endl << " Instrumentable? " << (f->isInstrumentable()?"yes":"no") << endl << " In shared library? " << (f->isSharedLib()?"yes":"no") << endl << " Number of BB: " << getBasicBlocksSize(f) << endl; if (f->isSharedLib()) { char sharedlibname[1024]; BPatch_module *mod = f->getModule(); mod->getFullName (sharedlibname, 1024); cout << " Full library name: " << sharedlibname << endl; } cout << endl; } else { cout << name << endl; } i++; } }
void handleModule(BPatch_module *mod, const char *name) { char funcname[BUFFER_STRING_LEN]; // get list of all functions std::vector<BPatch_function *>* functions; functions = mod->getProcedures(); // for each function ... for (unsigned i = 0; i < functions->size(); i++) { BPatch_function *function = functions->at(i); function->getName(funcname, BUFFER_STRING_LEN); printf(" FUNC: %s (%lx)\n", funcname, (unsigned long)function->getBaseAddr()); } }
static void ShowFunctions (BPatch_image *appImage) { BPatch_Vector<BPatch_function *> *vfunctions = appImage->getProcedures (false); cout << PACKAGE_NAME << ": " << vfunctions->size() << " functions found in binary " << endl; unsigned i = 0; while (i < vfunctions->size()) { char name[1024]; BPatch_function *f = (*vfunctions)[i]; f->getName (name, 1024); char mname[1024], tname[1024], modname[1024]; f->getMangledName (mname, 1024); f->getTypedName (tname, 1024); f->getModuleName (modname, 1024); cout << " * " << i+1 << " of " << vfunctions->size() << ", Name: " << name << endl << " Mangled Name: " << mname << endl << " Typed Name : " << tname << endl << " Module name : " << modname << endl << " Base address: " << f->getBaseAddr() << endl << " Instrumentable? " << (f->isInstrumentable()?"yes":"no") << endl << " In shared library? " << (f->isSharedLib()?"yes":"no") << endl; if (f->isSharedLib()) { //Old Dyninst API < 9.x //char sharedlibname[1024]; //mod->getFullName (sharedlibname, 1024); BPatch_module *mod = f->getModule(); string sharedlibname; sharedlibname = mod->getObject()->name(); cout << " Full library name: " << sharedlibname << endl; } cout << endl; i++; } }
// // Start Test Case #3 - (overload operator) // // static int mutatorTest(BPatch_thread *appThread, BPatch_image *appImage) test_results_t test5_3_Mutator::executeTest() { BPatch_Vector<BPatch_function *> bpfv; const char *fn = "overload_op_test::func_cpp"; if (NULL == appImage->findFunction(fn, bpfv) || !bpfv.size() || NULL == bpfv[0]){ logerror("**Failed** test #3 (overloaded operation)\n"); logerror(" Unable to find function %s\n", fn); return FAILED; } BPatch_function *f1 = bpfv[0]; BPatch_Vector<BPatch_point *> *point3_1 = f1->findPoint(BPatch_subroutine); assert(point3_1); if (point3_1->size() == 0) { logerror("**Failed test5_3 (overload operation)\n"); logerror(" Can't find overloaded operator call points\n"); return FAILED; } unsigned int index = 0; char fn3[256]; BPatch_function *func; while (index < point3_1->size()) { if ((func = (*point3_1)[index]->getCalledFunction()) != NULL && !strcmp("overload_op_test::operator++", func->getName(fn3, 256))) { break; } index ++; } if(!func) { logerror("**Failed** test #3 (overload operation)\n"); logerror(" Can't find the overload operator\n"); return FAILED; } if (0 != strcmp("overload_op_test::operator++", func->getName(fn3, 256))) { logerror("**Failed** test #3 (overload operation)\n"); logerror(" Can't find the overloaded operator\n"); return FAILED; } // FIXME It caught fprintf... BPatch_Vector<BPatch_point *> *point3_2 = func->findPoint(BPatch_exit); assert(point3_2); bpfv.clear(); const char *fn2 = "overload_op_test::call_cpp"; if (NULL == appImage->findFunction(fn2, bpfv) || !bpfv.size() || NULL == bpfv[0]){ logerror("**Failed** test #3 (overloaded operation)\n"); logerror(" Unable to find function %s\n", fn2); return FAILED; } BPatch_function *call3_1 = bpfv[0]; BPatch_variableExpr *this2 = appImage->findVariable("test5_3_test3"); if (this2 == NULL) { logerror( "**Failed** test #3 (overloaded operation)\n"); logerror( "Unable to find variable \"test5_3_test3\"\n"); return FAILED; } BPatch_Vector<BPatch_snippet *> opArgs; BPatch_arithExpr expr2_0(BPatch_addr, *this2); opArgs.push_back(&expr2_0); opArgs.push_back(new BPatch_retExpr()); BPatch_funcCallExpr call3_1Expr(*call3_1, opArgs); checkCost(call3_1Expr); appAddrSpace->insertSnippet(call3_1Expr, *point3_2); // int tag = 1; // while (tag != 0) {} return PASSED; }
int main (int argc, char **argv) { if(!parseOptions(argc,argv)) { return EXIT_FAILURE; } BPatch bpatch; BPatch_binaryEdit *appBin = bpatch.openBinary (originalBinary, !instrumentLibraries.empty()); if (appBin == NULL) { cerr << "Failed to open binary" << endl; return EXIT_FAILURE; } if (!appBin->loadLibrary (instLibrary)) { cerr << "Failed to open instrumentation library." << endl; cerr << "It needs to be located in the current working directory." << endl; return EXIT_FAILURE; } BPatch_image *appImage = appBin->getImage (); /* Find code coverage functions in the instrumentation library */ BPatch_function *initAflForkServer = findFuncByName (appImage, (char *) "initAflForkServer"); BPatch_function *bbCallback = findFuncByName (appImage, (char *) "bbCallback"); if (!initAflForkServer || !bbCallback ) { cerr << "Instrumentation library lacks callbacks!" << endl; return EXIT_FAILURE; } //get and iterate over all modules, instrumenting only the default and manualy specified ones vector < BPatch_module * >*modules = appImage->getModules (); vector < BPatch_module * >::iterator moduleIter; BPatch_module *defaultModule = NULL; string defaultModuleName; for (moduleIter = modules->begin (); moduleIter != modules->end (); ++moduleIter) { //find default module name char moduleName[1024]; (*moduleIter)->getName (moduleName, 1024); if (string (moduleName).find ("DEFAULT_MODULE") != string::npos) { defaultModuleName = "DEFAULT_MODULE"; } } if(defaultModuleName.empty()) defaultModuleName = string(originalBinary).substr(string(originalBinary).find_last_of("\\/")+1); int bbIndex = 0; for (moduleIter = modules->begin (); moduleIter != modules->end (); ++moduleIter) { char moduleName[1024]; (*moduleIter)->getName (moduleName, 1024); if ((*moduleIter)->isSharedLib ()) { if (instrumentLibraries.find (moduleName) == instrumentLibraries.end ()) { cout << "Skipping library: " << moduleName << endl; continue; } } if (string (moduleName).find (defaultModuleName) != string::npos) { defaultModule = (*moduleIter); if(skipMainModule) continue; } cout << "Instrumenting module: " << moduleName << endl; vector < BPatch_function * >*allFunctions = (*moduleIter)->getProcedures (); vector < BPatch_function * >::iterator funcIter; // iterate over all functions in the module for (funcIter = allFunctions->begin (); funcIter != allFunctions->end (); ++funcIter) { BPatch_function *curFunc = *funcIter; char funcName[1024]; curFunc->getName (funcName, 1024); if(string (funcName) == string("_start")) continue; // here's a bug on hlt insertBBCallback (appBin, curFunc, funcName, bbCallback, &bbIndex); } } //if entrypoint set ,find function , else find _init BPatch_function *funcToPatch = NULL; if(!entryPoint) { BPatch_Vector<BPatch_function*> funcs; defaultModule->findFunction("_init", funcs); if(!funcs.size()) { cerr << "Couldn't locate _init, specify entry point manualy. "<< endl; return EXIT_FAILURE; } // there should really be only one funcToPatch = funcs[0]; } else { funcToPatch = defaultModule->findFunctionByEntry(entryPoint); } if(!funcToPatch) { cerr << "Couldn't locate function at given entry point. "<< endl; return EXIT_FAILURE; } if(!insertCallToInit (appBin, initAflForkServer,defaultModule,funcToPatch)){ cerr << "Could not insert init callback at given entry point." << endl; return EXIT_FAILURE; } cout << "Saving the instrumented binary to " << instrumentedBinary << "..." << endl; // Output the instrumented binary if (!appBin->writeFile (instrumentedBinary)) { cerr << "Failed to write output file: " << instrumentedBinary << endl; return EXIT_FAILURE; } if(!runtimeLibraries.empty()) { cout << "Instrumenting runtime libraries." << endl; set<string>::iterator rtLibIter ; for(rtLibIter = runtimeLibraries.begin(); rtLibIter != runtimeLibraries.end(); rtLibIter++) { BPatch_binaryEdit *libBin = bpatch.openBinary ((*rtLibIter).c_str(), false); if (libBin == NULL) { cerr << "Failed to open binary "<< *rtLibIter << endl; return EXIT_FAILURE; } libBin->loadLibrary (instLibrary); BPatch_image *libImg = libBin->getImage (); vector < BPatch_module * >*modules = libImg->getModules (); moduleIter = modules->begin (); ++moduleIter; for ( ; moduleIter != modules->end (); ++moduleIter) { char moduleName[1024]; (*moduleIter)->getName (moduleName, 1024); cout << "Instrumenting module: " << moduleName << endl; vector < BPatch_function * >*allFunctions = (*moduleIter)->getProcedures (); vector < BPatch_function * >::iterator funcIter; // iterate over all functions in the module for (funcIter = allFunctions->begin (); funcIter != allFunctions->end (); ++funcIter) { BPatch_function *curFunc = *funcIter; char funcName[1024]; curFunc->getName (funcName, 1024); if(string (funcName) == string("_start")) continue; insertBBCallback (libBin, curFunc, funcName, bbCallback, &bbIndex); } } if (!libBin->writeFile ((*rtLibIter + ".ins").c_str())) { cerr << "Failed to write output file: " <<(*rtLibIter + ".ins").c_str() << endl; return EXIT_FAILURE; } else { cout << "Saved the instrumented library to " << (*rtLibIter + ".ins").c_str() << "." << endl; } } } cout << "All done! Happy fuzzing!" << endl; return EXIT_SUCCESS; }
// static int mutatorTest( BPatch_thread * appThread, BPatch_image * appImage ) { test_results_t test_stack_3_Mutator::executeTest() { bool passedTest; BPatch::bpatch->setInstrStackFrames(true); appProc->continueExecution(); static const frameInfo_t correct_frame_info[] = { #if defined( os_linux_test ) && (defined( arch_x86_test ) || defined( arch_x86_64_test )) { true, true, BPatch_frameNormal, "_dl_sysinfo_int80" }, #endif #if defined( os_aix_test ) && defined( arch_power_test ) /* AIX uses kill(), but the PC of a process in a syscall can not be correctly determined, and appears to be the address to which the syscall function will return. */ #elif defined( os_windows_test ) && (defined( arch_x86 ) || defined( arch_x86_64_test )) /* Windows/x86 does not use kill(), so its lowermost frame will be something unidentifiable in a system DLL. */ { false, false, BPatch_frameNormal, NULL }, #else { true, false, BPatch_frameNormal, "kill" }, #endif #if ! defined( os_windows_test ) /* Windows/x86's stop_process_() calls DebugBreak(); it's apparently normal to lose this frame. */ { true, false, BPatch_frameNormal, "stop_process_" }, #endif { true, false, BPatch_frameNormal, "test_stack_3_func3" }, { true, false, BPatch_frameTrampoline, NULL }, /* On AIX and x86 (and others), if our instrumentation fires before frame construction or after frame destruction, it's acceptable to not report the function (since, after all, it doesn't have a frame on the stack. */ { true, true, BPatch_frameNormal, "test_stack_3_func2" }, { true, false, BPatch_frameNormal, "test_stack_3_func1" }, { true, false, BPatch_frameNormal, "test_stack_3_mutateeTest" }, { true, false, BPatch_frameNormal, "main" } }; /* Wait for the mutatee to stop in test_stack_3_func1(). */ if (waitUntilStopped( bpatch, appProc, 1, "getCallStack through instrumentation") < 0) { appProc->terminateExecution(); return FAILED; } /* Instrument test_stack_3_func2() to call test_stack_3_func3(), which will trip another breakpoint. */ BPatch_Vector<BPatch_function *> instrumentedFunctions; const char *fName = "test_stack_3_func2"; appImage->findFunction(fName, instrumentedFunctions ); if (instrumentedFunctions.size() != 1) { // FIXME Print out a useful error message logerror("**Failed** test_stack_3\n"); logerror(" Unable to find function '%s'\n", fName); appProc->terminateExecution(); return FAILED; } BPatch_Vector<BPatch_point *> * functionEntryPoints = instrumentedFunctions[0]->findPoint( BPatch_entry ); if (functionEntryPoints->size() != 1) { // FIXME Print out a useful error message logerror("**Failed** test_stack_3\n"); logerror(" Unable to find entry point to function '%s'\n", fName); appProc->terminateExecution(); return FAILED; } BPatch_Vector<BPatch_function *> calledFunctions; const char *fName2 = "test_stack_3_func3"; appImage->findFunction(fName2, calledFunctions ); if (calledFunctions.size() != 1) { //FIXME Print out a useful error message logerror("**Failed** test_stack_3\n"); logerror(" Unable to find function '%s'\n", fName2); appProc->terminateExecution(); return FAILED; } BPatch_Vector<BPatch_snippet *> functionArguments; BPatch_funcCallExpr functionCall( * calledFunctions[0], functionArguments ); appProc->insertSnippet( functionCall, functionEntryPoints[0] ); /* Repeat for all three types of instpoints. */ BPatch_Vector<BPatch_point *> * functionCallPoints = instrumentedFunctions[0]->findPoint( BPatch_subroutine ); if (functionCallPoints->size() != 1) { logerror("**Failed** test_stack_3\n"); logerror(" Unable to find subroutine call points in '%s'\n", fName); appProc->terminateExecution(); return FAILED; } appProc->insertSnippet( functionCall, functionCallPoints[0] ); BPatch_Vector<BPatch_point *> * functionExitPoints = instrumentedFunctions[0]->findPoint( BPatch_exit ); if (functionExitPoints->size() != 1) { logerror("**Failed** test_stack_3\n"); logerror(" Unable to find exit points in '%s'\n", fName); appProc->terminateExecution(); return FAILED; } appProc->insertSnippet( functionCall, functionExitPoints[0] ); #if defined( DEBUG ) for( int i = 0; i < 80; i++ ) { ptrace( PTRACE_SINGLESTEP, appThread->getPid(), NULL, NULL ); } for( int i = 80; i < 120; i++ ) { ptrace( PTRACE_SINGLESTEP, appThread->getPid(), NULL, NULL ); BPatch_Vector<BPatch_frame> stack; appThread->getCallStack( stack ); dprintf("single-step stack walk, %d instructions after stop for instrumentation.\n", i ); for( unsigned i = 0; i < stack.size(); i++ ) { char name[ 40 ]; BPatch_function * func = stack[i].findFunction(); if( func == NULL ) { strcpy( name, "[UNKNOWN]" ); } else { func->getName( name, 40 ); } dprintf(" %10p: %s, fp = %p\n", stack[i].getPC(), name, stack[i].getFP() ); } /* end stack walk dumper */ dprintf("end of stack walk.\n" ); } /* end single-step iterator */ #endif /* defined( DEBUG ) */ /* After inserting the instrumentation, let it be called. */ appProc->continueExecution(); /* Wait for the mutatee to stop because of the instrumentation we just inserted. */ if (waitUntilStopped( bpatch, appProc, 1, "getCallStack through instrumentation (entry)") < 0) { appProc->terminateExecution(); return FAILED; } passedTest = true; if( !checkStack( appThread, correct_frame_info, sizeof(correct_frame_info)/sizeof(frameInfo_t), 3, "getCallStack through instrumentation (entry)" ) ) { passedTest = false; } /* Repeat for other two types of instpoints. */ appProc->continueExecution(); /* Wait for the mutatee to stop because of the instrumentation we just inserted. */ if (waitUntilStopped( bpatch, appProc, 1, "getCallStack through instrumentation (call)") < 0) { appProc->terminateExecution(); return FAILED; } if( !checkStack( appThread, correct_frame_info, sizeof(correct_frame_info)/sizeof(frameInfo_t), 3, "getCallStack through instrumentation (call)" ) ) { passedTest = false; } appProc->continueExecution(); /* Wait for the mutatee to stop because of the instrumentation we just inserted. */ if (waitUntilStopped( bpatch, appProc, 1, "getCallStack through instrumentation (exit)") < 0) { appProc->terminateExecution(); return FAILED; } if( !checkStack( appThread, correct_frame_info, sizeof(correct_frame_info)/sizeof(frameInfo_t), 3, "getCallStack through instrumentation (exit)" ) ) { passedTest = false; } if (passedTest) logerror("Passed test #3 (unwind through base and mini tramps)\n"); /* Return the mutatee to its normal state. */ appProc->continueExecution(); while (!appProc->isTerminated()) { // Workaround for issue with pgCC_high mutatee bpatch->waitForStatusChange(); } if (passedTest) return PASSED; return FAILED; } /* end mutatorTest3() */
test_results_t test1_36_Mutator::executeTest() { const char *funcName = "test1_36_func1"; BPatch_Vector<BPatch_function *> found_funcs; if ((NULL == appImage->findFunction(funcName, found_funcs)) || !found_funcs.size()) { logerror(" Unable to find function %s\n", funcName); return FAILED; } if (1 < found_funcs.size()) { logerror("%s[%d]: WARNING : found %d functions named %s. Using the first.\n", __FILE__, __LINE__, found_funcs.size(), funcName); } BPatch_Vector<BPatch_point *> *all_points36_1 = found_funcs[0]->findPoint(BPatch_subroutine); if (!all_points36_1 || (all_points36_1->size() < 1)) { logerror("Unable to find point %s - subroutines.\n", funcName); return FAILED; } const char *funcName2 = "test1_36_call1"; BPatch_point *point36_1 = NULL; for (unsigned i=0; i<(*all_points36_1).size(); i++) { BPatch_point *cur_point = (*all_points36_1)[i]; if (cur_point == NULL) continue; BPatch_function *func = cur_point->getCalledFunction(); char funcname[100]; if (!func) continue; if (func->getName(funcname, 99)) { if (strstr(funcname, funcName2)) point36_1 = cur_point; } } if (point36_1 == NULL) { logerror("Unable to find callsite %s\n", funcName2); return FAILED; } BPatch_variableExpr *expr36_1 = findVariable(appImage, "test1_36_globalVariable1", all_points36_1); BPatch_variableExpr *expr36_2 = findVariable(appImage, "test1_36_globalVariable2", all_points36_1); BPatch_variableExpr *expr36_3 = findVariable(appImage, "test1_36_globalVariable3", all_points36_1); BPatch_variableExpr *expr36_4 = findVariable(appImage, "test1_36_globalVariable4", all_points36_1); BPatch_variableExpr *expr36_5 = findVariable(appImage, "test1_36_globalVariable5", all_points36_1); BPatch_variableExpr *expr36_6 = findVariable(appImage, "test1_36_globalVariable6", all_points36_1); BPatch_variableExpr *expr36_7 = findVariable(appImage, "test1_36_globalVariable7", all_points36_1); BPatch_variableExpr *expr36_8 = findVariable(appImage, "test1_36_globalVariable8", all_points36_1); BPatch_variableExpr *expr36_9 = findVariable(appImage, "test1_36_globalVariable9", all_points36_1); BPatch_variableExpr *expr36_10 = findVariable(appImage, "test1_36_globalVariable10", all_points36_1); if (expr36_1 == NULL || expr36_2 == NULL || expr36_3 == NULL || expr36_4 == NULL || expr36_5 == NULL || expr36_6 == NULL || expr36_7 == NULL || expr36_8 == NULL || expr36_9 == NULL || expr36_10 == NULL) { logerror("**Failed** test #36 (callsite parameter referencing)\n"); logerror(" Unable to locate at least one of " "test1_36_globalVariable{1...10}\n"); return FAILED; } BPatch_Vector<BPatch_snippet *> snippet_seq; snippet_seq.push_back(makeTest36paramExpr(expr36_1, 0)); snippet_seq.push_back(makeTest36paramExpr(expr36_2, 1)); snippet_seq.push_back(makeTest36paramExpr(expr36_3, 2)); snippet_seq.push_back(makeTest36paramExpr(expr36_4, 3)); snippet_seq.push_back(makeTest36paramExpr(expr36_5, 4)); snippet_seq.push_back(makeTest36paramExpr(expr36_6, 5)); snippet_seq.push_back(makeTest36paramExpr(expr36_7, 6)); snippet_seq.push_back(makeTest36paramExpr(expr36_8, 7)); snippet_seq.push_back(makeTest36paramExpr(expr36_9, 8)); snippet_seq.push_back(makeTest36paramExpr(expr36_10, 9)); BPatch_sequence seqExpr(snippet_seq); checkCost(seqExpr); appAddrSpace->insertSnippet(seqExpr, *point36_1); return PASSED; }
void readTracePipe() { int read_len; char buf[ STRING_MAX ] = { '\0' }; if (config.pipefd < 0) return; do { errno = 0; sendMsg(config.outfd, ID_TRACE_READ, DEBUG); read_len = read(config.pipefd, buf, trace_msglen); buf[trace_msglen] = '\0'; if (read_len < trace_msglen) { if (read_len == -1 && errno == EAGAIN) { // No data on pipe. Break out of read loop // and re-poll for status change. sendMsg(config.outfd, ID_TRACE_READ, DEBUG, ID_PASS); break; } else if (read_len == 0 && errno == 0) { // Read EOF from pipefd. Close pipe and break. sendMsg(config.outfd, ID_TRACE_READ, DEBUG, ID_PASS); close(config.pipefd); config.pipefd = -1; break; } else if (read_len > 0) { // Partial data written to trace pipe. Report to monitor. sendMsg(config.outfd, ID_TRACE_READ, DEBUG, ID_FAIL, sprintf_static("Read partial message from trace pipe. Discarding message '%s'.", buf)); break; } else if (errno) { // Send error message to monitor. sendMsg(config.outfd, ID_TRACE_READ, DEBUG, ID_FAIL, sprintf_static("Mutator encountered error on trace pipe read(): %s", strerror(errno))); close(config.pipefd); config.pipefd = -1; break; } } void *traceMsg = (void *)strtol(buf, NULL, 16); map< void *, BPatch_function * >::iterator iter = trace_points.find(traceMsg); if (iter == trace_points.end()) { sendMsg(config.outfd, ID_TRACE_READ, DEBUG, ID_FAIL, sprintf_static("Read invalid message from trace pipe. 0x%s does not refer to a valid BPatch_point.", buf)); break; } sendMsg(config.outfd, ID_TRACE_READ, DEBUG, ID_PASS); BPatch_point *point = (BPatch_point *)traceMsg; const char *pType = "Unknown "; if (point->getPointType() == BPatch_entry) pType = "Entering "; if (point->getPointType() == BPatch_exit) pType = "Exiting "; const char *pName = "anonymous function"; BPatch_function *pFunc = (*iter).second; if (pFunc) { if (pFunc->getName(buf, sizeof(buf))) pName = sprintf_static("function %s", buf); else pName = sprintf_static("anonymous function at 0x%0*lx", sizeof(void *), pFunc->getBaseAddr()); } if (config.pipefd > 0) { // Could have been interrupted by mutatee exit. sendMsg(config.outfd, ID_TRACE_POINT, INFO, ID_INFO, strcat_static(pType, pName)); } } while (errno == 0); }
static void InstrumentCalls (BPatch_image *appImage, BPatch_addressSpace *appProcess, ApplicationType *appType, set<string> &OMPset, set<string> &USERset, map<string, vector<string> > & LoopLevels, bool instrumentMPI, bool instrumentOMP, bool instrumentUF) { unsigned i = 0; unsigned OMPinsertion = 0; unsigned OMPreplacement_intel_v11 = 0; unsigned MPIinsertion = 0; unsigned APIinsertion = 0; unsigned UFinsertion = 0; const char *PMPI_C_prefix = "PMPI_"; const char *PMPI_F_prefix = "pmpi_"; const char *MPI_C_prefix = "MPI_"; const char *MPI_F_prefix= "mpi_"; cout << PACKAGE_NAME << ": Obtaining functions from application image (this may take a while)..." << flush; BPatch_Vector<BPatch_function *> *vfunctions = appImage->getProcedures (false); cout << "Done" << endl; set<string> CUDAkernels; /* Look for CUDA kernels if the application is CUDA */ if (appType->get_isCUDA()) { cout << PACKAGE_NAME << ": Looking for CUDA kernels inside binary (this may take a while)..." << endl; i = 0; while (i < vfunctions->size()) { char name[1024]; BPatch_function *f = (*vfunctions)[i]; f->getName (name, sizeof(name)); BPatch_Vector<BPatch_point *> *vpoints = f->findPoint (BPatch_subroutine); if (vpoints != NULL) { unsigned j = 0; while (j < vpoints->size()) { BPatch_function *called = ((*vpoints)[j])->getCalledFunction(); if (NULL != called) { char calledname[1024]; called->getName (calledname, 1024); if (strncmp (calledname, "__device_stub__", strlen("__device_stub__")) == 0) { CUDAkernels.insert (name); if (VerboseLevel) cout << PACKAGE_NAME << ": Found kernel " << name << endl; } } j++; } } i++; } cout << PACKAGE_NAME << ": Finished looking for CUDA kernels" << endl; } cout << PACKAGE_NAME << ": Parsing executable looking for instrumentation points (" << vfunctions->size() << ") "; if (VerboseLevel) cout << endl; else cout << flush; /* The 1st step includes: a) gather information of openmp outlined routines (original is added to USERset), b) instrument openmp outlined routines c) instrument mpi calls d) instrument api calls */ i = 0; while (i < vfunctions->size()) { char name[1024], sharedlibname_c[1024]; BPatch_function *f = (*vfunctions)[i]; (f->getModule())->getFullName (sharedlibname_c, sizeof(sharedlibname_c)); f->getName (name, sizeof(name)); string sharedlibname = sharedlibname_c; string sharedlibname_ext; if (sharedlibname.rfind('.') != string::npos) sharedlibname_ext = sharedlibname.substr (sharedlibname.rfind('.')); else sharedlibname_ext = ""; /* For OpenMP apps, if the application has been linked with Extrae, just need to instrument the function calls that have #pragma omp in them. The outlined routines will be instrumented by the library attached to the binary */ if (!BinaryLinkedWithInstrumentation && instrumentOMP && appType->get_isOpenMP() && loadedModule != sharedlibname) { /* OpenMP instrumentation (just for OpenMP apps) */ if (appType->isMangledOpenMProutine (name)) { if (VerboseLevel) if (!BinaryLinkedWithInstrumentation) cout << PACKAGE_NAME << ": Instrumenting OpenMP outlined routine " << name << endl; if (!BinaryLinkedWithInstrumentation) { /* Instrument routine */ wrapTypeRoutine (f, name, OMPFUNC_EV, appImage); /* Add to list if not already there */ OMPset.insert (name); } /* Demangle name and add into the UF list if it didn't exist there */ string demangled = appType->demangleOpenMProutine (name); if (!XML_excludeAutomaticFunctions()) USERset.insert (demangled); if (VerboseLevel) { if (!XML_excludeAutomaticFunctions()) cout << PACKAGE_NAME << ": Adding demangled OpenMP routine " << demangled << " to the user function list" << endl; else cout << PACKAGE_NAME << ": Will not add demangled OpenMP routine " << demangled << " due to user request in the XML configuration file" << endl; } OMPinsertion++; } } if (sharedlibname_ext == ".f" || sharedlibname_ext == ".F" || /* fortran */ sharedlibname_ext == ".for" || sharedlibname_ext == ".FOR" || /* fortran */ sharedlibname_ext == ".f90" || sharedlibname_ext == ".F90" || /* fortran 90 */ sharedlibname_ext == ".i90" || /* fortran 90 through ifort */ sharedlibname_ext == ".f77" || sharedlibname_ext == ".F77" || /* fortran 77 */ sharedlibname_ext == ".c" || sharedlibname_ext == ".C" || /* C */ sharedlibname_ext == ".cxx" || sharedlibname_ext == ".cpp" || /* c++ */ sharedlibname_ext == ".c++" || /* c++ */ sharedlibname_ext == ".i" || /* some compilers generate this extension in intermediate files */ sharedlibname == "DEFAULT_MODULE" /* Dyninst specific container that represents the executable */ ) { /* API instrumentation (for any kind of apps) Skip calls from my own module */ BPatch_Vector<BPatch_point *> *vpoints = f->findPoint (BPatch_subroutine); if (vpoints == NULL) break; if (VerboseLevel >= 2) printCallingSites (i, vfunctions->size(), name, sharedlibname, vpoints); unsigned j = 0; while (j < vpoints->size()) { BPatch_function *called = ((*vpoints)[j])->getCalledFunction(); if (NULL != called) { char calledname[1024]; called->getName (calledname, 1024); /* Check API calls */ BPatch_function *patch_api = getAPIPatch (calledname); if (patch_api != NULL) { if (appProcess->replaceFunctionCall (*((*vpoints)[j]), *patch_api)) { APIinsertion++; if (VerboseLevel) cout << PACKAGE_NAME << ": Replaced call " << calledname << " in routine " << name << " (" << sharedlibname << ")" << endl; } else cerr << PACKAGE_NAME << ": Cannot replace " << calledname << " routine" << endl; } /* Check MPI calls */ if (!BinaryLinkedWithInstrumentation && instrumentMPI && appType->get_isMPI() && ( strncmp (calledname, PMPI_C_prefix, 5) == 0 || strncmp (calledname, MPI_C_prefix, 4) == 0 || strncmp (calledname, PMPI_F_prefix, 5) == 0 || strncmp (calledname, MPI_F_prefix, 4) == 0)) { BPatch_function *patch_mpi = getMPIPatch (calledname); if (patch_mpi != NULL) { if (appProcess->replaceFunctionCall (*((*vpoints)[j]), *patch_mpi)) { MPIinsertion++; if (VerboseLevel) cout << PACKAGE_NAME << ": Replaced call " << calledname << " in routine " << name << " (" << sharedlibname << ")" << endl; } else cerr << PACKAGE_NAME << ": Cannot replace " << calledname << " routine" << endl; } } /* Special instrumentation for calls in Intel OpenMP runtime v11/v12 currently only for __kmpc_fork_call */ if (!BinaryLinkedWithInstrumentation && appType->get_OpenMP_rte() == ApplicationType::Intel_v11 && strncmp (calledname, "__kmpc_fork_call", strlen("__kmpc_fork_call")) == 0) { BPatch_function *patch_openmp = getRoutine ( "__kmpc_fork_call_extrae_dyninst", appImage, false); if (patch_openmp != NULL) { if (appProcess->replaceFunctionCall (*((*vpoints)[j]), *patch_openmp)) { OMPreplacement_intel_v11++; if (VerboseLevel) cout << PACKAGE_NAME << ": Replaced call " << calledname << " in routine " << name << " (" << sharedlibname << ")" << endl; } else cerr << PACKAGE_NAME << ": Cannot replace " << calledname << " routine" << endl; } /* Instrument the routine that invokes the runtime */ if (!XML_excludeAutomaticFunctions()) USERset.insert (name); if (VerboseLevel) { if (!XML_excludeAutomaticFunctions()) cout << PACKAGE_NAME << ": Adding call to OpenMP routine " << name << " to the user function list" << endl; else cout << PACKAGE_NAME << ": Will not add call to OpenMP routine " << name << " due to user request in the XML configuration file" << endl; } } /* Special instrumentation for fork() / wait() / exec* calls */ if (!BinaryLinkedWithInstrumentation && ( strncmp (calledname, "fork", strlen("fork")) == 0 || strncmp (calledname, "wait", strlen("wait")) == 0 || strncmp (calledname, "waitpid", strlen("waitpid")) == 0 || strncmp (calledname, "system", strlen("system")) == 0 || strncmp (calledname, "execl", strlen("execl")) == 0 || strncmp (calledname, "execle", strlen("execle")) == 0 || strncmp (calledname, "execlp", strlen("execlp")) == 0 || strncmp (calledname, "execv", strlen("execv")) == 0 || strncmp (calledname, "execve", strlen("execve")) == 0 || strncmp (calledname, "execvp", strlen("execvp")) == 0 ) ) { /* Instrument the routine that invokes the runtime */ if (!XML_excludeAutomaticFunctions()) USERset.insert (name); if (VerboseLevel) { if (!XML_excludeAutomaticFunctions()) cout << PACKAGE_NAME << ": Adding routine " << name << " to the user function list because it calls to " << calledname << endl; else cout << PACKAGE_NAME << ": Will not add routine to the user function list " << name << " due to user request in the XML configuration file" << endl; } } /* Instrument routines that call CUDA */ if (appType->get_isCUDA()) { string scalledname (calledname); if (find (CUDAkernels.begin(), CUDAkernels.end(), scalledname) != CUDAkernels.end()) { if (!XML_excludeAutomaticFunctions()) USERset.insert (name); if (VerboseLevel) { if (!XML_excludeAutomaticFunctions()) cout << PACKAGE_NAME << ": Adding routine " << name << " to the user function list because it calls the CUDA kernel '" << calledname<< "'" << endl; else cout << PACKAGE_NAME << ": Will not instrument CUDA routine " << name << " due to user request in the XML configuration file" << endl; } } } } j++; } } i++; if (!VerboseLevel) { if (i == 1) cout << "1" << flush; else if (i%1000 == 0) cout << i << flush; else if (i%100 == 0) cout << "." << flush; } } if (!VerboseLevel) cout << ".Done" << endl; if (USERset.size() > 0 && instrumentUF) { /* Instrument user functions! */ cout << PACKAGE_NAME << ": Instrumenting user functions..."; if (VerboseLevel) cout << endl; else cout << flush; set<string>::iterator iter = USERset.begin(); while (iter != USERset.end()) { if (*iter != "main") { BPatch_function *f = getRoutine ((*iter).c_str(), appImage); if (f != NULL) { wrapTypeRoutine (f, *iter, USRFUNC_EV, appImage); vector<string> points = LoopLevels[*iter]; // LoopLevels['foo'] = [bb_1,loop_1.2.3,bb_5] instrumentLoops(f, *iter, appImage, points); instrumentBasicBlocks(f, appImage, points); UFinsertion++; if (VerboseLevel) cout << PACKAGE_NAME << ": Instrumenting user function : " << *iter << endl; } else { if (VerboseLevel) cout << PACKAGE_NAME << ": Unable to instrument user function : " << *iter << endl; } } else { if (VerboseLevel) cout << PACKAGE_NAME << ": Although 'main' symbol was in the instrumented functions list, it will not be instrumented" << endl; } iter++; } if (VerboseLevel) cout << PACKAGE_NAME << ": End of instrumenting functions" << endl; else cout << "Done" << endl; } cout << PACKAGE_NAME << ": " << APIinsertion << " API patches applied" << endl; if (appType->get_isMPI()) cout << PACKAGE_NAME << ": " << MPIinsertion << " MPI patches applied" << endl; if (appType->get_isOpenMP()) { cout << PACKAGE_NAME << ": " << OMPinsertion << " OpenMP patches applied to outlined routines" << endl; if (appType->get_OpenMP_rte() == ApplicationType::Intel_v11) cout << PACKAGE_NAME << ": " << OMPreplacement_intel_v11 << " OpenMP patches applied to specific locations for Intel runtime" << endl; } if (USERset.size() > 0) cout << PACKAGE_NAME << ": " << UFinsertion << " user function" << ((UFinsertion!=1)?"s":"") << " instrumented" << endl; }
int main(int argc, char **argv) { if (argc < 3 || strncmp(argv[1], "-h", 2) == 0 || strncmp(argv[1], "--h", 3) == 0) { cout << "Usage: " << argv[0] << USAGE; return false; } if (!parseOptions(argc, argv)) { return EXIT_FAILURE; } if (do_bb == true) { if (DYNINST_MAJOR_VERSION < 9 || (DYNINST_MAJOR_VERSION == 9 && DYNINST_MINOR_VERSION < 3) || (DYNINST_MAJOR_VERSION == 9 && DYNINST_MINOR_VERSION == 3 && DYNINST_PATCH_VERSION <= 2)) { if (dynfix == false) fprintf(stderr, "Warning: your dyninst version does not include a critical fix, you should use the -f option!\n"); } else { if (dynfix == true) fprintf(stderr, "Notice: your dyninst version is fixed, the -f option should not be necessary.\n"); } } BPatch bpatch; BPatch_binaryEdit *appBin = bpatch.openBinary(originalBinary, instrumentLibraries.size() != 1); if (appBin == NULL) { cerr << "Failed to open binary" << endl; return EXIT_FAILURE; } BPatch_image *appImage = appBin->getImage(); //get and iterate over all modules, instrumenting only the default and manually specified ones vector < BPatch_module * >*modules = appImage->getModules(); vector < BPatch_module * >::iterator moduleIter; vector < BPatch_function * >*funcsInModule; BPatch_module *defaultModule = NULL; string defaultModuleName; // look for _init if (defaultModuleName.empty()) { for (moduleIter = modules->begin(); moduleIter != modules->end(); ++moduleIter) { funcsInModule = (*moduleIter)->getProcedures(); vector < BPatch_function * >::iterator funcsIterator; for (funcsIterator = funcsInModule->begin(); funcsIterator != funcsInModule->end(); ++funcsIterator) { char funcName[1024]; (*funcsIterator)->getName(funcName, 1024); if (string(funcName) == string("_init")) { char moduleName[1024]; (*moduleIter)->getName(moduleName, 1024); defaultModuleName = string(moduleName); if (verbose) { cout << "Found _init in " << moduleName << endl; } break; } } if (!defaultModuleName.empty()) break; } } // last resort, by name of the binary if (defaultModuleName.empty()) defaultModuleName = string(originalBinary).substr(string(originalBinary).find_last_of("\\/") + 1); if (!appBin->loadLibrary(instLibrary)) { cerr << "Failed to open instrumentation library " << instLibrary << endl; cerr << "It needs to be located in the current working directory." << endl; return EXIT_FAILURE; } appImage = appBin->getImage(); /* Find code coverage functions in the instrumentation library */ BPatch_function *initAflForkServer; save_rdi = findFuncByName(appImage, (char *) "save_rdi"); restore_rdi = findFuncByName(appImage, (char *) "restore_rdi"); BPatch_function *bbCallback = findFuncByName(appImage, (char *) "bbCallback"); BPatch_function *forceCleanExit = findFuncByName(appImage, (char *) "forceCleanExit"); if (do_bb == true) initAflForkServer = findFuncByName(appImage, (char *) "initAflForkServer"); else initAflForkServer = findFuncByName(appImage, (char *) "initOnlyAflForkServer"); if (!initAflForkServer || !bbCallback || !save_rdi || !restore_rdi || !forceCleanExit) { cerr << "Instrumentation library lacks callbacks!" << endl; return EXIT_FAILURE; } int bbIndex = 0; // instrument all shared libraries: for (moduleIter = modules->begin(); moduleIter != modules->end(); ++moduleIter) { char moduleName[1024]; (*moduleIter)->getName(moduleName, 1024); if ((*moduleIter)->isSharedLib()) { if (instrumentLibraries.find(moduleName) == instrumentLibraries.end()) { cout << "Skipping library: " << moduleName << endl; continue; } } if (string(moduleName).find(defaultModuleName) != string::npos) { defaultModule = (*moduleIter); if (skipMainModule) continue; } if (do_bb == true) { cout << "Instrumenting module: " << moduleName << endl; vector < BPatch_function * >*allFunctions = (*moduleIter)->getProcedures(); vector < BPatch_function * >::iterator funcIter; // iterate over all functions in the module for (funcIter = allFunctions->begin(); funcIter != allFunctions->end(); ++funcIter) { BPatch_function *curFunc = *funcIter; char funcName[1024]; int do_patch = 1; curFunc->getName(funcName, 1024); if (string(funcName) == string("_start")) continue; // here's a bug on hlt // XXX: check what happens if removed if (!skipAddresses.empty()) { set < string >::iterator saiter; for (saiter = skipAddresses.begin(); saiter != skipAddresses.end() && do_patch == 1; saiter++) if (*saiter == string(funcName)) do_patch = 0; if (do_patch == 0) { cout << "Skipping instrumenting function " << funcName << endl; continue; } } insertBBCallback(appBin, curFunc, funcName, bbCallback, &bbIndex); } } } // if an entrypoint was set then find function, else find _init BPatch_function *funcToPatch = NULL; if (!entryPoint) { BPatch_Vector < BPatch_function * >funcs; defaultModule->findFunction("_init", funcs); if (!funcs.size()) { cerr << "Couldn't locate _init, specify entry point manually with -e 0xaddr" << endl; return EXIT_FAILURE; } // there should really be only one funcToPatch = funcs[0]; } else { funcToPatch = defaultModule->findFunctionByEntry(entryPoint); } if (!funcToPatch) { cerr << "Couldn't locate function at given entry point. " << endl; return EXIT_FAILURE; } if (!insertCallToInit(appBin, initAflForkServer, defaultModule, funcToPatch)) { cerr << "Could not insert init callback at given entry point." << endl; return EXIT_FAILURE; } if (!exitAddresses.empty()) { cout << "Instrumenting forced exit addresses." << endl; set < unsigned long >::iterator uliter; for (uliter = exitAddresses.begin(); uliter != exitAddresses.end(); uliter++) { if (*uliter > 0 && (signed long)*uliter != -1) { funcToPatch = defaultModule->findFunctionByEntry(*uliter); if (!funcToPatch) { cerr << "Could not find enty point 0x" << hex << *uliter << " (continuing)" << endl; } else { if (!insertCallToInit(appBin, forceCleanExit, defaultModule, funcToPatch)) cerr << "Could not insert force clean exit callback at 0x" << hex << *uliter << " (continuing)" << endl; } } } } cout << "Saving the instrumented binary to " << instrumentedBinary << " ..." << endl; // Output the instrumented binary if (!appBin->writeFile(instrumentedBinary)) { cerr << "Failed to write output file: " << instrumentedBinary << endl; return EXIT_FAILURE; } if (!runtimeLibraries.empty()) { cout << "Instrumenting runtime libraries." << endl; set < string >::iterator rtLibIter; for (rtLibIter = runtimeLibraries.begin(); rtLibIter != runtimeLibraries.end(); rtLibIter++) { BPatch_binaryEdit *libBin = bpatch.openBinary((*rtLibIter).c_str(), false); if (libBin == NULL) { cerr << "Failed to open binary " << *rtLibIter << endl; return EXIT_FAILURE; } BPatch_image *libImg = libBin->getImage(); vector < BPatch_module * >*modules = libImg->getModules(); moduleIter = modules->begin(); for (; moduleIter != modules->end(); ++moduleIter) { char moduleName[1024]; (*moduleIter)->getName(moduleName, 1024); cout << "Instrumenting module: " << moduleName << endl; vector < BPatch_function * >*allFunctions = (*moduleIter)->getProcedures(); vector < BPatch_function * >::iterator funcIter; // iterate over all functions in the module for (funcIter = allFunctions->begin(); funcIter != allFunctions->end(); ++funcIter) { BPatch_function *curFunc = *funcIter; char funcName[1024]; curFunc->getName(funcName, 1024); if (string(funcName) == string("_start")) continue; insertBBCallback(libBin, curFunc, funcName, bbCallback, &bbIndex); } } if (!libBin->writeFile((*rtLibIter + ".ins").c_str())) { cerr << "Failed to write output file: " << (*rtLibIter + ".ins").c_str() << endl; return EXIT_FAILURE; } else { cout << "Saved the instrumented library to " << (*rtLibIter + ".ins").c_str() << "." << endl; } } } cout << "All done! Happy fuzzing!" << endl; return EXIT_SUCCESS; }