private void LoadImportReferencesFromRelPlt(Dictionary <Address, ImportReference> importReferences) { var rel_plt = loader.GetSectionInfoByName(".rel.plt"); var symtab = rel_plt.LinkedSection; var plt = loader.GetSectionInfoByName(".plt"); var relRdr = loader.CreateReader(rel_plt.FileOffset); uint entries = rel_plt.EntryCount(); for (uint i = 0; i < entries; ++i) { uint offset; if (!relRdr.TryReadUInt32(out offset)) { return; } uint info; if (!relRdr.TryReadUInt32(out info)) { return; } uint sym = info >> 8; string symStr = loader.GetSymbolName(symtab, sym); var addr = plt.Address + (i + 1) * plt.EntrySize; importReferences[addr] = new NamedImportReference( addr, null, symStr); } }
/// <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)); } }
public override void Relocate(Program program) { base.Relocate(program); var dynsect = loader.GetSectionInfoByName(".dynamic"); var dynentries = loader.GetDynEntries(dynsect.FileOffset).ToDictionary(k => k.d_tag); var symtab = dynentries[DynamicSectionRenderer.DT_SYMTAB]; var pltgot = dynentries[DynamicSectionRenderer.DT_PLTGOT].d_val; var mips_local_gotno = dynentries[DynamicSectionRenderer.Mips.DT_MIPS_LOCAL_GOTNO].d_val; var mips_gotsym = dynentries[DynamicSectionRenderer.Mips.DT_MIPS_GOTSYM].d_val; var dyngot = pltgot + (mips_local_gotno - mips_gotsym) * 4; //loader.CreateReader() for (int i = mips_gotsym; i < loader.Symbols.Count; ++i) { } }