test_results_t test1_8_Mutator::executeTest() { // Find the entry point to the procedure "test1_8_func1" const char *funcName = "test1_8_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 *> *point8_1 = found_funcs[0]->findPoint(BPatch_entry); if (!point8_1 || ((*point8_1).size() == 0)) { logerror("Unable to find entry point to \"%s\".\n", funcName); return FAILED; } BPatch_Vector<BPatch_snippet*> vect8_1; const char *globalVar = "test1_8_globalVariable1"; BPatch_variableExpr *expr8_1 = findVariable(appImage, globalVar, point8_1); if (!expr8_1) { logerror("**Failed** test #3 (passing variables)\n"); logerror(" Unable to locate variable %s\n", globalVar); return FAILED; } BPatch_arithExpr arith8_1 (BPatch_assign, *expr8_1, BPatch_arithExpr(BPatch_plus, BPatch_arithExpr(BPatch_plus, BPatch_arithExpr(BPatch_plus, BPatch_constExpr(81), BPatch_constExpr(82)), BPatch_arithExpr(BPatch_plus, BPatch_constExpr(83), BPatch_constExpr(84))), BPatch_arithExpr(BPatch_plus, BPatch_arithExpr(BPatch_plus, BPatch_constExpr(85), BPatch_constExpr(86)), BPatch_arithExpr(BPatch_plus, BPatch_constExpr(87), BPatch_constExpr(88))))); vect8_1.push_back(&arith8_1); checkCost(BPatch_sequence(vect8_1)); if(!appAddrSpace->insertSnippet( BPatch_sequence(vect8_1), *point8_1)) return FAILED; return PASSED; }
test_results_t test1_7_Mutator::executeTest() { // Find the entry point to the procedure "func7_2" const char *funcName = "test1_7_func2"; 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 *> *point7_1 = found_funcs[0]->findPoint(BPatch_entry); if (!point7_1 || ((*point7_1).size() == 0)) { logerror("Unable to find entry point to \"%s\".\n", funcName); return FAILED; } BPatch_Vector<BPatch_snippet*> vect7_1; if ( genRelTest(appImage, vect7_1, BPatch_lt, 0, 1, "test1_7_globalVariable1") < 0) return FAILED; if ( genRelTest(appImage, vect7_1, BPatch_lt, 1, 0, "test1_7_globalVariable2") < 0 ) return FAILED; if ( genRelTest(appImage, vect7_1, BPatch_eq, 2, 2, "test1_7_globalVariable3") < 0 ) return FAILED; if ( genRelTest(appImage, vect7_1, BPatch_eq, 2, 3, "test1_7_globalVariable4") < 0 ) return FAILED; if ( genRelTest(appImage, vect7_1, BPatch_gt, 4, 3, "test1_7_globalVariable5") < 0 ) return FAILED; if ( genRelTest(appImage, vect7_1, BPatch_gt, 3, 4, "test1_7_globalVariable6") < 0 ) return FAILED; if ( genRelTest(appImage, vect7_1, BPatch_le, 3, 4, "test1_7_globalVariable7") < 0 ) return FAILED; if ( genRelTest(appImage, vect7_1, BPatch_le, 4, 3, "test1_7_globalVariable8") < 0 ) return FAILED; if ( genRelTest(appImage, vect7_1, BPatch_ne, 5, 6, "test1_7_globalVariable9") < 0 ) return FAILED; if ( genRelTest(appImage, vect7_1, BPatch_ne, 5, 5, "test1_7_globalVariable10") < 0 ) return FAILED; if ( genRelTest(appImage, vect7_1, BPatch_ge, 9, 7, "test1_7_globalVariable11") < 0 ) return FAILED; if ( genRelTest(appImage, vect7_1, BPatch_ge, 7, 9, "test1_7_globalVariable12") < 0 ) return FAILED; if ( genRelTest(appImage, vect7_1, BPatch_and, 1, 1, "test1_7_globalVariable13") < 0 ) return FAILED; if ( genRelTest(appImage, vect7_1, BPatch_and, 1, 0, "test1_7_globalVariable14") < 0 ) return FAILED; if ( genRelTest(appImage, vect7_1, BPatch_or, 1, 0, "test1_7_globalVariable15") < 0 ) return FAILED; if ( genRelTest(appImage, vect7_1, BPatch_or, 0, 0, "test1_7_globalVariable16") < 0 ) return FAILED; const char *funcName2 = "test1_7_func2"; BPatch_Vector<BPatch_function *> found_funcs2; if ((NULL == appImage->findFunction(funcName2, found_funcs2)) || !found_funcs2.size()) { logerror(" Unable to find function %s\n", funcName2); return FAILED; } if (1 < found_funcs2.size()) { logerror("%s[%d]: WARNING : found %d functions named %s. Using the first.\n", __FILE__, __LINE__, found_funcs2.size(), funcName2); } BPatch_Vector<BPatch_point *> *func7_1 = found_funcs2[0]->findPoint(BPatch_entry); if (!func7_1 || ((*func7_1).size() == 0)) { logerror("Unable to find entry points in \"%s\".\n", funcName2); return FAILED; } BPatch_variableExpr *constVar0, *constVar1, *constVar2, *constVar3, *constVar4, *constVar5, *constVar6, *constVar7, *constVar9; constVar0 = findVariable(appImage, "test1_7_constVar0", func7_1); constVar1 = findVariable(appImage, "test1_7_constVar1", func7_1); constVar2 = findVariable(appImage, "test1_7_constVar2", func7_1); constVar3 = findVariable(appImage, "test1_7_constVar3", func7_1); constVar4 = findVariable(appImage, "test1_7_constVar4", func7_1); constVar5 = findVariable(appImage, "test1_7_constVar5", func7_1); constVar6 = findVariable(appImage, "test1_7_constVar6", func7_1); constVar7 = findVariable(appImage, "test1_7_constVar7", func7_1); constVar9 = findVariable(appImage, "test1_7_constVar9", func7_1); if (!constVar0 || !constVar1 || !constVar2 || !constVar3 || !constVar4 || !constVar5 || !constVar6 || !constVar7 || !constVar9 ) { logerror("**Failed** test #7 (relational operators)\n"); logerror(" Unable to locate one of test1_7_constVar?\n"); return FAILED; } if ( genVRelTest(appImage, vect7_1, BPatch_lt, constVar0, constVar1, "test1_7_globalVariable1a") < 0 ) return FAILED; if ( genVRelTest(appImage, vect7_1, BPatch_lt, constVar1, constVar0, "test1_7_globalVariable2a") < 0 ) return FAILED; if ( genVRelTest(appImage, vect7_1, BPatch_eq, constVar2, constVar2, "test1_7_globalVariable3a") < 0 ) return FAILED; if ( genVRelTest(appImage, vect7_1, BPatch_eq, constVar2, constVar3, "test1_7_globalVariable4a") < 0 ) return FAILED; if ( genVRelTest(appImage, vect7_1, BPatch_gt, constVar4, constVar3, "test1_7_globalVariable5a") < 0 ) return FAILED; if ( genVRelTest(appImage, vect7_1, BPatch_gt, constVar3, constVar4, "test1_7_globalVariable6a") < 0 ) return FAILED; if ( genVRelTest(appImage, vect7_1, BPatch_le, constVar3, constVar4, "test1_7_globalVariable7a") < 0 ) return FAILED; if ( genVRelTest(appImage, vect7_1, BPatch_le, constVar4, constVar3, "test1_7_globalVariable8a") < 0 ) return FAILED; if ( genVRelTest(appImage, vect7_1, BPatch_ne, constVar5, constVar6, "test1_7_globalVariable9a") < 0 ) return FAILED; if ( genVRelTest(appImage, vect7_1, BPatch_ne, constVar5, constVar5, "test1_7_globalVariable10a") < 0 ) return FAILED; if ( genVRelTest(appImage, vect7_1, BPatch_ge, constVar9, constVar7, "test1_7_globalVariable11a") < 0 ) return FAILED; if ( genVRelTest(appImage, vect7_1, BPatch_ge, constVar7, constVar9, "test1_7_globalVariable12a") < 0 ) return FAILED; if ( genVRelTest(appImage, vect7_1, BPatch_and, constVar1, constVar1, "test1_7_globalVariable13a") < 0 ) return FAILED; if ( genVRelTest(appImage, vect7_1, BPatch_and, constVar1, constVar0, "test1_7_globalVariable14a") < 0 ) return FAILED; if ( genVRelTest(appImage, vect7_1, BPatch_or, constVar1, constVar0, "test1_7_globalVariable15a") < 0 ) return FAILED; if ( genVRelTest(appImage, vect7_1, BPatch_or, constVar0, constVar0, "test1_7_globalVariable16a") < 0 ) return FAILED; dprintf("relops test vector length is %d\n", vect7_1.size()); checkCost(BPatch_sequence(vect7_1)); if(!appAddrSpace->insertSnippet( BPatch_sequence(vect7_1), *point7_1)) return FAILED; return PASSED; }
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; }