Ejemplo n.º 1
0
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));
         }
      }
   }
}
Ejemplo n.º 2
0
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;
}