From c56556b91633b94bd48077cae2e24d6af5c4af51 Mon Sep 17 00:00:00 2001 From: Jason Hiser <jdhiser@gmail.com> Date: Sat, 8 Sep 2018 22:00:27 +0000 Subject: [PATCH] fixed naming issues with plt entries, fixed sizing to match ida's way of doing it as I think it makes more sense. also improved handling of .got.plt Former-commit-id: a35232e5854746b814afd83f0a46111d4ba3b95e --- tools/rida/rida.cpp | 79 ++++++++++++++++++++++++++++++++------------- 1 file changed, 57 insertions(+), 22 deletions(-) diff --git a/tools/rida/rida.cpp b/tools/rida/rida.cpp index 289288a20..05f89af00 100644 --- a/tools/rida/rida.cpp +++ b/tools/rida/rida.cpp @@ -79,7 +79,7 @@ class CreateFunctions_t ehframeToSccs(); addSectionToSccs(".init"); addSectionToSccs(".fini"); - pltSplit<Elf64_Sym>(".plt", ".plt.got"); + pltSplit<Elf64_Sym, Elf64_Rela, Elf64_Rel>(".plt", ".plt.got"); // if exeio->elf class == 64-bit nameFunctions<Elf64_Sym>(); // else @@ -208,11 +208,16 @@ class CreateFunctions_t sccs.insert(ranges); } - template<class T_Sym> + template<class T_Sym, class T_Rela, class T_Rel> void pltSplit(const string &pltSecName, const string &endSecName) { const auto dynsymSec=exeio.sections[".dynsym"]; const auto dynstrSec=exeio.sections[".dynstr"]; + const auto relapltSec=exeio.sections[".rela.plt"]; + const auto relpltSec=exeio.sections[".rel.plt"]; + const auto relSec=relapltSec ? relapltSec : relpltSec; + const auto relSecEntrySize=relapltSec ? sizeof(T_Rela) : sizeof(T_Rel); + const auto addRange=[&](const Address_t s, size_t len) { @@ -221,15 +226,25 @@ class CreateFunctions_t sccs.insert(RangeSet_t({Range_t({s,s+len})})); }; - const auto addName=[&](const Address_t addr, uint64_t dynsymIndex) + const auto addName=[&](const Address_t addr, uint64_t symIndex) { - if(!dynsymSec) return; if(!dynstrSec) return; - + if(!relSec) return; + + // get the data out of the plt section. + const auto relData=relSec->get_data(); + if(symIndex*relSecEntrySize >= (size_t)relSec->get_size()) return; + const auto relDataAsSymPtr=reinterpret_cast<const T_Rel *>(relData + symIndex*relSecEntrySize); + const auto &relEntry=*relDataAsSymPtr; + + // calculate index into dynsym, section. + const auto dynsymIndex=ELF64_R_SYM(relEntry.r_info); const auto dynsymData=dynsymSec->get_data(); const auto dynstrData=dynstrSec->get_data(); + cout<<dec<<"At entry "<<symIndex<<", reloc entry has dynsym index "<<dynsymIndex<<endl; + // the index into the .dynsym section for the relocation. const auto dynsymDataAsSymPtr=reinterpret_cast<const T_Sym *>(dynsymData); if(dynsymIndex*sizeof(T_Sym) >= (size_t)dynsymSec->get_size()) return; @@ -243,19 +258,25 @@ class CreateFunctions_t if(name_offset < 0U || name_offset > (size_t)dynstrSec->get_size()) return; - // get the name - const auto name=string(dynstrData+name_offset)+"@plt"; - - // find a function - auto func_it=find_if(ALLOF(sccs), [&](const RangeSet_t& s) - { - return s.begin() -> first == addr; - }); - if(func_it!=sccs.end()) - { - cout<<"Setting function at "<<hex<<addr<<" to name "<<name<<endl; - funcNames[*func_it]=name; - } + const auto applyName=[&](const string& part, const Address_t myAddr) + { + // get the name + const auto name=string(dynstrData+name_offset)+part+"@plt"; + + // find a function + auto func_it=find_if(ALLOF(sccs), [&](const RangeSet_t& s) + { + return s.begin() -> first == myAddr; + }); + if(func_it!=sccs.end()) + { + cout<<"Setting function at "<<hex<<myAddr<<" to name "<<name<<endl; + funcNames[*func_it]=name; + } + }; + + applyName("part1", addr); + applyName("part2", addr+6); }; const auto pltSec=exeio.sections[pltSecName]; @@ -276,18 +297,32 @@ class CreateFunctions_t const auto plt_skip=16; const auto plt_header_size=12; const auto plt_entry_size=16; + const auto plt_entry_size_first_part=6; addRange(startAddr,plt_header_size); - auto dynsymEntryIndex=1; + auto dynsymEntryIndex=0; for(auto i=startAddr+plt_skip; i<endAddr; i+=plt_skip) { - addRange(i,plt_entry_size); + addRange(i,plt_entry_size_first_part); + addRange(i+6,plt_entry_size-plt_entry_size_first_part); addName(i,dynsymEntryIndex++); } + + // deal with gotPlt Section. const auto gotPltSec=exeio.sections[endSecName]; - if(gotPltSec!=NULL) - addRange(gotPltSec->get_address(),gotPltSec->get_size()); + if(gotPltSec==NULL) + return; + + // 64-bit, at least, entries are 6 bytes, with 2 bytes of padding. + const auto gotPltEntrySize=8; + const auto gotPltRangeSize=6; + const auto gotPltStartAddr=gotPltSec->get_address(); + + for(auto i=0U; i + gotPltRangeSize < (size_t)gotPltSec->get_size(); i+=gotPltEntrySize) + { + addRange(gotPltStartAddr+i,gotPltRangeSize); + } } -- GitLab