From d559b996ed5ceb0f96c20086bc55ef4e5027d5be Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Thu, 24 Jun 2021 16:13:29 -0700 Subject: [PATCH] beginning work on pe file dctor... --- .gitmodules | 3 + dependencies/linux-pe | 1 + include/llodctor/llodctor_base.hpp | 7 +- include/llodctor/llodctor_pe.hpp | 3 +- include/lloiff.hpp | 2 +- include/llosymbol/llosymbol_base.hpp | 4 +- .../llosymbol_loader_base.hpp | 10 +- .../llosymbol_loader/llosymbol_loader_map.cpp | 5 + .../llosymbol_loader/llosymbol_loader_map.hpp | 18 +++ include/lloutils.hpp | 29 +++++ llo-s1.vcxproj | 41 +++++- llo-s1.vcxproj.filters | 120 ++++++++++++++++++ src/llodctor_pe.cpp | 14 +- src/main.cpp | 84 +++++++++--- 14 files changed, 310 insertions(+), 31 deletions(-) create mode 160000 dependencies/linux-pe create mode 100644 include/llosymbol_loader/llosymbol_loader_map.cpp diff --git a/.gitmodules b/.gitmodules index 6f6a91b..e33db3e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "dependencies/cli-parser"] path = dependencies/cli-parser url = https://githacks.org/_xeroxz/cli-parser.git +[submodule "dependencies/linux-pe"] + path = dependencies/linux-pe + url = https://github.com/can1357/linux-pe.git diff --git a/dependencies/linux-pe b/dependencies/linux-pe new file mode 160000 index 0000000..db2b7af --- /dev/null +++ b/dependencies/linux-pe @@ -0,0 +1 @@ +Subproject commit db2b7af6e6beae1bc391ff8f8e5c97b963dc3258 diff --git a/include/llodctor/llodctor_base.hpp b/include/llodctor/llodctor_base.hpp index 9cb6ca8..1dc8277 100644 --- a/include/llodctor/llodctor_base.hpp +++ b/include/llodctor/llodctor_base.hpp @@ -12,6 +12,7 @@ namespace llo::s1 /// class dctor_base_t { + protected: /// /// vector of bytes containing the raw image to be deconstructed... /// @@ -20,7 +21,7 @@ namespace llo::s1 /// /// symbol loader used when generating iff... /// - llo::s1::symbol_loader_base_t* symbol_loader; + llo::s1::symbol_loader_base_t *symbol_loader; public: /// @@ -28,7 +29,7 @@ namespace llo::s1 /// /// vector of bytes containing the raw image... explicit dctor_base_t( std::vector< std::uint8_t > &image, - llo::s1::symbol_loader_base_t* symbol_loader = nullptr ) + llo::s1::symbol_loader_base_t *symbol_loader = nullptr ) : raw_img{ image }, symbol_loader{ symbol_loader } { } @@ -39,6 +40,6 @@ namespace llo::s1 /// /// /// - virtual bool generate( lloiff_t &iff ) = 0; + virtual void generate( lloiff_t &iff ) = 0; }; } // namespace llo::s1 \ No newline at end of file diff --git a/include/llodctor/llodctor_pe.hpp b/include/llodctor/llodctor_pe.hpp index f58ee81..770fdd5 100644 --- a/include/llodctor/llodctor_pe.hpp +++ b/include/llodctor/llodctor_pe.hpp @@ -1,5 +1,6 @@ #pragma once #include +#include namespace llo::s1 { @@ -12,6 +13,6 @@ namespace llo::s1 { } - bool generate( lloiff_t &iff ) override; + void generate( lloiff_t &iff ) override; }; } // namespace llo::s1 \ No newline at end of file diff --git a/include/lloiff.hpp b/include/lloiff.hpp index e500ad1..8e377e5 100644 --- a/include/lloiff.hpp +++ b/include/lloiff.hpp @@ -24,7 +24,7 @@ namespace llo { public: llo::utils::hash_t< std::string > section_name; - std::vector< llo::symbol::symbol_base_t > symbols; + std::vector< std::shared_ptr< llo::symbol::symbol_base_t > > symbols; std::vector< std::uint8_t > section_raw; }; diff --git a/include/llosymbol/llosymbol_base.hpp b/include/llosymbol/llosymbol_base.hpp index 60cf30d..a62d250 100644 --- a/include/llosymbol/llosymbol_base.hpp +++ b/include/llosymbol/llosymbol_base.hpp @@ -31,7 +31,7 @@ namespace llo::symbol { } - virtual symbol_type_t get_type() const; - virtual std::size_t get_size() const; + virtual symbol_type_t get_type() const = 0; + virtual std::size_t get_size() const = 0; }; } // namespace llo::symbol \ No newline at end of file diff --git a/include/llosymbol_loader/llosymbol_loader_base.hpp b/include/llosymbol_loader/llosymbol_loader_base.hpp index 8ec0311..5020cc6 100644 --- a/include/llosymbol_loader/llosymbol_loader_base.hpp +++ b/include/llosymbol_loader/llosymbol_loader_base.hpp @@ -10,10 +10,16 @@ namespace llo::s1 class symbol_loader_base_t { std::string symbols_path; + public: - symbol_loader_base_t( const std::string &&path ) : symbols_path{ path } + explicit symbol_loader_base_t( std::string &&path ) : symbols_path{ path } { } - virtual void load( llo::lloiff_t && ) = 0; + + symbol_loader_base_t( std::string &path ) : symbols_path{ path } + { + } + + virtual void load( llo::lloiff_t &) = 0; }; } // namespace llo::s1 \ No newline at end of file diff --git a/include/llosymbol_loader/llosymbol_loader_map.cpp b/include/llosymbol_loader/llosymbol_loader_map.cpp new file mode 100644 index 0000000..eeeaf48 --- /dev/null +++ b/include/llosymbol_loader/llosymbol_loader_map.cpp @@ -0,0 +1,5 @@ +#include + +void llo::s1::symbol_loader_map_t::load( llo::lloiff_t &iff ) +{ +} \ No newline at end of file diff --git a/include/llosymbol_loader/llosymbol_loader_map.hpp b/include/llosymbol_loader/llosymbol_loader_map.hpp index e69de29..379c00a 100644 --- a/include/llosymbol_loader/llosymbol_loader_map.hpp +++ b/include/llosymbol_loader/llosymbol_loader_map.hpp @@ -0,0 +1,18 @@ +#include + +namespace llo::s1 +{ + class symbol_loader_map_t : public symbol_loader_base_t + { + public: + explicit symbol_loader_map_t( std::string &&path ) : symbol_loader_base_t( path ) + { + } + + symbol_loader_map_t( std::string &path ) : symbol_loader_base_t( path ) + { + } + + void load( llo::lloiff_t &iff ) override; + }; +} // namespace llo::s1 \ No newline at end of file diff --git a/include/lloutils.hpp b/include/lloutils.hpp index 3375282..a75bbb5 100644 --- a/include/lloutils.hpp +++ b/include/lloutils.hpp @@ -1,7 +1,12 @@ #pragma once +#include #include +#include #include +#include +#include #include +#include #include #include @@ -28,6 +33,30 @@ namespace llo::utils return uniform_distribution( mt ); } + /// + /// reads a binary file off disk into an std::vector... + /// + /// file path... + /// vector to fill up with bytes... + /// returns true if no errors happened... + inline bool open_binary_file( std::string file, std::vector< uint8_t > &data ) + { + std::ifstream fstr( file, std::ios::binary ); + + if ( !fstr.is_open() ) + return false; + + fstr.unsetf( std::ios::skipws ); + fstr.seekg( 0, std::ios::end ); + + const auto file_size = fstr.tellg(); + + fstr.seekg( NULL, std::ios::beg ); + data.reserve( static_cast< uint32_t >( file_size ) ); + data.insert( data.begin(), std::istream_iterator< uint8_t >( fstr ), std::istream_iterator< uint8_t >() ); + return true; + } + /// /// hash class, used in lloiff, symbols, sections, and much more... /// diff --git a/llo-s1.vcxproj b/llo-s1.vcxproj index 2ad9a65..d2fc82a 100644 --- a/llo-s1.vcxproj +++ b/llo-s1.vcxproj @@ -11,6 +11,7 @@ + @@ -47,9 +48,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -66,11 +99,13 @@ + + @@ -109,11 +144,11 @@ true - $(ProjectDir)include;$(IncludePath);$(ProjectDir)include;$(ProjectDir)dependencies\fcml\include\ + $(ProjectDir)include;$(IncludePath);$(ProjectDir)include;$(ProjectDir)dependencies\fcml\include\;$(ProjectDir)dependencies\cli-parser\;$(ProjectDir)dependencies\linux-pe\includes;$(ProjectDir)dependencies\xtils\ false - $(VC_IncludePath);$(WindowsSDK_IncludePath);;$(ProjectDir)include;$(ProjectDir)dependencies\fcml\include\ + $(VC_IncludePath);$(WindowsSDK_IncludePath);;$(ProjectDir)include;$(ProjectDir)dependencies\fcml\include\;$(ProjectDir)dependencies\cli-parser\;$(ProjectDir)dependencies\linux-pe\includes;$(ProjectDir)dependencies\xtils\ @@ -137,7 +172,7 @@ true NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true - stdcpp17 + stdcpplatest Console diff --git a/llo-s1.vcxproj.filters b/llo-s1.vcxproj.filters index 4961785..79255d5 100644 --- a/llo-s1.vcxproj.filters +++ b/llo-s1.vcxproj.filters @@ -27,6 +27,21 @@ {3c4da18e-ebe9-4cf0-8edc-025d26da4d13} + + {6d02947c-bc11-46d5-a571-5ed1ec5c54cb} + + + {199f9012-40e3-45c4-963e-11da136be320} + + + {a3e87fb9-6f1a-4d3e-87e5-1869fdae603b} + + + {6d7474df-553d-4b37-8424-fa35c45ae9ca} + + + {98d78f45-088b-441d-b20f-f4b2e7cec972} + @@ -185,11 +200,113 @@ Header Files\llodisposition + + Header Files\llodctor + + + Header Files + + + Header Files\linux-pe + + + Header Files\linux-pe\nt + + + Header Files\linux-pe\nt + + + Header Files\linux-pe\nt + + + Header Files\linux-pe\nt + + + Header Files\linux-pe\nt\directories + + + Header Files\linux-pe\nt\directories + + + Header Files\linux-pe\nt\directories + + + Header Files\linux-pe\nt\directories + + + Header Files\linux-pe\nt\directories + + + Header Files\linux-pe\nt\directories + + + Header Files\linux-pe\nt\directories + + + Header Files\linux-pe\nt\directories + + + Header Files\linux-pe\nt\directories + + + Header Files\linux-pe\nt\directories + + + Header Files\linux-pe\nt\directories + + + Header Files\linux-pe\coff + + + Header Files\linux-pe\coff + + + Header Files\linux-pe\coff + + + Header Files\linux-pe\coff + + + Header Files\linux-pe\coff + + + Header Files\linux-pe\coff + + + Header Files\linux-pe\coff + + + Header Files\linux-pe\coff + + + Header Files\linux-pe\coff + + + Header Files\linux-pe\coff + + + Header Files\linux-pe\coff\auxiliaries + + + Header Files\linux-pe\coff\auxiliaries + + + Header Files\linux-pe\coff\auxiliaries + + + Header Files\linux-pe\coff\auxiliaries + + + Header Files\linux-pe\coff\auxiliaries + Resource Files + + Header Files\linux-pe + @@ -207,5 +324,8 @@ Header Files\fcml + + Source Files + \ No newline at end of file diff --git a/src/llodctor_pe.cpp b/src/llodctor_pe.cpp index beabb77..ffa1dd6 100644 --- a/src/llodctor_pe.cpp +++ b/src/llodctor_pe.cpp @@ -1,6 +1,16 @@ #include -bool llo::s1::dctor_pe_t::generate( lloiff_t &iff ) +void llo::s1::dctor_pe_t::generate( lloiff_t &iff ) { - return false; + auto dos_header = reinterpret_cast< win::dos_header_t * >( raw_img.data() ); + auto sections = dos_header->get_nt_headers()->get_sections(); + auto section_count = dos_header->get_nt_headers()->file_header.num_sections; + + for ( auto idx = 0u; idx < section_count; ++idx, ++sections ) + { + + } + + if ( symbol_loader ) + symbol_loader->load( iff ); } diff --git a/src/main.cpp b/src/main.cpp index fc8c77a..07d0790 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,36 +1,86 @@ #define NOMINMAX +#define _CRT_SECURE_NO_WARNINGS + +#include +#include #include -#include -#include +#include int __cdecl main( int argc, const char *argv[] ) { - // read the file path in from cli... - std::string file_name = "test.exe"; + argparse::argument_parser_t cli_parser( "llo stage-one", "llo stage one demo" ); + cli_parser.add_argument() + .names( { "-i", "--input" } ) + .description( "input file, must be a supported file format..." ) + .required( true ); - // open the image from disk... - std::vector< std::uint8_t > image; + cli_parser.add_argument() + .names( { "-s", "--symbols" } ) + .description( "path to symbols file, must be a supported file format... pdb, map, etc..." ); - llo::lloiff_t iff( file_name ); - llo::s1::dctor_pe_t pe_dctor( image ); + cli_parser.enable_help(); + auto err = cli_parser.parse( argc, argv ); + + if ( err ) + { + std::cout << err << std::endl; + cli_parser.print_help(); + return -1; + } - std::printf( "> iff name = %s, hash = 0x%p\n", iff.get_name().get_data().c_str(), iff.get_name().get_hash() ); + auto file_name{ cli_parser.get< std::string >( "input" ) }; - if ( !pe_dctor.generate( iff ) ) + if ( !std::filesystem::exists( file_name ) ) { - std::printf( "> failed to generate iff...\n" ); + std::printf( "[!] input file does not exist...\n" ); return -1; } - const auto &iff_sections = iff.get_sections(); - for ( auto §ion : iff_sections ) + std::vector< std::uint8_t > image; + + if ( !llo::utils::open_binary_file( file_name, image ) ) { - std::printf( "> section name = %s, section uq hash = 0x%p\n", section.section_name.get_data().c_str(), - section.section_name.get_unique_hash() ); + std::printf( "[!] failed to read file off disk...\n" ); + return -1; + } - for ( auto &symbol : section.symbols ) + std::shared_ptr< llo::s1::symbol_loader_base_t > symbol_loader = nullptr; + + if ( cli_parser.exists( "symbols" ) ) + { + std::filesystem::path symbols_file{ cli_parser.get< std::string >( "symbols" ) }; + if ( symbols_file.extension().compare( ".map" ) ) + { + symbol_loader = std::make_shared< llo::s1::symbol_loader_map_t >( symbols_file.string() ); + } + else if ( symbols_file.extension().compare( ".pdb" ) ) { - std::printf( "> symbol type = %d, symbol size = 0x%x\n", symbol.get_type(), symbol.get_size() ); + // TODO: + // symbol_loader = std::make_shared< llo::s1::symbol_loader_pdb_t >( symbols_file ); } } + + std::shared_ptr< llo::s1::dctor_base_t > file_dctor = nullptr; + std::filesystem::path file_path{ file_name }; + + if ( file_path.extension().compare( ".exe" ) || file_path.extension().compare( ".dll" ) || + file_path.extension().compare( ".sys" ) ) + { + file_dctor = std::make_shared< llo::s1::dctor_pe_t >( image, symbol_loader.get() ); + } + else if ( file_path.extension().compare( ".o" ) ) + { + // TODO: elf file format... + return -1; + } + else + { + std::printf( "[!] unknown file extension: %s\n", file_path.extension().c_str() ); + return -1; + } + + llo::lloiff_t iff( file_name ); + file_dctor->generate( iff ); + + std::printf( "> number of sections = %d\n", iff.get_sections().size() ); } \ No newline at end of file