diff options
Diffstat (limited to 'afl-dyninst.cpp')
-rw-r--r-- | afl-dyninst.cpp | 732 |
1 files changed, 0 insertions, 732 deletions
diff --git a/afl-dyninst.cpp b/afl-dyninst.cpp deleted file mode 100644 index 450d903..0000000 --- a/afl-dyninst.cpp +++ /dev/null @@ -1,732 +0,0 @@ -#include <climits> -#include <cstdlib> -#include <fcntl.h> -#include <getopt.h> -#include <iostream> -#include <sstream> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <string> -#include <sys/mman.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <unistd.h> -#include <vector> - -// DyninstAPI includes -#include "BPatch.h" -#include "BPatch_addressSpace.h" -#include "BPatch_binaryEdit.h" -#include "BPatch_flowGraph.h" -#include "BPatch_function.h" -#include "BPatch_point.h" -#include "BPatch_process.h" -#include "dyninstversion.h" // if this include errors, compile and install https://github.com/dyninst/dyninst - -using namespace std; -using namespace Dyninst; - -// cmd line options -char *originalBinary; -char *instrumentedBinary; -char *entryPointName = NULL; -int verbose = 0; - -Dyninst::Address entryPoint; -set<string> todo; -set<string> instrumentLibraries; -set<string> runtimeLibraries; -set<string> skipAddresses; -set<string> onlyAddresses; -set<unsigned long> exitAddresses; -unsigned int bbMinSize = 10; -int bbSkip = 0, performance = 1; -bool skipMainModule = false, do_bb = true, dynfix = false; -unsigned long int insertions = 0; -uintptr_t mapaddr = 0; - -BPatch_function *save_rdi; -BPatch_function *restore_rdi; - -const char *functions[] = {"main", "_main", "_initproc", "_init", "start", "_start", NULL}; - -const char *instLibrary = "libAflDyninst.so"; - -static const char *OPT_STR = "fi:o:l:e:E:vs:dr:m:S:I:Dx"; -static const char *USAGE = " -fvxD -i <binary> -o <binary> -e <address> -E <address> -s <number> -S <funcname> -I <funcname> -m <size>\n \ - -i: input binary \n \ - -o: output binary\n \ - -r: runtime library to instrument (path to, repeat for more than one)\n \ - -e: entry point address to patch (required for stripped binaries)\n \ - -E: exit point - force exit(0) at this address (repeat for more than one)\n \ - -s: number of initial basic blocks to skip in binary\n \ - -m: minimum size of a basic bock to instrument (default: 10)\n \ - -f: fix a dyninst bug that leads to crashes (performance loss, only dyninst9)\n \ - -I: only instrument this function and nothing else (repeat for more than one)\n \ - -S: do not instrument this function (repeat for more than one)\n \ - -D: instrument only a simple fork server and also forced exit functions\n \ - -x: experimental performance mode (~25-50% speed improvement)\n \ - -v: verbose output\n \ - Note: options -l and -d have been deprecated, use -r and -D instead.\n"; - -bool parseOptions(int argc, char **argv) { - int c; - - while ((c = getopt(argc, argv, OPT_STR)) != -1) { - switch ((char)c) { - case 'x': - performance++; - /* - if (performance == 3) { - #if ( __amd64__ || __x86_64__ ) - fprintf(stderr, "Warning: performance level 3 is currently totally experimental\n"); - #else - fprintf(stderr, "Warning: maximum performance level for non-intelx64 x86 is 2\n"); - performance = 2; - #endif - } else*/ - if (performance > 2) performance = 2; - break; - case 'I': - onlyAddresses.insert(optarg); - break; - case 'S': - skipAddresses.insert(optarg); - break; - case 'e': - if ((entryPoint = strtoul(optarg, NULL, 16)) < 0x1000) - entryPointName = optarg; - break; - case 'i': - originalBinary = optarg; - instrumentLibraries.insert(optarg); - break; - case 'o': - instrumentedBinary = optarg; - break; - case 'l': - fprintf(stderr, "Error: option -l has been removed due implementation issues, dyninst behaviour and dyninst bugs. Please use -r.\n"); - exit(-1); - break; - case 'E': - exitAddresses.insert(strtoul(optarg, NULL, 16)); - break; - case 'r': - runtimeLibraries.insert(optarg); - break; - case 's': - bbSkip = atoi(optarg); - break; - case 'm': - bbMinSize = atoi(optarg); - break; - case 'd': - //skipMainModule = true; - fprintf(stderr, "Warning: option -d has been deprecated, use -D instead or ignore the generated -o file.\n"); - break; - case 'f': -#if (__amd64__ || __x86_64__) -#if (DYNINST_MAJOR_VERSION < 10) - dynfix = true; -#endif -#endif - break; - case 'D': - do_bb = false; - break; - case 'v': - verbose++; - break; - default: - cerr << "Usage: " << argv[0] << USAGE; - return false; - } - } - - if (originalBinary == NULL) { - cerr << "Input binary is required!" << endl; - cerr << "Usage: " << argv[0] << USAGE; - return false; - } - - if (instrumentedBinary == NULL) { - cerr << "Output binary is required!" << endl; - cerr << "Usage: " << argv[0] << USAGE; - return false; - } - - return true; -} - -BPatch_function *findFuncByName(BPatch_image *appImage, char *funcName) { - BPatch_Vector<BPatch_function *> funcs; - - if (NULL == appImage->findFunction(funcName, funcs) || !funcs.size() || NULL == funcs[0]) { - cerr << "Failed to find " << funcName << " function." << endl; - return NULL; - } - - return funcs[0]; -} - -// insert callback to initialization function in the instrumentation library -// either at _init or at manualy specified entry point. -bool insertCallToInit(BPatch_addressSpace *appBin, BPatch_function *instIncFunc, BPatch_module *module, BPatch_function *funcInit, bool install_hack) { - /* Find the instrumentation points */ - vector<BPatch_point *> points; - vector<BPatch_point *> *funcEntry = funcInit->findPoint(BPatch_entry); - BPatch_image *appImage = appBin->getImage(); - BPatchSnippetHandle *handle; - - if (NULL == funcEntry) { - cerr << "Failed to find entry for function. " << endl; - return false; - } - - // THIS BLOCK IS DISABLED - dyninst is too volatile for this to work reliably - // disabled because performance can not be greater than 2 - if (performance >= 3 && install_hack == true) { - cout << "Inserting global variables" << endl; - // we set up a fake map so we do not have crashes if the the forkserver - // is not installed in _init but later for speed reasons. - // we could also check in the bb() code if map == 0 but that would - // cost precious instructions. - BPatch_variableExpr *fakemap = appBin->malloc(65536); - BPatch_constExpr fakemap_ptr(fakemap->getBaseAddr()); - BPatch_variableExpr *map = appBin->malloc(*(appImage->findType("size_t")), "map"); - BPatch_arithExpr initmap(BPatch_assign, *map, fakemap_ptr); - - appBin->insertSnippet(initmap, *funcEntry, BPatch_firstSnippet); - BPatch_constExpr map_ptr(map->getBaseAddr()); - BPatch_variableExpr *prev_id = appBin->malloc(*(appImage->findType("size_t")), "prev_id"); - BPatch_arithExpr initprevid(BPatch_assign, *prev_id, BPatch_constExpr(0)); - - appBin->insertSnippet(initprevid, *funcEntry); - BPatch_Vector<BPatch_snippet *> instArgs; - cout << "Inserting init callback." << endl; - instArgs.push_back(&map_ptr); - BPatch_funcCallExpr instIncExpr(*instIncFunc, instArgs); - - handle = appBin->insertSnippet(instIncExpr, *funcEntry, BPatch_callBefore, BPatch_lastSnippet); - } else { - BPatch_Vector<BPatch_snippet *> instArgs; - cout << "Inserting init callback." << endl; - BPatch_funcCallExpr instIncExpr(*instIncFunc, instArgs); - - handle = appBin->insertSnippet(instIncExpr, *funcEntry, BPatch_callBefore, BPatch_lastSnippet); - } - - if (!handle) { - cerr << "Failed to insert init callback." << endl; - return false; - } - return true; -} - -// inserts a callback for each basic block assigning it an instrumentation -// time 16bit random ID just as afl -bool insertBBCallback(BPatch_addressSpace *appBin, BPatch_function *curFunc, char *funcName, BPatch_function *instBBIncFunc, int *bbIndex) { - BPatch_image *appImage = appBin->getImage(); - BPatch_flowGraph *appCFG = curFunc->getCFG(); - unsigned short randID; - - if (!appCFG) { - cerr << "Failed to find CFG for function " << funcName << endl; - return false; - } - - BPatch_Set<BPatch_basicBlock *> allBlocks; - if (!appCFG->getAllBasicBlocks(allBlocks)) { - cerr << "Failed to find basic blocks for function " << funcName << endl; - return false; - } else if (allBlocks.size() == 0) { - cerr << "No basic blocks for function " << funcName << endl; - return false; - } - - BPatch_Set<BPatch_basicBlock *>::iterator iter; - for (iter = allBlocks.begin(); iter != allBlocks.end(); iter++) { - if (*bbIndex < bbSkip || (*iter)->size() < bbMinSize) { // skip over first bbSkip bbs or below minimum size - (*bbIndex)++; - continue; - } - - BPatch_point *bbEntry = (*iter)->findEntryPoint(); - - if (performance >= 1) { - if ((*iter)->isEntryBlock() == false) { - bool good = false; - - BPatch_Vector<BPatch_basicBlock *> sources; - (*iter)->getSources(sources); - for (unsigned int i = 0; i < sources.size() && good == false; i++) { - BPatch_Vector<BPatch_basicBlock *> targets; - sources[i]->getTargets(targets); - if (targets.size() > 1) - good = true; - } - if (good == false) - continue; - } - } - - unsigned long address = (*iter)->getStartAddress(); - - randID = rand() % USHRT_MAX; - if (verbose >= 1) { - cout << "Instrumenting Basic Block 0x" << hex << address << " of " << funcName << " with size " << dec << (*iter)->size() << " with random id " << randID << "/0x" << hex << randID << endl; - } - - if (NULL == bbEntry) { - // warn the user, but continue - cerr << "Failed to find entry for basic block at 0x" << hex << address << endl; - (*bbIndex)++; - continue; - } - - BPatchSnippetHandle *handle; - - // level 3 is disabled - if (performance >= 3) { - // these are dummy instructions we overwrite later - BPatch_variableExpr *pid = appImage->findVariable("prev_id"); - BPatch_arithExpr new_prev_id(BPatch_assign, *pid, BPatch_arithExpr(BPatch_divide, BPatch_constExpr(8), BPatch_constExpr(2))); - - handle = appBin->insertSnippet(new_prev_id, *bbEntry, BPatch_lastSnippet); - BPatch_variableExpr *map = appImage->findVariable("map"); - BPatch_variableExpr *pid2 = appImage->findVariable("prev_id"); - BPatch_arithExpr map_idx(BPatch_arithExpr(BPatch_plus, *map, BPatch_arithExpr(BPatch_divide, *pid2, BPatch_constExpr(2)))); - - if (mapaddr == 0) { - printf("Map for AFL is installed at: %p\n", (void *)map->getBaseAddr()); - mapaddr = (uintptr_t)map->getBaseAddr(); - } - handle = appBin->insertSnippet(map_idx, *bbEntry, BPatch_firstSnippet); - } else { - BPatch_Vector<BPatch_snippet *> instArgs1; - BPatch_Vector<BPatch_snippet *> instArgs; - BPatch_constExpr bbId(randID); - - instArgs.push_back(&bbId); -#if (DYNINST_MAJOR_VERSION < 10) - BPatch_funcCallExpr instIncExpr1(*save_rdi, instArgs1); - BPatch_funcCallExpr instIncExpr3(*restore_rdi, instArgs1); -#endif - BPatch_funcCallExpr instIncExpr(*instBBIncFunc, instArgs); - - -#if (DYNINST_MAJOR_VERSION < 10) - if (dynfix == true) - handle = appBin->insertSnippet(instIncExpr1, *bbEntry, BPatch_callBefore, BPatch_firstSnippet); -#endif - handle = appBin->insertSnippet(instIncExpr, *bbEntry, BPatch_callBefore); -#if (DYNINST_MAJOR_VERSION < 10) - if (dynfix == true) - handle = appBin->insertSnippet(instIncExpr3, *bbEntry, BPatch_callBefore, BPatch_lastSnippet); -#endif - } - - if (!handle) { - // warn the user, but continue to next bb - cerr << "Failed to insert instrumention in basic block at 0x" << hex << address << endl; - (*bbIndex)++; - continue; - } else - insertions++; - - (*bbIndex)++; - } - - return true; -} - -int main(int argc, char **argv) { - char *func2patch = NULL; - int loop; - - cout << "afl-dyninst (c) 2017-2021 by Aleksandar Nikolic and Marc Heuse [https://github.com/vanhauser-thc/afl-dyninst] Apache 2.0 License" << endl; - - 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 (__amd64__ || __x86_64__) - 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"); - } - } -#endif - - BPatch bpatch; - - if (performance >= 2) { - bpatch.setSaveFPR(false); - bpatch.setTrampRecursive(true); - } - - BPatch_addressSpace *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, *firstModule = NULL; - string defaultModuleName; - - // look for _init - if (defaultModuleName.empty()) { - for (loop = 0; functions[loop] != NULL && func2patch == NULL; loop++) { - for (moduleIter = modules->begin(); moduleIter != modules->end(); ++moduleIter) { - vector<BPatch_function *>::iterator funcsIterator; - char moduleName[1024]; - - if (firstModule == NULL) - firstModule = (*moduleIter); - (*moduleIter)->getName(moduleName, 1024); - funcsInModule = (*moduleIter)->getProcedures(); - if (verbose >= 2) - cout << "Looking for init function " << functions[loop] << " in " << moduleName << endl; - for (funcsIterator = funcsInModule->begin(); funcsIterator != funcsInModule->end(); ++funcsIterator) { - char funcName[1024]; - - (*funcsIterator)->getName(funcName, 1024); - if (verbose >= 3 && loop == 0) - printf("module: %s function: %s\n", moduleName, funcName); - if (string(funcName) == string(functions[loop])) { - func2patch = (char *)functions[loop]; - defaultModuleName = string(moduleName); - defaultModule = (*moduleIter); - if (verbose >= 1) { - cout << "Found " << func2patch << " in " << moduleName << endl; - } - break; - } - } - if (!defaultModuleName.empty()) - break; - } - if (func2patch != NULL) - break; - } - } - // last resort, by name of the binary - if (defaultModuleName.empty()) - defaultModuleName = string(originalBinary).substr(string(originalBinary).find_last_of("\\/") + 1); - if (defaultModule == NULL) - defaultModule = firstModule; - - 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; - } - - /* Find code coverage functions in the instrumentation library */ - BPatch_function *initAflForkServer; - -#if (DYNINST_MAJOR_VERSION < 10) - save_rdi = findFuncByName(appImage, (char *)"save_rdi"); - restore_rdi = findFuncByName(appImage, (char *)"restore_rdi"); -#endif - BPatch_function *bbCallback = findFuncByName(appImage, (char *)"bbCallback"); - BPatch_function *forceCleanExit = findFuncByName(appImage, (char *)"forceCleanExit"); - - if (do_bb == true) { - if (performance >= 3) - initAflForkServer = findFuncByName(appImage, (char *)"initAflForkServerVar"); - else - initAflForkServer = findFuncByName(appImage, (char *)"initAflForkServer"); - } else - initAflForkServer = findFuncByName(appImage, (char *)"initOnlyAflForkServer"); - - if (!initAflForkServer || !bbCallback || !forceCleanExit -#if (DYNINST_MAJOR_VERSION < 10) - || !save_rdi || !restore_rdi -#endif - ) { - cerr << "Instrumentation library lacks callbacks!" << endl; - return EXIT_FAILURE; - } - - int bbIndex = 0; - - // if an entrypoint was set then find function, else find _init - BPatch_function *funcToPatch = NULL; - - if (entryPoint == 0 && entryPointName == NULL) { - if (func2patch == NULL) { - cerr << "Couldn't locate _init, specify entry point manually with -e 0xaddr" << endl; - return EXIT_FAILURE; - } - BPatch_Vector<BPatch_function *> funcs; - defaultModule->findFunction(func2patch, 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 { - if (entryPointName != NULL) { - for (moduleIter = modules->begin(); moduleIter != modules->end() && funcToPatch == 0; ++moduleIter) { - BPatch_Vector<BPatch_function *> funcs; - (*moduleIter)->findFunction(entryPointName, funcs); - if (funcs.size() > 0) { - char moduleName[1024]; - - funcToPatch = funcs[0]; - defaultModule = (*moduleIter); - defaultModule->getName(moduleName, 1024); - defaultModuleName = string(moduleName); - printf("Found entypoint %s in module %s\n", entryPointName, moduleName); - break; - } - } - } - if (!funcToPatch) { - if (verbose > 1) - printf("Looking for entrypoint %p\n", (char *)entryPoint); - funcToPatch = defaultModule->findFunctionByEntry(entryPoint); - if (!funcToPatch && defaultModule != firstModule) { - funcToPatch = firstModule->findFunctionByEntry(entryPoint); - if (funcToPatch) - defaultModule = firstModule; - } - if (!funcToPatch) { // ok lets go hardcore ... - if (verbose > 1) - printf("OK we did not find the entrypoint so far, lets dig deeper ...\n"); - for (moduleIter = modules->begin(); moduleIter != modules->end() && funcToPatch != NULL; ++moduleIter) { - vector<BPatch_function *>::iterator funcsIterator; - funcToPatch = (*moduleIter)->findFunctionByEntry(entryPoint); - if (funcToPatch) - defaultModule = (*moduleIter); - } - } - if (funcToPatch && verbose >= 1) { - char moduleName[1024]; - - defaultModule->getName(moduleName, 1024); - defaultModuleName = string(moduleName); - printf("Found entypoint %p in module %s\n", (void *)entryPoint, moduleName); - } - } - } - if (!funcToPatch) { - cerr << "Couldn't locate function at given entry point. " << endl; - cerr << "Try: readelf -ls " << originalBinary << " | egrep 'Entry|FUNC.*GLOBAL.*DEFAULT' | egrep -v '@|UND'" << endl; - return EXIT_FAILURE; - } - if (!insertCallToInit(appBin, initAflForkServer, defaultModule, funcToPatch, true)) { - cerr << "Could not insert init callback at given entry point." << endl; - return EXIT_FAILURE; - } - - for (moduleIter = modules->begin(); moduleIter != modules->end(); ++moduleIter) { - char moduleName[1024]; - - (*moduleIter)->getName(moduleName, 1024); - if ((*moduleIter)->isSharedLib()) { - if (instrumentLibraries.find(moduleName) == instrumentLibraries.end() && string(moduleName).find(".so") != string::npos) { - cout << "Skipping library: " << moduleName << endl; - continue; - } - } - - if (string(moduleName).find(defaultModuleName) != string::npos) { - 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("_init") || string(funcName) == string("__libc_csu_init") || string(funcName) == string("_start")) { - if (verbose) - cout << "Skipping instrumenting function " << funcName << endl; - 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; - } - } - if (!onlyAddresses.empty()) { - do_patch = 0; - set<string>::iterator saiter; - for (saiter = onlyAddresses.begin(); saiter != onlyAddresses.end() && do_patch == 1; saiter++) - if (*saiter == string(funcName)) - do_patch = 1; - if (do_patch == 0) { - cout << "Skipping instrumenting function " << funcName << endl; - continue; - } - } - insertBBCallback(appBin, curFunc, funcName, bbCallback, &bbIndex); - } - } - } - - 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, false)) - 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 - BPatch_binaryEdit *appBinr = dynamic_cast<BPatch_binaryEdit *>(appBin); - - if (!appBinr->writeFile(instrumentedBinary)) { - cerr << "Failed to write output file: " << instrumentedBinary << endl; - return EXIT_FAILURE; - } - todo.insert(instrumentedBinary); - - if (!runtimeLibraries.empty()) { - cout << "Instrumenting runtime libraries." << endl; - set<string>::iterator rtLibIter; - for (rtLibIter = runtimeLibraries.begin(); rtLibIter != runtimeLibraries.end(); rtLibIter++) { - BPatch_addressSpace *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]; - int do_patch = 1; - - curFunc->getName(funcName, 1024); - if (string(funcName) == string("_init") || string(funcName) == string("__libc_csu_init") || string(funcName) == string("_start")) - continue; - 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(libBin, curFunc, funcName, bbCallback, &bbIndex); - } - } - appBinr = dynamic_cast<BPatch_binaryEdit *>(libBin); - if (!appBinr->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; - todo.insert(*rtLibIter + ".ins"); - } - } - } - - printf("Did a total of %lu basic block insertions\n", insertions); - - if (performance >= 3) { - int fd; - struct stat st; - uint64_t i, found = 0; - unsigned char *ptr; - - unsigned char snip1[] = {0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00}; - unsigned char snip2[] = {0x08, 0x00, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00}; - unsigned char fullsnip[] = {0x53, 0x50, 0x41, 0x52, 0x48, 0xBB, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x8b, 0x03, 0x48, 0x85, 0xc0, 0x74, 0x28, 0x49, 0xBA, 0x08, 0x00, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x41, 0x8b, 0x1a, 0x66, 0x81, 0xf3, 0x99, 0x99, 0x48, 0x0f, 0xb7, 0xdb, 0x80, 0x04, 0x18, 0x01, 0x66, 0x41, 0x8b, 0x1a, 0x66, 0xd1, 0xfb, 0x66, 0x41, 0x89, 0x1a, 0x41, 0x5a, 0x58, 0x5b, 0x90, 0x90, 0x90, 0x90}; - memcpy(snip1, (char *)&mapaddr, sizeof(mapaddr)); - memcpy(fullsnip + 6, (char *)&mapaddr, sizeof(mapaddr)); - mapaddr += sizeof(mapaddr); - memcpy(snip2, (char *)&mapaddr, sizeof(mapaddr)); - memcpy(fullsnip + 24, (char *)&mapaddr, sizeof(mapaddr)); - set<string>::iterator fn; - for (fn = todo.begin(); fn != todo.end(); fn++) { - cout << "Reinstrumenting " << *fn << " ..." << endl; - if ((fd = open((const char *)(fn->c_str()), O_RDWR)) == -1 || fstat(fd, &st) != 0) { - cerr << "Error: file is gone: " << *fn << endl; - exit(-1); - } - if ((size_t)st.st_size < (size_t)sizeof(fullsnip)) { - cerr << "Error: somethings horrible wrong here with " << *fn << " ..." << endl; - continue; - } - ptr = (unsigned char *)mmap(NULL, st.st_size, PROT_WRITE | PROT_READ, MAP_SHARED, fd, 0); - for (i = 2; i < (size_t)st.st_size - (size_t)sizeof(fullsnip); i++) { - if (memcmp(ptr + i, snip1, sizeof(snip1)) == 0 && memcmp(ptr + i + sizeof(snip1) + 4, snip2, sizeof(snip2)) == 0) { - found++; - fullsnip[0x27] = rand() % 256; - fullsnip[0x28] = rand() % 256; - memcpy(ptr + i - 2, fullsnip, sizeof(fullsnip)); - } - } - // printf("found %lu entries, snipsize %u\n", found, (unsigned int)sizeof(fullsnip)); - munmap((void *)ptr, st.st_size); - close(fd); - } - if (found == insertions) { - printf("SUCCESS! Performance level 3 succeeded :)\n"); - } else { - fprintf(stderr, "Error: can not complete performance level 3, could not find all insertions (%lu of %lu).\n", found, insertions); - exit(-1); - } - } - - cout << "All done! Happy fuzzing!" << endl; - return EXIT_SUCCESS; -} |