示例#1
0
/*
 * BPatch_image::getProcedures
 *
 * Returns a list of all procedures in the image upon success, and NULL
 * upon failure.
 */
BPatch_Vector<BPatch_variableExpr *> *BPatch_image::getGlobalVariablesInt()
{
    BPatch_variableExpr *var;
    BPatch_Vector<BPatch_variableExpr *> *varlist =
        new BPatch_Vector<BPatch_variableExpr *>;

    if (varlist == NULL) return NULL;

    // XXX - should this stuff really be by image ??? jkh 3/19/99
    BPatch_Vector<BPatch_module *> *mods = getModules();
    //BPatch_type *type;
    for (unsigned int m = 0; m < mods->size(); m++) {
        BPatch_module *module = (*mods)[m];
        char name[255];
        module->getName(name, sizeof(name));
        pdvector<pdstring> keys = module->getModuleTypes()->globalVarsByName.keys();
        int limit = keys.size();
        for (int j = 0; j < limit; j++) {
            pdstring name = keys[j];
            var = createVarExprByName(module, name.c_str());
            if (var != NULL)
                varlist->push_back(var);
        }
    }


    return varlist;
}
示例#2
0
void BPatch_basicBlock::getOutgoingEdges(BPatch_Vector<BPatch_edge*>& out)
{
  std::set<BPatch_edge*>::iterator outIter = outgoingEdges.begin();
  while (outIter != outgoingEdges.end()) {
    out.push_back(*outIter);
    outIter++;
  }
}
示例#3
0
void BPatch_basicBlock::getIncomingEdges(BPatch_Vector<BPatch_edge*>& inc)
{
  std::set<BPatch_edge*>::iterator incIter = incomingEdges.begin();
  while (incIter != incomingEdges.end()) {
    inc.push_back(*incIter);
    incIter++;
  }
}
示例#4
0
void source_helper(ParseAPI::Edge* e,
		   BPatch_Vector<BPatch_basicBlock*>& srcs,
		   BPatch_flowGraph* flowGraph,
		   func_instance* func)
{
  BPatch_basicBlock* b = flowGraph->findBlock(func->obj()->findBlock(e->src()));
  assert(b);
  srcs.push_back(b);
}
bool BPatch_loopTreeNode::getCalleesInt(BPatch_Vector<BPatch_function *> &v,
                                        BPatch_process *p)
{
   for (unsigned i=0; i<callees.size(); i++)
   {
      BPatch_function *f = p->func_map->get(callees[i]);
      v.push_back(f);
   }
   return true;
}
bool BPatch_loopTreeNode::getCallees(BPatch_Vector<BPatch_function *> &v,
                                     BPatch_addressSpace *p)
{
    for (unsigned i=0; i<callees.size(); i++) {
        //  get() will not allocate a NULL entry in the map
        BPatch_function *f = p->findOrCreateBPFunc(callees[i], NULL);
        v.push_back(f);
    }
    return true;
}
示例#7
0
BPatchSnippetHandle *BPatch_addressSpace::insertSnippet(const BPatch_snippet &expr,
      BPatch_point &point,
      BPatch_callWhen when,
      BPatch_snippetOrder order)
{
   BPatch_Vector<BPatch_point *> points;
   points.push_back(&point);
   return insertSnippet(expr,
         points,
         when,
         order);
}
示例#8
0
/* This function should be deprecated. */
bool BPatch_module::getLineToAddrInt( unsigned int lineNo, BPatch_Vector< unsigned long > & buffer, bool ) {
    if (hasBeenRemoved_) return false;

	std::vector< std::pair< Address, Address > > ranges;
	if( ! getAddressRangesInt( NULL, lineNo, ranges ) ) { return false; }

	for( unsigned int i = 0; i < ranges.size(); ++i ) {
		buffer.push_back( ranges[i].first );
		}

	return true;
	} /* end getLineToAddr() */
示例#9
0
//returns the successors of the basic block in a set
void BPatch_basicBlock::getTargets(BPatch_Vector<BPatch_basicBlock*>& tgrts){
  BPatch_basicBlock *b;
  pdvector<block_instance *> out_blocks;
  const PatchBlock::edgelist &itrgs = iblock->targets();
  for (PatchBlock::edgelist::const_iterator iter = itrgs.begin(); iter != itrgs.end(); ++iter) {
    edge_instance* iedge = SCAST_EI(*iter);
    // We don't include interprocedural predecessors in the BPatch layer
    if (iedge->interproc() || iedge->sinkEdge()) continue;

    b = flowGraph->findBlock(iedge->trg());
    if (b) tgrts.push_back(b);
  }
}
示例#10
0
BPatch_Vector<BPatch_function *> *pd_image::getIncludedFunctions()
{
  BPatch_Vector<BPatch_function *> *ret = new BPatch_Vector<BPatch_function *>();
  for (unsigned int i = 0; i < some_mods.size(); ++i) {
    BPatch_Vector<BPatch_function *> *temp;
    temp = getIncludedFunctions(some_mods[i]->get_dyn_module());
    if (NULL == temp) continue;
    for (unsigned j = 0; j < temp->size(); j++) {
        ret->push_back((*temp)[j]);
    }
  }
  return ret;
}
示例#11
0
bool BPatch_module::getVariablesInt(BPatch_Vector<BPatch_variableExpr *> &vars)
{
    if (hasBeenRemoved_) return false;

     BPatch_variableExpr *var;
     parseTypesIfNecessary();
     
     pdvector<pdstring> keys = moduleTypes->globalVarsByName.keys();
     int limit = keys.size();
     for (int j = 0; j < limit; j++) {
         pdstring name = keys[j];
         var = img->createVarExprByName(this, name.c_str());
         if (var != NULL)
             vars.push_back(var);
     }
     if (limit) 
         return true;

     // We may not have top-level (debugging derived) variable info.
     // If not, go into the low-level code.
     const pdvector<int_variable *> &allVars = mod->getAllVariables();

     for (unsigned i = 0; i < allVars.size(); i++) {
         BPatch_variableExpr *var = img->createVarExprByName(this, 
                                                             allVars[i]->symTabName().c_str());
         if (var)
             vars.push_back(var);
     }

     if (vars.size())
         return true;
     
#ifdef IBM_BPATCH_COMPAT
     //  IBM getVariables can be successful while returning an empty set of vars
     return true;
#else
     return false;
#endif
}
示例#12
0
//returns the source block corresponding to the basic block
//which is created looking at the machine code.
bool
BPatch_basicBlock::getSourceBlocks(BPatch_Vector<BPatch_sourceBlock*>& sBlocks)
{
  if(!sourceBlocks)
    flowGraph->createSourceBlocks();

  if(!sourceBlocks)
    return false;

  for(unsigned int i=0;i<sourceBlocks->size();i++)
    sBlocks.push_back((*sourceBlocks)[i]);

  return true;
}
示例#13
0
BPatch_Vector<BPatch_point*>* BPatch_memoryAccess::filterPoints(
    const BPatch_Vector<BPatch_point *> &points,
    unsigned int numMAs)
{
    BPatch_Vector<BPatch_point*> *result = new BPatch_Vector<BPatch_point *>;

    for(unsigned int i = 0; i < points.size(); ++i) {
        const BPatch_memoryAccess *ma = points[i]->getMemoryAccess();
        if(ma)
            if(ma->getNumberOfAccesses() >= numMAs)
                result->push_back(points[i]);
    }
    return result;
}
示例#14
0
/*
 * BPatch_localVarCollection::getAllVars()
 * this function returns all the local variables in the collection.
 */
BPatch_Vector<BPatch_localVar *> *BPatch_localVarCollection::getAllVars() {
    dictionary_hash_iter<pdstring, BPatch_localVar *> li(localVariablesByName);

    pdstring               name;
    BPatch_localVar     *localVar;

    BPatch_Vector<BPatch_localVar *> *localVarVec = new BPatch_Vector<BPatch_localVar *>;

    // get all local vars in the localVariablesByName collection
    while (li.next(name, localVar))
	localVarVec->push_back(localVar);

    return localVarVec;
}
示例#15
0
/*
 * BPatch_thread::getCallStack
 *
 * Returns information about the frames currently on the thread's stack.
 *
 * stack	The vector to fill with the stack trace information.
 */
bool BPatch_thread::getCallStack(BPatch_Vector<BPatch_frame>& stack)
{
    pdvector<Frame> stackWalk;

    if (!llthread->walkStack(stackWalk) ) {
        proccontrol_printf("%s[%d]: failed to perform stackwalk on thread %d\n",
                           FILE__, __LINE__, llthread->getLWP());
        return false;
    }

    for (unsigned int i = 0; i < stackWalk.size(); i++) {
        bool isSignalFrame = false;
        bool isInstrumentation = false;
        BPatch_point *point = NULL;

        Frame frame = stackWalk[i];
        instPoint *iP = NULL;

        isSignalFrame = frame.isSignalFrame();
        isInstrumentation = frame.isInstrumentation();

        if (isInstrumentation)
        {
            if (NULL != (iP = frame.getPoint()))
            {
                point = proc->findOrCreateBPPoint(NULL, iP, BPatch_point::convertInstPointType_t(iP->type()));
            }

            if (!point)
            {
                isInstrumentation = false;
            }
        }


        stack.push_back(BPatch_frame(this,
                                     (void *)frame.getPC(),
                                     (void *)frame.getFP(),
                                     isSignalFrame,
                                     isInstrumentation,
                                     point));
    }
    return true;
}
示例#16
0
static int genVRelTest(BPatch_image *appImage,
		BPatch_Vector<BPatch_snippet*> &vect7_1, 
		BPatch_relOp op, BPatch_variableExpr *r1, 
		BPatch_variableExpr *r2, const char *var1)
{
	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 -1;
	}

	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 -1;
	}

	BPatch_variableExpr *expr1_1 = findVariable(appImage, var1, point7_1);

	if (!expr1_1) 
	{
		logerror("**Failed** test #7 (relational operators)\n");
		logerror("    Unable to locate variable %s\n", var1);
		return -1;
	}

	BPatch_ifExpr *tempExpr1 = new BPatch_ifExpr(
			BPatch_boolExpr(op, *r1, *r2), 
			BPatch_arithExpr(BPatch_assign, *expr1_1, BPatch_constExpr(74)));
	vect7_1.push_back(tempExpr1);

	return 0;
}
示例#17
0
/*
 * BPatch_image::getProcedures
 *
 * Returns a list of all procedures in the image upon success, and NULL
 * upon failure.
 */
BPatch_Vector<BPatch_function *> *BPatch_image::getProceduresInt(bool incUninstrumentable)
{
    BPatch_Vector<BPatch_function *> *proclist =
        new BPatch_Vector<BPatch_function *>;

    if (proclist == NULL) return NULL;

    // XXX Also, what should we do about getting rid of this?  Should
    //     the BPatch_functions already be made and kept around as long
    //     as the process is, so the user doesn't have to delete them?
    BPatch_Vector<BPatch_module *> *mods = getModules();

    for (unsigned int i = 0; i < (unsigned) mods->size(); i++) {
        BPatch_Vector<BPatch_function *> *funcs = (*mods)[i]->getProcedures(incUninstrumentable);
        for (unsigned int j=0; j < (unsigned) funcs->size(); j++) {
            proclist->push_back((*funcs)[j]);
        }
    }

    return proclist;
}
示例#18
0
BPatch_Vector<BPatch_point*>*
BPatch_basicBlock::findPointByPredicate(insnPredicate& f)
{
  BPatch_Vector<BPatch_point*>* ret = new BPatch_Vector<BPatch_point*>;
  block_instance::Insns insns;
  block()->getInsns(insns);
  for (block_instance::Insns::iterator iter = insns.begin();
       iter != insns.end(); ++iter) {
    if(f(iter->second)) {
      instPoint *p = instPoint::preInsn(ifunc(), block(), iter->first, iter->second, true);
      BPatch_point *tmp = flowGraph->getAddSpace()->findOrCreateBPPoint(flowGraph->getFunction(),
                                                                        p,
                                                                        BPatch_locInstruction);
      if(!tmp) {
        fprintf(stderr, "WARNING: failed to create instpoint for load/store/prefetch %s at 0x%lx\n",
                iter->second.format().c_str(), iter->first);
      }
      else {
        ret->push_back(tmp);
      }
    }
  }
  return ret;
}
示例#19
0
// 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;
}
示例#20
0
bool insertTraceSnippet(dynHandle *dh, BPatch_function *func, BPatch_Vector<BPatch_point *> *points)
{
   char *buf;
   BPatch_point *point;
   BPatch_callWhen when;
   BPatch_snippetOrder order;

   int warn_cnt = 0, pass_cnt = 0;

   sendMsg(config.outfd, ID_TRACE_INSERT, VERB3);

   for (unsigned int i = 0; i < points->size(); ++i) {
      if (!shouldInsert())
         continue;
      sendMsg(config.outfd, ID_TRACE_INSERT_ONE, VERB4);

      point = (*points)[i];
      buf = sprintf_static("%0*lx", trace_msglen, (void *)point);

      BPatch_constExpr data(buf);
      BPatch_constExpr len(trace_msglen);

      BPatch_Vector< BPatch_snippet * > param;
      param.push_back( trace_fd );
      param.push_back( &data );
      param.push_back( &len );

      // write(trace_fd, buf, trace_msglen);
      BPatch_funcCallExpr writeCall(*trace_write, param);

      // if (trace_fd > 0)
      BPatch_boolExpr checkFd(BPatch_gt, *trace_fd, BPatch_constExpr( 0 ));

      BPatch_ifExpr traceSnippet(checkFd, writeCall);

      switch (point->getPointType()) {
         case BPatch_entry:
            when = BPatch_callBefore;
            order = BPatch_firstSnippet;
            break;

         case BPatch_exit:
            when = BPatch_callAfter;
            order = BPatch_lastSnippet;
            break;

         default:
            sendMsg(config.outfd, ID_TRACE_INSERT_ONE, VERB4, ID_FAIL,
                    "Internal error.  Attempting to trace non entry/exit point.");
            ++warn_cnt;
            continue;
      }

      BPatchSnippetHandle *handle = dh->addSpace->insertSnippet(traceSnippet, *point, when, order);
      if (!handle) {
         sendMsg(config.outfd, ID_TRACE_INSERT_ONE, VERB4, ID_FAIL,
                 "Error detected in BPatch_process::insertSnippet().");
         ++warn_cnt;
         continue;
      }
      sendMsg(config.outfd, ID_TRACE_INSERT_ONE, VERB4, ID_PASS);
      ++pass_cnt;
      trace_points[(void *)point] = func;
   }

   if (warn_cnt) {
      sendMsg(config.outfd, ID_TRACE_INSERT, VERB3, ID_WARN,
              sprintf_static("%d warning(s), %d passed.", warn_cnt, pass_cnt));
   } else {
      sendMsg(config.outfd, ID_TRACE_INSERT, VERB3, ID_PASS);
   }
   return true;
}
示例#21
0
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;
}
示例#22
0
test_results_t test1_23_Mutator::executeTest() 
{
	const char *funcName = "test1_23_call1";
	BPatch_Vector<BPatch_function *> found_funcs;

	if ((NULL == appImage->findFunction(funcName, found_funcs, 1)) 
			|| !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 *> *point23_calls = found_funcs[0]->findPoint(BPatch_subroutine);    

	if (!point23_calls || (point23_calls->size() < 1)) 
	{
		logerror("**Failed** test #23 (local variables)\n");
		logerror("  Unable to find point %s - subroutine calls\n", funcName);
		return FAILED;
	}

	/* We only want the first one... */
	BPatch_Vector<BPatch_point *> point23_1;
	point23_1.push_back((*point23_calls)[0]);

	BPatch_variableExpr *var1 = appImage->findVariable(*(point23_1[0]),
			"localVariable23_1");
	BPatch_variableExpr *var2 = appImage->findVariable(*(point23_1[0]),
			"test1_23_shadowVariable1");
	BPatch_variableExpr *var3 = appImage->findVariable("test1_23_shadowVariable2");
	BPatch_variableExpr *var4 = appImage->findVariable("test1_23_globalVariable1");

	if (!var1 || !var2 || !var3 || !var4) 
	{
		logerror("**Failed** test #23 (local variables)\n");

		if (!var1)
		{
			logerror("  can't find local variable localVariable23_1\n");
			BPatch_function *f = point23_1[0]->getCalledFunction();
			assert(f);
			BPatch_Vector<BPatch_localVar *> *lvars = f->getVars();
			assert(lvars);
			logerror("%s[%d]:  have vars\n", FILE__, __LINE__);
			for (unsigned int i = 0; i < lvars->size(); ++i)
			{
				logerror("\t%s\n", (*lvars)[i]->getName());
			}
		}
		if (!var2)
			logerror("  can't find local variable test1_23_shadowVariable1\n");
		if (!var3)
			logerror("  can't find global variable test1_23_shadowVariable2\n");
		return FAILED;
	}

	BPatch_arithExpr expr23_1(BPatch_assign, *var1, BPatch_constExpr(2300001));
	BPatch_arithExpr expr23_2(BPatch_assign, *var2, BPatch_constExpr(2300012));
	BPatch_arithExpr expr23_3(BPatch_assign, *var3, BPatch_constExpr(2300023));
	BPatch_arithExpr expr23_4(BPatch_assign, *var4, *var1);

	BPatch_Vector<BPatch_snippet *> exprs;

	exprs.push_back(&expr23_1);
	exprs.push_back(&expr23_2);
	exprs.push_back(&expr23_3);
	exprs.push_back(&expr23_4);

	BPatch_sequence allParts(exprs);


	appAddrSpace->insertSnippet(allParts, point23_1);

	return PASSED;
}
示例#23
0
test_results_t test1_28_Mutator::executeTest() 
{
	int i;

	if (isMutateeFortran(appImage)) 
	{
		return SKIPPED;
	}

	//	   Create the types
	BPatch_type *intType = appImage->findType("int");
	assert(intType);

	BPatch_Vector<char *> names;
	BPatch_Vector<BPatch_type *> types;

	names.push_back(const_cast<char*>("field1"));
	names.push_back(const_cast<char*>("field2"));
	types.push_back(intType);
	types.push_back(intType);

	//	struct28_1 { int field1, int field 2; }
	BPatch_type *struct28_1 = BPatch::bpatch->createStruct("test1_28_struct1", names, types);
	BPatch_type *union28_1 = BPatch::bpatch->createUnion("testUnion27_1", names, types);
	assert(union28_1);

	names.push_back(const_cast<char*>("field3"));
	names.push_back(const_cast<char*>("field4"));

	BPatch_type *intArray = BPatch::bpatch->createArray("intArray", intType, 0, 9);

	types.push_back(intArray);
	types.push_back(struct28_1);

	// struct28_2 { int field1, int field 2, int field3[10],struct26_1 field4 } 

	BPatch_type *struct28_2 = BPatch::bpatch->createStruct("test1_28_struct2", names, types);
	BPatch_type *type28_2 = BPatch::bpatch->createTypedef("type28_2", struct28_2);

	// now create variables of these types.

	BPatch_variableExpr *globalVariable28_1 = 
		appImage->findVariable("test1_28_globalVariable1");

	if (!globalVariable28_1)
	{
		logerror("[%s:%u] - Unable to find variable test1_28_globalVariable1\n", 
				__FILE__, __LINE__);
		return FAILED;
	}

	globalVariable28_1->setType(type28_2);

	BPatch_variableExpr *globalVariable28_8 = 
		appImage->findVariable("test1_28_globalVariable8");

	if (!globalVariable28_8)
	{
		logerror("[%s:%u] - Unable to find variable test1_28_globalVariable8\n", 
				__FILE__, __LINE__);
		return FAILED;
	}

	globalVariable28_8->setType(union28_1);

	//     Next verify that we can find a local variable in call28
	const char *fname = "test1_28_call1";
	BPatch_Vector<BPatch_function *> found_funcs;

	if ((NULL == appImage->findFunction(fname, found_funcs)) || !found_funcs.size()) 
	{
		logerror("    Unable to find function %s\n", fname);
		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(), fname);
	}

	BPatch_Vector<BPatch_point *> *point28 = found_funcs[0]->findPoint(BPatch_entry);

	assert(point28 && (point28->size() == 1));

	// FIXME We didn't look up a local variable!?

	BPatch_variableExpr *gvar[8];

	for (i=1; i <= 7; i++) 
	{
		char name[80];

		sprintf(name, "test1_28_globalVariable%d", i);
		gvar[i] = appImage->findVariable(name);
		if (!gvar[i]) 
		{
			logerror("**Failed** test #28 (user defined fields)\n");
			logerror("  can't find variable %s\n", name);
			return FAILED;
		}
	}

	// start of code for globalVariable28
	BPatch_Vector<BPatch_variableExpr *> *fields = gvar[1]->getComponents();
	assert(fields && (fields->size() == 4));

	for (i=0; i < 4; i++) 
	{
		char fieldName[80];
		sprintf(fieldName, "field%d", i+1);
		if (strcmp(fieldName, (*fields)[i]->getName())) 
		{
			logerror("field %d of the struct is %s, not %s\n",
					i+1, fieldName, (*fields)[i]->getName());
			return FAILED;
		}
	}

	// 	   globalVariable28 = globalVariable28.field1
	BPatch_arithExpr assignment1(BPatch_assign, *gvar[2], *((*fields)[0]));
	appAddrSpace->insertSnippet(assignment1, *point28);

	// 	   globalVariable28 = globalVariable28.field2
	BPatch_arithExpr assignment2(BPatch_assign, *gvar[3], *((*fields)[1]));
	appAddrSpace->insertSnippet(assignment2, *point28);

	// 	   globalVariable28 = globalVariable28.field3[0]
	BPatch_arithExpr assignment3(BPatch_assign, *gvar[4], 
			BPatch_arithExpr(BPatch_ref, *((*fields)[2]), BPatch_constExpr(0)));
	appAddrSpace->insertSnippet(assignment3, *point28);

	// 	   globalVariable28 = globalVariable28.field3[5]
	BPatch_arithExpr assignment4(BPatch_assign, *gvar[5], 
			BPatch_arithExpr(BPatch_ref, *((*fields)[2]), BPatch_constExpr(5)));
	appAddrSpace->insertSnippet(assignment4, *point28);

	BPatch_Vector<BPatch_variableExpr *> *subfields = 
		(*fields)[3]->getComponents();
	assert(subfields != NULL);

	// 	   globalVariable28 = globalVariable28.field4.field1
	BPatch_arithExpr assignment5(BPatch_assign, *gvar[6], *((*subfields)[0]));
	appAddrSpace->insertSnippet(assignment5, *point28);

	// 	   globalVariable28 = globalVariable28.field4.field2
	BPatch_arithExpr assignment6(BPatch_assign, *gvar[7], *((*subfields)[1]));
	appAddrSpace->insertSnippet(assignment6, *point28);

	// 
	BPatch_Vector<BPatch_variableExpr *> *unionfields = globalVariable28_8->getComponents();

	int n=1;
	int val1, val2, val3; 

	((*unionfields)[0])->writeValue(&n,true);
	((*unionfields)[0])->readValue(&val1);

	if (val1 != 1) 
	{
		logerror("**Failed** test #28 (user defined fields)\n");
		logerror("  union field1 has wrong value after first set\n");
		return FAILED;
	}

	n=2;
	((*unionfields)[1])->writeValue(&n,true);
	((*unionfields)[1])->readValue(&val2);
	if (val2 != 2) 
	{
		logerror("**Failed** test #28 (user defined fields)\n");
		logerror("  union field2 has wrong value after second set\n");
		return FAILED;
	}

	((*unionfields)[1])->readValue(&val3);
	if (val3 != 2) 
	{
		logerror("**Failed** test #28 (user defined fields)\n");
		logerror("  union field1 has wrong value after second set\n");
		return FAILED;
	}

	// create a scalar
	BPatch_type *newScalar1 = BPatch::bpatch->createScalar("scalar1", 8);
	assert(newScalar1);

	int scalarSize = newScalar1->getSize();

	if (scalarSize != 8) 
	{
		logerror("**Failed** test #28 (user defined fields)\n");
		logerror("  created scalar is %d bytes, expected %d\n", scalarSize, 8);
		return FAILED;
	}

	// create an enum
	BPatch_Vector<char *> enumItems;
	BPatch_Vector<int> enumVals;

	enumItems.push_back(const_cast<char*>("item1"));
	enumItems.push_back(const_cast<char*>("item2"));
	enumItems.push_back(const_cast<char*>("item3"));

	enumVals.push_back(42);
	enumVals.push_back(43);
	enumVals.push_back(44);

	BPatch_type *newEnum1 = BPatch::bpatch->createEnum("enum1", enumItems);
	BPatch_type *newEnum2 = BPatch::bpatch->createEnum("enum2", enumItems, enumVals);

	if (!newEnum1 || !newEnum2) 
	{
		logerror("**Failed** test #28 (user defined fields)\n");
		logerror("  failed to create enums as expected\n");
		return FAILED;
	}

	if (!newEnum1->isCompatible(newEnum1)) 
	{
		logerror("**Failed** test #28 (user defined fields)\n");
		logerror("  identical enums reported incompatible\n");
		return FAILED;
	}

	if (newEnum1->isCompatible(newEnum2)) 
	{
		logerror("**Failed** test #28 (user defined fields)\n");
		logerror("  different enums declared compatible\n");
		return FAILED;

	}

	return PASSED;
}
示例#24
0
test_results_t snip_ref_shlib_var_Mutator::mutatorTest() 
{
	//  The check function returns 1 on success (value changed as expected)
	//  or 0 on failure.
	const char *check_fname  = "check_snip_ref_shlib_var";
	const char *inst_func_name = "srsv1";
	BPatch_Vector<BPatch_function *> funcs;

	appImage->findFunction(inst_func_name, funcs);

	if (!funcs.size())
	{
		logerror("%s[%d]:  failed to find function %s\n", 
				FILE__, __LINE__, inst_func_name);
		return FAILED;
	}

	BPatch_function *inst_func = funcs[0];

	std::vector<BPatch_point *> *pts= inst_func->findPoint(BPatch_entry);

	if (!pts || !pts->size())
	{
		logerror("%s[%d]:   failed to find entry point to %s\n", 
				FILE__, __LINE__, inst_func_name);
		return FAILED;
	}

	BPatch_point *entry_point = (*pts)[0];

	BPatch_Vector<BPatch_snippet *> allInst;
	BPatch_snippet *snip;

	snip = doVarAssign("gv_srsv1", "snip_ref_shlib_var1");
	if (NULL == snip) return FAILED;
	allInst.push_back(snip);

	snip = doVarAssign("gv_srsv2", "snip_ref_shlib_var2");
	if (NULL == snip) return FAILED;
	allInst.push_back(snip);

	snip = doVarArrayAssign("gv_srsv3", "snip_ref_shlib_var3", 0);
	if (NULL == snip) return FAILED;
	allInst.push_back(snip);

	snip = doVarAssign("gv_srsv4", "snip_ref_shlib_var4");
	if (NULL == snip) return FAILED;
	allInst.push_back(snip);

	snip = doVarAssign("gv_srsv5", "snip_ref_shlib_var5");
	if (NULL == snip) return FAILED;
	allInst.push_back(snip);

#if 0
	snip = doVarAssign("gv_srsv6", "snip_ref_shlib_var6");
	if (NULL == snip) return FAILED;
	allInst.push_back(snip);
#endif

	snip = doVarArrayAssign("gv_srsv7", "snip_ref_shlib_var7", 0);
	if (NULL == snip) return FAILED;
	allInst.push_back(snip);

	BPatch_sequence my_ass(allInst);

	if (!appAddrSpace->insertSnippet(my_ass, *entry_point))
	{
		logerror("%s[%d]:  failed to insert snippet\n", FILE__, __LINE__);
		return FAILED;
	}


	return PASSED;
}
示例#25
0
bool initTraceInMutatee(dynHandle *dh)
{
   // Chicken: Can't use goto for error handling because it would branch past
   // variable initialization.

   // Egg: Can't define variables at top of function (with dummy constructors)
   // because BPatch_funcCallExpr() needs a valid BPatch_function object.

   // Temporary solution: Deviate from similar functions and rely on external
   // error handling.

   // Permanent solution: BPatch_snippet and derivitives should have default
   // constructors.

   int value;
   BPatch_function *openFunc;
   BPatch_Vector< BPatch_function * > funcs;

   sendMsg(config.outfd, ID_TRACE_FIND_OPEN, VERB2, ID_TEST);
   if (!dh->image->findFunction("^(__)?open(64)?$", funcs)) {
      sendMsg(config.outfd, ID_TRACE_FIND_OPEN, VERB2, ID_FAIL,
              "Failure in BPatch_image::findFunction()");
      return false;

   } else if (funcs.size() == 0) {
      sendMsg(config.outfd, ID_TRACE_FIND_OPEN, VERB2, ID_FAIL,
              "Could not find any functions named 'open' in mutatee");
      return false;
   }
   sendMsg(config.outfd, ID_TRACE_FIND_OPEN, VERB2, ID_PASS);
   openFunc = funcs[0];

   //
   // Initialize global variables
   //
   trace_msglen = sizeof(void *) * 2;
   trace_fd = allocateIntegerInMutatee(dh, -1);
   funcs.clear();
   sendMsg(config.outfd, ID_TRACE_FIND_WRITE, VERB2);
   if (!dh->image->findFunction("^(__)?write$", funcs)) {
      sendMsg(config.outfd, ID_TRACE_FIND_WRITE, VERB2, ID_FAIL,
              "Failure in BPatch_image::findFunction()");
      return false;

   } else if (funcs.size() == 0) {
      sendMsg(config.outfd, ID_TRACE_FIND_WRITE, VERB2, ID_FAIL,
              "Could not find any functions named 'write' in mutatee");
      return false;
   }
   sendMsg(config.outfd, ID_TRACE_FIND_WRITE, VERB2, ID_PASS);
   trace_write = funcs[0];

   // "open(config.pipe_filename, O_WRONLY | O_DSYNC)"
   BPatch_constExpr path(config.pipe_filename);
   BPatch_constExpr flags(O_WRONLY | O_DSYNC);

   BPatch_Vector< BPatch_snippet * > param;
   param.push_back( &path );
   param.push_back( &flags );
   BPatch_funcCallExpr openCall(*openFunc, param); // Problem child. See above.

   // "fd = open(config.pipe_filename, O_WRONLY)"
   BPatch_arithExpr assign(BPatch_assign, *trace_fd, openCall);

   // Run the snippet.
   sendMsg(config.outfd, ID_TRACE_OPEN_WRITER, VERB2);
   dh->proc->oneTimeCode(assign);
   trace_fd->readValue(&value);
   if (value < 0) {
      sendMsg(config.outfd, ID_TRACE_OPEN_WRITER, VERB2, ID_FAIL,
              "Error detected in mutatee's call to open()");
      return false;
   }
   sendMsg(config.outfd, ID_TRACE_OPEN_WRITER, VERB2, ID_PASS);

   return true;
}
示例#26
0
//
// Start Test Case #3 - (overload operator)
//      
// static int mutatorTest(BPatch_thread *appThread, BPatch_image *appImage)
test_results_t test5_3_Mutator::executeTest() {

  BPatch_Vector<BPatch_function *> bpfv;
  const char *fn = "overload_op_test::func_cpp";
  if (NULL == appImage->findFunction(fn, bpfv) || !bpfv.size()
      || NULL == bpfv[0]){
    logerror("**Failed** test #3 (overloaded operation)\n");
    logerror("    Unable to find function %s\n", fn);
    return FAILED;
  }
  BPatch_function *f1 = bpfv[0];  
  BPatch_Vector<BPatch_point *> *point3_1 = f1->findPoint(BPatch_subroutine);

  assert(point3_1);
  if (point3_1->size() == 0) {
    logerror("**Failed test5_3 (overload operation)\n");
    logerror("    Can't find overloaded operator call points\n");
    return FAILED;
  }

  unsigned int index = 0;
  char fn3[256];
  BPatch_function *func;
  while (index < point3_1->size()) {
     if ((func = (*point3_1)[index]->getCalledFunction()) != NULL &&
         !strcmp("overload_op_test::operator++", func->getName(fn3, 256)))
     {
        break;
     }
     index ++;
  }
  if(!func) {
    logerror("**Failed** test #3 (overload operation)\n");
    logerror("    Can't find the overload operator\n");
    return FAILED;
  }

  if (0 != strcmp("overload_op_test::operator++", func->getName(fn3, 256))) {
    logerror("**Failed** test #3 (overload operation)\n");
    logerror("    Can't find the overloaded operator\n");
    return FAILED;
  }
  // FIXME It caught fprintf...

  BPatch_Vector<BPatch_point *> *point3_2 = func->findPoint(BPatch_exit);
  assert(point3_2);
  
  bpfv.clear();
  const char *fn2 = "overload_op_test::call_cpp";
  if (NULL == appImage->findFunction(fn2, bpfv) || !bpfv.size()
      || NULL == bpfv[0]){
    logerror("**Failed** test #3 (overloaded operation)\n");
    logerror("    Unable to find function %s\n", fn2);
    return FAILED;
  }
  BPatch_function *call3_1 = bpfv[0];  
  
  BPatch_variableExpr *this2 = appImage->findVariable("test5_3_test3");
  if (this2 == NULL) {
    logerror( "**Failed** test #3 (overloaded operation)\n");
    logerror( "Unable to find variable \"test5_3_test3\"\n");
    return FAILED;
  }

  BPatch_Vector<BPatch_snippet *> opArgs;
  BPatch_arithExpr expr2_0(BPatch_addr, *this2);
  opArgs.push_back(&expr2_0);
  opArgs.push_back(new BPatch_retExpr());
  BPatch_funcCallExpr call3_1Expr(*call3_1, opArgs);
  
  checkCost(call3_1Expr);
  appAddrSpace->insertSnippet(call3_1Expr, *point3_2);
  //  int tag = 1;
  //  while (tag != 0) {}
  
  return PASSED;
}
示例#27
0
test_results_t test1_40_Mutator::executeTest() 
{
	const char *monitorFuncName = "test1_40_monitorFunc";
	const char *callSiteAddrVarName = "test1_40_callsite5_addr";

	BPatch_function *monitorFunc = NULL;
	BPatch_Vector<BPatch_function *> bpfv;

	BPatch_function *call40_1 = findFunction40("test1_40_call1", appImage);
	RETURNONNULL(call40_1);
	RETURNONFAIL(setVar40("test1_40_addr_of_call1", call40_1->getBaseAddr(),appImage));

	BPatch_function *call40_2 = findFunction40("test1_40_call2", appImage);
	RETURNONNULL(call40_2);
	RETURNONFAIL(setVar40("test1_40_addr_of_call2", call40_2->getBaseAddr(),appImage));

	BPatch_function *call40_3 = findFunction40("test1_40_call3", appImage);
	RETURNONNULL(call40_3);
	RETURNONFAIL(setVar40("test1_40_addr_of_call3", call40_3->getBaseAddr(),appImage));

	//  call40_5 is the "dispatcher" of function pointers
	BPatch_function *targetFunc = findFunction40("test1_40_call5", appImage);
	RETURNONNULL(targetFunc);
	//RETURNONFAIL(setVar40("test1_40_addr_of_call5", call40_5->getBaseAddr(),appImage));

	monitorFunc = findFunction40(monitorFuncName, appImage);
	RETURNONNULL(monitorFunc);

	BPatch_Vector<BPatch_point *> *calls = targetFunc->findPoint(BPatch_subroutine);
	if (!calls) 
	{
		logerror("**Failed test #40 (monitor call sites)\n");
		logerror("  cannot find call points for test1_40_call5\n");
		return FAILED;
	}

	BPatch_Vector<BPatch_point *> dyncalls;
	for (unsigned int i = 0; i < calls->size(); ++i) 
	{
		BPatch_point *pt = (*calls)[i];
		if (pt->isDynamic())
			dyncalls.push_back(pt);
	}

	if (dyncalls.size() != 1) 
	{
		logerror("**Failed test #40 (monitor call sites)\n");
		logerror("  wrong number of dynamic points found (%d -- not 1)\n",
				dyncalls.size());
		logerror("  total number of calls found: %d\n", calls->size());
		return FAILED;
	}

	// write address of anticipated call site into mutatee var.
	void *callsite_address = dyncalls[0]->getAddress();
	RETURNONFAIL(setVar40(callSiteAddrVarName, callsite_address, appImage));

	//  issue command to monitor calls at this site, and we're done.
	if (! dyncalls[0]->monitorCalls(monitorFunc)) 
	{
		logerror("**Failed test #40 (monitor call sites)\n");
		logerror("  cannot monitor calls\n");
		return FAILED;
	}

	return PASSED;
}