void DICFG::parse_all(void) { BPatch_addressSpace *handle = cfg_handle; SymtabCodeSource *sts = cfg_sts; CodeObject *co = cfg_co; // Parse the binary co->parse(); /* Parse the functions found by the BPatch API */ BPatch_image *image = handle->getImage(); std::vector<BPatch_module *> *mods = image->getModules(); std::vector<BPatch_module *>::iterator mods_iter; for (mods_iter = mods->begin(); mods_iter != mods->end(); mods_iter++) { address_t mod_start = (address_t)(*mods_iter)->getBaseAddr(); address_t mod_end = (address_t)(*mods_iter)->getBaseAddr() + (*mods_iter)->getSize(); if((get_start_addr() == 0) || (mod_start < get_start_addr())) { set_start_addr(mod_start); } if((get_end_addr() == 0) || (mod_end > get_end_addr())) { set_end_addr(mod_end); } std::vector<BPatch_function *> *funcs = (*mods_iter)->getProcedures(false); std::vector<BPatch_function *>::iterator funcs_iter = funcs->begin(); for(; funcs_iter != funcs->end(); funcs_iter++) { co->parse((Address)(*funcs_iter)->getBaseAddr(), true); } } /* Parse PLT entries */ Symtab *symtab = Symtab::findOpenSymtab(string((char *) this->get_module_name().c_str())); vector<SymtabAPI::relocationEntry> fbt; vector<SymtabAPI::relocationEntry>::iterator fbt_iter; symtab->getFuncBindingTable(fbt); for (fbt_iter = fbt.begin(); fbt_iter != fbt.end(); fbt_iter++) { co->parse((Address)((*fbt_iter).target_addr()), true); } const CodeObject::funclist& funcs = co->funcs(); insert_functions_and_bbs(funcs); for (fbt_iter = fbt.begin(); fbt_iter != fbt.end(); fbt_iter++) { address_t plt_fun_addr = (address_t)(*fbt_iter).target_addr(); if((get_start_addr() == 0) || (plt_fun_addr < get_start_addr())) { set_start_addr(plt_fun_addr); } if((get_end_addr() == 0) || (plt_fun_addr > get_end_addr())) { set_end_addr(plt_fun_addr); } mark_function_as_plt(plt_fun_addr); } }
int main() { BPatch bpatch; BPatch_process* appProc = bpatch.processCreate("/bin/ls", NULL); BPatch_image* img = NULL; img = appProc->getImage(); vector<BPatch_module*> *mdl = img->getModules(); vector<BPatch_module*>::iterator moduleIter = mdl->begin(); void* addr = (*moduleIter)->getBaseAddr(); printf("0x%x\n",addr); return 0; }
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; }
// Instrument a function: eztrace_code0(code_entry) is called at the // beginning of the function and eztrace_code0(code_entry) is called // at the end of the function. // If code_entry or code_exit is null, the corresponding call to // eztrace_code0 is skipped static int __intercept_function(BPatch_addressSpace *app, const char* function_name, uint32_t code_entry, uint32_t code_exit) { BPatch_image *appImage; BPatch_Vector<BPatch_point*> *points; BPatch_Vector<BPatch_function *> functions; BPatch_Vector<BPatch_function *> record_event0_ptr; appImage = app->getImage(); // search for record_event0 function BPatch_Vector<BPatch_module*> *loaded_modules = appImage->getModules(); printf("Threre are %d modules\n", loaded_modules->size()); for(int i=0; i< loaded_modules->size(); i++) { BPatch_module* cur_mod = (*loaded_modules)[i]; char mod_name[80]; cur_mod->getName(mod_name, 80); cur_mod->findFunction("record_event0", record_event0_ptr, false); if(!record_event0_ptr.size()) { printf("\tfunction record_event0 not found in module %s\n", mod_name); } else { printf("Found ! in module %s\n", mod_name); break; } } if(!record_event0_ptr.size()) { printf("Cannot find record_event0 function\n"); return -1; } printf("PLOP\n"); for(int i=0; i< loaded_modules->size(); i++) { BPatch_module* cur_mod = (*loaded_modules)[i]; char mod_name[80]; cur_mod->getName(mod_name, 80); cur_mod->findFunction(function_name, functions, false); if(!functions.size()) { printf("\tfunction %s not found in module %s\n", function_name, mod_name); } else { printf("Found %s! \n", function_name ); break; } } if(!functions.size()) { fprintf(stderr, "warning: cannot find function %s in executable\n", function_name); return 0; } // Instrument the entry of the function if(code_entry) { // We need to call eztrace_generic(code, nb_param, param1, param2, ...) points = functions[0]->findPoint(BPatch_entry); BPatch_Vector<BPatch_snippet*> dummyArgs; // Create the parameter (code_entry) BPatch_constExpr code(code_entry); dummyArgs.push_back(&code); // Create the function call #if 0 BPatch_Vector<BPatch_function *> funcs; appImage->findFunction("record_event0", funcs); BPatch_function *dummyFunc = funcs[0]; BPatch_funcCallExpr dummyCall(*dummyFunc, dummyArgs); #else BPatch_funcCallExpr dummyCall(*record_event0_ptr[0], dummyArgs); #endif //Insert the function call at the point app->insertSnippet(dummyCall, *points); } // Instrument the exit of the function if(code_exit) { // the function parameters are not available here, so we have to // call eztrace_code0(code) points = functions[0]->findPoint(BPatch_exit); // Create the parameter (code_entry) BPatch_Vector<BPatch_snippet*> dummyArgs; BPatch_constExpr code(code_exit); dummyArgs.push_back(&code); // Create the function call #if 0 BPatch_Vector<BPatch_function *> funcs; appImage->findFunction("record_event0", funcs); BPatch_function *dummyFunc = funcs[0]; BPatch_funcCallExpr dummyCall(*dummyFunc, dummyArgs); #else BPatch_funcCallExpr dummyCall(*record_event0_ptr[0], dummyArgs); #endif //Insert the function call at the point app->insertSnippet(dummyCall, *points); } return 1; }
void dyninst_analyze_address_taken(BPatch_addressSpace *handle, DICFG *cfg) { /* XXX: this is the most naive address-taken analysis that can be used by the * lbr_analysis_pass. More sophisticated ones can be (and are) plugged in in the pass. * This naive solution is provided only for comparison with more sophisticated ones. * * This analysis looks for instruction operands that correspond to known function addresses, * and then marks these functions as having their address taken. In particular, we * do /not/ look for function pointers stored in (static) memory, or for function * pointers that are computed at runtime. */ SymtabCodeSource *sts; CodeObject *co; std::vector<BPatch_object*> objs; handle->getImage()->getObjects(objs); assert(objs.size() > 0); const char *bin = objs[0]->pathName().c_str(); // Create a new binary object sts = new SymtabCodeSource((char*)bin); co = new CodeObject(sts); // Parse the binary co->parse(); BPatch_image *image = handle->getImage(); std::vector<BPatch_module *> *mods = image->getModules(); std::vector<BPatch_module *>::iterator mods_iter; for (mods_iter = mods->begin(); mods_iter != mods->end(); mods_iter++) { std::vector<BPatch_function *> *funcs = (*mods_iter)->getProcedures(false); std::vector<BPatch_function *>::iterator funcs_iter = funcs->begin(); for(; funcs_iter != funcs->end(); funcs_iter++) { co->parse((Address)(*funcs_iter)->getBaseAddr(), true); BPatch_flowGraph *fg = (*funcs_iter)->getCFG(); std::set<BPatch_basicBlock*> blocks; fg->getAllBasicBlocks(blocks); std::set<BPatch_basicBlock*>::iterator block_iter; for (block_iter = blocks.begin(); block_iter != blocks.end(); ++block_iter) { BPatch_basicBlock *block = (*block_iter); std::vector<Instruction::Ptr> insns; block->getInstructions(insns); std::vector<Instruction::Ptr>::iterator insn_iter; for (insn_iter = insns.begin(); insn_iter != insns.end(); ++insn_iter) { Instruction::Ptr ins = *insn_iter; std::vector<Operand> ops; ins->getOperands(ops); std::vector<Operand>::iterator op_iter; for (op_iter = ops.begin(); op_iter != ops.end(); ++op_iter) { Expression::Ptr expr = (*op_iter).getValue(); struct OperandAnalyzer : public Dyninst::InstructionAPI::Visitor { virtual void visit(BinaryFunction* op) {}; virtual void visit(Dereference* op) {} virtual void visit(Immediate* op) { address_t addr; ArmsFunction *func; switch(op->eval().type) { case s32: addr = op->eval().val.s32val; break; case u32: addr = op->eval().val.u32val; break; case s64: addr = op->eval().val.s64val; break; case u64: addr = op->eval().val.u64val; break; default: return; } func = cfg_->find_function(addr); if(func) { printf("Instruction [%s] references function 0x%jx\n", ins_->format().c_str(), addr); func->set_addr_taken(); } } virtual void visit(RegisterAST* op) {} OperandAnalyzer(DICFG *cfg, Instruction::Ptr ins) { cfg_ = cfg; ins_ = ins; }; DICFG *cfg_; Instruction::Ptr ins_; }; OperandAnalyzer oa(cfg, ins); expr->apply(&oa); } } } } } }
// static int mutatorTest(char *pathname, BPatch *bpatch) test_results_t test1_41_Mutator::executeTest() { unsigned int n=0; const char *child_argv[5]; child_argv[n++] = pathname; if (debugPrint) child_argv[n++] = const_cast<char*>("-verbose"); child_argv[n++] = const_cast<char*>("-run"); child_argv[n++] = const_cast<char*>("test1_41"); // run test41 in mutatee child_argv[n++] = NULL; int counts[iterations]; // Run the mutatee twice, querying line info each time & store the info for (n = 0; n < iterations; n++) { dprintf("Starting \"%s\"\n", pathname); BPatch_process *proc = bpatch->processCreate(pathname, child_argv, NULL); if (!proc) { logerror("*ERROR*: unable to create handle for executable\n", n); logerror("**Failed** test #41 (repeated line information)\n"); return FAILED; } dprintf("Mutatee started, pid=%d\n", n, proc->getPid()); BPatch_image *image = proc->getImage(); if (!image) { logerror("*ERROR*: unable to get image from thread\n"); logerror("**Failed** test #41 (repeated line information)\n"); return FAILED; } if (isMutateeFortran(image)) { // This shouldn't happen.. proc->terminateExecution(); logerror("Skipped test #41 (repeated line information)\n"); return SKIPPED; } BPatch_module *module = image->findModule("test1_41_mutatee.c", true); if (!module) { module = image->findModule("solo_mutatee_boilerplate.c", true); if (true) { logerror("*ERROR*: unable to get module from image\n"); logerror("Looking for \"test1_41_solo_me.c\" or \"solo_mutatee_boilerplate.c\". Available modules:\n"); BPatch_Vector<BPatch_module *> *mods = image->getModules(); char buffer[512]; for (unsigned i = 0; i < mods->size(); i++) { BPatch_module *mod = (*mods)[i]; char name[512]; mod->getName(name, 512); sprintf(buffer, "\t%s\n", name); logerror(buffer); } } } if (!module) { fprintf(stderr, "%s[%d]: could not find module solo_mutatee_boilerplate.c\n", FILE__, __LINE__); // First try again for 'test1_41_solo_me.c' module = image->findModule("test1_41_solo_me.c", true); if (!module) { logerror("*ERROR*: unable to get module from image\n"); logerror("Looking for \"test1_41_solo_me.c\" or \"solo_mutatee_boilerplate.c\". Available modules:\n"); BPatch_Vector<BPatch_module *> *mods = image->getModules(); char buffer[512]; for (unsigned i = 0; i < mods->size(); i++) { BPatch_module *mod = (*mods)[i]; char name[512]; mod->getName(name, 512); sprintf(buffer, "\t%s\n", name); logerror(buffer); } logerror("**Failed** test #41 (repeated line information)\n"); return FAILED; } } char buffer[16384]; // FIXME ugly magic number; No module name should be that long.. module->getName(buffer, sizeof(buffer)); BPatch_Vector<BPatch_statement> statements; bool res = module->getStatements(statements); if (!res) { fprintf(stderr, "%s[%d]: getStatements()\n", __FILE__, __LINE__); return FAILED; } counts[n] = statements.size(); dprintf("Trial %d: found %d statements\n", n, statements.size()); proc->terminateExecution(); } // Make sure we got the same info each time we ran the mutatee int last_count = -1; for (int i = 0; i < iterations; i++) { if ((last_count >= 0) && (last_count != counts[i])) { logerror("*ERROR*: statement counts didn't match: %d vs. %d\n", last_count, counts[i]); logerror("**Failed** test #41 (repeated line information)\n"); return FAILED; } last_count = counts[i]; } logerror("Passed test #41 (repeated line information)\n"); return PASSED; }
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; }