Esempio n. 1
0
/** a basic block is instrumented if it is one of the leaf nodes
  * in the immediate dominator tree of the control flow graph 
  * or it has an outgoing edge to a basic block that it does 
  * not dominate
  */
bool FCUseDominator::validateBasicBlock(BPatch_basicBlock* bb){
	bool ret = false;

	BPatch_Vector<BPatch_basicBlock*> immediateDominates;
	bb->getImmediateDominates(immediateDominates);

	/** if it is a leaf node */
	if(!immediateDominates.size())
		ret = true;
	else{
		/** or it has outgoing edge to basic block
		  * it does not dominate
		  */
		BPatch_Set<BPatch_basicBlock*> allDom;
		bb->getAllDominates(allDom);

		BPatch_Vector<BPatch_basicBlock*> targets;
		bb->getTargets(targets);

		for(unsigned int j=0;j<targets.size();j++)
			if(!allDom.contains(targets[j])){
				/** target is not in the set 
				  * basic block dominates
				  */
				ret = true;
				break;
			}
	}
	return ret;
}
Esempio n. 2
0
/**
 * Build a CFG on top of the BPatch_flowGraph that matches
 * the original, but with an extra entry block and using
 * dominatorBB's instead of BPatch_basicBlocks.
 **/
void dominatorBB::dominatorPredAndSucc() {
   unsigned i;

   if (!bpatchBlock)
      return;

   //Predecessors
   BPatch_Vector<BPatch_basicBlock*> blocks;
   bpatchBlock->getSources(blocks);
   for (i=0; i<blocks.size(); i++)
   {
      dominatorBB *p = dom_cfg->bpatchToDomBB(blocks[i]);
      assert(p);
      pred.push_back(p);
   }

   if (bpatchBlock->isEntryBlock() || !blocks.size()) {
      dom_cfg->entryBlock->succ.push_back(this);
      pred.push_back(dom_cfg->entryBlock);
   }

   //Successors
   blocks.clear();
   bpatchBlock->getTargets(blocks);
   for (i=0; i<blocks.size(); i++)
   {
      dominatorBB *s = dom_cfg->bpatchToDomBB(blocks[i]);
      assert(s);
      succ.push_back(s);
   }
}
Esempio n. 3
0
void Instrumentcall (BPatch_image *appImage, BPatch_process *appProcess)
{
	unsigned insertion = 0;
	unsigned i = 0;

	BPatch_Vector<BPatch_function *> *vfunctions = appImage->getProcedures (true);
	cout << vfunctions->size() << " functions found in binary " << endl;

	cout << "Parsing functions " << flush;

	while (i < vfunctions->size())
	{
		char name[1024], sharedlibname[1024];

		BPatch_function *f = (*vfunctions)[i];
		(f->getModule())->getFullName (sharedlibname, 1024);
		f->getName (name, 1024);

		BPatch_Vector<BPatch_point *> *vpoints = f->findPoint (BPatch_subroutine);

		unsigned j = 0;
		while (j < vpoints->size())
		{
			BPatch_function *called = ((*vpoints)[j])->getCalledFunction();
			if (NULL != called)
			{
				char calledname[1024];
				called->getName (calledname, 1024);
				if (strcmp (calledname, "functionB") == 0)
				{
					string s = "functionA";
					BPatch_function *patch = getRoutine (s, appImage);
					if (patch != NULL)
					{
						bool replaced = appProcess->replaceFunctionCall (*((*vpoints)[j]), *patch);
						if (replaced)
							cout << "call to functionA has been successfully replaced by a call to functionB" << endl;
						else
							cout << "call to functionA failed to replace a call to functionB" << endl;

						insertion++;
					}
				}
			}
			j++;
		}

		i++;
	}

	cout << endl;

	cout << "insertion = " << insertion << endl;
}
Esempio n. 4
0
static BPatch_function *findFunction40(const char *fname, 
		BPatch_image *appImage)
{
	BPatch_Vector<BPatch_function *> bpfv;
	if (NULL == appImage->findFunction(fname, bpfv) || (bpfv.size() != 1)) 
	{

		logerror("**Failed test #40 (monitor call sites)\n");
		logerror("  Expected 1 functions matching %s, got %d\n",
				fname, bpfv.size());
		return NULL;
	}
	return bpfv[0];
}
Esempio n. 5
0
static void ShowFunctions (BPatch_image *appImage)
{
	BPatch_Vector<BPatch_function *> *vfunctions = appImage->getProcedures (false);
	cout << PACKAGE_NAME << ": " << vfunctions->size() << " functions found in binary " << endl;

	unsigned i = 0;
	while (i < vfunctions->size())
	{
		char name[1024];
		BPatch_function *f = (*vfunctions)[i];

		f->getName (name, 1024);

		if (VerboseLevel)
		{
			char mname[1024], tname[1024], modname[1024];
			f->getMangledName (mname, 1024);
			f->getTypedName (tname, 1024);
			f->getModuleName (modname, 1024);

			cout << " * " << i+1 << " of " << vfunctions->size() << ", Name: " << name << endl
			     << "    Mangled Name: " << mname << endl
			     << "    Typed Name  : " << tname << endl
			     << "    Module name : " << modname << endl
			     << "    Base address: " << f->getBaseAddr() << endl
			     << "    Instrumentable? " << (f->isInstrumentable()?"yes":"no") << endl
			     << "    In shared library? " << (f->isSharedLib()?"yes":"no") << endl
                 << "    Number of BB: " << getBasicBlocksSize(f) << endl; 

			if (f->isSharedLib())
			{
				char sharedlibname[1024];
				BPatch_module *mod = f->getModule();

				mod->getFullName (sharedlibname, 1024);
				cout << "    Full library name: " << sharedlibname << endl;
				
			}
			cout << endl;
		}
		else
		{
			cout << name << endl;
		}

		i++;
	} 
}
Esempio n. 6
0
/*
 * BPatch_image::findType
 *
 * Returns a BPatch_type* representing the named type.  If no such type
 * exists, returns NULL.
 *
 * name		The name of type to look up.
 */
BPatch_type *BPatch_image::findTypeInt(const char *name)
{
    BPatch_type *type;

    assert(BPatch::bpatch != NULL);

    // XXX - should this stuff really be by image ??? jkh 3/19/99
    BPatch_Vector<BPatch_module *> *mods = getModules();
    for (int m = mods->size() -1; m >= 0; m--) {
        BPatch_module *module = (*mods)[m];
        type = module->getModuleTypes()->findType(name);
        if (type) {
            return type;
        }
    }

    // check the default base types
    type = BPatch::bpatch->stdTypes->findType(name);
    if (type)  {
        return type;
    }

    // check the API types of last resort
    type = BPatch::bpatch->APITypes->findType(name);
    return type;

}
Esempio n. 7
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;
}
Esempio n. 8
0
void test_thread_2_Mutator::dumpVars() {
  BPatch_Vector<BPatch_variableExpr *> vars;
  appImage->getVariables(vars);
  for (unsigned int i = 0; i < vars.size(); ++i) {
    logerror("\t%s\n", vars[i]->getName());
  }
}
Esempio n. 9
0
BPatch_function* getMutateeFunction(const char *name) {                                   
	BPatch_Vector<BPatch_function *> funcs;
	mainImg->findFunction(name, funcs, true, true, true);
	if (funcs.size() != 1)
		return NULL;
	return funcs.at(0); 
}                                                                                         
Esempio n. 10
0
ostream& operator<<(ostream& os,BPatch_basicBlock& bb)
{
  unsigned i;
  os << "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";
  os << "Basic Block : " << bb.blockNo() <<" : [ ";
  os << ostream::hex << bb.getStartAddress() << " , ";
  os << ostream::hex << bb.getLastInsnAddress() << " | ";
  os << ostream::dec << bb.getEndAddress() - bb.getStartAddress() << " ]\n";

  if(bb.isEntryBlock())
    os <<"Type : ENTRY TO CFG\n";
  else if(bb.isExitBlock())
    os <<"Type : EXIT FROM CFG\n";

  cout << "Pred :\n";
  BPatch_Vector<BPatch_basicBlock *> elements;
  bb.getSources(elements);
  for (i=0; i<elements.size(); i++)
    os << "\t<- " << elements[i]->blockNo() << "\n";

  cout << "Succ:\n";
  elements.clear();
  bb.getTargets(elements);
  for (i=0; i<elements.size(); i++)
    os << "\t-> " << elements[i]->blockNo() << "\n";

  os << "Immediate Dominates: ";
  if(bb.immediateDominates){
     for (std::set<BPatch_basicBlock *>::iterator iter = bb.immediateDominates->begin();
          iter != bb.immediateDominates->end(); ++iter) {
        os << (*iter)->blockNo() << " ";
     }
  }
  os << "\n";

  os << "Immediate Dominator: ";
  if(!bb.immediateDominator)
    os << "None\n";
  else
    os << bb.immediateDominator->blockNo() << "\n";

  os << "\n";
  os << "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";
  return os;
}
static void ShowFunctions (BPatch_image *appImage)
{
	BPatch_Vector<BPatch_function *> *vfunctions = appImage->getProcedures (false);
	cout << PACKAGE_NAME << ": " << vfunctions->size() << " functions found in binary " << endl;

	unsigned i = 0;
	while (i < vfunctions->size())
	{
		char name[1024];
		BPatch_function *f = (*vfunctions)[i];

		f->getName (name, 1024);

		char mname[1024], tname[1024], modname[1024];
		f->getMangledName (mname, 1024);
		f->getTypedName (tname, 1024);
		f->getModuleName (modname, 1024);

		cout << " * " << i+1 << " of " << vfunctions->size() << ", Name: " << name << endl
		     << "    Mangled Name: " << mname << endl
		     << "    Typed Name  : " << tname << endl
		     << "    Module name : " << modname << endl
		     << "    Base address: " << f->getBaseAddr() << endl
		     << "    Instrumentable? " << (f->isInstrumentable()?"yes":"no") << endl
		     << "    In shared library? " << (f->isSharedLib()?"yes":"no") << endl;

		if (f->isSharedLib())
		{
			//Old Dyninst API < 9.x
			//char sharedlibname[1024];
			//mod->getFullName (sharedlibname, 1024);

			BPatch_module *mod = f->getModule();

			string sharedlibname;
			sharedlibname = mod->getObject()->name();
			cout << "    Full library name: " << sharedlibname << endl;
		}
		cout << endl;

		i++;
	} 
}
Esempio n. 12
0
bool BPatch_basicBlock::getLineNumbers(unsigned int &_startLine,
                                          unsigned int  &_endLine)
{
  BPatch_Vector<BPatch_sourceBlock *> sbvec;
  getSourceBlocks(sbvec);
  if (!sbvec.size()) return false;

  unsigned int temp_start = UINT_MAX, temp_end = 0;
  _startLine = UINT_MAX;
  _endLine = 0;

  //  Loop through all source blocks and accumulate the smallest start line
  //  and the largest end line.  (is there a better way? -- don't we know this a priori?)
  for (unsigned int i = 0; i < sbvec.size(); ++i) {
    sbvec[i]->getLineNumbers(temp_start, temp_end);
    if (temp_start < _startLine) _startLine = temp_start;
    if (temp_end > _endLine) _endLine = temp_end;
  }
  return true;
}
Esempio n. 13
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;
}
Esempio n. 14
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;
}
Esempio n. 15
0
//
// Start Test Case #1 - (zero arg function call)
//
test_results_t test1_1_Mutator::executeTest() {
  const char *funcName = "test1_1_func1_1";
  const char* testName = "zero arg function call";
  int testNo = 1;

  // Find the entry point to the procedure "func1_1"
  
  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 *> *point1_1 = found_funcs[0]->findPoint(BPatch_entry);


  if (!point1_1 || ((*point1_1).size() == 0)) {
    logerror("**Failed** test #%d (%s)\n", testNo,testName);
    logerror("    Unable to find entry point to \"%s.\"\n", funcName);
    return FAILED;
  }

  BPatch_Vector<BPatch_function *> bpfv;
  const char *fn = "test1_1_call1_1";
  if (NULL == appImage->findFunction(fn, bpfv) || !bpfv.size()
      || NULL == bpfv[0]){
    logerror("**Failed** test #%d (%s)\n", testNo, testName);
    logerror("    Unable to find function %s\n", fn);
    return FAILED;
  }
  BPatch_function *call1_func = bpfv[0];
  
  BPatch_Vector<BPatch_snippet *> call1_args;
  BPatch_funcCallExpr call1Expr(*call1_func, call1_args);

  checkCost(call1Expr);

  if(!appAddrSpace->insertSnippet(call1Expr, *point1_1))
      return FAILED;

  dprintf("Inserted snippet\n");

  return PASSED;
} // test1_1_Mutator::executeTest()
Esempio n. 16
0
bool instrumentFunctionExit(dynHandle *dh, BPatch_function *func)
{
   BPatch_Vector<BPatch_point *> *points;
   BPatchSnippetHandle *handle;
   BPatch_snippet incSnippet; 

   sendMsg(config.outfd, ID_INST_FUNC_EXIT, VERB2);

   if (! generateInstrumentation (dh, func, &incSnippet))
    	goto fail;

   sendMsg(config.outfd, ID_INST_FIND_POINTS, VERB3);
   points = func->findPoint(BPatch_exit);
   if (!points) {
      sendMsg(config.outfd, ID_INST_FIND_POINTS, VERB3, ID_FAIL,
              "Failure in BPatch_function::findPoint(BPatch_exit)");
      goto fail;

   } else if (points->size() == 0) {
      sendMsg(config.outfd, ID_INST_FIND_POINTS, VERB3, ID_WARN,
              "No instrumentation points found in function");
      goto fail;

   } else {
      sendMsg(config.outfd, ID_INST_FIND_POINTS, VERB3, ID_PASS);
   }

   sendMsg(config.outfd, ID_INST_INSERT_CODE, VERB3);
   if (shouldInsert()) {
      handle = dh->addSpace->insertSnippet(incSnippet, *points);
      if (!handle) {
         sendMsg(config.outfd, ID_INST_INSERT_CODE, VERB3, ID_FAIL,
                 "Failure in BPatch_process::insertSnippet()");
         goto fail;

      } else
         sendMsg(config.outfd, ID_INST_INSERT_CODE, VERB3, ID_PASS);
   }

   if (trace_fd) insertTraceSnippet(dh, func, points);

   sendMsg(config.outfd, ID_INST_FUNC_EXIT, VERB2, ID_PASS);
   return true;

 fail:
   sendMsg(config.outfd, ID_INST_FUNC_EXIT, VERB2, ID_WARN,
           "Failure while instrumenting function exit.");
   return false;
}
Esempio n. 17
0
/** the execution counts of the basic block given and the basic blocks
  * whose execution can be deduced from the given basic block is updated.
  * If a is immediate dominator of b and if b is executed then we can
  * deduce a is also executed. So this method iteratively updates
  * execution counts of the basic blocks through the path towards the root
  * of the immediate dominator tree starting from the basic block given
  */
int FCUseDominator::updateExecutionCounts(BPatch_basicBlock* bb,int ec){
	for(BPatch_basicBlock* id = bb;
	    id != NULL;
	    id = id->getImmediateDominator())
	{
		if(!executionCounts[id->getBlockNumber()]){
			BPatch_Vector<BPatch_sourceBlock*> sb;
			id->getSourceBlocks(sb);
			for(unsigned int i=0;i<sb.size();i++)
				updateLinesCovered(sb[i]);
		}
		executionCounts[id->getBlockNumber()] += ec;
	}
    return Error_OK;
}
Esempio n. 18
0
static bool hasBackEdge(BPatch_basicBlock *bb, std::set<int> visited)
{
	if (visited.find(bb->getBlockNumber()) != visited.end())
		return true;

	visited.insert(bb->getBlockNumber());

	BPatch_Vector<BPatch_basicBlock*> targets;
	bb->getTargets(targets);

	unsigned int i;
	for (i = 0; i < targets.size(); i++) 
	{
		if (hasBackEdge(targets[i], visited))
			return true;
	}

	return false;
}
Esempio n. 19
0
static BPatch_point *findPoint(BPatch_function *f, BPatch_procedureLocation loc,
                        int testno, const char *testname)
{
  assert(f);
  BPatch_Vector<BPatch_point *> *pts = f->findPoint(loc);

  if (!pts) {
	  logerror("%s[%d]:  failed to find point\n", FILE__, __LINE__);
    FAIL_MES(TESTNAME, TESTDESC);
    return NULL;
  }

  if (pts->size() != 1) {
	  logerror("%s[%d]:  failed to find point: found too many\n", FILE__, __LINE__);
      FAIL_MES(TESTNAME, TESTDESC);
      return NULL;
  }

  return (*pts)[0];
}
Esempio n. 20
0
pd_image::pd_image(BPatch_image *d_image, pd_process *p_proc) :
   appImage(d_image), parent_proc(p_proc)
{
   all_pd_images.push_back(this);

   BPatch_Vector<BPatch_module *> *mods = parent_proc->getAllModules();

   for (unsigned int m = 0; m < mods->size(); m++)  {
       BPatch_module *curr = (BPatch_module *) (*mods)[m];
       addModule(curr);
   }

   char namebuf[NAME_LEN];
   d_image->getProgramName(namebuf, NAME_LEN);
   _name = pdstring(namebuf);
   d_image->getProgramFileName(namebuf, NAME_LEN);

   _fname = pdstring(namebuf);

   //fprintf(stderr, "%s[%d]:  new pd_image: '%s'/'%s'\n", 
   //        __FILE__, __LINE__, _name.c_str(), _fname.c_str());
}
Esempio n. 21
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
}
Esempio n. 22
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;
}
Esempio n. 23
0
// static bool mutatorTest3and4(int testno, const char *testname)
test_results_t test_thread_2_Mutator::executeTest() {
  test3_threadCreateCounter = 0;
  callback_tids.clear();

  BPatchAsyncThreadEventCallback createcb = threadCreateCB;
  if (!bpatch->registerThreadEventCallback(BPatch_threadCreateEvent, createcb))
  {
    FAIL_MES(TESTNAME, TESTDESC);
    logerror("%s[%d]:  failed to register thread callback\n",
	     __FILE__, __LINE__);
    appThread->getProcess()->terminateExecution();
    return FAILED;
  }

#if 0
  //  unset mutateeIde to trigger thread (10) spawn.
  int zero = 0;
  // FIXME Check the return code for setVar
  setVar("mutateeIdle", (void *) &zero, TESTNO, TESTDESC);
  dprintf("%s[%d]:  continue execution for test %d\n", __FILE__, __LINE__, TESTNO);
  appThread->continueExecution();
#endif

  if( !appProc->continueExecution() ) {
      logerror("%s[%d]: failed to continue process\n", FILE__, __LINE__);
      appProc->terminateExecution();
      return FAILED;
  }

  //  wait until we have received the desired number of events

  int err = 0;
  BPatch_Vector<BPatch_thread *> threads;
  BPatch_process *appProc = appThread->getProcess();
  assert(appProc);
  appProc->getThreads(threads);
  int active_threads = 11; // FIXME Magic number
  threads.clear();
  while (((test3_threadCreateCounter < TEST3_THREADS)
         || (active_threads > 1)) && !appProc->isTerminated() ) {
    dprintf("%s[%d]: waiting for completion for test; ((%d < %d) || (%d > 1)) && !(%d)\n",
	    __FILE__, __LINE__, test3_threadCreateCounter, TEST3_THREADS,
	    active_threads, 1, appProc->isTerminated());
    if( !bpatch->waitForStatusChange() ) {
        logerror("%s[%d]: failed to wait for events\n", __FILE__, __LINE__);
        err = 1;
        break;
    }

    appProc->getThreads(threads);
    active_threads = threads.size();
    threads.clear();
  }

  if( appProc->isTerminated() ) {
      logerror("%s[%d]:  BAD NEWS:  somehow the process died\n", __FILE__, __LINE__);
      return FAILED;
  }

  dprintf("%s[%d]: ending test %d, num active threads = %d\n",
            __FILE__, __LINE__, TESTNO, active_threads);
  dprintf("%s[%d]:  stop execution for test %d\n", __FILE__, __LINE__, TESTNO);
  appProc->stopExecution();

  //   read all tids from the mutatee and verify that we got them all
  unsigned long mutatee_tids[TEST3_THREADS];
  const char *threads_varname = "test3_threads";
  if (getVar(threads_varname, (void *) mutatee_tids,
	     (sizeof(unsigned long) * TEST3_THREADS),
	     TESTNO, TESTDESC)) {
    appProc->terminateExecution();
    return FAILED;
  }

  if (debugPrint()) {
    dprintf("%s[%d]:  read following tids for test%d from mutatee\n", __FILE__, __LINE__, TESTNO);

    for (unsigned int i = 0; i < TEST3_THREADS; ++i) {
       dprintf("\t%lu\n", mutatee_tids[i]);
    }
  }

  for (unsigned int i = 0; i < TEST3_THREADS; ++i) {
     bool found = false;
     for (unsigned int j = 0; j < callback_tids.size(); ++j) {
       if (callback_tids[j] == mutatee_tids[i]) {
         found = true;
         break;
       }
     }

    if (!found) {
      FAIL_MES(TESTNAME, TESTDESC);
      logerror("%s[%d]:  could not find record for tid %lu: have these:\n",
             __FILE__, __LINE__, mutatee_tids[i]);
       for (unsigned int j = 0; j < callback_tids.size(); ++j) {
          logerror("%lu\n", callback_tids[j]);
       }
      err = 1;
      break;
    }
  }

  dprintf("%s[%d]: removing thread callback\n", __FILE__, __LINE__);
  if (!bpatch->removeThreadEventCallback(BPatch_threadCreateEvent, createcb)) {
    FAIL_MES(TESTNAME, TESTDESC);
    logerror("%s[%d]:  failed to remove thread callback\n",
           __FILE__, __LINE__);
    err = 1;
  }

  if (!err)  {
    logerror("No error reported, terminating process and returning success\n");
    PASS_MES(TESTNAME, TESTDESC);
    appProc->terminateExecution();
    logerror("\t Process terminated\n");
    return PASSED;
  }
  appProc->terminateExecution();
  return FAILED;
}
Esempio n. 24
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;
}
Esempio n. 25
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;
}
Esempio n. 26
0
//
// Start Test Case #30 - (line information)
//
// static int mutatorTest(BPatch_thread *appThread, BPatch_image *appImage)
// {
test_results_t test1_30_Mutator::executeTest() {
  unsigned long n;
  unsigned long baseAddr,lastAddr;
  unsigned int call30_1_line_no;
  unsigned short lineNo;
  char fileName[256];

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

  const char *funcName = "test1_30_mutatee";
  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 *> *point30_1 = found_funcs[0]->findPoint(BPatch_entry);
	//instrument with the function that will set the line number

	if (!point30_1 || (point30_1->size() < 1)) {
		logerror("Unable to find point %s - entry.\n", funcName);
		return FAILED;
	}

	BPatch_Vector<BPatch_function *> bpfv;
	const char *fn = "test1_30_call1";
	if (NULL == appImage->findFunction(fn, bpfv) || !bpfv.size()
	    || NULL == bpfv[0]){
	  logerror("    Unable to find function %s\n", fn);
	  return FAILED;
	}
	
	BPatch_function *call30_1func = bpfv[0];

	BPatch_Vector<BPatch_snippet *> nullArgs;
	BPatch_funcCallExpr call30_1Expr(*call30_1func, nullArgs);

	checkCost(call30_1Expr);
    	appAddrSpace->insertSnippet(call30_1Expr, *point30_1);

	//get the line number of the function call30_1
	BPatch_variableExpr *expr30_7 = 
		appImage->findVariable("test1_30_globalVariable7");
	if (expr30_7 == NULL) {
        	logerror("**Failed** test #30 (line information)\n");
        	logerror("    Unable to locate test1_30_globalVariable7\n");
        	return FAILED;
    	}
	expr30_7->readValue(&n);
	call30_1_line_no = (unsigned)(n+1);

        call30_1func->getAddressRange(baseAddr, lastAddr);

	//now write the base address and last address of the function
	BPatch_variableExpr *expr30_8 = 
			appImage->findVariable("test1_30_globalVariable8");
	if (expr30_8 == NULL) {
		logerror("**Failed** test #30 (line information)\n");
		logerror("    Unable to locate test1_30_globalVariable8\n");
	}

	BPatch_variableExpr *expr30_9 = 
			appImage->findVariable("test1_30_globalVariable9");
	if (expr30_9 == NULL) {
		logerror("**Failed** test #30 (line information)\n");
		logerror("    Unable to locate test1_30_globalVariable9\n");
	}

	expr30_8->writeValue(&baseAddr);
	expr30_9->writeValue(&lastAddr);
	
	
	//check getLineAddr for appImage
	BPatch_variableExpr *expr30_3 =
			appImage->findVariable("test1_30_globalVariable3");
	if (expr30_3 == NULL) {
        	logerror("**Failed** test #30 (line information)\n");
        	logerror("    Unable to locate test1_30_globalVariable3\n");
        	return FAILED;
    	}

    	
        std::vector<Dyninst::SymtabAPI::AddressRange > ranges;
        if( appImage->getAddressRanges( "test1_30_mutatee.c", call30_1_line_no, ranges ) ) {
    	    n = ranges[0].first;
    	    expr30_3->writeValue( & n );
        }else{
            logerror("BPatch_image->getAddressRanges returned false!\n");
            return FAILED;
        }
    	


	//check getLineAddr for module
	BPatch_variableExpr *expr30_4 =
			appImage->findVariable("test1_30_globalVariable4");
	if (expr30_4 == NULL) {
        	logerror("**Failed** test #30 (line information)\n");
        	logerror("    Unable to locate test1_30_globalVariable4\n");
        	return FAILED;
    	}
	BPatch_Vector<BPatch_module*>* appModules = appImage->getModules();
	for(unsigned int i=0;i<appModules->size();i++){
	  char mname[256];
	  (*appModules)[i]->getName(mname,255);mname[255] = '\0';
	  if(!strncmp(mname,"test1_30_mutatee.c",15)){
	    ranges.clear();
	    if( (*appModules)[i]->getAddressRanges( NULL, call30_1_line_no, ranges ) ) {
	      n = ranges[0].first;
	      expr30_4->writeValue( & n );
	    }
	    else
        {
            logerror("BPatch_module->getAddressRanges returned false!\n");
            return FAILED;
        }
	    break;
	  }
	}

	//check getLineAddr works for the function
	BPatch_variableExpr *expr30_5 =
		appImage->findVariable("test1_30_globalVariable5");
	if (expr30_5 == NULL) {
        	logerror("**Failed** test #30 (line information)\n");
        	logerror("    Unable to locate test1_30_globalVariable5\n");
        	return FAILED;
	}
	//check whether getLineFile works for appThread
	BPatch_variableExpr *expr30_6 =
		appImage->findVariable("test1_30_globalVariable6");
	if (expr30_6 == NULL) {
        	logerror("**Failed** test #30 (line information)\n");
        	logerror("    Unable to locate test1_30_globalVariable6\n");
        	return FAILED;
	}
	/* since the first line address of a function changes with the
	   compiler type (gcc,native) we need to check with next address
	   etc. Instead I use the last address of the function*/

	//std::vector< std::pair< const char *, unsigned int > > lines;
        BPatch_Vector<BPatch_statement> lines;
	if (appImage->getSourceLines( lastAddr - 1, lines)) {
		//n = lines[0].second;
		n = lines[0].lineNumber();
		expr30_6->writeValue( & n );
	}
	else {
	  logerror("appThread->getLineAndFile returned false!\n");
	}
        return PASSED;
}
Esempio n. 27
0
int main (int argc, char **argv)
{

    if(!parseOptions(argc,argv)) {
        return EXIT_FAILURE;
    }

    BPatch bpatch;

    BPatch_binaryEdit *appBin = bpatch.openBinary (originalBinary, !instrumentLibraries.empty());
    if (appBin == NULL) {
        cerr << "Failed to open binary" << endl;
        return EXIT_FAILURE;
    }

    if (!appBin->loadLibrary (instLibrary)) {
        cerr << "Failed to open instrumentation library." << endl;
        cerr << "It needs to be located in the current working directory." << endl;
        return EXIT_FAILURE;
    }

    BPatch_image *appImage = appBin->getImage ();

    /* Find code coverage functions in the instrumentation library */
    BPatch_function *initAflForkServer =
        findFuncByName (appImage, (char *) "initAflForkServer");
    BPatch_function *bbCallback =
        findFuncByName (appImage, (char *) "bbCallback");
    if (!initAflForkServer || !bbCallback ) {
        cerr << "Instrumentation library lacks callbacks!" << endl;
        return EXIT_FAILURE;
    }

    //get and iterate over all modules, instrumenting only the default and manualy specified ones
    vector < BPatch_module * >*modules = appImage->getModules ();
    vector < BPatch_module * >::iterator moduleIter;
    BPatch_module *defaultModule = NULL;
    string defaultModuleName;
    for (moduleIter = modules->begin (); moduleIter != modules->end (); ++moduleIter) {
    //find default module name
        char moduleName[1024];
        (*moduleIter)->getName (moduleName, 1024);    
        if (string (moduleName).find ("DEFAULT_MODULE") != string::npos) {
            defaultModuleName = "DEFAULT_MODULE";
        }
    }
    if(defaultModuleName.empty()) 
        defaultModuleName = string(originalBinary).substr(string(originalBinary).find_last_of("\\/")+1);
    int bbIndex = 0;
    for (moduleIter = modules->begin (); moduleIter != modules->end (); ++moduleIter) {
        char moduleName[1024];
        (*moduleIter)->getName (moduleName, 1024);

        if ((*moduleIter)->isSharedLib ()) {
            if (instrumentLibraries.find (moduleName) == instrumentLibraries.end ()) {
                cout << "Skipping library: " << moduleName << endl;
                continue;
            }
        }

        if (string (moduleName).find (defaultModuleName) != string::npos) {
            defaultModule = (*moduleIter);
            if(skipMainModule) continue;
        }
        cout << "Instrumenting module: " << moduleName << endl;
        vector < BPatch_function * >*allFunctions =
            (*moduleIter)->getProcedures ();
        vector < BPatch_function * >::iterator funcIter;

        // iterate over all functions in the module
        for (funcIter = allFunctions->begin (); funcIter != allFunctions->end ();
             ++funcIter) {
            BPatch_function *curFunc = *funcIter;
            char funcName[1024];
            curFunc->getName (funcName, 1024);
            if(string (funcName) == string("_start")) continue; // here's a bug on hlt
            insertBBCallback (appBin, curFunc, funcName, bbCallback, &bbIndex);
        }

    }

    //if entrypoint set ,find function  , else find _init
    BPatch_function *funcToPatch = NULL;
    if(!entryPoint) {
        BPatch_Vector<BPatch_function*> funcs;
        defaultModule->findFunction("_init", funcs);
        if(!funcs.size()) {
            cerr << "Couldn't locate _init, specify entry point manualy. "<< endl;
            return EXIT_FAILURE;
        }
        // there should really be only one
        funcToPatch = funcs[0];
    } else {
        funcToPatch = defaultModule->findFunctionByEntry(entryPoint);
    }
    if(!funcToPatch) {
        cerr << "Couldn't locate function at given entry point. "<< endl;
        return EXIT_FAILURE;
    }
    if(!insertCallToInit (appBin,  initAflForkServer,defaultModule,funcToPatch)){
        cerr << "Could not insert init callback at given entry point." << endl;
        return EXIT_FAILURE;
    }

    cout << "Saving the instrumented binary to " << instrumentedBinary << "..." << endl;
    // Output the instrumented binary
    if (!appBin->writeFile (instrumentedBinary)) {
        cerr << "Failed to write output file: " << instrumentedBinary << endl;
        return EXIT_FAILURE;
    }

    if(!runtimeLibraries.empty()) {
        cout << "Instrumenting runtime libraries." << endl;
        set<string>::iterator rtLibIter ;
        for(rtLibIter = runtimeLibraries.begin(); rtLibIter != runtimeLibraries.end(); rtLibIter++) {
            BPatch_binaryEdit *libBin = bpatch.openBinary ((*rtLibIter).c_str(), false);
            if (libBin == NULL) {
                cerr << "Failed to open binary "<< *rtLibIter << endl;
                return EXIT_FAILURE;
            }
            libBin->loadLibrary (instLibrary);
            BPatch_image *libImg = libBin->getImage ();
            vector < BPatch_module * >*modules = libImg->getModules ();
            moduleIter = modules->begin ();
            ++moduleIter;
            for ( ; moduleIter != modules->end (); ++moduleIter) {
                char moduleName[1024];
                (*moduleIter)->getName (moduleName, 1024);
                cout << "Instrumenting module: " << moduleName << endl;
                vector < BPatch_function * >*allFunctions =
                    (*moduleIter)->getProcedures ();
                vector < BPatch_function * >::iterator funcIter;
                // iterate over all functions in the module
                for (funcIter = allFunctions->begin (); funcIter != allFunctions->end ();
                     ++funcIter) {
                    BPatch_function *curFunc = *funcIter;
                    char funcName[1024];
                    curFunc->getName (funcName, 1024);
                    if(string (funcName) == string("_start")) continue;
                    insertBBCallback (libBin, curFunc, funcName, bbCallback, &bbIndex);
                }
            }
            if (!libBin->writeFile ((*rtLibIter + ".ins").c_str())) {
                cerr << "Failed to write output file: " <<(*rtLibIter + ".ins").c_str() << endl;
                return EXIT_FAILURE;
            } else {
                cout << "Saved the instrumented library to " << (*rtLibIter + ".ins").c_str() << "." << endl;
            }
        }
    }

    cout << "All done! Happy fuzzing!" << endl;
    return EXIT_SUCCESS;

}
Esempio n. 28
0
// static int mutatorTest( BPatch_thread * appThread, BPatch_image * appImage ) {
test_results_t test_stack_3_Mutator::executeTest() {
  bool passedTest;

  BPatch::bpatch->setInstrStackFrames(true);
  appProc->continueExecution();
  static const frameInfo_t correct_frame_info[] = {
	
#if defined( os_linux_test ) && (defined( arch_x86_test ) || defined( arch_x86_64_test ))
    { true, true, BPatch_frameNormal, "_dl_sysinfo_int80" },
#endif
#if defined( os_aix_test ) && defined( arch_power_test )
    /* AIX uses kill(), but the PC of a process in a syscall can
       not be correctly determined, and appears to be the address
       to which the syscall function will return. */
#elif defined( os_windows_test ) && (defined( arch_x86 ) || defined( arch_x86_64_test ))
    /* Windows/x86 does not use kill(), so its lowermost frame will be 
       something unidentifiable in a system DLL. */
    { false, false, BPatch_frameNormal, NULL },
#else
    { true, false, BPatch_frameNormal, "kill" },	
#endif
#if ! defined( os_windows_test )
    /* Windows/x86's stop_process_() calls DebugBreak(); it's 
       apparently normal to lose this frame. */
    { true, false, BPatch_frameNormal, "stop_process_" },
#endif
    { true, false, BPatch_frameNormal, "test_stack_3_func3" },
    { true, false, BPatch_frameTrampoline, NULL },
    /* On AIX and x86 (and others), if our instrumentation fires
       before frame construction or after frame destruction, it's 
       acceptable to not report the function (since, after all, it
       doesn't have a frame on the stack. */
    { true, true, BPatch_frameNormal, "test_stack_3_func2" },
    { true, false, BPatch_frameNormal, "test_stack_3_func1" },
    { true, false, BPatch_frameNormal, "test_stack_3_mutateeTest" },
    { true, false, BPatch_frameNormal, "main" }
  };
	
  /* Wait for the mutatee to stop in test_stack_3_func1(). */
  if (waitUntilStopped( bpatch, appProc, 1, "getCallStack through instrumentation") < 0) {
      appProc->terminateExecution();
    return FAILED;
  }
	
  /* Instrument test_stack_3_func2() to call test_stack_3_func3(), which will trip another breakpoint. */
  BPatch_Vector<BPatch_function *> instrumentedFunctions;	
  const char *fName = "test_stack_3_func2";
  appImage->findFunction(fName, instrumentedFunctions );
  if (instrumentedFunctions.size() != 1) {
    // FIXME Print out a useful error message
    logerror("**Failed** test_stack_3\n");
    logerror("    Unable to find function '%s'\n", fName);
    appProc->terminateExecution();
    return FAILED;
  }
	
  BPatch_Vector<BPatch_point *> * functionEntryPoints = instrumentedFunctions[0]->findPoint( BPatch_entry );
  if (functionEntryPoints->size() != 1) {
    // FIXME Print out a useful error message
    logerror("**Failed** test_stack_3\n");
    logerror("    Unable to find entry point to function '%s'\n", fName);
    appProc->terminateExecution();
    return FAILED;
  }
	
  BPatch_Vector<BPatch_function *> calledFunctions;
  const char *fName2 = "test_stack_3_func3";
  appImage->findFunction(fName2, calledFunctions );
  if (calledFunctions.size() != 1) {
    //FIXME Print out a useful error message
    logerror("**Failed** test_stack_3\n");
    logerror("    Unable to find function '%s'\n", fName2);
    appProc->terminateExecution();
    return FAILED;
  }
	
  BPatch_Vector<BPatch_snippet *> functionArguments;
  BPatch_funcCallExpr functionCall( * calledFunctions[0], functionArguments );
	
  appProc->insertSnippet( functionCall, functionEntryPoints[0] );

  /* Repeat for all three types of instpoints. */
  BPatch_Vector<BPatch_point *> * functionCallPoints = instrumentedFunctions[0]->findPoint( BPatch_subroutine );
  if (functionCallPoints->size() != 1) {
    logerror("**Failed** test_stack_3\n");
    logerror("    Unable to find subroutine call points in '%s'\n", fName);
    appProc->terminateExecution();
    return FAILED;
  }
  appProc->insertSnippet( functionCall, functionCallPoints[0] );
	
  BPatch_Vector<BPatch_point *> * functionExitPoints = instrumentedFunctions[0]->findPoint( BPatch_exit );
  if (functionExitPoints->size() != 1) {
    logerror("**Failed** test_stack_3\n");
    logerror("    Unable to find exit points in '%s'\n", fName);
    appProc->terminateExecution();
    return FAILED;
  }
  appProc->insertSnippet( functionCall, functionExitPoints[0] );

#if defined( DEBUG )
  for( int i = 0; i < 80; i++ ) { ptrace( PTRACE_SINGLESTEP, appThread->getPid(), NULL, NULL ); }
	
  for( int i = 80; i < 120; i++ ) {
    ptrace( PTRACE_SINGLESTEP, appThread->getPid(), NULL, NULL );
		
    BPatch_Vector<BPatch_frame> stack;
    appThread->getCallStack( stack );
		
    dprintf("single-step stack walk, %d instructions after stop for instrumentation.\n", i );
    for( unsigned i = 0; i < stack.size(); i++ ) {
      char name[ 40 ];
      BPatch_function * func = stack[i].findFunction();
		
      if( func == NULL ) { strcpy( name, "[UNKNOWN]" ); }
      else { func->getName( name, 40 ); }
			
      dprintf("  %10p: %s, fp = %p\n", stack[i].getPC(), name, stack[i].getFP() );
    } /* end stack walk dumper */
    dprintf("end of stack walk.\n" );
  } /* end single-step iterator */
#endif /* defined( DEBUG ) */		

  /* After inserting the instrumentation, let it be called. */
  appProc->continueExecution();
	  
  /* Wait for the mutatee to stop because of the instrumentation we just inserted. */
  if (waitUntilStopped( bpatch, appProc, 1, "getCallStack through instrumentation (entry)") < 0) {
      appProc->terminateExecution();
    return FAILED;
  }

  passedTest = true;
  if( !checkStack( appThread, correct_frame_info,
		   sizeof(correct_frame_info)/sizeof(frameInfo_t),
		   3, "getCallStack through instrumentation (entry)" ) ) {
    passedTest = false;
  }

  /* Repeat for other two types of instpoints. */
  appProc->continueExecution();

  /* Wait for the mutatee to stop because of the instrumentation we just inserted. */
  if (waitUntilStopped( bpatch, appProc, 1, "getCallStack through instrumentation (call)") < 0) {
      appProc->terminateExecution();
    return FAILED;
  }

  if( !checkStack( appThread, correct_frame_info,
		   sizeof(correct_frame_info)/sizeof(frameInfo_t),
		   3, "getCallStack through instrumentation (call)" ) ) {
    passedTest = false;
  }
    	
  appProc->continueExecution();

  /* Wait for the mutatee to stop because of the instrumentation we just inserted. */
  if (waitUntilStopped( bpatch, appProc, 1, "getCallStack through instrumentation (exit)") < 0) {
      appProc->terminateExecution();
    return FAILED;
  }

  if( !checkStack( appThread, correct_frame_info,
		   sizeof(correct_frame_info)/sizeof(frameInfo_t),
		   3, "getCallStack through instrumentation (exit)" ) ) {
    passedTest = false;
  }

  if (passedTest)
    logerror("Passed test #3 (unwind through base and mini tramps)\n");

  /* Return the mutatee to its normal state. */
  appProc->continueExecution();

  while (!appProc->isTerminated()) {
    // Workaround for issue with pgCC_high mutatee
    bpatch->waitForStatusChange();
  }

  if (passedTest)
    return PASSED;
  return FAILED;
} /* end mutatorTest3() */
Esempio n. 29
0
void prepareTestCase3(procType proc_type, BPatch_thread *thread, forkWhen when)
{
   static BPatchSnippetHandle *parSnippetHandle3;

   if(proc_type == Parent_p  &&  when == PreFork) {
      BPatch_image *parImage = thread->getImage();

      BPatch_Vector<BPatch_function *> found_funcs;
      const char *inFunction = "func7_3";
      if ((NULL == parImage->findFunction(inFunction, found_funcs, 1)) || !found_funcs.size()) {
	fprintf(stderr, "    Unable to find function %s\n",
		inFunction);
	exit(1);
      }
      
      if (1 < found_funcs.size()) {
	fprintf(stderr, "%s[%d]:  WARNING  : found %d functions named %s.  Using the first.\n", 
		__FILE__, __LINE__, found_funcs.size(), inFunction);
      }
      
      BPatch_Vector<BPatch_point *> *points7_3p = found_funcs[0]->findPoint(BPatch_entry);

      if(doError(3, !points7_3p || ((*points7_3p).size() == 0),
		 "  Unable to find entry point to \"func7_3\".\n")) return;
      BPatch_point *point7_3p = (*points7_3p)[0];

      BPatch_variableExpr *var7_3p = 
	 parImage->findVariable("globalVariable7_3");
      if(doError(3, (var7_3p==NULL),
		 "  Unable to locate variable globalVariable7_3\n")) return;

      BPatch_arithExpr expr7_3p(BPatch_assign, *var7_3p,BPatch_constExpr(642));

      parSnippetHandle3 =
	 thread->insertSnippet(expr7_3p, *point7_3p, BPatch_callBefore);
   } else if(proc_type == Parent_p  &&  when == PostFork) {
      bool result = thread->deleteSnippet(parSnippetHandle3);
      if(result == false) {
	 fprintf(stderr, "  error, couldn't delete snippet\n");
	 passedTest[3] = false;
	 return;
      }
   } else if(proc_type == Child_p  &&  when == PostFork) {
      BPatch_image *childImage = thread->getImage();

      BPatch_Vector<BPatch_function *> found_funcs;
      const char *inFunction = "func7_3";
      if ((NULL == childImage->findFunction(inFunction, found_funcs, 1)) || !found_funcs.size()) {
	fprintf(stderr, "    Unable to find function %s\n",
		inFunction);
	exit(1);
      }
      
      if (1 < found_funcs.size()) {
	fprintf(stderr, "%s[%d]:  WARNING  : found %d functions named %s.  Using the first.\n", 
		__FILE__, __LINE__, found_funcs.size(), inFunction);
      }
      
      BPatch_Vector<BPatch_point *> *points7_3c = found_funcs[0]->findPoint(BPatch_entry);
      
      if(doError(3, !points7_3c || ((*points7_3c).size() == 0),
		 "  Unable to find entry point to \"func7_3\".\n")) return;
      BPatch_point *point7_3c = (*points7_3c)[0];

      BPatch_Vector<BPatchSnippetHandle *> childSnippets =
	 point7_3c->getCurrentSnippets();
      if(doError(3, (childSnippets.size()==0),
		 " No snippets were found at func7_3\n")) return;

      for(unsigned i=0; i<childSnippets.size(); i++) {
	 bool result = thread->deleteSnippet(childSnippets[i]);
	 if(result == false) {
	    fprintf(stderr, "  error, couldn't delete snippet\n");
	    passedTest[3] = false;
	    return;
	 }
      }
   }
}
Esempio n. 30
0
test_results_t test1_19_Mutator::executeTest() 
{
    // Avoid a race condition in fast & loose mode

    while (!appProc->isStopped())
	{
		BPatch::bpatch->waitForStatusChange();
    }

    appProc->continueExecution();

    if (waitUntilStopped(BPatch::bpatch, appProc, 19, "oneTimeCode") < 0)
	{
      return FAILED;
    }

    BPatch_Vector<BPatch_function *> bpfv;
    const char *fn = "test1_19_call1";

    if (NULL == appImage->findFunction(fn, bpfv) || !bpfv.size()
	|| NULL == bpfv[0])
	{
      logerror("    Unable to find function %s\n", fn);
      return FAILED;
    }

    BPatch_function *call19_1_func = bpfv[0];

    BPatch_Vector<BPatch_snippet *> nullArgs;
    BPatch_funcCallExpr call19_1Expr(*call19_1_func, nullArgs);
    checkCost(call19_1Expr);

    appProc->oneTimeCode(call19_1Expr);

    // Let the mutatee run to check the result
    appProc->continueExecution();

    // Wait for the next test

    if (waitUntilStopped(BPatch::bpatch, appProc, 19, "oneTimeCode") < 0)
	{
      return FAILED;
    }

    bpfv.clear();
    const char *fn2 = "test1_19_call2";

    if (NULL == appImage->findFunction(fn2, bpfv) || !bpfv.size()
	|| NULL == bpfv[0])
	{
      logerror("    Unable to find function %s\n", fn2);
      return FAILED;
    }

    BPatch_function *call19_2_func = bpfv[0];

    BPatch_funcCallExpr call19_2Expr(*call19_2_func, nullArgs);
    checkCost(call19_2Expr);

    int callbackFlag = 0;

    // Register a callback that will set the flag callbackFlag
    BPatchOneTimeCodeCallback oldCallback = 
       BPatch::bpatch->registerOneTimeCodeCallback(test19_oneTimeCodeCallback);

    appProc->oneTimeCodeAsync(call19_2Expr, (void *)&callbackFlag);

    while (!appProc->isTerminated() && !appProc->isStopped() )
    {
		BPatch::bpatch->waitForStatusChange();
    }
    
    // Continue mutatee after one-time code runs
    appProc->continueExecution();

    // Wait for the callback to be called
    while (!appProc->isTerminated() && !callbackFlag) {
        if( !BPatch::bpatch->waitForStatusChange() ) {
            logerror("   FAILED: could not wait for callback to be called\n");
            return FAILED;
        }
    }

    if( !callbackFlag ) {
        logerror("     FAILED: process %d terminated while waiting for async oneTimeCode\n",
                appProc->getPid());
        return FAILED;
    }

    // After the oneTimeCode is completed, there could be a crash due to bugs in
    // the RPC code, wait for termination
    while( !appProc->isTerminated() ) {
        if( !BPatch::bpatch->waitForStatusChange() ) {
            logerror("   FAILED: could not wait for process to terminate\n");
            return FAILED;
        }
    }

    // Restore old callback (if there was one)
	BPatch::bpatch->registerOneTimeCodeCallback(oldCallback);

    return PASSED;
} // test1_19_Mutator::executeTest()