示例#1
0
        public override void LoadSectionHeaders()
        {
            // Create the sections.
            var inames = new List <uint>();
            var links  = new List <uint>();
            var infos  = new List <uint>();
            var rdr    = imgLoader.CreateReader(Header.e_shoff);

            for (uint i = 0; i < Header.e_shnum; ++i)
            {
                var shdr = Elf32_SHdr.Load(rdr);
                if (shdr == null)
                {
                    break;
                }
                var section = new ElfSection
                {
                    Number     = i,
                    Type       = shdr.sh_type,
                    Flags      = shdr.sh_flags,
                    Address    = Address.Ptr32(shdr.sh_addr),
                    FileOffset = shdr.sh_offset,
                    Size       = shdr.sh_size,
                    Alignment  = shdr.sh_addralign,
                    EntrySize  = shdr.sh_entsize,
                };
                Sections.Add(section);
                inames.Add(shdr.sh_name);
                links.Add(shdr.sh_link);
                infos.Add(shdr.sh_info);
            }

            // Get section names and crosslink sections.

            for (int i = 0; i < Sections.Count; ++i)
            {
                var section = Sections[i];
                section.Name = ReadSectionName(inames[i]);

                ElfSection linkSection = null;
                ElfSection relSection  = null;
                switch (section.Type)
                {
                case SectionHeaderType.SHT_REL:
                case SectionHeaderType.SHT_RELA:
                    linkSection = GetSectionByIndex(links[i]);
                    relSection  = GetSectionByIndex(infos[i]);
                    break;

                case SectionHeaderType.SHT_DYNAMIC:
                case SectionHeaderType.SHT_HASH:
                case SectionHeaderType.SHT_SYMTAB:
                case SectionHeaderType.SHT_DYNSYM:
                    linkSection = GetSectionByIndex(links[i]);
                    break;
                }
                section.LinkedSection    = linkSection;
                section.RelocatedSection = relSection;
            }
        }
示例#2
0
 public SymtabSegmentRenderer(ElfImageLoader loader, Elf32_SHdr shdr)
 {
     this.loader = loader;
     this.shdr = shdr;
 }
示例#3
0
 public RelaSegmentRenderer(ElfImageLoader loader, Elf32_SHdr shdr)
 {
     this.loader = loader;
     this.shdr   = shdr;
 }
示例#4
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);
            }
        }
示例#5
0
 private ImageMapSegmentRenderer CreateRenderer(Elf32_SHdr shdr)
 {
     switch (shdr.sh_type)
     {
     case SectionHeaderType.SHT_DYNAMIC:
         return new DynamicSectionRenderer(this, shdr);
     case SectionHeaderType.SHT_RELA:
         return new RelaSegmentRenderer(this, shdr);
     default: return null;
     }
 }
示例#6
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);
 }
示例#7
0
        // Add appropriate symbols to the symbol table.  secIndex is the section index of the symbol table.
        private void AddSyms(Elf32_SHdr pSect)
        {
            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");
            uint addrPlt = siPlt!=null ? siPlt.sh_addr : 0;
            var siRelPlt = GetSectionInfoByName32(".rel.plt");
            uint sizeRelPlt = 8; // Size of each entry in the .rel.plt table
            if (siRelPlt == null)
            {
                siRelPlt = GetSectionInfoByName32(".rela.plt");
                sizeRelPlt = 12; // Size of each entry in the .rela.plt table is 12 bytes
            }
            uint 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)) //= (ADDRESS)elfRead4((int)m_pSym[i].st_value);
                    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);
            }
#if NYI
            ADDRESS uMain = GetMainEntryPoint();
            if (uMain != NO_ADDRESS && m_SymTab.find(uMain) == m_SymTab.end())
            {
                // Ugh - main mustn't have the STT_FUNC attribute. Add it
                string sMain = "main";
                m_SymTab[uMain] = sMain;
            }
            return;
#endif
        }
示例#8
0
 public DynamicSectionRenderer(ElfImageLoader loader, Elf32_SHdr shdr)
 {
     this.loader = loader;
     this.shdr   = shdr;
 }
 public DynamicSectionRenderer(ElfImageLoader loader, Elf32_SHdr shdr)
 {
     this.loader = loader;
     this.shdr = shdr;
 }
示例#10
0
 public SymtabSegmentRenderer32(ElfLoader32 loader, Elf32_SHdr shdr)
 {
     this.loader = loader;
     this.shdr   = shdr;
 }
示例#11
0
 public RelSegmentRenderer(ElfLoader32 loader, Elf32_SHdr shdr)
 {
     this.loader = loader;
     this.shdr   = shdr;
 }