From 41bd01e1550bbd1d78ac328a49d047e920cc086a Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Sun, 27 Jun 2021 20:22:39 -0700 Subject: [PATCH] fucking burnt out on this code, needs work, dont have the time --- include/theo/engine/engine.hpp | 52 +++++++++++++++++++--- include/theo/engine/iff.hpp | 21 ++++++--- include/theo/engine/swapchain.hpp | 22 +++------ include/theo/obf_pass/obf_pass.hpp | 35 --------------- include/theo/obf_pass/obf_pass_wrapper.hpp | 46 ------------------- include/theo/symbol.hpp | 27 ----------- include/theo/theo.hpp | 4 +- src/main.cpp | 9 ++++ src/theo/engine/engine.cpp | 25 +++++------ src/theo/engine/iff.cpp | 46 ++++++++++++------- src/theo/engine/swapchain.cpp | 23 ++++------ src/theo/obf_pass/obf_pass_wrapper.cpp | 0 src/theo/symbol.cpp | 0 theodosius.vcxproj | 9 ++-- theodosius.vcxproj.filters | 18 ++------ 15 files changed, 133 insertions(+), 204 deletions(-) delete mode 100644 include/theo/obf_pass/obf_pass_wrapper.hpp delete mode 100644 include/theo/symbol.hpp delete mode 100644 src/theo/obf_pass/obf_pass_wrapper.cpp delete mode 100644 src/theo/symbol.cpp diff --git a/include/theo/engine/engine.hpp b/include/theo/engine/engine.hpp index 54f0feb..7f545b9 100644 --- a/include/theo/engine/engine.hpp +++ b/include/theo/engine/engine.hpp @@ -3,20 +3,62 @@ #include #include #include -#include namespace theo { + class obf_pass_t + { + public: + obf_pass_t() + { + } + + virtual void obfuscate( theo::iff_t & ) = 0; + }; + + class obf_pass_section_t : public obf_pass_t + { + public: + obf_pass_section_t() + { + } + + virtual void obfuscate( theo::iff_t::section_t &iff_section ) = 0; + + void obfuscate( theo::iff_t &iff ) override + { + std::for_each( iff.sections.begin(), iff.sections.end(), + [ & ]( theo::iff_t::section_t &iff_section ) { obfuscate( iff_section ); } ); + } + }; + + class obf_pass_deadstore_t : public obf_pass_section_t + { + using callback_t = std::function< void( theo::iff_t::section_t &iff_section ) >; + const callback_t callback; + + public: + obf_pass_deadstore_t( const callback_t &callback ) : callback( callback ) + { + } + + void obfuscate( theo::iff_t::section_t &iff_section ) override + { + // TODO impliment deadstore here... + callback( iff_section ); + } + }; + class engine_t { public: explicit engine_t( const std::vector< std::uint8_t > &lib_img ); - engine_t &add_pass( const obf_pass_t &pass ); - engine_t &add_passes( const std::vector< obf_pass_t > &passes ); - void run( std::vector< std::uint8_t > &result ); + void push( std::shared_ptr< obf_pass_t > obf_pass ); + void pop(); + void run(); private: + std::vector< std::shared_ptr< obf_pass_t > > obf_passes; std::shared_ptr< theo::swapchain_t > swapchain; - std::vector< theo::obf_pass_t > obf_passes; }; } // namespace theo \ No newline at end of file diff --git a/include/theo/engine/iff.hpp b/include/theo/engine/iff.hpp index fb8aa85..fe47013 100644 --- a/include/theo/engine/iff.hpp +++ b/include/theo/engine/iff.hpp @@ -3,14 +3,18 @@ #include #include +#define XED_ENCODER +extern "C" +{ + #include + #include + #include +} + namespace theo { class iff_t { - /// - /// swapchain_t is the only one who needs to call iff_t::flush... - /// so its a friend class... flush is also private... - /// friend class swapchain_t; public: @@ -18,15 +22,18 @@ namespace theo { coff::section_header_t header; std::vector< std::pair< std::uint32_t, coff::symbol_t > > symbols; + std::vector< xed_decoded_inst_t > instrs; }; explicit iff_t( coff::image_t *img ); std::vector< section_t > sections; + static std::shared_ptr< theo::iff_t > make( coff::image_t *img ) + { + return std::make_shared< theo::iff_t >( img ); + } + private: - /// - /// flush changes from "sections" back to img... - /// void flush(); coff::image_t *img; }; diff --git a/include/theo/engine/swapchain.hpp b/include/theo/engine/swapchain.hpp index 2181af4..492ef52 100644 --- a/include/theo/engine/swapchain.hpp +++ b/include/theo/engine/swapchain.hpp @@ -8,28 +8,18 @@ namespace theo { class swapchain_t { - /// - /// pair of front and back buffers... - /// changes are flushed to the back buffer, then the front - /// buffer gets overwritten by the back buffer when swapped... - /// - struct pair_t + public: + struct buffers_t { std::vector< std::uint8_t > front, back; + std::shared_ptr< iff_t > iff; }; - std::vector< pair_t > objs; - std::vector< std::uint8_t > archive; - - public: explicit swapchain_t( const std::vector< std::uint8_t > &img ); static std::shared_ptr< swapchain_t > make( const std::vector< std::uint8_t > &img ); + void swap( buffers_t &buffers ); - /// - /// if theo::swapchain::swap takes in an empty vector then it will simply fill it up - /// instead of flushing the iff data to the back buffer then swapping... - /// - /// - void swap( std::vector< iff_t > &iffs ); + std::vector< buffers_t > objs; + const std::vector< std::uint8_t > archive; }; } // namespace theo \ No newline at end of file diff --git a/include/theo/obf_pass/obf_pass.hpp b/include/theo/obf_pass/obf_pass.hpp index 1897922..e69de29 100644 --- a/include/theo/obf_pass/obf_pass.hpp +++ b/include/theo/obf_pass/obf_pass.hpp @@ -1,35 +0,0 @@ -#pragma once -#include -#include - -namespace theo -{ - enum class lvl_t - { - /// - /// callback gets passed entire IFF structures... - /// - l_iff, - - /// - /// callback gets passed entire IFF section structures... - /// - l_section, - - /// - /// callback gets passed entire IFF symbols... - /// - l_symbol - }; - - class obf_pass_t - { - friend class engine_t; - virtual void obfuscate( const theo::iff_t & ) = 0; - lvl_t lvl; - - public: - explicit obf_pass_t( const lvl_t &pass_lvl ); - lvl_t get_lvl() const; - }; -} // namespace theo \ No newline at end of file diff --git a/include/theo/obf_pass/obf_pass_wrapper.hpp b/include/theo/obf_pass/obf_pass_wrapper.hpp deleted file mode 100644 index d8ec054..0000000 --- a/include/theo/obf_pass/obf_pass_wrapper.hpp +++ /dev/null @@ -1,46 +0,0 @@ -#pragma once -#include -#include -#include - -namespace theo -{ - /// - /// obfuscation pass at the IFF level... - /// - class obf_pass_iff_t : public obf_pass_t - { - void obfuscate( const theo::iff_t & ) override; - - public: - obf_pass_iff_t() : obf_pass_t( lvl_t::l_iff ) - { - } - }; - - /// - /// obfuscation pass at the IFF section level... - /// - class obf_pass_section_t : public obf_pass_t - { - void obfuscate( const theo::iff_t & ) override; - - public: - obf_pass_section_t() : obf_pass_t( lvl_t::l_section ) - { - } - }; - - /// - /// obfuscation pass at the IFF symbol level.. - /// - class obf_pass_symbol_t : public obf_pass_t - { - void obfuscate( const theo::iff_t & ) override; - - public: - obf_pass_symbol_t() : obf_pass_t( lvl_t::l_symbol ) - { - } - }; -} // namespace theo \ No newline at end of file diff --git a/include/theo/symbol.hpp b/include/theo/symbol.hpp deleted file mode 100644 index 15a9de1..0000000 --- a/include/theo/symbol.hpp +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once -#include -#include - -#define XED_DECODER -extern "C" -{ -#include -} - -namespace theo -{ - class symbol_t - { - std::uint32_t symbol_table_idx; - coff::symbol_t coff_symbol; - - std::vector< symbol_t * > deps; - std::vector< xed_decoded_inst_t > instrs; - - void on_update(); - - public: - symbol_t(); - void add_dep( const symbol_t &dep ); - }; -} // namespace theo \ No newline at end of file diff --git a/include/theo/theo.hpp b/include/theo/theo.hpp index 41ecceb..9ee0352 100644 --- a/include/theo/theo.hpp +++ b/include/theo/theo.hpp @@ -1,4 +1,2 @@ #pragma once -#include -#include -#include \ No newline at end of file +#include \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 4baed47..6a6e04a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -26,4 +26,13 @@ int __cdecl main( int argc, const char *argv[] ) std::vector< std::uint8_t > lib; umtils->open_binary_file( cli_parser.get< std::string >( "i" ), lib ); theo::engine_t theo( lib ); + + auto deadstore_pass = std::make_shared< theo::obf_pass_deadstore_t >( []( theo::iff_t::section_t &iff_section ) { + std::printf( "> section name = %s\n", iff_section.header.name.to_string().data() ); + std::printf( "> number of instructions = %d\n", iff_section.instrs.size() ); + } ); + + theo.push( deadstore_pass ); + theo.run(); + std::getchar(); } \ No newline at end of file diff --git a/src/theo/engine/engine.cpp b/src/theo/engine/engine.cpp index 1781718..58c3113 100644 --- a/src/theo/engine/engine.cpp +++ b/src/theo/engine/engine.cpp @@ -6,27 +6,26 @@ namespace theo { } - engine_t &theo::engine_t::add_pass( const obf_pass_t &pass ) + void engine_t::push( std::shared_ptr< obf_pass_t > obf_pass ) { - obf_passes.push_back( pass ); - return *this; + obf_passes.insert( obf_passes.begin(), obf_pass ); } - engine_t &theo::engine_t::add_passes( const std::vector< obf_pass_t > &passes ) + void engine_t::pop() { - obf_passes.insert( obf_passes.end(), passes.begin(), passes.end() ); - return *this; + obf_passes.erase( obf_passes.begin() ); } - void theo::engine_t::run( std::vector< std::uint8_t > &result ) + void engine_t::run() { - std::for_each( obf_passes.begin(), obf_passes.end(), [ & ]( theo::obf_pass_t &obf_pass ) { - std::vector< theo::iff_t > iffs; - swapchain->swap( iffs ); + // for each obj, run obfuscation pass on it... + std::for_each( swapchain->objs.begin(), swapchain->objs.end(), [ & ]( swapchain_t::buffers_t &buffer ) { + std::for_each( obf_passes.begin(), obf_passes.end(), [ & ]( std::shared_ptr< theo::obf_pass_t > pass ) { + pass->obfuscate( *buffer.iff ); - std::for_each( iffs.begin(), iffs.end(), [ & ]( const theo::iff_t &iff ) { - obf_pass.obfuscate( iff ); - swapchain->swap( iffs ); + // apply changes made by obfuscation pass to the back buffer... + // then swap the back buffer to the front... + swapchain->swap( buffer ); } ); } ); } diff --git a/src/theo/engine/iff.cpp b/src/theo/engine/iff.cpp index 6094ecd..dfaeba2 100644 --- a/src/theo/engine/iff.cpp +++ b/src/theo/engine/iff.cpp @@ -4,27 +4,39 @@ namespace theo { iff_t::iff_t( coff::image_t *img ) { - // add sections to iff... - std::for_each( img->get_sections(), img->get_sections() + img->file_header.num_sections, - [ & ]( const coff::section_header_t §ion_header ) { - sections.emplace_back( section_header ); + const auto img_ptr = reinterpret_cast< std::uint8_t * >( img ); + const auto num_sections = img->file_header.num_sections; - // add symbols to section... - const auto num_symbols = img->file_header.num_symbols; - for ( auto idx = 0u; idx < num_symbols; ++idx ) - // important to note that we are making a COPY of this symbol... - sections.back().symbols.push_back( { idx, *img->get_symbol( idx ) } ); - } ); + for ( auto section_num = 0u; section_num != num_sections; ++section_num ) + { + const auto section = img->get_section( section_num ); + iff_t::section_t iff_section{ *section }; + + if ( section->characteristics.mem_execute && section->size_raw_data ) + { + xed_error_enum_t err; + xed_decoded_inst_t instr; + std::uint32_t offset = 0u; + const xed_state_t istate{ XED_MACHINE_MODE_LONG_64, XED_ADDRESS_WIDTH_64b }; + xed_decoded_inst_zero_set_mode( &instr, &istate ); + + // decodes instructions for this given section... + while ( ( err = xed_decode( &instr, img_ptr + section->ptr_raw_data + offset, + section->size_raw_data - offset ) ) == XED_ERROR_NONE ) + { + offset += xed_decoded_inst_get_length( &instr ); + iff_section.instrs.push_back( instr ); + } + } + + // add all symbols for this section... + for ( auto idx = 0u; idx < img->file_header.num_symbols; ++idx ) + if ( img->get_symbol( idx )->section_index - 1 == section_num ) + iff_section.symbols.push_back( { idx, *img->get_symbol( idx ) } ); + } } void iff_t::flush() { - // for each section, loop over symbols to see if they have changed... - std::for_each( sections.begin(), sections.end(), [ & ]( const iff_t::section_t &iff_section ) { - std::for_each( iff_section.symbols.begin(), iff_section.symbols.end(), [ & ]( const auto &symbol_data ) { - const auto &[ symbol_idx, symbol ] = symbol_data; - img->get_symbol( symbol_idx )->value = symbol.value; - } ); - } ); } } // namespace theo \ No newline at end of file diff --git a/src/theo/engine/swapchain.cpp b/src/theo/engine/swapchain.cpp index db30637..e12bc19 100644 --- a/src/theo/engine/swapchain.cpp +++ b/src/theo/engine/swapchain.cpp @@ -8,7 +8,9 @@ namespace theo // extract obj files from lib archive... std::for_each( lib.begin(), lib.end(), [ & ]( const auto &coff_data ) { const auto &[ coff_name, coff_img ] = coff_data; - objs.push_back( { { coff_img.begin(), coff_img.end() }, { coff_img.begin(), coff_img.end() } } ); + buffers_t buffers{ { coff_img.begin(), coff_img.end() }, { coff_img.begin(), coff_img.end() } }; + buffers.iff = theo::iff_t::make( reinterpret_cast< coff::image_t * >( buffers.front.data() ) ); + objs.push_back( buffers ); } ); } @@ -17,19 +19,12 @@ namespace theo return std::make_shared< theo::swapchain_t >( img ); } - void theo::swapchain_t::swap( std::vector< iff_t > &iffs ) + void theo::swapchain_t::swap( buffers_t &buffers ) { - if ( iffs.empty() ) - { - for ( auto &[ front, back ] : objs ) - { - theo::iff_t iff( reinterpret_cast< coff::image_t * >( front.data() ) ); - iffs.push_back( iff ); - } - } - else - { - // TODO flush results to the back buffer and swap front and back... - } + // flush changes to the back buffer... + buffers.iff->flush(); + + // then swap buffers so that the front now sees the changes... + buffers.front = buffers.back; } } // namespace theo \ No newline at end of file diff --git a/src/theo/obf_pass/obf_pass_wrapper.cpp b/src/theo/obf_pass/obf_pass_wrapper.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/src/theo/symbol.cpp b/src/theo/symbol.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/theodosius.vcxproj b/theodosius.vcxproj index 8776af0..378e1fa 100644 --- a/theodosius.vcxproj +++ b/theodosius.vcxproj @@ -15,8 +15,6 @@ - - @@ -95,8 +93,6 @@ - - @@ -134,11 +130,11 @@ true - $(ProjectDir)dependencies\xtils;$(ProjectDir)dependencies\linux-pe\includes;$(ProjectDir)dependencies\xed\obj\wkit\include\xed\;$(ProjectDir)dependencies\cli-parser\;$(ProjectDir)include\;$(IncludePath);$(ProjectDir)include\ + $(ProjectDir)dependencies\xtils;$(ProjectDir)dependencies\linux-pe\includes;$(ProjectDir)dependencies\xed\obj\wkit\include\xed\;$(ProjectDir)dependencies\cli-parser\;$(ProjectDir)include\;$(IncludePath);$(ProjectDir)include\;$(ProjectDir)dependencies\xed\include\public\xed\ false - $(ProjectDir)dependencies\xtils;$(ProjectDir)dependencies\linux-pe\includes;$(ProjectDir)dependencies\xed\obj\wkit\include\xed\;$(ProjectDir)dependencies\cli-parser\;$(IncludePath);$(ProjectDir)include\ + $(ProjectDir)dependencies\xtils;$(ProjectDir)dependencies\linux-pe\includes;$(ProjectDir)dependencies\xed\obj\wkit\include\xed\;$(ProjectDir)dependencies\cli-parser\;$(IncludePath);$(ProjectDir)include\;$(ProjectDir)dependencies\xed\include\public\xed\ @@ -170,6 +166,7 @@ true stdcpplatest true + Disabled Console diff --git a/theodosius.vcxproj.filters b/theodosius.vcxproj.filters index 717bcd0..f669636 100644 --- a/theodosius.vcxproj.filters +++ b/theodosius.vcxproj.filters @@ -63,12 +63,6 @@ Source Files\theo\engine - - Source Files\theo\obf_pass - - - Source Files\theo - @@ -283,9 +277,6 @@ Header Files\xed - - Header Files\theo - Header Files\theo\engine @@ -295,14 +286,11 @@ Header Files\theo\engine - - Header Files\theo\obf_pass - - - Header Files\theo\obf_pass - Header Files\theo + + Header Files\theo\obf_pass + \ No newline at end of file