bool DysectAPI::CodeLocation::addProcLib(Walker* proc) { if(procLibraries.find(proc) != procLibraries.end()) { return true; } LibraryState *libState = proc->getProcessState()->getLibraryTracker(); if(!libState) { return Err::warn(false, "Library state could not be retrieved"); } vector<LibAddrPair> libs; if(!libState->getLibraries(libs)) { return Err::warn(false, "Cannot get libraries from library state"); } vector<LibAddrPair>::iterator libIter; bool found = false; for(libIter = libs.begin(); libIter != libs.end(); libIter++) { string curLibName = libIter->first; if(curLibName == libName) { Dyninst::Address addr = libIter->second; procLibraries.insert(pair<Walker*, Dyninst::Address>(proc, addr)); found = true; } } return found; }
bool Frame::getLibOffset(std::string &lib, Dyninst::Offset &offset, void*& symtab) const { LibraryState *libstate = getWalker()->getProcessState()->getLibraryTracker(); if (!libstate) { sw_printf("[%s:%u] - getLibraryAtAddr, had no library tracker\n", FILE__, __LINE__); setLastError(err_unsupported, "No valid library tracker registered"); return false; } LibAddrPair la; bool result = libstate->getLibraryAtAddr(getRA(), la); if (!result) { sw_printf("[%s:%u] - getLibraryAtAddr returned false for %x\n", FILE__, __LINE__, getRA()); return false; } lib = la.first; offset = getRA() - la.second; #if defined(WITH_SYMTAB_API) symtab = static_cast<void *>(SymtabWrapper::getSymtab(lib)); #else symtab = NULL; #endif return true; }
DysectAPI::DysectErrorCode SymbolTable::getLibraries(vector<LibAddrPair>& libs, Walker* proc) { assert(proc); assert(proc->getProcessState()); LibraryState *libState = proc->getProcessState()->getLibraryTracker(); if(!libState) { return Err::warn(Error, "Library state could not be retrieved"); } if(!libState->getLibraries(libs)) { return Err::warn(Error, "Cannot get libraries from library state"); } return OK; }
DysectAPI::DysectErrorCode SymbolTable::getLibraryByAddr(Dyninst::Stackwalker::LibAddrPair& lib, Dyninst::Address addr, Dyninst::Stackwalker::Walker* proc) { assert(proc); assert(proc->getProcessState()); LibraryState *libState; bool ret; libState = proc->getProcessState()->getLibraryTracker(); if(!libState) { return Err::warn(Error, "Could not load library tracker"); } if(!libState->getLibraryAtAddr(addr, lib)) { return Err::warn(Error, "Failed to get library at address 0x%lx", addr); } return OK; }
DysectAPI::DysectErrorCode SymbolTable::getLibraries(vector<LibAddrPair>& libs, Walker* proc) { assert(proc); assert(proc->getProcessState()); LibraryState *libState = proc->getProcessState()->getLibraryTracker(); if(!libState) { DYSECTWARN(Error, "Couldn't get libstate. Trying to set default librrary tracket\n"); proc->getProcessState()->setDefaultLibraryTracker(); libState = proc->getProcessState()->getLibraryTracker(); assert(libState); } if(!libState) { return DYSECTWARN(Error, "Library state could not be retrieved"); } if(!libState->getLibraries(libs, true)) { return DYSECTWARN(Error, "Cannot get libraries from library state"); } return OK; }
void SigHandlerStepperImpl::registerStepperGroup(StepperGroup *group) { sw_printf("[%s:%u] - Begin SigHandlerStepperImpl::registerStepperGroup\n", FILE__, __LINE__); ProcessState *ps = getProcessState(); assert(ps); LibraryState *libs = getProcessState()->getLibraryTracker(); if (!libs) { sw_printf("[%s:%u] - Custom library tracker. Don't know how to" " to get libc\n", FILE__, __LINE__); return; } SymbolReaderFactory *fact = Walker::getSymbolReader(); if (!fact) { sw_printf("[%s:%u] - Failed to get symbol reader\n", FILE__, __LINE__); return; } sw_printf("[%s:%u] - Got lib tracker and sym reader OK, checking for __restore_rt...\n", FILE__, __LINE__); if (!init_libc) { /** * Get __restore_rt out of libc **/ sw_printf("[%s:%u] - Getting __restore_rt from libc\n", FILE__, __LINE__); LibAddrPair libc_addr; Dyninst::SymReader *libc = NULL; Symbol_t libc_restore; bool result = libs->getLibc(libc_addr); if (!result) { sw_printf("[%s:%u] - Unable to find libc, not registering restore_rt" "tracker.\n", FILE__, __LINE__); } if (!init_libc) { if (result) { init_libc = true; libc = fact->openSymbolReader(libc_addr.first); if (!libc) { sw_printf("[%s:%u] - Unable to open libc, not registering restore_rt\n", FILE__, __LINE__); } } if (result && libc) { init_libc = true; libc_restore = libc->getSymbolByName("__restore_rt"); if (!libc->isValidSymbol(libc_restore)) { sw_printf("[%s:%u] - Unable to find restore_rt in libc\n", FILE__, __LINE__); } else { Dyninst::Address start = libc->getSymbolOffset(libc_restore) + libc_addr.second; Dyninst::Address end = libc->getSymbolSize(libc_restore) + start; if (start == end) end = start + 16; //Estimate--annoying sw_printf("[%s:%u] - Registering libc restore_rt as at %lx to %lx\n", FILE__, __LINE__, start, end); group->addStepper(parent_stepper, start, end); } } } } if (!init_libthread) { /** * Get __restore_rt out of libpthread **/ sw_printf("[%s:%u] - Getting __restore_rt out of libpthread\n", FILE__, __LINE__); LibAddrPair libpthread_addr; Dyninst::SymReader *libpthread = NULL; Symbol_t libpthread_restore; bool result = libs->getLibthread(libpthread_addr); if (!result) { sw_printf("[%s:%u] - Unable to find libpthread, not registering restore_rt" "pthread tracker.\n", FILE__, __LINE__); } if (result) { libpthread = fact->openSymbolReader(libpthread_addr.first); if (!libpthread) { sw_printf("[%s:%u] - Unable to open libc, not registering restore_rt\n", FILE__, __LINE__); } init_libthread = true; } if (libpthread) { libpthread_restore = libpthread->getSymbolByName("__restore_rt"); if (!libpthread->isValidSymbol(libpthread_restore)) { sw_printf("[%s:%u] - Unable to find restore_rt in libpthread\n", FILE__, __LINE__); } else { Dyninst::Address start = libpthread->getSymbolOffset(libpthread_restore) + libpthread_addr.second; Dyninst::Address end = libpthread->getSymbolSize(libpthread_restore) + start; if (start == end) end = start + 16; //Estimate--annoying sw_printf("[%s:%u] - Registering libpthread restore_rt as at %lx to %lx\n", FILE__, __LINE__, start, end); group->addStepper(parent_stepper, start, end); } } } /** * Get symbols out of vsyscall page **/ sw_printf("[%s:%u] - Getting vsyscall page symbols\n", FILE__, __LINE__); vsys_info *vsyscall = getVsysInfo(ps); if (!vsyscall) { #if !defined(arch_x86_64) sw_printf("[%s:%u] - Odd. Couldn't find vsyscall page. Signal handler" " stepping may not work\n", FILE__, __LINE__); #endif } else { SymReader *vsys_syms = vsyscall->syms; if (!vsys_syms) { sw_printf("[%s:%u] - Vsyscall page wasn't parsed\n", FILE__, __LINE__); } else { for (unsigned i=0; i<NUM_VSYS_SIGRETURNS; i++) { Symbol_t sym; sym = vsys_syms->getSymbolByName(vsys_sigreturns[i]); if (!vsys_syms->isValidSymbol(sym)) continue; Dyninst::Offset offset = vsys_syms->getSymbolOffset(sym); Dyninst::Address addr; if (offset < vsyscall->start) addr = offset + vsyscall->start; else addr = offset; unsigned long size = vsys_syms->getSymbolSize(sym); if (!size) size = ps->getAddressWidth(); group->addStepper(parent_stepper, addr, addr + size); } } } }
void BottomOfStackStepperImpl::initialize() { ProcessState *proc = walker->getProcessState(); assert(proc); sw_printf("[%s:%u] - Initializing BottomOfStackStepper\n", FILE__, __LINE__); LibraryState *libs = proc->getLibraryTracker(); if (!libs) { sw_printf("[%s:%u] - Error initing StackBottom. No library state for process.\n", FILE__, __LINE__); return; } SymbolReaderFactory *fact = Walker::getSymbolReader(); if (!fact) { sw_printf("[%s:%u] - Failed to get symbol reader\n"); return; } if (!aout_init) { LibAddrPair aout_addr; SymReader *aout = NULL; Symbol_t start_sym; bool result = libs->getAOut(aout_addr); if (result) { aout = fact->openSymbolReader(aout_addr.first); aout_init = true; } if (aout) { start_sym = aout->getSymbolByName(START_FUNC_NAME); if (aout->isValidSymbol(start_sym)) { Dyninst::Address start = aout->getSymbolOffset(start_sym)+aout_addr.second; Dyninst::Address end = aout->getSymbolSize(start_sym) + start; if (start == end) { sw_printf("[%s:%u] - %s symbol has 0 length, using length of %lu\n", FILE__, __LINE__, START_FUNC_NAME, START_HEURISTIC_LENGTH); end = start + START_HEURISTIC_LENGTH; } sw_printf("[%s:%u] - Bottom stepper taking %lx to %lx for start\n", FILE__, __LINE__, start, end); ra_stack_tops.push_back(std::pair<Address, Address>(start, end)); } } } if (!libthread_init) { LibAddrPair libthread_addr; SymReader *libthread = NULL; Symbol_t clone_sym, startthread_sym; bool result = libs->getLibthread(libthread_addr); if (result) { libthread = fact->openSymbolReader(libthread_addr.first); libthread_init = true; } if (libthread) { clone_sym = libthread->getSymbolByName(CLONE_FUNC_NAME); if (libthread->isValidSymbol(clone_sym)) { Dyninst::Address start = libthread->getSymbolOffset(clone_sym) + libthread_addr.second; Dyninst::Address end = libthread->getSymbolSize(clone_sym) + start; sw_printf("[%s:%u] - Bottom stepper taking %lx to %lx for clone\n", FILE__, __LINE__, start, end); ra_stack_tops.push_back(std::pair<Address, Address>(start, end)); } startthread_sym = libthread->getSymbolByName(START_THREAD_FUNC_NAME); if (libthread->isValidSymbol(startthread_sym)) { Dyninst::Address start = libthread->getSymbolOffset(startthread_sym) + libthread_addr.second; Dyninst::Address end = libthread->getSymbolSize(startthread_sym) + start; sw_printf("[%s:%u] - Bottom stepper taking %lx to %lx for start_thread\n", FILE__, __LINE__, start, end); ra_stack_tops.push_back(std::pair<Address, Address>(start, end)); } } } }
static void registerLibSpotterSelf(ProcSelf *pself) { if (lib_trap_addr_self) return; if (lib_trap_addr_self_err) return; //Get the address to install a trap to LibraryState *libs = pself->getLibraryTracker(); if (!libs) { sw_printf("[%s:%u] - Not using lib tracker, don't know how " "to get library load address\n", FILE__, __LINE__); lib_trap_addr_self_err = true; return; } lib_trap_addr_self = libs->getLibTrapAddress(); if (!lib_trap_addr_self) { sw_printf("[%s:%u] - Error getting trap address, can't install lib tracker", FILE__, __LINE__); lib_trap_addr_self_err = true; return; } //Use /proc/PID/maps to make sure that this address is valid and writable unsigned maps_size; map_entries *maps = getVMMaps(getpid(), maps_size); if (!maps) { sw_printf("[%s:%u] - Error reading proc/%d/maps. Can't install lib tracker", FILE__, __LINE__, getpid()); lib_trap_addr_self_err = true; return; } bool found = false; for (unsigned i=0; i<maps_size; i++) { if (maps[i].start <= lib_trap_addr_self && maps[i].end > lib_trap_addr_self) { found = true; if (maps[i].prems & PREMS_WRITE) { break; } int pgsize = getpagesize(); Address first_page = (lib_trap_addr_self / pgsize) * pgsize; unsigned size = pgsize; if (first_page + size < lib_trap_addr_self+MAX_TRAP_LEN) size += pgsize; int result = mprotect((void*) first_page, size, PROT_READ|PROT_WRITE|PROT_EXEC); if (result == -1) { int errnum = errno; sw_printf("[%s:%u] - Error setting premissions for page containing %lx. " "Can't install lib tracker: %s\n", FILE__, __LINE__, lib_trap_addr_self, strerror(errnum)); free(maps); lib_trap_addr_self_err = true; return; } } } free(maps); if (!found) { sw_printf("[%s:%u] - Couldn't find page containing %lx. Can't install lib " "tracker.", FILE__, __LINE__, lib_trap_addr_self); lib_trap_addr_self_err = true; return; } char trap_buffer[MAX_TRAP_LEN]; unsigned actual_len; getTrapInstruction(trap_buffer, MAX_TRAP_LEN, actual_len, true); local_lib_state = libs; signal(SIGTRAP, lib_trap_handler); memcpy((void*) lib_trap_addr_self, trap_buffer, actual_len); sw_printf("[%s:%u] - Successfully install lib tracker at 0x%lx\n", FILE__, __LINE__, lib_trap_addr_self); }