diff --git a/SConscript b/SConscript index 718e08038424c9fab7cc1c603d92e28bbe3091f8..529021a66d0ab99b16cd62e95542127071555b96 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 827ce8221aa5c74dc7c4a53d2c3d93147b20afcb..bbdb80a84fba36a4cd815c08589e13b6c2994b41 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 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/SConscript b/src/SConscript index 231f1e62cd11a32a96c38446eac353a2d94f061a..76e6b7eaa932659f60ebdc88b1737c7d72013c4d 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 161b22b4412aabc97a5b426322c2920cf3e122ce..cea2def260f65e223d8cbbbc3cca21c7877b1dc7 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 832384d68af152e093a5fddeee214a6b6cd357f7..4864b3b08f1e9ee87dc9eada16118a9596f8fa13 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 c23a3cb79e395f9a840e9f6af328c5865df1bde2..58333e8f5faa7ba17e687497736caa6935df9fa0 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; }