public DynamicSectionRenderer(ElfImageLoader loader, Elf32_SHdr shdr)
 {
     this.loader = loader;
     this.shdr = shdr;
 }
Exemple #2
0
        private void DumpRela(Elf32_SHdr sh)
        {
            var entries = sh.sh_size / sh.sh_entsize;
            var symtab = sh.sh_link;
            var rdr = CreateReader(sh.sh_offset);
            for (int i = 0; i < entries; ++i)
            {
                uint offset;
                if (!rdr.TryReadUInt32(out offset))
                    return;
                uint info;
                if (!rdr.TryReadUInt32(out info))
                    return;
                int addend;
                if (!rdr.TryReadInt32(out addend))
                    return;

                uint sym = info >> 8;
                string symStr = GetStrPtr((int)symtab, sym);
                Debug.Print("  RELA {0:X8} {1,3} {2:X8} {3:X8} {4}", offset, info&0xFF, sym, addend, symStr);
            }
        }
Exemple #3
0
 private ImageMapSegmentRenderer CreateRenderer(Elf32_SHdr shdr)
 {
     switch (shdr.sh_type)
     {
     case SectionHeaderType.SHT_DYNAMIC:
         return new DynamicSectionRenderer(this, shdr);
     case SectionHeaderType.SHT_DYNSYM:
         return new SymtabSegmentRenderer(this, shdr);
     case SectionHeaderType.SHT_REL:
         return new RelSegmentRenderer(this, shdr);
     case SectionHeaderType.SHT_RELA:
         return new RelaSegmentRenderer(this, shdr);
     default: return null;
     }
 }
Exemple #4
0
 public string GetStrPtr(Elf32_SHdr sect, uint offset)
 {
     if (sect == null)
     {
         // Most commonly, this will be an null, because a call to GetSectionByName() failed
         throw new ArgumentException("GetStrPtr passed null section.");
     }
     // Get a pointer to the start of the string table and add the offset
     return ReadAsciiString( RawImage, sect.sh_offset + offset);
 }
Exemple #5
0
        // Add appropriate symbols to the symbol table.  secIndex is the section index of the symbol table.
        public IEnumerable<ElfSymbol> ReadAllSymbols(Elf32_SHdr pSect)
        {
            if (pSect == null)
                yield break;
            int e_type = this.Header32.e_type;
            // Calc number of symbols
            uint nSyms = pSect.sh_size / pSect.sh_entsize;
            uint offSym = pSect.sh_offset;
            //m_pSym = (Elf32_Sym*)pSect.uHostAddr; // Pointer to symbols
            uint strIdx = pSect.sh_link; // sh_link points to the string table

            var siPlt = GetSectionInfoByName32(".plt");
            ADDRESS addrPlt = siPlt!=null ? siPlt.sh_addr : 0;
            var siRelPlt = GetSectionInfoByName32(".rel.plt");
            uint sizeRelPlt = siRelPlt.sh_entsize; // Size of each entry in the .rel.plt table
            if (siRelPlt == null)
            {
                siRelPlt = GetSectionInfoByName32(".rela.plt");
                sizeRelPlt = siRelPlt.sh_entsize; // Size of each entry in the .rela.plt table is 12 bytes
            }
            ADDRESS addrRelPlt = 0;
            uint numRelPlt = 0;
            if (siRelPlt != null)
            {
                addrRelPlt = siRelPlt.sh_addr;
                numRelPlt = sizeRelPlt != 0 ? siRelPlt.sh_size / sizeRelPlt : 0u;
            }
            // Number of entries in the PLT:
            // int max_i_for_hack = siPlt ? (int)siPlt.uSectionSize / 0x10 : 0;
            // Index 0 is a dummy entry
            var symRdr = CreateReader(offSym);
            for (int i = 1; i < nSyms; i++)
            {
                uint name;
                if (!symRdr.TryReadUInt32(out name))
                    break;
                uint val;
                if (!symRdr.TryReadUInt32(out val))
                    break;
                uint size;
                if (!symRdr.TryReadUInt32(out size))
                    break;
                byte info;
                if (!symRdr.TryReadByte(out info))
                    break;
                byte other;
                if (!symRdr.TryReadByte(out other))
                    break;
                ushort shndx;
                if (!symRdr.TryReadLeUInt16(out shndx))
                    break;

                if (name == 0)
                    continue; // Weird: symbol w no name.
                if (shndx >= SectionHeaders.Count)
                {

                }
                else
                {
                    var otherSection = SectionHeaders[shndx];
                }
                string str = GetStrPtr((int)strIdx, name);
                // Hack off the "@@GLIBC_2.0" of Linux, if present
                int pos;
                if ((pos = str.IndexOf("@@")) >= 0)
                    str = str.Remove(pos);
                // Ensure no overwriting (except functions)
#if Nilx
                if (@m_SymTab.ContainsKey(val) || ELF32_ST_TYPE(m_pSym[i].st_info) == STT_FUNC)
                {
                    if (val == 0 && siPlt != null)
                    { //&& i < max_i_for_hack) {
                        throw new NotImplementedException();
                        // Special hack for gcc circa 3.3.3: (e.g. test/pentium/settest).  The value in the dynamic symbol table
                        // is zero!  I was assuming that index i in the dynamic symbol table would always correspond to index i
                        // in the .plt section, but for fedora2_true, this doesn't work. So we have to look in the .rel[a].plt
                        // section. Thanks, gcc!  Note that this hack can cause strange symbol names to appear
                        //val = findRelPltOffset(i, addrRelPlt, sizeRelPlt, numRelPlt, addrPlt);
                    }
                    else if (e_type == ET_REL)
                    {
                        throw new NotImplementedException();
#if NYI
                        int nsec = elfRead2(m_pSym[i].st_shndx);
                        if (nsec >= 0 && nsec < m_iNumSections)
                            val += GetSectionInfo(nsec)->uNativeAddr;
#endif
                    }

                    m_SymTab[val] = str;
                }
#endif
                //Debug.Print("  Symbol {0} ({0:X}) with address {1:X} (segment {2} {2:X}): {3}", i, val, shndx, str);
                yield return new ElfSymbol
                {
                    Name = str,
                    Value = val,
                    Info = info,
                };
            }
        }
 public RelaSegmentRenderer(ElfImageLoader loader, Elf32_SHdr shdr)
 {
     this.loader = loader;
     this.shdr = shdr;
 }