public DynamicSectionRenderer(ElfImageLoader loader, Elf32_SHdr shdr) { this.loader = loader; this.shdr = shdr; }
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); } }
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; } }
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); }
// 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; }