diff --git a/include/arch/archARM64.hpp b/include/arch/archARM64.hpp new file mode 100644 index 0000000000000000000000000000000000000000..33d91390ab708f0051039bbc9117522fbe9519b2 --- /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 0000000000000000000000000000000000000000..63385e0b83a494e35a14ad75f857ba927b74f01e --- /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 0000000000000000000000000000000000000000..53a4fb7ca5f77754783820348ea444ef13d13a64 --- /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 a47f99660d5dc2ba66d931a4add479c78ac16be7..c4c1b41463d23a9b65ab40b737a6fd7bfcb63b30 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 68c034eb3941d64e9d408127bc4de37246abcb03..e291d04ac15eb5f66a1b782e21853255427811c9 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 e051344d3ee869c24288fe88fd194d9a0566a598..46878a4bca602a850194579f6a7791243c14aac2 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 0000000000000000000000000000000000000000..7af208ba1d5f1558faa5758831dd753d50378205 --- /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 8e1be9dbf6fe69f9e899bdfcbdc21d9370541fe7..a2cce4ed86a438932f4c1332fc53890d6f2db8d0 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 1f3d0bd0348e1a868b1bddee6ca4336e3bb866a3..805cb59da8bac076425da7148f36223878ac2e18 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/ '''