public override void Render(ImageSegment segment, Program program, Formatter formatter) { var entries = shdr.EntryCount(); var symtab = shdr.LinkedSection; var rdr = loader.CreateReader(shdr.FileOffset); for (ulong i = 0; i < entries; ++i) { ulong offset; if (!rdr.TryReadUInt64(out offset)) { return; } ulong info; if (!rdr.TryReadUInt64(out info)) { return; } ulong addend; if (!rdr.TryReadUInt64(out addend)) { return; } ulong sym = info >> 32; string symStr = loader.GetSymbol64(symtab, sym); formatter.Write("{0:X8} {1,3} {2:X8} {3:X16} {4} ({5})", offset, info & 0xFFFFFFFF, sym, addend, symStr, sym); formatter.WriteLine(); } }
/// <remarks> /// According to the ELF x86_64 documentation, the .rela.plt and .plt tables /// should contain the same number of entries, even if the individual entry /// sizes are distinct. The entries in .real.plt refer to symbols while the /// entries in .plt are (writeable) pointers. Any caller that jumps to one /// of pointers in the .plt table is a "trampoline", and should be replaced /// in the decompiled code with just a call to the symbol obtained from the /// .real.plt section. /// </remarks> public override void Relocate(Program program) { base.Relocate(program); this.importReferences = program.ImportReferences; var rela_plt = loader.GetSectionInfoByName(".rela.plt"); var plt = loader.GetSectionInfoByName(".plt"); var relaRdr = loader.CreateReader(rela_plt.FileOffset); for (ulong i = 0; i < rela_plt.EntryCount(); ++i) { // Read the .rela.plt entry ulong offset; if (!relaRdr.TryReadUInt64(out offset)) { return; } ulong info; if (!relaRdr.TryReadUInt64(out info)) { return; } long addend; if (!relaRdr.TryReadInt64(out addend)) { return; } ulong sym = info >> 32; string symStr = loader.GetSymbol64(rela_plt.LinkedSection, sym); var addr = plt.Address + (uint)(i + 1) * plt.EntrySize; importReferences.Add( addr, new NamedImportReference(addr, null, symStr)); } }