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