public override void Render(ImageSegment segment, Program program, Formatter formatter) { var entries = shdr.sh_size / shdr.sh_entsize; var symtab = (int)shdr.sh_link; var rdr = loader.CreateReader(shdr.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; } uint sym = info >> 8; string symStr = loader.GetSymbolName(symtab, sym); formatter.Write("{0:X8} {1,3} {2:X8} {3}", offset, info & 0xFF, sym, symStr); formatter.WriteLine(); } }
public override void Render(ImageSegment segment, Program program, Formatter formatter) { var entries = shdr.Size / shdr.EntrySize; var symtab = shdr.LinkedSection; var rdr = loader.CreateReader(shdr.FileOffset); for (ulong 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 = loader.GetSymbolName(symtab, sym); formatter.Write("{0:X8} {1,3} {2:X8} {3:X8} {4} ({5})", offset, info & 0xFF, sym, addend, symStr, sym); formatter.WriteLine(); } }
/// <remarks> /// According to the ELF PPC32 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); var rela_plt = loader.GetSectionInfoByName(".rela.plt"); if (rela_plt == null) { return; } var plt = loader.GetSectionInfoByName(".plt"); var relaRdr = loader.CreateReader(rela_plt.FileOffset); var pltRdr = loader.CreateReader(plt.FileOffset); for (int i = 0; i < rela_plt.EntryCount(); ++i) { // Read the .rela.plt entry uint offset; if (!relaRdr.TryReadUInt32(out offset)) { return; } uint info; if (!relaRdr.TryReadUInt32(out info)) { return; } int addend; if (!relaRdr.TryReadInt32(out addend)) { return; } // Read the .plt entry. We don't care about its contents, // only its address. Anyone accessing that address is // trying to access the symbol. uint thunkAddress; if (!pltRdr.TryReadUInt32(out thunkAddress)) { break; } uint sym = info >> 8; string symStr = loader.GetSymbolName(rela_plt.LinkedSection, sym); var addr = plt.Address + (uint)i * 4; program.ImportReferences.Add( addr, new NamedImportReference(addr, null, symStr)); } }