int main (int argc, const char* argv[]) { BPatch bpatch; // argv[2] is muttee's file name, will be muttee's argv[0] BPatch_process *proc = bpatch.processCreate(argv[2], argv + 2); // Options to tune performance char *s; if ((s = getenv("SET_TRAMP_RECURSIVE")) && (strcmp(s, "true") == 0)) bpatch.setTrampRecursive(true); if ((s = getenv("SET_SAVE_FPR")) && (strcmp(s, "false") == 0)) bpatch.setSaveFPR(false); BPatch_object *ipa = proc->loadLibrary(argv[1]); BPatch_image *image = proc->getImage(); std::vector<BPatch_function *> tracepoints, probes; image->findFunction("do_stuff", tracepoints); BPatch_function *tracepoint = tracepoints[0]; image->findFunction("tpbench_no_arg", probes); BPatch_function *probe = probes[0]; std::vector<BPatch_snippet*> args; BPatch_funcCallExpr call_probe(*probe, args); proc->insertSnippet(call_probe, (tracepoint->findPoint(BPatch_exit))[0]); proc->detach(true); return 0; }
void prepareTestCase9(procType proc_type, BPatch_thread *thread, forkWhen when) { const int TN = 9; if(proc_type == Parent_p && when == PreFork) { BPatch_image *parImage = thread->getImage(); var7_9p = thread->malloc(*(parImage->findType("int"))); if(doError(TN, (var7_9p==NULL), " Unable to malloc variable in parent\n")) return; BPatch_arithExpr a_expr7_9p(BPatch_assign, *var7_9p, BPatch_constExpr(10)); thread->oneTimeCode(a_expr7_9p); } else if(proc_type == Parent_p && when == PostFork) { // can't delete var7_9p here, since then the getInheritedVariable // would be operating on a freed variable } else if(proc_type == Child_p && when == PostFork) { var7_9c = thread->getInheritedVariable(*var7_9p); parentThread->free(*var7_9p); BPatch_image *childImage = thread->getImage(); BPatch_Vector<BPatch_function *> found_funcs; const char *inFunction = "func7_9"; if ((NULL == childImage->findFunction(inFunction, found_funcs, 1)) || !found_funcs.size()) { fprintf(stderr, " Unable to find function %s\n", inFunction); exit(1); } if (1 < found_funcs.size()) { fprintf(stderr, "%s[%d]: WARNING : found %d functions named %s. Using the first.\n", __FILE__, __LINE__, found_funcs.size(), inFunction); } BPatch_Vector<BPatch_point *> *points7_9c = found_funcs[0]->findPoint(BPatch_entry); if(doError(TN, !points7_9c || ((*points7_9c).size() == 0), " Unable to find entry point to \"func7_9\".\n")) return; BPatch_point *point7_9c = (*points7_9c)[0]; BPatch_arithExpr a_expr7_9c(BPatch_plus, *var7_9c, BPatch_constExpr(5)); BPatch_arithExpr b_expr7_9c(BPatch_assign, *var7_9c, a_expr7_9c); thread->insertSnippet(b_expr7_9c, *point7_9c, BPatch_callBefore); } }
void prepareTestCase1(procType proc_type, BPatch_thread *thread, forkWhen when) { static BPatchSnippetHandle *parSnippetHandle1; if(proc_type == Parent_p && when == PreFork) { BPatch_image *parImage = thread->getImage(); BPatch_Vector<BPatch_function *> found_funcs; const char *inFunction = "func7_1"; if ((NULL == parImage->findFunction(inFunction, found_funcs, 1)) || !found_funcs.size()) { fprintf(stderr, " Unable to find function %s\n", inFunction); exit(1); } if (1 < found_funcs.size()) { fprintf(stderr, "%s[%d]: WARNING : found %d functions named %s. Using the first.\n", __FILE__, __LINE__, found_funcs.size(), inFunction); } BPatch_Vector<BPatch_point *> *point7_1p = found_funcs[0]->findPoint(BPatch_entry); if(doError(1, !point7_1p || ((*point7_1p).size() == 0), " Unable to find entry point to \"func7_1\".\n")) return; BPatch_variableExpr *var7_1p = parImage->findVariable("globalVariable7_1"); if(doError(1, (var7_1p==NULL), " Unable to locate variable globalVariable7_1\n")) return; BPatch_arithExpr expr7_1p(BPatch_assign, *var7_1p,BPatch_constExpr(321)); parSnippetHandle1 = thread->insertSnippet(expr7_1p, *point7_1p, BPatch_callBefore); if(doError(1, (parSnippetHandle1 == NULL), " Unable to insert snippet into parent for test 1\n")) return; } else if(proc_type == Parent_p && when == PostFork) { thread->deleteSnippet(parSnippetHandle1); } }
void prepareTestCase4(procType proc_type, BPatch_thread *thread, forkWhen when) { const int TN = 4; static BPatchSnippetHandle *parSnippetHandle4; if(proc_type == Child_p && when == PostFork) { BPatch_image *childImage = thread->getImage(); BPatch_Vector<BPatch_function *> found_funcs; const char *inFunction = "func7_4"; if ((NULL == childImage->findFunction(inFunction, found_funcs, 1)) || !found_funcs.size()) { fprintf(stderr, " Unable to find function %s\n", inFunction); exit(1); } if (1 < found_funcs.size()) { fprintf(stderr, "%s[%d]: WARNING : found %d functions named %s. Using the first.\n", __FILE__, __LINE__, found_funcs.size(), inFunction); } BPatch_Vector<BPatch_point *> *points7_4c = found_funcs[0]->findPoint(BPatch_entry); if(doError(TN, !points7_4c || ((*points7_4c).size() == 0), " Unable to find entry point to \"func7_4\".\n")) return; BPatch_point *point7_4c = (*points7_4c)[0]; BPatch_variableExpr *var7_4c = childImage->findVariable("globalVariable7_4"); if(doError(TN, (var7_4c==NULL), " Unable to locate variable globalVariable7_4\n")) return; BPatch_arithExpr a_expr7_4c(BPatch_plus, *var7_4c,BPatch_constExpr(211)); BPatch_arithExpr b_expr7_4c(BPatch_assign, *var7_4c, a_expr7_4c); parSnippetHandle4 = thread->insertSnippet(b_expr7_4c, *point7_4c, BPatch_callBefore); } }
// 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 prepareTestCase3(procType proc_type, BPatch_thread *thread, forkWhen when) { static BPatchSnippetHandle *parSnippetHandle3; if(proc_type == Parent_p && when == PreFork) { BPatch_image *parImage = thread->getImage(); BPatch_Vector<BPatch_function *> found_funcs; const char *inFunction = "func7_3"; if ((NULL == parImage->findFunction(inFunction, found_funcs, 1)) || !found_funcs.size()) { fprintf(stderr, " Unable to find function %s\n", inFunction); exit(1); } if (1 < found_funcs.size()) { fprintf(stderr, "%s[%d]: WARNING : found %d functions named %s. Using the first.\n", __FILE__, __LINE__, found_funcs.size(), inFunction); } BPatch_Vector<BPatch_point *> *points7_3p = found_funcs[0]->findPoint(BPatch_entry); if(doError(3, !points7_3p || ((*points7_3p).size() == 0), " Unable to find entry point to \"func7_3\".\n")) return; BPatch_point *point7_3p = (*points7_3p)[0]; BPatch_variableExpr *var7_3p = parImage->findVariable("globalVariable7_3"); if(doError(3, (var7_3p==NULL), " Unable to locate variable globalVariable7_3\n")) return; BPatch_arithExpr expr7_3p(BPatch_assign, *var7_3p,BPatch_constExpr(642)); parSnippetHandle3 = thread->insertSnippet(expr7_3p, *point7_3p, BPatch_callBefore); } else if(proc_type == Parent_p && when == PostFork) { bool result = thread->deleteSnippet(parSnippetHandle3); if(result == false) { fprintf(stderr, " error, couldn't delete snippet\n"); passedTest[3] = false; return; } } else if(proc_type == Child_p && when == PostFork) { BPatch_image *childImage = thread->getImage(); BPatch_Vector<BPatch_function *> found_funcs; const char *inFunction = "func7_3"; if ((NULL == childImage->findFunction(inFunction, found_funcs, 1)) || !found_funcs.size()) { fprintf(stderr, " Unable to find function %s\n", inFunction); exit(1); } if (1 < found_funcs.size()) { fprintf(stderr, "%s[%d]: WARNING : found %d functions named %s. Using the first.\n", __FILE__, __LINE__, found_funcs.size(), inFunction); } BPatch_Vector<BPatch_point *> *points7_3c = found_funcs[0]->findPoint(BPatch_entry); if(doError(3, !points7_3c || ((*points7_3c).size() == 0), " Unable to find entry point to \"func7_3\".\n")) return; BPatch_point *point7_3c = (*points7_3c)[0]; BPatch_Vector<BPatchSnippetHandle *> childSnippets = point7_3c->getCurrentSnippets(); if(doError(3, (childSnippets.size()==0), " No snippets were found at func7_3\n")) return; for(unsigned i=0; i<childSnippets.size(); i++) { bool result = thread->deleteSnippet(childSnippets[i]); if(result == false) { fprintf(stderr, " error, couldn't delete snippet\n"); passedTest[3] = false; return; } } } }
void execFunc(BPatch_thread *thread) { BPatch_Vector<BPatch_function *> bpfv; if (inTest == 1 || inTest == 2) { printf("**Failed Test #%d\n", inTest); printf(" execCallback invoked, but exec was not called!\n"); } else if (inTest == 3) { dprintf("in exec callback for %d\n", thread->getPid()); // insert code into parent BPatch_Vector<BPatch_snippet *> nullArgs; BPatch_image *appImage = thread->getImage(); assert(appImage); char *fn = "func3_2"; if (NULL == appImage->findFunction(fn, bpfv) || !bpfv.size() || NULL == bpfv[0]){ fprintf(stderr, " Unable to find function %s\n",fn); exit(1); } BPatch_function *func3_2_parent = bpfv[0]; BPatch_funcCallExpr callExpr(*func3_2_parent, nullArgs); bpfv.clear(); char *fn2 = "func3_1"; if (NULL == appImage->findFunction(fn2, bpfv) || !bpfv.size() || NULL == bpfv[0]){ fprintf(stderr, " Unable to find function %s\n",fn2); exit(1); } BPatch_function *func3_1_parent = bpfv[0]; BPatch_Vector<BPatch_point *> *point = func3_1_parent->findPoint(BPatch_exit); assert(point); thread->insertSnippet(callExpr, *point); dprintf("%s[%d]: MUTATEE: exec callback for %d, done with insert snippet\n", __FILE__, __LINE__, thread->getPid()); } else if (inTest == 4) { dprintf("in exec callback for %d\n", thread->getPid()); // insert code into child BPatch_Vector<BPatch_snippet *> nullArgs; BPatch_image *appImage = thread->getImage(); assert(appImage); char *fn3 = "func4_4"; if (NULL == appImage->findFunction(fn3, bpfv) || !bpfv.size() || NULL == bpfv[0]){ fprintf(stderr, " Unable to find function %s\n",fn3); exit(1); } BPatch_function *func4_4_child = bpfv[0]; BPatch_funcCallExpr callExpr1(*func4_4_child, nullArgs); bpfv.clear(); char *fn4 = "func4_2"; if (NULL == appImage->findFunction(fn4, bpfv) || !bpfv.size() || NULL == bpfv[0]){ fprintf(stderr, " Unable to find function %s\n",fn4); exit(1); } BPatch_function *func4_2_child = bpfv[0]; BPatch_Vector<BPatch_point *> *point1 = func4_2_child->findPoint(BPatch_exit); assert(point1); thread->insertSnippet(callExpr1, *point1); } else { printf("in exec callback for %d\n", thread->getPid()); } }
void forkFunc(BPatch_thread *parent, BPatch_thread *child) { dprintf("forkFunc called with parent %p, child %p\n", parent, child); BPatch_image *appImage; BPatch_Vector<BPatch_function *> bpfv; BPatch_Vector<BPatch_snippet *> nullArgs; if (child) mythreads[threadCount++] = child; if (!child) { dprintf("in prefork for %d\n", parent->getPid()); } else { dprintf("in fork of %d to %d\n", parent->getPid(), child->getPid()); } if (inTest == 1) { // nothing to do for this case } else if (inTest == 2) { if (!child) return; // skip prefork case // Make a race condition always show up -- we don't run // until the processes have had a chance. #if !defined(os_windows) sleep(1); #endif // That'll make erroneous continues break... // insert code into parent appImage = parent->getImage(); assert(appImage); char *fn = "func2_3"; if (NULL == appImage->findFunction(fn, bpfv) || !bpfv.size() || NULL == bpfv[0]){ fprintf(stderr, " Unable to find function %s\n",fn); exit(1); } BPatch_function *func2_3_parent = bpfv[0]; BPatch_funcCallExpr callExpr2(*func2_3_parent, nullArgs); bpfv.clear(); char *fn2 = "func2_2"; if (NULL == appImage->findFunction(fn2, bpfv) || !bpfv.size() || NULL == bpfv[0]){ fprintf(stderr, " Unable to find function %s\n",fn2); exit(1); } BPatch_function *func2_2_parent = bpfv[0]; BPatch_Vector<BPatch_point *> *point2 = func2_2_parent->findPoint(BPatch_exit); assert(point2); parent->insertSnippet(callExpr2, *point2); dprintf("MUTATEE: after insert in fork of %d to %d\n", parent->getPid(), child->getPid()); // insert different code into child appImage = child->getImage(); assert(appImage); bpfv.clear(); char *fn3 = "func2_4"; if (NULL == appImage->findFunction(fn3, bpfv) || !bpfv.size() || NULL == bpfv[0]){ fprintf(stderr, " Unable to find function %s\n",fn3); exit(1); } BPatch_function *func2_4_child = bpfv[0]; BPatch_funcCallExpr callExpr1(*func2_4_child, nullArgs); bpfv.clear(); char *fn4 = "func2_2"; if (NULL == appImage->findFunction(fn4, bpfv) || !bpfv.size() || NULL == bpfv[0]){ fprintf(stderr, " Unable to find function %s\n",fn4); exit(1); } BPatch_function *func2_2_child = bpfv[0]; BPatch_Vector<BPatch_point *> *point1 = func2_2_child->findPoint(BPatch_exit); assert(point1); child->insertSnippet(callExpr1, *point1); dprintf("MUTATEE: after insert2 in fork of %d to %d\n", parent->getPid(), child->getPid()); test2Child = child; test2Parent = parent; } else if (inTest == 4) { if (!child) return; // skip prefork case // insert code into parent appImage = parent->getImage(); assert(appImage); char *fn5 = "func4_3"; if (NULL == appImage->findFunction(fn5, bpfv) || !bpfv.size() || NULL == bpfv[0]){ fprintf(stderr, " Unable to find function %s\n",fn5); exit(1); } BPatch_function *func4_3_parent = bpfv[0]; BPatch_funcCallExpr callExpr2(*func4_3_parent, nullArgs); bpfv.clear(); char *fn6 = "func4_2"; if (NULL == appImage->findFunction(fn6, bpfv) || !bpfv.size() || NULL == bpfv[0]){ fprintf(stderr, " Unable to find function %s\n",fn6); exit(1); } BPatch_function *func4_2_parent = bpfv[0]; BPatch_Vector<BPatch_point *> *point2 = func4_2_parent->findPoint(BPatch_exit); assert(point2); parent->insertSnippet(callExpr2, *point2); // code goes into child after in-exec in this test. test4Child = child; } }
int main(int argc, const char *argv[]) { // Use BPatch_* classes to initialize BPatch bpatch; BPatch_binaryEdit* app = bpatch.openBinary("mutatee/c"); BPatch_image* image = app->getImage(); BPatch_Vector<BPatch_function *> found_funcs; app->loadLibrary("mutatee/liblib.so"); found_funcs.clear(); image->findFunction("foo3", found_funcs); Function* foo3_func = found_funcs[0]->getParseAPIFunc(); // Here we go, create PatchAPI objects! vector<AddressSpace*> addrSpaces; app->getAS(addrSpaces); mapped_object* obj = addrSpaces[0]->getAOut(); DynAddrSpacePtr as = DynAddrSpace::create(obj); PatchMgrPtr mgr = PatchMgr::create(as); mapped_object* lib_obj = addrSpaces[1]->getAOut(); as->loadLibrary(lib_obj); // Find Points PatchFunction* foo3 = lib_obj->getFunc(foo3_func); const vector<PatchBlock*>& blks = foo3->getCallBlocks(); for (int i = 0; i < blks.size(); i++) { vector<Point*> func_points; mgr->findPoints(blks[i], Point::PreInsn|Point::PostInsn, inserter(func_points, func_points.begin())); cerr << std::hex << blks[i]->start() << "--" << func_points.size() << " points found\n"; } /* vector<Point*> pts; mgr->findPoints(foo3, Point::FuncExit, inserter(pts, pts.begin())); cerr << pts.size() << " exit points found\n"; const vector<PatchBlock*>& blks2 = foo3->getExitBlocks(); cerr << blks2.size() << " exit blocks\n"; // Insert snippets BPatch_variableExpr *intCounter = app->malloc(*image->findType("int")); BPatch_arithExpr addOne(BPatch_assign, *intCounter, BPatch_arithExpr(BPatch_plus, *intCounter, BPatch_constExpr(1))); BPatch_arithExpr addTwo(BPatch_assign, *intCounter, BPatch_arithExpr(BPatch_plus, *intCounter, BPatch_constExpr(2))); BPatch_arithExpr addThree(BPatch_assign, *intCounter, BPatch_arithExpr(BPatch_plus, *intCounter, BPatch_constExpr(3))); BPatch_arithExpr addFour(BPatch_assign, *intCounter, BPatch_arithExpr(BPatch_plus, *intCounter, BPatch_constExpr(4))); SnippetRep<AstNodePtr> one(addOne.ast_wrapper); SnippetRep<AstNodePtr> two(addTwo.ast_wrapper); SnippetRep<AstNodePtr> three(addThree.ast_wrapper); SnippetRep<AstNodePtr> four(addFour.ast_wrapper); SnippetPtr snippet = Snippet::create(&one); SnippetPtr snippet1 = Snippet::create(&two); SnippetPtr snippet2 = Snippet::create(&three); SnippetPtr snippet3 = Snippet::create(&four); vector<InstancePtr> errorInstances; mgr->batchStart(); func_points[0]->push_back(snippet); mgr->batchFinish(errorInstances); */ }
static void prepareTestCase5(procType proc_type, BPatch_thread *thread, forkWhen when) { static BPatchSnippetHandle *parSnippetHandle5; logerror("prepareTestCase5, %d, %p, %d\n", proc_type, thread, when); if(proc_type == Parent_p && when == PreFork) { BPatch_image *parImage = thread->getProcess()->getImage(); BPatch_Vector<BPatch_function *> found_funcs; const char *inFunction = "test_fork_9_func1"; if ((NULL == parImage->findFunction(inFunction, found_funcs, 1)) || !found_funcs.size()) { logerror(" Unable to find function %s\n", inFunction); exit(1); } if (1 < found_funcs.size()) { logerror("%s[%d]: WARNING : found %d functions named %s. Using the first.\n", __FILE__, __LINE__, found_funcs.size(), inFunction); } BPatch_Vector<BPatch_point *> *points7_5p = found_funcs[0]->findPoint(BPatch_entry); if(doError(&passedTest, !points7_5p || ((*points7_5p).size() == 0), " Unable to find entry point to \"test_fork_9_func1\".\n")) return; BPatch_point *point7_5p = (*points7_5p)[0]; BPatch_variableExpr *var7_5p = parImage->findVariable("test_fork_9_global1"); if(doError(&passedTest, (var7_5p==NULL), " Unable to locate variable test_fork_9_global1\n")) return; BPatch_arithExpr expr7_5p(BPatch_plus, *var7_5p, BPatch_constExpr(9)); BPatch_arithExpr b_expr7_5p(BPatch_assign, *var7_5p, expr7_5p); parSnippetHandle5 = thread->getProcess()->insertSnippet(b_expr7_5p, *point7_5p, BPatch_callBefore); } else if(proc_type == Parent_p && when == PostFork) { BPatch_image *parImage = thread->getProcess()->getImage(); BPatch_Vector<BPatch_function *> found_funcs; const char *inFunction = "test_fork_9_func1"; if ((NULL == parImage->findFunction(inFunction, found_funcs, 1)) || !found_funcs.size()) { logerror(" Unable to find function %s\n", inFunction); exit(1); } if (1 < found_funcs.size()) { logerror("%s[%d]: WARNING : found %d functions named %s. Using the first.\n", __FILE__, __LINE__, found_funcs.size(), inFunction); } BPatch_Vector<BPatch_point *> *points7_5p = found_funcs[0]->findPoint(BPatch_entry); if(doError(&passedTest, !points7_5p || ((*points7_5p).size() == 0), " Unable to find entry point to \"test_fork_9_func1\".\n")) return; BPatch_point *point7_5p = (*points7_5p)[0]; BPatch_variableExpr *var7_5p = parImage->findVariable("test_fork_9_global1"); if(doError(&passedTest, (var7_5p==NULL), " Unable to locate variable test_fork_9_global1\n")) return; BPatch_arithExpr a_expr7_5p(BPatch_plus, *var7_5p, BPatch_constExpr(11)); BPatch_arithExpr b_expr7_5p(BPatch_assign, *var7_5p, a_expr7_5p); parSnippetHandle5 = thread->getProcess()->insertSnippet(b_expr7_5p, *point7_5p, BPatch_callBefore, BPatch_lastSnippet); BPatch_arithExpr c_expr7_5p(BPatch_plus, *var7_5p, BPatch_constExpr(13)); BPatch_arithExpr d_expr7_5p(BPatch_assign, *var7_5p, c_expr7_5p); parSnippetHandle5 = thread->getProcess()->insertSnippet(d_expr7_5p, *point7_5p, BPatch_callBefore); } else if(proc_type == Child_p && when == PostFork) { BPatch_image *childImage = thread->getProcess()->getImage(); BPatch_Vector<BPatch_function *> found_funcs; const char *inFunction = "test_fork_9_func1"; if ((NULL == childImage->findFunction(inFunction, found_funcs, 1)) || !found_funcs.size()) { logerror(" Unable to find function %s\n", inFunction); exit(1); } if (1 < found_funcs.size()) { logerror("%s[%d]: WARNING : found %d functions named %s. Using the first.\n", __FILE__, __LINE__, found_funcs.size(), inFunction); } BPatch_Vector<BPatch_point *> *points7_5c = found_funcs[0]->findPoint(BPatch_entry); if(doError(&passedTest, !points7_5c || ((*points7_5c).size() == 0), " Unable to find entry point to \"test_fork_9_func1\".\n")) return; BPatch_point *point7_5c = (*points7_5c)[0]; BPatch_variableExpr *var7_5c = childImage->findVariable("test_fork_9_global1"); if(doError(&passedTest, (var7_5c==NULL), " Unable to locate variable test_fork_9_global1\n")) return; BPatch_arithExpr a_expr7_5c(BPatch_plus, *var7_5c, BPatch_constExpr(5)); BPatch_arithExpr b_expr7_5c(BPatch_assign, *var7_5c, a_expr7_5c); parSnippetHandle5 = thread->getProcess()->insertSnippet(b_expr7_5c, *point7_5c, BPatch_callBefore, BPatch_lastSnippet); BPatch_arithExpr c_expr7_5c(BPatch_plus, *var7_5c, BPatch_constExpr(3)); BPatch_arithExpr d_expr7_5c(BPatch_assign, *var7_5c, c_expr7_5c); parSnippetHandle5 = thread->getProcess()->insertSnippet(d_expr7_5c, *point7_5c, BPatch_callBefore); } }
int main(int argc, char *argv[], char* envp[]) { if (argc < 2) { fprintf(stderr, "Usage: %s prog_filename prog_aruments\n", argv[0]); return 3; } #if 0 if (strcmp(argv[1], "prog") != 0 && strcmp(argv[1], "all")) { fprintf(stderr, "Options for patch selection are 'progonly' or 'all'\n"); return 3; } #endif int patchall = 0; //strcmp(argv[1], "all") != 0; // Create process BPatch_process *appProc = bpatch.processCreate(argv[1], (const char**) &(argv[1])); // Load pthread into the process... appProc->loadLibrary("libpthread.so.0"); // Get the process image BPatch_image *appImage = appProc->getImage(); // Find all the instrumentable procedures BPatch_Vector<BPatch_function*> *functions = appImage->getProcedures(); /************************************************************************* * General function search * *************************************************************************/ // Find the printf function BPatch_Vector<BPatch_function*> printfFuncs; appImage->findFunction("printf", printfFuncs); if (printfFuncs.size() == 0) appImage->findFunction("_printf", printfFuncs); if (printfFuncs.size() == 0) appImage->findFunction("__printf", printfFuncs); if(printfFuncs.size() == 0) { fprintf(stderr, "Could not find printf() function"); return 2; } // Find the exit function BPatch_Vector<BPatch_function*> exitFuncs; appImage->findFunction("exit", exitFuncs); if (exitFuncs.size() == 0) appImage->findFunction("_exit", exitFuncs); if (exitFuncs.size() == 0) appImage->findFunction("__exit", exitFuncs); if(exitFuncs.size() == 0) { fprintf(stderr, "Could not find exit() function"); return 2; } // Find the perror function BPatch_Vector<BPatch_function*> perrorFuncs; appImage->findFunction("perror", perrorFuncs); if (perrorFuncs.size() == 0) appImage->findFunction("_perror", perrorFuncs); if (perrorFuncs.size() == 0) appImage->findFunction("__perror", perrorFuncs); if(perrorFuncs.size() == 0) { fprintf(stderr, "Could not find perror() function"); return 2; } BPatch_Vector<BPatch_snippet*> mainEntryBlock; /************************************************************************ * Error exit call * ************************************************************************/ BPatch_Vector<BPatch_snippet*> exitArgs; BPatch_constExpr exitCode(-2); exitArgs.push_back(&exitCode); // Open call BPatch_funcCallExpr exitOnErrorCall(*exitFuncs[0], exitArgs); /************************************************************************ * Open imitate device patch * * **********************************************************************/ // Find main() BPatch_Vector<BPatch_function*> mainFunctions; appImage->findFunction("main", mainFunctions); if (mainFunctions.size() == 0) appImage->findFunction("_main", mainFunctions); if (mainFunctions.size() == 0) appImage->findFunction("__main", mainFunctions); if(mainFunctions.size() == 0) { fprintf(stderr, "Could not find main() function"); return 2; } // find open() BPatch_Vector<BPatch_function*> openFunctions; appImage->findFunction("open64", openFunctions); if (openFunctions.size() == 0) appImage->findFunction("open", openFunctions); if (openFunctions.size() == 0) appImage->findFunction("_open", openFunctions); if (openFunctions.size() == 0) appImage->findFunction("__open", openFunctions); if(openFunctions.size() == 0) { fprintf(stderr, "Could not find open() function"); return 2; } // Get main() entry point BPatch_Vector<BPatch_point*> *mainPoints = mainFunctions[0]->findPoint(BPatch_entry); // Open call arguments BPatch_Vector<BPatch_snippet*> openArgs; BPatch_constExpr fileName("/dev/imitate0"); BPatch_constExpr fileFlags(O_RDWR); openArgs.push_back(&fileName); openArgs.push_back(&fileFlags); // Open call BPatch_funcCallExpr openDevCall(*openFunctions[0], openArgs); // Allocate file descriptor BPatch_variableExpr *devFd = appProc->malloc(*appImage->findType("int")); // Assign fd with result of open call BPatch_arithExpr openDevice(BPatch_assign, *devFd, openDevCall); // defFd check BPatch_boolExpr devFdCheck(BPatch_lt, *devFd, BPatch_constExpr(0)); // perror message BPatch_Vector<BPatch_snippet*> devFdErrorArgs; BPatch_constExpr devFdErrorMsg("Opening imitate kernel device"); devFdErrorArgs.push_back(&devFdErrorMsg); BPatch_funcCallExpr devFdError(*perrorFuncs[0], devFdErrorArgs); BPatch_Vector<BPatch_snippet*> openErrorBlock; openErrorBlock.push_back(&devFdError); openErrorBlock.push_back(&exitOnErrorCall); // if (devFd < 0) { perror(...) } BPatch_ifExpr devFdBlock(devFdCheck, BPatch_sequence(openErrorBlock)); mainEntryBlock.push_back(&openDevice); mainEntryBlock.push_back(&devFdBlock); /************************************************************************* * Send ioctl IMITATE_APP_RECORD to module * *************************************************************************/ // find ioctl() BPatch_Vector<BPatch_function*> ioctlFunctions; appImage->findFunction("ioctl", ioctlFunctions); if (ioctlFunctions.size() == 0) appImage->findFunction("_ioctl", ioctlFunctions); if (ioctlFunctions.size() == 0) appImage->findFunction("__ioctl", ioctlFunctions); if(ioctlFunctions.size() == 0) { fprintf(stderr, "Could not find ioctl() function"); return 2; } // ioctl() arguments BPatch_Vector<BPatch_snippet*> ioctlArgs; BPatch_constExpr operation(IMITATE_APP_RECORD); fprintf(stderr, "PPID: %d\n", getppid()); BPatch_constExpr monitorPid(getppid()); ioctlArgs.push_back(devFd); ioctlArgs.push_back(&operation); ioctlArgs.push_back(&monitorPid); // ioctl() call BPatch_funcCallExpr ioctlCall(*ioctlFunctions[0], ioctlArgs); // ioctl() result check BPatch_boolExpr ioctlCheck(BPatch_lt, ioctlCall, BPatch_constExpr(0)); // perror message BPatch_Vector<BPatch_snippet*> ioctlErrorArgs; BPatch_constExpr ioctlErrorMsg("Notifying imitate kernel driver of RECORD"); ioctlErrorArgs.push_back(&ioctlErrorMsg); BPatch_funcCallExpr ioctlError(*perrorFuncs[0], ioctlErrorArgs); BPatch_Vector<BPatch_snippet*> ioctlErrorBlock; ioctlErrorBlock.push_back(&ioctlError); ioctlErrorBlock.push_back(&exitOnErrorCall); // if (ioctl(...) < 0) { perror(...) } BPatch_ifExpr ioctlBlock(ioctlCheck, BPatch_sequence(ioctlErrorBlock)); // Add ioctl check to entry block mainEntryBlock.push_back(&ioctlBlock); /************************************************************************* * Counter mmap() * *************************************************************************/ // Find the mmap function BPatch_Vector<BPatch_function*> mmapFuncs; appImage->findFunction("mmap", mmapFuncs); if (mmapFuncs.size() == 0) appImage->findFunction("_mmap", mmapFuncs); if (mmapFuncs.size() == 0) appImage->findFunction("__mmap", mmapFuncs); if(mmapFuncs.size() == 0) { fprintf(stderr, "Could not find mmap() function"); return 2; } // Allocate counter BPatch_variableExpr *counterAddr = appProc->malloc(sizeof(sched_counter_t*)); sched_counter_t counterVal = 0; counterAddr->writeValue(&counterVal, sizeof(sched_counter_t*), false); // Notify kernel of address BPatch_Vector<BPatch_snippet*> mmapArgs; BPatch_constExpr mmapStart(0); BPatch_constExpr mmapLength(sizeof(sched_counter_t)); BPatch_constExpr mmapProt(PROT_READ | PROT_WRITE); BPatch_constExpr mmapFlags(MAP_SHARED); BPatch_constExpr mmapOffset(0); mmapArgs.push_back(&mmapStart); mmapArgs.push_back(&mmapLength); mmapArgs.push_back(&mmapProt); mmapArgs.push_back(&mmapFlags); mmapArgs.push_back(devFd); mmapArgs.push_back(&mmapOffset); // mmap() call BPatch_funcCallExpr mmapCall(*mmapFuncs[0], mmapArgs); // assign result to counterAddr BPatch_arithExpr mmapAssign(BPatch_assign, *counterAddr, mmapCall); // Add to entry block mainEntryBlock.push_back(&mmapAssign); // mmap() result check BPatch_boolExpr mmapCheck(BPatch_eq, *counterAddr, BPatch_constExpr(MAP_FAILED)); // perror message BPatch_Vector<BPatch_snippet*> mmapErrorArgs; BPatch_constExpr mmapErrorMsg("Memory mapping schedule (back edge) counter"); mmapErrorArgs.push_back(&mmapErrorMsg); BPatch_funcCallExpr mmapError(*perrorFuncs[0], mmapErrorArgs); BPatch_Vector<BPatch_snippet*> mmapErrorBlock; mmapErrorBlock.push_back(&mmapError); mmapErrorBlock.push_back(&exitOnErrorCall); // if (mmap(...) == MAP_FAILED) { perror(...) } BPatch_ifExpr mmapBlock(mmapCheck, BPatch_sequence(mmapErrorBlock)); mainEntryBlock.push_back(&mmapBlock); // Patch main entry BPatch_sequence mainEntrySeq(mainEntryBlock); appProc->insertSnippet(mainEntrySeq, *mainPoints); /************************************************************************* * Back-edge patching * *************************************************************************/ #if 0 printf("intCounter address: %x\n PID: %d\n", intCounter->getBaseAddr(), appProc->getPid()); fflush(stdout); #endif // Find the mutex lock/unlock functions BPatch_Vector<BPatch_function*> mutexLockFunctions; appImage->findFunction("pthread_mutex_lock", mutexLockFunctions); if (mutexLockFunctions.size() == 0) appImage->findFunction("_pthread_mutex_lock", mutexLockFunctions); if (mutexLockFunctions.size() == 0) appImage->findFunction("__pthread_mutex_lock", mutexLockFunctions); if(mutexLockFunctions.size() == 0) { fprintf(stderr, "Could not find pthread_mutex_lock() function"); return 2; } BPatch_Vector<BPatch_function*> mutexUnlockFunctions; appImage->findFunction("pthread_mutex_unlock", mutexUnlockFunctions); if (mutexUnlockFunctions.size() == 0) appImage->findFunction("_pthread_mutex_unlock", mutexUnlockFunctions); if (mutexUnlockFunctions.size() == 0) appImage->findFunction("__pthread_mutex_unlock", mutexUnlockFunctions); if(mutexUnlockFunctions.size() == 0) { fprintf(stderr, "Could not find pthread_mutex_unlock() function"); return 2; } // Allocate a mutex pthread_mutex_t mutexValue = PTHREAD_MUTEX_INITIALIZER; BPatch_variableExpr *mutex = appProc->malloc(sizeof(pthread_mutex_t)); mutex->writeValue(&mutexValue, sizeof(pthread_mutex_t), false); // Build mutex lock call BPatch_Vector<BPatch_snippet*> mutexArgs; BPatch_constExpr mutexAddress(mutex->getBaseAddr()); mutexArgs.push_back(&mutexAddress); BPatch_funcCallExpr mutexLockCall(*mutexLockFunctions[0], mutexArgs); BPatch_funcCallExpr mutexUnlockCall(*mutexUnlockFunctions[0], mutexArgs); BPatch_arithExpr derefCounter(BPatch_deref, *counterAddr); // Create 'increment counter' snippet BPatch_arithExpr addOneToCounter(BPatch_assign, derefCounter, BPatch_arithExpr(BPatch_plus, derefCounter, BPatch_constExpr(1))); BPatch_Vector<BPatch_snippet*> snippet; snippet.push_back(&mutexLockCall); snippet.push_back(&addOneToCounter); snippet.push_back(&mutexUnlockCall); BPatch_sequence addOneAtomic(snippet); char *name = (char*) malloc(sizeof(char)*200); char *modname = (char*) malloc(sizeof(char)*200); if (! (name && modname)) { fprintf(stderr, "%s %d: Out of memory!", __FILE__, __LINE__); return 1; } appProc->beginInsertionSet(); // Iterate through the procedures for (int i = 0; i < functions->size(); i++) { (*functions)[i]->getName(name, 199); (*functions)[i]->getModuleName(modname, 199); if ((patchall && strcmp(modname, "DEFAULT_MODULE") != 0) || strncmp(name, "pthread", 7) == 0 || strncmp(modname, "libpthread", 10) == 0 || strncmp(modname, "libdyninst", 10) == 0 || (name[0] == '_' && name[1] != '_' && strncmp(modname, "libc", 4) == 0)) continue; fprintf(stderr, "patcher: Patching function: '%s' (%s)", name, modname); // Patch back-edge for call if (strcmp(name, "main") != 0) appProc->insertSnippet(addOneAtomic, *((*functions)[i]->findPoint(BPatch_entry))); // Get the control flow graph for the procedure BPatch_flowGraph *graph = (*functions)[i]->getCFG(); // Find the loops BPatch_Vector<BPatch_basicBlockLoop*> *loops = new BPatch_Vector<BPatch_basicBlockLoop*>(); graph->getLoops(*loops); // Patch the loop back-edges for(int j = 0; j < loops->size(); j++) { appProc->insertSnippet(addOneAtomic, *((*loops)[j]->getBackEdge()->getPoint())); fprintf(stderr, ".", (int) (*loops)[j]->getBackEdge()->getPoint()->getAddress()); } fprintf(stderr, "\n"); // Free the loops found delete(loops); } fprintf(stderr, "Finalising patches..."); fflush(stderr); appProc->finalizeInsertionSet(false); fprintf(stderr, "Done.\n----------------------------------------\n"); // Clear up memory used to store the name free(name); free(modname); #if 0 /************************************************************************* * Exit point counter print patch * *************************************************************************/ // Patch exit() function to print out no of back branches at the end // Get exit() exit point BPatch_Vector<BPatch_point*> *exitPoints = exitFuncs[0]->findPoint(BPatch_entry); // Build printf() call: // printf("Total Total Back-branches: %d\n", counter); // Build arguments to printf() BPatch_Vector<BPatch_snippet*> printfArgs; BPatch_constExpr formatString("Total Back-branches: %d\n"); printfArgs.push_back(&formatString); printfArgs.push_back(&derefCounter); // Build call to printf() BPatch_funcCallExpr printfCall(*printfFuncs[0], printfArgs); // Patch into exit() appProc->insertSnippet(printfCall, *exitPoints); #endif // Continue mutatee... appProc->continueExecution(); // Wait for mutatee to finish while (!appProc->isTerminated()) { bpatch.waitForStatusChange(); } fprintf(stderr, "----------------------------------------\n"); fprintf(stderr, "Done.\n"); return 0; }
int main (int argc, char *argv[]) { set<string> Routines; char *env_var; int index; if ((env_var = getenv ("DYNINSTAPI_RT_LIB")) == NULL) { env_var = (char*) malloc ((1+strlen("DYNINSTAPI_RT_LIB=")+strlen(DYNINST_RT_LIB))*sizeof(char)); if (env_var == NULL) { cerr << PACKAGE_NAME << ": Cannot allocate memory to define DYNINSTAPI_RT_LIB!" << endl; exit (-1); } sprintf (env_var, "DYNINSTAPI_RT_LIB=%s", DYNINST_RT_LIB); putenv (env_var); } else cout << PACKAGE_NAME << ": Warning, DYNINSTAPI_RT_LIB already set and pointing to " << env_var << endl; /* Parse the params */ index = processParams (argc, argv, Routines); /* Does the binary exists? */ if (!__Extrae_Utils_file_exists(argv[index])) { cout << PACKAGE_NAME << ": Executable " << argv[index] << " cannot be found!" << endl; exit (-1); } if (Routines.size() > 0) { set<string>::iterator it; cout << PACKAGE_NAME << ": Will instrument routines "; for (it = Routines.begin(); it != Routines.end(); it++) cout << *it << " "; cout << endl; } /* Create an instance of the BPatch library */ bpatch = new BPatch; /* Register a callback function that prints any error messages */ bpatch->registerErrorCallback (errorFunc); /* Don't check recursion in snippets */ bpatch->setTrampRecursive (true); cout << "Welcome to " << PACKAGE_STRING << " launcher using DynInst " << DYNINST_MAJOR << "." << DYNINST_MINOR << "." << DYNINST_SUBMINOR << endl; int i = 1; while (argv[index+i] != NULL) { cout << PACKAGE_NAME << ": Argument " << i << " - " << argv[index+i] << endl; i++; } cout << PACKAGE_NAME << ": Creating process for image binary " << argv[index]; cout.flush (); BPatch_process * appProcess = bpatch->processCreate ((const char*) argv[index], (const char**) &argv[index], (const char**) environ); if (appProcess == NULL) { cerr << endl << PACKAGE_NAME << ": Error creating the target application process" << endl; exit (-1); } cout << endl; /* Stop the execution in order to load the instrumentation library */ cout << PACKAGE_NAME << ": Stopping mutatee execution" << endl; if (!appProcess->stopExecution()) { cerr << PACKAGE_NAME << ": Cannot stop execution of the target application" << endl; exit (-1); } cout << PACKAGE_NAME << ": Acquiring process image" << endl; BPatch_image *appImage = appProcess->getImage(); if (appImage == NULL) { cerr << PACKAGE_NAME << ": Error while acquiring application image" << endl; exit (-1); } cout << PACKAGE_NAME << ": Looking for printf symbol in application image" << endl; appImage->findFunction ("printf", printfFuncs); if (printfFuncs.size() == 0) { cerr << PACKAGE_NAME << ": Error! Cannot locate printf function within image" << endl; exit (-1); } if (!ListFunctions) { InstrumentCalls (appImage, appProcess, Routines); cout << PACKAGE_NAME << ": Starting program execution" << endl; if (!appProcess->continueExecution()) { /* If the application cannot continue, terminate the mutatee and exit */ cerr << PACKAGE_NAME << ": Cannot continue execution of the target application" << endl; appProcess->terminateExecution(); exit (-1); } while (!appProcess->isTerminated()) bpatch->waitForStatusChange(); if (appProcess->terminationStatus() == ExitedNormally) appProcess->getExitCode(); else if(appProcess->terminationStatus() == ExitedViaSignal) appProcess->getExitSignal(); delete appProcess; } else ShowFunctions (appImage); return 0; }