Beispiel #1
0
Process::cb_ret_t Backend::handleTimeEvent() {
  // Get all subscribed events
  set<Event*>& events = Time::getTimeSubscribers();

  set<Event*>::iterator eventIter = events.begin();
  for(;eventIter != events.end(); eventIter++) {
    Event* event = *eventIter;
    ProcessSet::ptr procset = ((Time *)event)->getProcset();
    ProcessSet::iterator procIter = procset->begin();
    if(procset->size() == 0)
      continue;
    if(!event || !event->isEnabled(*procIter))
      continue; // this is to avoid a race condition where a time event occurs in the middle of iterating through the processes
    DYSECTVERBOSE(true, "Time event with timeout %d detected on %d processes", ((Time *)event)->getTimeout(), procset->size());
    for(;procIter != procset->end(); procIter++) {
      Process::ptr procPtr = *procIter;
      if(event && event->isEnabled(procPtr)) {
        Thread::ptr threadPtr = procPtr->threads().getInitialThread();
        Walker *proc = (Walker *)procPtr->getData();
        handleEvent(procPtr, threadPtr, event);
      }
    }
    if(event->getOwner()->getLifeSpan() == fireOnce)
      event->disable();
  }

  return Process::cbDefault;
}
Beispiel #2
0
MachSyscall makeFromID(Process::ptr proc, MachSyscall::SyscallIDIndependent id)
{
    Architecture arch = proc->getArchitecture();
    OSType os = proc->getOS();
    Platform plat(arch,os);
    return MachSyscall::makeFromPlatform(plat, id);
}
Beispiel #3
0
bool PCLibraryState::getAOut(LibAddrPair &ao)
{
   Process::ptr proc = pdebug->getProc();
   CHECK_PROC_LIVE;

   Library::ptr lib = proc->libraries().getExecutable();
   if (!lib) {
      sw_printf("[%s:%u] - Could not get executable\n", FILE__, __LINE__);
      return false;
   }
   ao = LibAddrPair(lib->getName(), lib->getLoadAddress());
   return true;
}
Beispiel #4
0
bool PCLibraryState::updateLibraries()
{
   Process::ptr proc = pdebug->getProc();
   CHECK_PROC_LIVE;

   LibraryPool::iterator i;
   for (i = proc->libraries().begin(); i != proc->libraries().end(); i++)
   {
      checkForNewLib(*i);
   }

   return true;
}
Beispiel #5
0
bool StackCallback::beginStackWalk(Thread::ptr thr)
{
   assert(!cur);
   Process::ptr proc = thr->getProcess();
   ProcessState *pstate = ProcessState::getProcessStateByPid(proc->getPid());
   if (!pstate) {
      sw_printf("[%s:%u] - Error, unknown process state for %d while starting stackwalk\n",
                FILE__, __LINE__, proc->getPid());
      return false;
   }

   cur_walker = pstate->getWalker();
   cur = tree.getHead();

   return true;
}
Beispiel #6
0
bool PCLibraryState::findInCache(Process::ptr proc, Address addr, LibAddrPair &lib) {
   cache_t tmp;

   if (!loadedLibs.find(addr, tmp)) {
      return false;
   }

   Library::ptr lib_ptr = tmp.second;
   if (proc->libraries().find(lib_ptr) != proc->libraries().end()) {
      lib = tmp.first;
      return true;
   }
   removeLibFromCache(tmp);

   return false;
}
Beispiel #7
0
bool Location::disable(ProcessSet::ptr lprocset) {
  assert(owner != 0);
 
  if(codeLocations.empty()) {
    return Err::verbose(true, "No code locations");

  }

  if(!lprocset) {
    return Err::warn(false, "Process set not present");
  }

  ProcessSet::iterator procIter = lprocset->begin();
  for(;procIter != lprocset->end(); procIter++) {
    Process::ptr procPtr = *procIter;

    Walker* proc = (Walker*)procPtr->getData();

    vector<DysectAPI::CodeLocation*>::iterator locationIter = codeLocations.begin();
    for(;locationIter != codeLocations.end(); locationIter++) {
      DysectAPI::CodeLocation* location = *locationIter;

      if(!location->addProcLib(proc)) {
        return Err::warn(false, "Symbol not found in process");
      }

      vector<Dyninst::Address> addrs;
      
      if(!location->getAddrs(proc, addrs) || addrs.empty()) {
        return Err::warn(false, "Addresses for symbol could not be determined");
      }

      // Breakpoint locations at hand
      for(int i = 0; i < addrs.size() ; i++) {
        Dyninst::Address addr = addrs[i];
        
        if(!procPtr->rmBreakpoint(addr, bp)) {
          Err::verbose(false, "Breakpoint not removed! %s", ProcControlAPI::getLastErrorMsg());
        }
      }
    }
  }

  return true;
}
Beispiel #8
0
ProcessSet::ptr ProcessMgr::filterExited(ProcessSet::ptr inSet) { 
  if(!inSet)
    return inSet;

  if(inSet->empty())
    return inSet;

  ProcessSet::ptr procs = ProcessSet::newProcessSet();
  // Filter out exited processes
  ProcessSet::iterator procIter = inSet->begin();
  for(; procIter != inSet->end(); procIter++) {
    Process::ptr process = *procIter;

    if(process->isTerminated() || process->isExited() || process->isCrashed() || process->isDetached()) {
      continue;
    }

    procs->insert(process);
  }
  
  return procs;
}
Beispiel #9
0
bool PCLibraryState::getLibraries(std::vector<LibAddrPair> &libs, bool allow_refresh)
{
   Process::ptr proc = pdebug->getProc();
   CHECK_PROC_LIVE;

   LibraryPool::iterator i;
   for (i = proc->libraries().begin(); i != proc->libraries().end(); i++)
   {
      if (allow_refresh)
         checkForNewLib(*i);
      libs.push_back(LibAddrPair((*i)->getName(), (*i)->getLoadAddress()));
   }

   vector<pair<LibAddrPair, unsigned int> > arch_libs;
   vector<pair<LibAddrPair, unsigned int> >::iterator j;
   updateLibsArch(arch_libs);
   for (j = arch_libs.begin(); j != arch_libs.end(); j++) {
      libs.push_back(j->first);
   }

   return true;
}
Beispiel #10
0
bool Location::enable(ProcessSet::ptr lprocset) {
  assert(owner != 0);
 
  if(codeLocations.empty()) {
    return Err::verbose(true, "No code locations");

  }

  if(!lprocset) {
    return Err::warn(false, "Process set not present");
  }
  
  ProcessSet::iterator procIter = lprocset->begin();

  AddressSet::ptr addrset = AddressSet::newAddressSet();

  if(lprocset->size() <= 0) {
    return Err::info(true, "Process set empty!");
  }

  // Find library location for target processes
  for(;procIter != lprocset->end(); procIter++) {
    Process::ptr procPtr = *procIter;

    Walker* proc = (Walker*)procPtr->getData();

    vector<DysectAPI::CodeLocation*>::iterator locationIter = codeLocations.begin();
    for(;locationIter != codeLocations.end(); locationIter++) {
      DysectAPI::CodeLocation* location = *locationIter;

      if(!location->addProcLib(proc)) {
        return Err::warn(false, "Symbol not found in process");
      }

      vector<Dyninst::Address> addrs;
      
      if(!location->getAddrs(proc, addrs) || addrs.empty()) {
        return Err::warn(false, "Addresses for symbol could not be determined");
      }

      // Breakpoint locations at hand
      for(int i = 0; i < addrs.size() ; i++) {
        Dyninst::Address addr = addrs[i];
        
        if(!procPtr->addBreakpoint(addr, bp)) {
          return Err::verbose(false, "Breakpoint not installed: %s", ProcControlAPI::getLastErrorMsg());
        } else {
          Err::verbose(true, "Breakpoint installed at %lx", addr);
        }

        //addrset->insert(addr, procPtr);
      }

      //if(addrs.empty()) {
      //  Err::verbose(true, "No addresses");
      //}
    }

  }
  
  //if(addrset->size() <= 0) {
  //  return Err::verbose(true, "Empty address set");
  //}

  
  //if(!lprocset->addBreakpoint(addrset, nbp)) {
  //  return Err::warn(false, "Could not insert breakpoints!");
  //} else {
  //  Err::info(true, "%d breakpoints inserted in %d processes", addrset->size(), lprocset->size());
  //}

  return true;
}
Beispiel #11
0
ProcDebug::ProcDebug(Process::ptr p) :
   ProcessState(p->getPid()),
   proc(p)
{
}
Beispiel #12
0
bool PCLibraryState::memoryScan(Process::ptr proc, Address addr, LibAddrPair &lib) {

   LibraryPool::iterator i;
   Library::ptr nearest_predecessor = Library::ptr();
   signed int pred_distance = 0;
   Library::ptr nearest_successor = Library::ptr();
   signed int succ_distance = 0;


   /**
    * Search the entire library list for the dynamic sections that come
    * directly before and after our target address (nearest_predecessor
    * and nearest_successor).
    *
    * They dynamic linker (and who-knows-what on future systems) can have a
    * dynamic address of zero.  Remember any library with a zero dynamic
    * address with zero_dynamic_libs, and manually check those if the
    * nearest_successor and nearest_predecessor.
    **/
   std::vector<Library::ptr> zero_dynamic_libs;
   for (i = proc->libraries().begin(); i != proc->libraries().end(); i++)
   {
      Library::ptr slib = *i;
      checkForNewLib(slib);

      Address dyn_addr = slib->getDynamicAddress();
      if (!dyn_addr) {
         zero_dynamic_libs.push_back(slib);
         continue;
      }

      signed int distance = addr - dyn_addr;
      if (distance == 0) {
         lib.first = slib->getName();
         lib.second = slib->getLoadAddress();
         sw_printf("[%s:%u] - Found library %s contains address %lx\n",
                   FILE__, __LINE__, lib.first.c_str(), addr);
         return true;
      }
      else if (distance < 0) {
         if (!pred_distance || pred_distance < distance) {
            nearest_predecessor = slib;
            pred_distance = distance;
         }
      }
      else if (distance > 0) {
         if (!succ_distance || succ_distance > distance) {
            nearest_successor = slib;
            succ_distance = distance;
         }
      }
   }

   /**
    * Likely a static binary, set nearest_predecessor so that
    * the following check will test it.
    **/
   if (!nearest_predecessor && !nearest_successor) {
      nearest_predecessor = proc->libraries().getExecutable();
   }

   /**
    * Check if predessor contains our address first--this should be the typical case
    **/
   if (nearest_predecessor && checkLibraryContains(addr, nearest_predecessor)) {
      lib.first = nearest_predecessor->getName();
      lib.second = nearest_predecessor->getLoadAddress();
      sw_printf("[%s:%u] - Found library %s contains address %lx\n",
                FILE__, __LINE__, lib.first.c_str(), addr);
      return true;
   }
   /**
    * Check successor
    **/
   if (nearest_successor && checkLibraryContains(addr, nearest_successor)) {
      lib.first = nearest_successor->getName();
      lib.second = nearest_successor->getLoadAddress();
      sw_printf("[%s:%u] - Found library %s contains address %lx\n",
                FILE__, __LINE__, lib.first.c_str(), addr);
      return true;
   }

   /**
    * The address wasn't located by the dynamic section tests.  Check
    * any libraries without dynamic pointers, plus the executable.
    **/
   std::vector<Library::ptr>::iterator k = zero_dynamic_libs.begin();
   for (; k != zero_dynamic_libs.end(); k++) {
      if (checkLibraryContains(addr, *k)) {
         lib.first = (*k)->getName();
         lib.second = (*k)->getLoadAddress();
         return true;
      }
   }
   if(checkLibraryContains(addr, proc->libraries().getExecutable()))
   {

     lib.first = proc->libraries().getExecutable()->getName();
     lib.second = proc->libraries().getExecutable()->getLoadAddress();
     sw_printf("[%s:%u] - Found executable %s contains address %lx\n", FILE__,
	       __LINE__, lib.first.c_str(), addr);
     return true;
   }

   sw_printf("[%s:%u] - Could not find library for addr %lx\n",
             FILE__, __LINE__, addr);
   return false;
}
Beispiel #13
0
DysectErrorCode Backend::irpc(Process::ptr process, string libraryPath, string funcName, void *arg, int argLength) {
  int funcAddrOffset = -1, argOffset = -1;
  bool result, found = false;
  unsigned char *begin, *end, *c, *buffer;
  unsigned long size, *valuePtr, *ptr, value;
  string libraryName;
  Symtab *symtab = NULL;
  Address loadAddress;
  Offset funcOffset;
  vector<SymtabAPI::Function *> functions;

  if (symtabs.find(libraryPath) == symtabs.end()) {
    result = Symtab::openFile(symtab, libraryPath.c_str());
    if (result == false) {
      DYSECTWARN(false, "Failed to find file %s for symtab", libraryPath.c_str());
      return Error;
    }
  }
  else {
    symtab = symtabs[libraryPath];
  }

  libraryName = basename(libraryPath.c_str());
  LibraryPool &libs = process->libraries();
  LibraryPool::iterator libsIter;
  for (libsIter = libs.begin(); libsIter != libs.end(); libsIter++)
  {
      Library::ptr libraryPtr = *libsIter;
      if (libraryPtr->getName().find(libraryName) == string::npos)
          continue;

      loadAddress = (*libsIter)->getLoadAddress();
      found = true;
      DYSECTLOG(true, "found library %s at 0x%lx", libraryName.c_str(), loadAddress);
      break;
  }
  if (found == false) {
    DYSECTWARN(false, "Failed to find library %s", libraryName.c_str());
    return Error;
  }

  begin = call_snippet_begin;
  end = call_snippet_end;
  size = (unsigned long)*end - (unsigned long)*begin;
  for (c = begin; c != end; c++) {
    valuePtr = (unsigned long *)c;
    if (*valuePtr == 0x1122334455667788) {
      funcAddrOffset =  (long)(c - begin);
    }
    if (*valuePtr == 0xaabbccddeeffaabb) {
      argOffset =  (long)(c - begin);
    }
  }

  result = symtab->findFunctionsByName(functions, funcName);
  if (result == false || functions.size() < 1) {
    DYSECTWARN(false, "Failed to find %s function", funcName.c_str());
    return Error;
  }
  funcOffset = functions[0]->getOffset();
  DYSECTLOG(true, "found %s at offset 0x%lx", funcName.c_str(), funcOffset);

  buffer = (unsigned char *)malloc(size);
  if (!buffer) {
    DYSECTWARN(false, "Failed to allocate %d bytes for target %d", size);
    return Error;
  }
  memcpy(buffer, begin, size);
  c = buffer + funcAddrOffset;
  value = loadAddress + funcOffset;
  memcpy(c, &value, sizeof(unsigned long));
  c = buffer + argOffset;
  memcpy(c, arg, argLength);

  IRPC::ptr irpc;
  irpc = IRPC::createIRPC((void *)buffer, size, false);
  if (!irpc) {
    DYSECTWARN(false, "Failed to create IRPC in target");
    return Error;
  }
  result = process->postIRPC(irpc);
  if (!result) {
    DYSECTWARN(false, "Failed to post IRPC in target");
    return Error;
  }

  DYSECTLOG(true, "irpc successful for target");
  return OK;
}
Beispiel #14
0
bool Probe::processRequests() {
  if(requestQueue.empty()) {
    return true;
  }

  pthread_mutex_lock(&requestQueueMutex); 
  vector<ProbeRequest*> queue = requestQueue;
  requestQueue.clear();
  pthread_mutex_unlock(&requestQueueMutex); 

  ProcessSet::ptr continueSet = ProcessSet::newProcessSet();
 
  // Sort queue

  deque<ProbeRequest*> sortedQueue;
  vector<ProbeRequest*>::iterator requestIter = queue.begin();
  for(int i = 0; requestIter != queue.end(); requestIter++) {
    ProbeRequest* request = *requestIter;

    if(!request) {
      DYSECTWARN(true, "Invalid request in request queue");
      break;
    }

    if(request->type == DisableType) {
      sortedQueue.push_back(request);
    } else {
      sortedQueue.push_front(request);
    }
  }

  if (sortedQueue.size() == 0)
    return true;

  DYSECTVERBOSE(true, "Handling %d process requests", sortedQueue.size());

  deque<ProbeRequest*>::iterator sortedRequestIter = sortedQueue.begin();
  for(int i = 0; sortedRequestIter != sortedQueue.end(); sortedRequestIter++) {
    ProbeRequest* request = *sortedRequestIter;

    if(!request) {
      DYSECTWARN(true, "Invalid request in request queue");
      break;
    }

    DYSECTVERBOSE(true, "processRequests() %d", i++);

    Probe* probe = request->probe;
    if(!probe) {
      DYSECTWARN(false, "Probe not found for disable request!");
      break;
    }

    ProcessSet::ptr waitingProcs = request->scope;
    if(waitingProcs && waitingProcs->size() > 0) {
      DYSECTVERBOSE(true, "Adding %d request processes to %d continue set...", waitingProcs->size(), continueSet->size());
      continueSet = continueSet->set_union(waitingProcs);
    }

    ProcessSet::ptr operationSet = ProcessSet::newProcessSet();
    ProcessSet::ptr stopSet = ProcessSet::newProcessSet();

    ProcessSet::ptr scope = request->scope;
    if(scope && scope->size() > 0) {
      DYSECTVERBOSE(true, "Adding processes from scope set (%d) to affected procs (%d)", scope->size(), operationSet->size());
      operationSet = operationSet->set_union(scope);
    }

    //
    // Filter out detached
    //
    operationSet = ProcessMgr::filterDetached(operationSet);
    stopSet = ProcessMgr::filterDetached(stopSet);
    DYSECTVERBOSE(true, "%d procs in op set, %d procs in stop set", operationSet->size(), stopSet->size());

    //
    // Stop processes
    //
  
    stopSet = operationSet->getAnyThreadRunningSubset();
    if(stopSet && stopSet->size() > 0) {
      DYSECTVERBOSE(true, "Stopping %d processes", stopSet->size());
      
      stopSet->stopProcs();
    }

    //
    // Carry out operations
    //

    if(operationSet && operationSet->size() > 0) {
      if(request->type == DisableType) {
        DYSECTVERBOSE(true, "Disabling %d processes", operationSet->size());
        probe->disable(operationSet);
      } else {
        DYSECTVERBOSE(true, "Enabling %d processes", operationSet->size());
        probe->enableChildren(operationSet);
      }
    }
    
    //
    // Processes must be started when all operations have been carried out.
    //
    if(operationSet && operationSet->size() > 0) {
      continueSet = continueSet->set_union(operationSet);
    }

    delete(request);
  }

  continueSet = ProcessMgr::filterDetached(continueSet);

  if(continueSet && continueSet->size() > 0) {
    DYSECTVERBOSE(true, "Continuing %d processes", continueSet->size());
    if(continueSet->size() == 1) {
      ProcessSet::iterator procIter = continueSet->begin();
      Process::ptr process = *procIter;
      DYSECTVERBOSE(true, "Continuing process %d", process->getPid());
    }
    
    continueSet->continueProcs();
  }

  DYSECTVERBOSE(true, "Done handling requests");

  return true;
}
Beispiel #15
0
test_results_t pc_libraryMutator::executeTest()
{
	//std::cerr << "ExecuteTest" << std::endl;
   proclibs.clear();
   got_breakpoint = false;
   myerror = false;

   Process::registerEventCallback(EventType::Breakpoint, on_breakpoint);
   Process::registerEventCallback(EventType::Library, on_library);

   std::vector<Process::ptr>::iterator i;

   for (i = comp->procs.begin(); i != comp->procs.end(); i++) {
      std::string libc_fullname;
      Library::ptr libc_lib;

      Process::ptr proc = *i;
      Process::const_ptr cproc = proc;
      proc_info_lib &pi = proclibs[cproc];
      
      for (LibraryPool::iterator j = proc->libraries().begin();
           j != proc->libraries().end(); j++)
      {
         Library::ptr lib = *j;
#if !defined(os_windows_test)
		 if (lib->getName().find("libc") != std::string::npos) {
            pi.found_libc = true;
            libc_fullname = lib->getName();
            libc_lib = lib;
         }
#else
		 if (lib->getName().find("msvcrt") != std::string::npos) {
			 pi.found_libc = true;
			 libc_fullname = lib->getName();
			 libc_lib = lib;
		 }
#endif
		 if (lib->getName().find("pc_library_mutatee") != std::string::npos ||
           lib->getName().find("pc_library.") != std::string::npos) {
            pi.found_exec = true;
         }
      }
	  if(!libc_fullname.empty()) {
		  Library::ptr libc_lib2 = proc->libraries().getLibraryByName(libc_fullname);
		  if (libc_lib != libc_lib2) {
			  logerror("Failed to find libc in getLibraryByName\n");
			  myerror = true;
		  }
	  }


      bool result = proc->continueProc();
      if (!result) {
         logerror("Failed to continue process\n");
         myerror = true;
      }
   }

   syncloc loc[NUM_PARALLEL_PROCS];
   bool result = comp->recv_broadcast((unsigned char *) loc, sizeof(syncloc));
   if (!result) {
      logerror("Failed to recieve sync broadcast\n");
      myerror = true;
   }
   for (unsigned j=0; j<comp->procs.size(); j++) {
      if (loc[j].code != SYNCLOC_CODE) {
         logerror("Recieved unexpected message code\n");
         myerror = true;
      }
   }

   result = comp->send_broadcast((unsigned char *) loc, sizeof(syncloc));
   if (!result) {
      logerror("Failed to send sync broadcast\n");
      myerror = true;
   }

   if (got_breakpoint) {
      logerror("Recieved breakpoint, shouldn't have\n");
      myerror = true;
   }
   if (comp->procs.size() != proclibs.size()) {
      logerror("Didn't get library events from enough processes\n");
      myerror = true;
   }
   for (std::map<Process::const_ptr, proc_info_lib>::iterator j = proclibs.begin();
        j != proclibs.end(); j++)
   {
      const proc_info_lib &pi = j->second;
      if (pi.loaded_libtesta == -1) {
         logerror("Didn't load libtestA\n");
         myerror = true;
      }
      if (pi.loaded_libtestb == -1) {
         logerror("Didn't load libtestB\n");
         myerror = true;
      }
      if (pi.unloaded_libtesta == -1) {
         logerror("Didn't unload libtestA\n");
         myerror = true;
      }
      if (pi.unloaded_libtestb == -1) {
         logerror("Didn't unload libtestB\n");
         myerror = true;
      }
      if (pi.loaded_libtesta != 0 ||
          pi.loaded_libtestb != 1 ||
          pi.unloaded_libtestb != 2 ||
          pi.unloaded_libtesta != 3)
      {
         logerror("Unexpected library load order\n");
         myerror = true;
      }
	  if(!isAttach)
	  {
#if !defined(os_windows_test)
		  if (!pi.found_exec) {
			 logerror("Failed to find executable\n");
			 myerror = true;
		  }
#endif
		  if (!pi.found_libc) {
			 logerror("Failed to find libc\n");
			 myerror = true;
		  }
	  }
   }
   
   Process::removeEventCallback(on_library);
   Process::removeEventCallback(on_breakpoint);

   return myerror ? FAILED : PASSED;
}