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)); } } } }
FrameFuncHelper::alloc_frame_t aarch64_LookupFuncStart::allocatesFrame(Address addr) { LibAddrPair lib; unsigned int mem[FUNCTION_PROLOG_TOCHECK/4]; Address func_addr; unsigned cur; int push_fp_ra_pos = -1, mov_sp_fp_pos = -1; alloc_frame_t res = alloc_frame_t(unknown_t, unknown_s); bool result; SymReader *reader; Offset off; Symbol_t sym; result = checkCache(addr, res); if (result) { sw_printf("[%s:%u] - Cached value for %lx is %d/%d\n", FILE__, __LINE__, addr, (int) res.first, (int) res.second); return res; } result = proc->getLibraryTracker()->getLibraryAtAddr(addr, lib); if (!result) { sw_printf("[%s:%u] - No library at %lx\n", FILE__, __LINE__, addr); goto done; } reader = LibraryWrapper::getLibrary(lib.first); if (!reader) { sw_printf("[%s:%u] - Failed to open symbol reader %s\n", FILE__, __LINE__, lib.first.c_str() ); goto done; } off = addr - lib.second; sym = reader->getContainingSymbol(off); if (!reader->isValidSymbol(sym)) { sw_printf("[%s:%u] - Could not find symbol in binary\n", FILE__, __LINE__); goto done; } func_addr = reader->getSymbolOffset(sym) + lib.second; result = proc->readMem(mem, func_addr, FUNCTION_PROLOG_TOCHECK); if (!result) { sw_printf("[%s:%u] - Error. Couldn't read from memory at %lx\n", FILE__, __LINE__, func_addr); goto done; } //Try to find a 'push (r|e)bp' for (cur=0; cur<FUNCTION_PROLOG_TOCHECK/4; cur++) { if ( (mem[cur]&push_fp_ra_mask) == push_fp_ra ) { push_fp_ra_pos = cur*4; break; } } //Try to find the mov esp->ebp for (cur = cur+1; cur<FUNCTION_PROLOG_TOCHECK/4; cur++) { if(mem[cur] == mov_sp_fp){ mov_sp_fp_pos = cur*4; break; } } if ((push_fp_ra_pos != -1) && (mov_sp_fp_pos != -1)) res.first = standard_frame; else if ((push_fp_ra_pos != -1) && (mov_sp_fp_pos == -1)) res.first = savefp_only_frame; else res.first = no_frame; // if the addr is earlier than the frame building instructions // mark it as unset_frame. // on ARMv8, if the target process is not broken by BP, // the frame type should always be set_frame, since the current // PC should pointed to the function body, but never to the prologe. if ((push_fp_ra_pos != -1) && (addr <= func_addr + push_fp_ra_pos)) res.second = unset_frame; else if ((mov_sp_fp_pos != -1) && (addr <= func_addr + mov_sp_fp_pos)) res.second = halfset_frame; else res.second = set_frame; done: sw_printf("[%s:%u] - Function containing %lx has frame type %d/%d\n", FILE__, __LINE__, addr, (int) res.first, (int) res.second); updateCache(addr, res); return res; }