From 2c6f952f67820c02df9a7ae43821b5aa45ffbfa3 Mon Sep 17 00:00:00 2001 From: Jason Hiser <jdhiser@gmail.com> Date: Wed, 19 Dec 2018 10:58:54 -0500 Subject: [PATCH] added arch helper base class and x86, arm64 specializations --- include/arch/archARM64.hpp | 15 +++++++++++++++ include/arch/archX86.hpp | 13 +++++++++++++ include/arch/archbase.hpp | 13 +++++++++++++ include/zipr_all.h | 3 +++ include/zipr_impl.h | 3 +++ src/SConscript | 3 ++- src/archbase.cpp | 25 +++++++++++++++++++++++++ src/zipr.cpp | 25 +++++++++++++------------ test/SConscript | 3 +-- 9 files changed, 88 insertions(+), 15 deletions(-) create mode 100644 include/arch/archARM64.hpp create mode 100644 include/arch/archX86.hpp create mode 100644 include/arch/archbase.hpp create mode 100644 src/archbase.cpp diff --git a/include/arch/archARM64.hpp b/include/arch/archARM64.hpp new file mode 100644 index 0000000..33d9139 --- /dev/null +++ b/include/arch/archARM64.hpp @@ -0,0 +1,15 @@ +#ifndef ARCHARM64_HPP +#define ARCHARM64_HPP + +class ZiprArchitectureHelperARM64_t : public ZiprArchitectureHelperBase_t +{ + public: + virtual libIRDB::Instruction_t* createNewJumpInstruction(libIRDB::FileIR_t *p_firp, libIRDB::Instruction_t* p_existing) override + { + return IRDBUtility::addNewDatabits(p_firp, p_existing, "\x06\x00\x00\x00"); + // A Brandh unconditional, in binary is: 0001010 00000000 00000000 00000000 + // it includes a 26-bit immediate, which is +/- 128MB, which should be a good enough "jump anywhere" + // for now. + } +}; +#endif diff --git a/include/arch/archX86.hpp b/include/arch/archX86.hpp new file mode 100644 index 0000000..63385e0 --- /dev/null +++ b/include/arch/archX86.hpp @@ -0,0 +1,13 @@ +#ifndef ARCHX86_HPP +#define ARCHX86_HPP + + +class ZiprArchitectureHelperX86_t : public ZiprArchitectureHelperBase_t +{ + public: + virtual libIRDB::Instruction_t* createNewJumpInstruction(libIRDB::FileIR_t *p_firp, libIRDB::Instruction_t* p_existing) override + { + return IRDBUtility::addNewAssembly(p_firp, p_existing, "jmp 0"); + } +}; +#endif diff --git a/include/arch/archbase.hpp b/include/arch/archbase.hpp new file mode 100644 index 0000000..53a4fb7 --- /dev/null +++ b/include/arch/archbase.hpp @@ -0,0 +1,13 @@ +#ifndef ARCHBASE_HPP +#define ARCHBASE_HPP + + +class ZiprArchitectureHelperBase_t +{ + public: + virtual libIRDB::Instruction_t* createNewJumpInstruction(libIRDB::FileIR_t *p_firp, libIRDB::Instruction_t* p_existing)=0; + static std::unique_ptr<ZiprArchitectureHelperBase_t> factory(libIRDB::FileIR_t* p_firp); + +}; + +#endif diff --git a/include/zipr_all.h b/include/zipr_all.h index a47f996..c4c1b41 100644 --- a/include/zipr_all.h +++ b/include/zipr_all.h @@ -37,6 +37,7 @@ #include <list> #include <map> #include <libIRDB-core.hpp> +#include <Rewrite_Utility.hpp> #include <algorithm> #include "elfio/elfio.hpp" @@ -57,11 +58,13 @@ using namespace Zipr_SDK; #include <plugin_man.h> #include <zipr_dollop_man.h> #include <zipr_utils.h> +#include <arch/archbase.hpp> #include <zipr_impl.h> #include <zipr_optimizations.h> #include <zipr_stats.h> #include <elfwrite.h> #include <ehwrite.h> + }; #endif diff --git a/include/zipr_impl.h b/include/zipr_impl.h index 68c034e..e291d04 100644 --- a/include/zipr_impl.h +++ b/include/zipr_impl.h @@ -32,6 +32,8 @@ #define zipr_impl_h #include <climits> +#include <arch/archbase.hpp> +#include <memory> class Stats_t; @@ -512,6 +514,7 @@ class ZiprImpl_t : public Zipr_t ZiprIntegerOption_t m_variant, m_architecture, m_seed; ZiprStringOption_t m_dollop_map_filename; ZiprIntegerOption_t m_paddable_minimum_distance; + std::unique_ptr<ZiprArchitectureHelperBase_t> archhelper; std::list<DollopEntry_t *> m_des_to_replop; diff --git a/src/SConscript b/src/SConscript index e051344..46878a4 100644 --- a/src/SConscript +++ b/src/SConscript @@ -23,6 +23,7 @@ files= ''' zipr_dollop_man.cpp elfwrite.cpp ehwrite.cpp + archbase.cpp ''' # ELFIO needs to be first so we get the zipr version instead of the sectrans version. the zipr version is modified to include get_offset. @@ -63,7 +64,7 @@ myenv=myenv.Clone(CPPPATH=Split(cpppath), LIBS=Split(libs), LIBPATH=Split(libpat #print 'myenv=' #print myenv.Dump() -myenv.Append(CXXFLAGS=" -Wno-deprecated") +myenv.Append(CXXFLAGS=" -Wno-deprecated -fmax-errors=2") ziprexe=myenv.Program("zipr.exe", Split(files)) install=myenv.Install("$ZIPR_INSTALL/bin/", ziprexe) diff --git a/src/archbase.cpp b/src/archbase.cpp new file mode 100644 index 0000000..7af208b --- /dev/null +++ b/src/archbase.cpp @@ -0,0 +1,25 @@ + + +#include <zipr_all.h> + +namespace zipr +{ +#include <arch/archX86.hpp> +#include <arch/archARM64.hpp> +} +#include <memory> +#include <Rewrite_Utility.hpp> + +using namespace std; +using namespace libIRDB; +using namespace zipr; + +unique_ptr<ZiprArchitectureHelperBase_t> ZiprArchitectureHelperBase_t::factory(FileIR_t* p_firp) +{ + auto ret= p_firp->GetArchitecture()->getMachineType() == admtX86_64 ? (ZiprArchitectureHelperBase_t*)new ZiprArchitectureHelperX86_t () : + p_firp->GetArchitecture()->getMachineType() == admtI386 ? (ZiprArchitectureHelperBase_t*)new ZiprArchitectureHelperX86_t () : + p_firp->GetArchitecture()->getMachineType() == admtAarch64 ? (ZiprArchitectureHelperBase_t*)new ZiprArchitectureHelperARM64_t() : + throw domain_error("Cannot init architecture"); + + return unique_ptr<ZiprArchitectureHelperBase_t>(ret); +} diff --git a/src/zipr.cpp b/src/zipr.cpp index 8e1be9d..a2cce4e 100644 --- a/src/zipr.cpp +++ b/src/zipr.cpp @@ -84,9 +84,9 @@ template < typename T > std::string to_string( const T& n ) void ZiprImpl_t::Init() { + bss_needed=0; use_stratafier_mode=false; - ostream *error = &cout, *warn = NULL; m_zipr_options.AddNamespace(new ZiprOptionsNamespace_t("global")); @@ -126,6 +126,8 @@ void ZiprImpl_t::Init() } plugman = ZiprPluginManager_t(this, &m_zipr_options); + archhelper=ZiprArchitectureHelperBase_t::factory(m_firp); + /* * Parse again now that the plugins registered something. */ @@ -4522,34 +4524,33 @@ void ZiprImpl_t::FixTwoByteWithPrefix() void ZiprImpl_t::FixMultipleFallthroughs() { - int count=0; - map<Instruction_t*, InstructionSet_t> fallthrough_from; - for_each(m_firp->GetInstructions().begin(), m_firp->GetInstructions().end(), - [&fallthrough_from](Instruction_t* insn) + auto count=0; + auto fallthrough_from=map<Instruction_t*, InstructionSet_t>(); + + for(auto & insn : m_firp->GetInstructions()) { - Instruction_t* ft=insn->GetFallthrough(); + auto ft=insn->GetFallthrough(); if(ft) fallthrough_from[ft].insert(insn); - }); + }; - for_each(fallthrough_from.begin(), fallthrough_from.end(), [&](const pair<Instruction_t*, InstructionSet_t>& p) + for(auto &p : fallthrough_from) { - Instruction_t* ft=p.first; + auto ft=p.first; if(p.second.size()>1) { // skip the first one, because something can fallthrough, just not everything. for_each(next(p.second.begin()), p.second.end(), [&](Instruction_t* from) { - Instruction_t* newjmp=addNewAssembly(m_firp, NULL, "jmp 0"); + auto newjmp=archhelper->createNewJumpInstruction(m_firp,NULL); count++; - newjmp->SetTarget(ft); from->SetFallthrough(newjmp); }); }; - }); + } // after we've inserted all the jumps, assemble them. m_firp->AssembleRegistry(); diff --git a/test/SConscript b/test/SConscript index 1f3d0bd..805cb59 100644 --- a/test/SConscript +++ b/test/SConscript @@ -39,8 +39,7 @@ cpppath=''' $ZIPR_HOME/third_party/ELFIO/elfio-2.2 $SECURITY_TRANSFORMS_HOME/include/ $SECURITY_TRANSFORMS_HOME/libIRDB/include/ - $SECURITY_TRANSFORMS_HOME/beaengine/include - $SECURITY_TRANSFORMS_HOME/beaengine/beaengineSources/Includes/ + $SECURITY_TRANSFORMS_HOME/libtransform/include/ $ZIPR_HOME/include/ $ZIPR_SDK/include/ ''' -- GitLab