From 0cae407e21cf99617054cf4fee3df6d4e4e81b19 Mon Sep 17 00:00:00 2001 From: Jason Hiser <jdhiser@gmail.com> Date: Fri, 27 Jul 2018 17:43:14 +0000 Subject: [PATCH] first working first, complete with test --- SConscript | 13 ++++++++++ include/ehp.hpp | 6 +++-- lib/.gitignore | 0 src/SConscript | 3 ++- src/ehp.cpp | 63 ++++++++++++++++++++++++++++++++++++++++++------ src/ehp_priv.hpp | 9 ++++--- test/test.cpp | 26 ++++++++++++++++++++ 7 files changed, 105 insertions(+), 15 deletions(-) create mode 100644 lib/.gitignore diff --git a/SConscript b/SConscript index 718e080..529021a 100644 --- a/SConscript +++ b/SConscript @@ -3,6 +3,19 @@ import os Import('env') +env.Replace(debug=ARGUMENTS.get("debug",0)) +if int(env['debug']) == 1: + print "Setting debug mode" + env.Append(CFLAGS=" -g ") + env.Append(CXXFLAGS=" -g ") + env.Append(LINKFLAGS=" -g ") +else: + print "Setting release mode" + env.Append(CFLAGS=" -O3 ") + env.Append(CXXFLAGS=" -O3 ") + env.Append(LINKFLAGS=" -O3 ") + + lib=SConscript("src/SConscript") Return('lib') diff --git a/include/ehp.hpp b/include/ehp.hpp index 827ce82..bbdb80a 100644 --- a/include/ehp.hpp +++ b/include/ehp.hpp @@ -92,6 +92,8 @@ class LSDACallSite_t public: virtual ~LSDACallSite_t() {} virtual shared_ptr<LSDCallSiteActionVector_t> getActionTable() const =0; + virtual uint64_t getCallSiteAddress() const =0; + virtual uint64_t getCallSiteEndAddress() const =0; virtual uint64_t getLandingPadAddress() const =0; virtual void print() const=0; }; @@ -140,8 +142,8 @@ class EHFrameParser_t virtual const shared_ptr<FDEVector_t> getFDEs() const =0; virtual const shared_ptr<CIEVector_t> getCIEs() const =0; - static unique_ptr<EHFrameParser_t> factory(const char* const filename); - static unique_ptr<EHFrameParser_t> factory( + static unique_ptr<const EHFrameParser_t> factory(const string filename); + static unique_ptr<const EHFrameParser_t> factory( uint8_t ptrsize, const string eh_frame_data, const uint64_t eh_frame_data_start_addr, const string eh_frame_hdr_data, const uint64_t eh_frame_hdr_data_start_addr, diff --git a/lib/.gitignore b/lib/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/src/SConscript b/src/SConscript index 231f1e6..76e6b7e 100644 --- a/src/SConscript +++ b/src/SConscript @@ -9,6 +9,7 @@ files="ehp.cpp" cpppath=''' ../include + ../third-party/elfio-code ''' @@ -16,7 +17,7 @@ LIBPATH="$SECURITY_TRANSFORMS_HOME/lib" LIBS=Split("") myenv=myenv.Clone(CPPPATH=Split(cpppath)) -myenv.Append(CXXFLAGS = " -std=c++11 -Wall -Werror -fmax-errors=1") +myenv.Append(CXXFLAGS = " -std=c++11 -Wall -Werror -fmax-errors=2") lib=myenv.Library("ehp", Split(files), LIBPATH=LIBPATH, LIBS=LIBS) install=myenv.Install("../lib/", lib) diff --git a/src/ehp.cpp b/src/ehp.cpp index 161b22b..cea2def 100644 --- a/src/ehp.cpp +++ b/src/ehp.cpp @@ -6,16 +6,19 @@ #include <string.h> #include <map> #include <assert.h> -#include <elf.h> #include <algorithm> #include <memory> -#include "ehp.hpp" +#include <ehp.hpp> #include "ehp_priv.hpp" #include "scoop_replacement.hpp" +#include <elfio/elfio.hpp> +#include <elf.h> + using namespace std; using namespace EHP; +using namespace ELFIO; #define ALLOF(s) begin(s), end(s) @@ -1613,6 +1616,17 @@ void split_eh_frame_impl_t<ptrsize>::print() const }); } + +template <int ptrsize> +shared_ptr<CallSiteVector_t> lsda_t<ptrsize>::getCallSites() const +{ + auto ret=shared_ptr<CallSiteVector_t>(new CallSiteVector_t()); + transform(ALLOF(call_site_table), back_inserter(*ret), + [](const lsda_call_site_t<ptrsize> &a) { return shared_ptr<LSDACallSite_t>(new lsda_call_site_t<ptrsize>(a));}); + return shared_ptr<CallSiteVector_t>(ret); +} + + template <int ptrsize> const shared_ptr<FDEVector_t> split_eh_frame_impl_t<ptrsize>::getFDEs() const { @@ -1633,12 +1647,41 @@ const shared_ptr<CIEVector_t> split_eh_frame_impl_t<ptrsize>::getCIEs() const -unique_ptr<EHFrameParser_t> EHFrameParser_t::factory(const char* const filename) +unique_ptr<const EHFrameParser_t> EHFrameParser_t::factory(const string filename) { - assert(0); + auto elfiop=unique_ptr<elfio>(new elfio); + if(!elfiop->load(filename)) + { + throw invalid_argument(string() + "Cannot open file: " + filename); + } + + auto get_info=[&](const string name) -> pair<string,uint64_t> + { + const auto &sec=elfiop->sections[name.c_str()]; + auto contents=string(sec->get_data(), sec->get_size()); + auto addr=sec->get_address(); + return {contents,addr}; + + }; + + const auto eh_frame_section=get_info(".eh_frame"); + const auto eh_frame_hdr_section=get_info(".eh_frame_hdr"); + const auto gcc_except_table_section=get_info(".gcc_except_table"); + + const auto ptrsize = elfiop->get_class()==ELFCLASS64 ? 8 : + elfiop->get_class()==ELFCLASS32 ? 4 : + 0; + if(ptrsize==0) + throw invalid_argument(string() + "Invalid ELF class in : " + filename); + + return EHFrameParser_t::factory(ptrsize, + eh_frame_section.first, eh_frame_section.second, + eh_frame_hdr_section.first, eh_frame_hdr_section.second, + gcc_except_table_section.first, gcc_except_table_section.second); + } -unique_ptr<EHFrameParser_t> EHFrameParser_t::factory( +unique_ptr<const EHFrameParser_t> EHFrameParser_t::factory( uint8_t ptrsize, const string eh_frame_data, const uint64_t eh_frame_data_start_addr, const string eh_frame_hdr_data, const uint64_t eh_frame_hdr_data_start_addr, @@ -1648,13 +1691,17 @@ unique_ptr<EHFrameParser_t> EHFrameParser_t::factory( const auto eh_frame_sr=ScoopReplacement_t(eh_frame_data,eh_frame_data_start_addr); const auto eh_frame_hdr_sr=ScoopReplacement_t(eh_frame_hdr_data,eh_frame_hdr_data_start_addr); const auto gcc_except_table_sr=ScoopReplacement_t(gcc_except_table_data,gcc_except_table_data_start_addr); + auto ret_val=(EHFrameParser_t*)nullptr; if(ptrsize==4) - return unique_ptr<EHFrameParser_t>(new split_eh_frame_impl_t<4>(eh_frame_sr,eh_frame_hdr_sr,gcc_except_table_sr)); + ret_val=new split_eh_frame_impl_t<4>(eh_frame_sr,eh_frame_hdr_sr,gcc_except_table_sr); else if(ptrsize==8) - return unique_ptr<EHFrameParser_t>(new split_eh_frame_impl_t<8>(eh_frame_sr,eh_frame_hdr_sr,gcc_except_table_sr)); + ret_val=new split_eh_frame_impl_t<8>(eh_frame_sr,eh_frame_hdr_sr,gcc_except_table_sr); else throw std::out_of_range("ptrsize must be 4 or 8"); - + + ret_val->parse(); + + return unique_ptr<const EHFrameParser_t>(ret_val); } diff --git a/src/ehp_priv.hpp b/src/ehp_priv.hpp index 832384d..4864b3b 100644 --- a/src/ehp_priv.hpp +++ b/src/ehp_priv.hpp @@ -9,7 +9,6 @@ #include <string.h> #include <map> #include <assert.h> -#include <elf.h> #include <algorithm> #include <memory> #include <set> @@ -243,6 +242,8 @@ class lsda_call_site_t : public LSDACallSite_t, private eh_frame_util_t<ptrsize> const std::vector<lsda_call_site_action_t <ptrsize> >& getActionTableInternal() const { return action_table; } std::vector<lsda_call_site_action_t <ptrsize> >& getActionTableInternal() { return action_table; } + uint64_t getCallSiteAddress() const { return call_site_addr ; } + uint64_t getCallSiteEndAddress() const { return call_site_end_addr ; } uint64_t getLandingPadAddress() const { return landing_pad_addr ; } bool parse_lcs( @@ -267,7 +268,7 @@ class lsda_call_site_t : public LSDACallSite_t, private eh_frame_util_t<ptrsize> template <int ptrsize> using call_site_table_t = std::vector<lsda_call_site_t <ptrsize> > ; template <int ptrsize> -class lsda_t : private LSDA_t, private eh_frame_util_t<ptrsize> +class lsda_t : public LSDA_t, private eh_frame_util_t<ptrsize> { private: uint8_t landing_pad_base_encoding; @@ -296,7 +297,7 @@ class lsda_t : private LSDA_t, private eh_frame_util_t<ptrsize> ); void print() const; - shared_ptr<CallSiteVector_t> getCallSites() const { assert(0); } + shared_ptr<CallSiteVector_t> getCallSites() const ; const call_site_table_t<ptrsize> getCallSitesInternal() const { return call_site_table;} }; @@ -342,7 +343,7 @@ class fde_contents_t : public FDEContents_t, eh_frame_util_t<ptrsize> const eh_program_t<ptrsize>& getProgram() const ; eh_program_t<ptrsize>& getProgram() ; - shared_ptr<LSDA_t> getLSDA() const { assert(0); } + shared_ptr<LSDA_t> getLSDA() const { return shared_ptr<LSDA_t>(new lsda_t<ptrsize>(lsda)) ; } const lsda_t<ptrsize>& getLSDAInternal() const { return lsda; } bool parse_fde( diff --git a/test/test.cpp b/test/test.cpp index c23a3cb..58333e8 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -2,6 +2,7 @@ #include <ehp.hpp> #include <iostream> +#include <assert.h> using namespace std; using namespace EHP; @@ -13,6 +14,28 @@ void usage(int argc, char* argv[]) } + +void print_lps(const EHFrameParser_t* ehp) +{ + const auto fdes=ehp->getFDEs(); + cout<<hex; + for(const auto fde : *fdes) + { + cout<<"Found FDE at : " << fde->getStartAddress() << "-"<<fde->getEndAddress()<<endl; + const auto lsda=fde->getLSDA(); + assert(lsda); + const auto callsites=lsda->getCallSites(); + assert(callsites); + + for(const auto cs : *callsites) + { + cout<<"\tCall site (0x"<<cs->getCallSiteAddress()<<"-"<<cs->getCallSiteEndAddress() + <<") with landing pad=0x"<<cs->getLandingPadAddress()<<endl; + } + } + cout<<dec; +} + int main(int argc, char* argv[]) { @@ -24,5 +47,8 @@ int main(int argc, char* argv[]) auto ehp = EHFrameParser_t::factory(argv[1]); ehp->print(); + + print_lps(ehp.get()); + return 0; } -- GitLab