Example #1
0
//------------------------------------------------------------------------
// process all imports of a pe file
// returns: -1:could not read an impdir; 0-ok;
// other values can be returned by the visitor
inline int pe_loader_t::process_imports(linput_t *li, pe_import_visitor_t &piv)
{
    if ( pe.impdir.rva == 0 )
        return 0;

    if ( transvec.empty() )
        process_sections(li);

    int code = 0;
    bool is_memory_linput = get_linput_type(li) == LINPUT_PROCMEM;
    for ( int ni=0; ; ni++ )
    {
        off_t off = pe.impdir.rva + ni*sizeof(peimpdir_t);
        peimpdir_t &id = piv.id;

        if ( !vmread(li, off, &id, sizeof(id)) )
        {
            int code = piv.impdesc_error(off);
            if ( code != 0 )
                break;
            // we continue if the import descriptor is within the page belonging
            // to the program
            if ( !is_memory_linput )
            {
                uint32 fsize = pe.align_up_in_file(qlsize(li));
                if ( map_ea(off)+sizeof(id) > fsize )
                    return -1;
            }
        }
        if ( id.dllname == 0 && id.table1 == 0 )
            break;
        ea_t ltable = id.table1;  //OriginalFirstThunk
        ea_t atable = id.looktab; //FirstThunk
        bool ok = true;
        char dll[MAXSTR];
        asciiz(li, id.dllname, dll, sizeof(dll), &ok);
        if ( !ok || dll[0] == '\0' )
            break;
        ansi2idb(dll);
        if ( !is_memory_linput && (map_ea(ltable) == BADADDR || ltable < pe.hdrsize) )
            ltable = atable;
        atable += get_imagebase();
        int code = piv.visit_module(dll, atable, ltable);
        if ( code != 0 )
            break;
        code = process_import_table(li, pe, atable, ltable, piv);
        if ( code != 0 )
            break;
    }
    return code;
}
Example #2
0
//--------------------------------------------------------------------------
static void read_dyninfo(ulong offset, ulong size)
{
  qlseek(li, offset);
  const int entsize = elf64 ? sizeof(Elf64_Dyn) : sizeof(Elf32_Dyn);
  for(int i = 1; i < size; i += entsize )
  {
    Elf64_Dyn dyn;
    if ( elf64 )
    {
      if(lread8bytes(li, &dyn.d_tag, mf) ||
         lread8bytes(li, &dyn.d_un, mf))  errstruct();
    }
    else
    {
      ulong tag, val;
      if(lread4bytes(li, &tag, mf) ||
         lread4bytes(li, &val, mf))  errstruct();
      dyn.d_tag = tag;
      dyn.d_un = val;
    }
    switch ( WC4(dyn.d_tag) )
    {
      case DT_STRTAB:
        dynstr_off = map_ea(dyn.d_un);
        break;
      case DT_SYMTAB:
        dynsym_off = map_ea(dyn.d_un);
        break;
      case DT_REL:
        dynrel_off = map_ea(dyn.d_un);
        break;
      case DT_RELA:
        dynrela_off = map_ea(dyn.d_un);
        break;
      case DT_STRSZ:
        dynstr_size = ulong(dyn.d_un);
        break;
      case DT_RELSZ:
        dynrel_size = ulong(dyn.d_un);
        break;
      case DT_RELASZ:
        dynrela_size = ulong(dyn.d_un);
        break;
    }
  }
  ulong off = dynstr_off;
  if ( dynrel_off  ) off = qmin(dynrel_off, off);
  if ( dynrela_off ) off = qmin(dynrela_off, off);
  dynsym_size = off - dynsym_off;
}
Example #3
0
//------------------------------------------------------------------------
inline bool pe_loader_t::vseek(linput_t *li, uint32 rva)
{
    ea_t fpos = get_linput_type(li) == LINPUT_PROCMEM ? rva : map_ea(rva);
    if ( fpos != BADADDR )
    {
        qlseek(li, int32(fpos));
        return true;
    }
    qlseek(li, rva, SEEK_SET);
    return false;
}
Example #4
0
//--------------------------------------------------------------------------
static int parse_dyninfo(const dyninfo_t &dyninfo)
{
  for ( int i=0; i < dyninfo.size(); i++ )
  {
    const Elf64_Dyn &dyn = dyninfo[i];
    switch ( dyn.d_tag )
    {
      case DT_STRTAB:
        dynstr_off = map_ea(dyn.d_un);
        break;
      case DT_SYMTAB:
        dynsym_off = map_ea(dyn.d_un);
        break;
      case DT_REL:
        dynrel_off = map_ea(dyn.d_un);
        break;
      case DT_RELA:
        dynrela_off = map_ea(dyn.d_un);
        break;
      case DT_STRSZ:
        dynstr_size = uint32(dyn.d_un);
        break;
      case DT_RELSZ:
        dynrel_size = uint32(dyn.d_un);
        break;
      case DT_RELASZ:
        dynrela_size = uint32(dyn.d_un);
        break;
    }
  }
  size_t off = dynstr_off;
  if ( dynrel_off  ) off = qmin(dynrel_off, off);
  if ( dynrela_off ) off = qmin(dynrela_off, off);
  dynsym_size = off - dynsym_off;
  return 0;
}
Example #5
0
//------------------------------------------------------------------------
// this function tries to read from a file as if it was reading from memory
// if translation not found for the given RVA then ZEROs are returned
// in addition, if it tries to read beyond a translation physical size
// the additional bytes will be returned as zeros
inline bool pe_loader_t::vmread(linput_t *li, uint32 rva, void *buf, size_t sz)
{
    // clear whole user buffer
    memset(buf, 0, sz);

    size_t may_read = sz;
    if ( get_linput_type(li) == LINPUT_PROCMEM )
    {
        qlseek(li, rva, SEEK_SET);
    }
    else
    {
        transl_t *t;
        ea_t fpos = map_ea(rva, &t);

        // cannot find translation?
        if ( fpos == BADADDR )
        {
            qlseek(li, int32(rva), SEEK_SET);
            return true;
        }
        qlseek(li, int32(fpos));

        // reading beyond section's limit?
        uint32 after_read_pos = uint32(fpos+sz);
        if ( after_read_pos >= (t->pos+t->psize) )
        {
            // check if position belongs to the header and if reading beyond the limit
            if ( uint32(fpos) < pe.allhdrsize && after_read_pos > pe.allhdrsize )
                may_read = pe.allhdrsize - size_t(fpos);
            else
                may_read = t->pos+t->psize - fpos; // just read as much as section limit allows
        }
    }
    return qlread(li, buf, may_read) == (ssize_t)may_read;
}