From a371b2f00efabb470165a6b5418b5dc00ce09dd5 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Sat, 5 Jun 2021 16:05:44 -0700 Subject: [PATCH] added labels to the source code.. --- src/compiler.cpp | 71 +++++++++++++++++++++++++++--------------------- src/compiler.h | 6 ++-- src/main.cpp | 56 +++++++++++++++----------------------- src/parser.cpp | 8 +++--- src/parser.h | 2 +- 5 files changed, 71 insertions(+), 72 deletions(-) diff --git a/src/compiler.cpp b/src/compiler.cpp index f397cef..9294e2f 100644 --- a/src/compiler.cpp +++ b/src/compiler.cpp @@ -50,10 +50,10 @@ namespace vm { for ( auto itr = vmctx->vm_handlers.begin(); itr != vmctx->vm_handlers.end(); ++itr ) { - vinstrs.push_back( { label_data->label_name } ); + virt_labels.push_back( { label_data->label_name } ); if ( itr->profile && itr->profile->name == vinstr.name ) { - vinstrs.back().vinstrs.push_back( { ( std::uint8_t )( itr - vmctx->vm_handlers.begin() ), + virt_labels.back().vinstrs.push_back( { ( std::uint8_t )( itr - vmctx->vm_handlers.begin() ), vinstr.imm, itr->profile->imm_size } ); break; } @@ -62,11 +62,12 @@ namespace vm return true; } ); - return &vinstrs; + return &virt_labels; } std::vector< compiled_label_data > compiler_t::encrypt() { + std::vector< compiled_label_data > result; const auto end_of_module = vmctx->image_size + vmctx->image_base; // decryption key starts off as the image @@ -74,7 +75,7 @@ namespace vm std::uintptr_t decrypt_key = end_of_module, start_addr; if ( vmctx->exec_type == vmp2::exec_type_t::backward ) { - std::for_each( vinstrs.begin(), vinstrs.end(), [ & ]( const vinstr_data &vinstr ) { + std::for_each( virt_labels.begin(), virt_labels.end(), [ & ]( const vinstr_data &vinstr ) { ( ++decrypt_key ) += vinstr.imm_size ? vinstr.imm_size / 8 : 0; } ); } @@ -82,46 +83,54 @@ namespace vm // invert the encoded virtual instructions operands if vip advances backward... if ( vmctx->exec_type == vmp2::exec_type_t::backward ) - std::reverse( vinstrs.begin(), vinstrs.end() ); + std::reverse( virt_labels.begin(), virt_labels.end() ); // loop over the instructions and encrypt them... - for ( auto &vinstr : vinstrs ) + for ( auto &label : virt_labels ) { - std::printf( "> decrypt key = 0x%p\n", decrypt_key ); + result.push_back( { label.label_name, start_addr } ); - auto vm_handler_idx = vinstr.vm_handler; - std::tie( vinstr.vm_handler, decrypt_key ) = - vm::instrs::encrypt_operand( calc_jmp_transforms, vinstr.vm_handler, decrypt_key ); - - if ( !vinstr.imm_size ) + for ( auto &vinstr : label.vinstrs ) { - result_buffer.push_back( vinstr.vm_handler ); - continue; - } + std::printf( "> decrypt key = 0x%p\n", decrypt_key ); - auto transforms = vmctx->vm_handlers.at( vm_handler_idx ).transforms; + auto vm_handler_idx = vinstr.vm_handler; + std::tie( vinstr.vm_handler, decrypt_key ) = + vm::instrs::encrypt_operand( calc_jmp_transforms, vinstr.vm_handler, decrypt_key ); - std::tie( vinstr.operand, decrypt_key ) = - vm::instrs::encrypt_operand( transforms, vinstr.operand, decrypt_key ); + if ( !vinstr.imm_size ) + { + result.back().vinstrs.push_back( vinstr.vm_handler ); + continue; + } - // operands must be backwards if VIP advances backward... - if ( vmctx->exec_type == vmp2::exec_type_t::backward ) - { - for ( auto idx = 0u; idx < vinstr.imm_size / 8; ++idx ) - result_buffer.push_back( reinterpret_cast< std::uint8_t * >( &vinstr.operand )[ idx ] ); + auto transforms = vmctx->vm_handlers.at( vm_handler_idx ).transforms; - result_buffer.push_back( vinstr.vm_handler ); - } - else - { - result_buffer.push_back( vinstr.vm_handler ); + std::tie( vinstr.operand, decrypt_key ) = + vm::instrs::encrypt_operand( transforms, vinstr.operand, decrypt_key ); - for ( auto idx = 0u; idx < vinstr.imm_size / 8; ++idx ) - result_buffer.push_back( reinterpret_cast< std::uint8_t * >( &vinstr.operand )[ idx ] ); + // operands must be backwards if VIP advances backward... + if ( vmctx->exec_type == vmp2::exec_type_t::backward ) + { + for ( auto idx = 0u; idx < vinstr.imm_size / 8; ++idx ) + result.back().vinstrs.push_back( reinterpret_cast< std::uint8_t * >( &vinstr.operand )[ idx ] ); + + result.back().vinstrs.push_back( vinstr.vm_handler ); + } + else + { + result.back().vinstrs.push_back( vinstr.vm_handler ); + + for ( auto idx = 0u; idx < vinstr.imm_size / 8; ++idx ) + result.back().vinstrs.push_back( reinterpret_cast< std::uint8_t * >( &vinstr.operand )[ idx ] ); + } } + + result.back().enc_alloc_rva = encrypt_rva( start_addr ); + start_addr += result.back().vinstrs.size(); } - return { start_addr, &result_buffer }; + return result; } std::uint64_t compiler_t::encrypt_rva( std::uint64_t rva ) diff --git a/src/compiler.h b/src/compiler.h index 6644e89..5a186d5 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -32,7 +32,7 @@ namespace vm struct compiled_label_data { std::string label_name; - std::uintptr_t enc_alloc_rva; + std::uintptr_t alloc_rva, enc_alloc_rva; std::vector< std::uint8_t > vinstrs; }; @@ -44,9 +44,11 @@ namespace vm std::vector< compiled_label_data > encrypt(); private: + std::uint64_t encrypt_rva( std::uint64_t rva ); + vm::ctx_t *vmctx; transform::map_t calc_jmp_transforms; - std::vector< vlabel_data > vinstrs; + std::vector< vlabel_data > virt_labels; std::vector< zydis_decoded_instr_t > encrypt_vinstrs_rva; }; } // namespace vm \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 319f1ad..a27cd89 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -22,11 +22,6 @@ void yyerror( char *msg ) std::printf( "[!] parsing failure: %s\n", msg ); } -void generate_header( std::vector< std::uint8_t > &virt_instrs, std::string image_path ) -{ - -} - int __cdecl main( int argc, const char *argv[] ) { argparse::argument_parser_t argp( "vmassembler", "virtual instruction assembler" ); @@ -98,51 +93,44 @@ int __cdecl main( int argc, const char *argv[] ) // encode virtual instructions... // - auto [ encoded_success, vinstrs ] = compiler.encode(); + auto virt_labels = compiler.encode(); std::printf( "[+] finished encoding... encoded instructions below...\n" ); - if ( !encoded_success ) - { - std::printf( "[!] failed to encode virtual instructions...\n" ); - return -1; - } - - for ( auto &vinstr : *vinstrs ) + for ( auto &label : *virt_labels ) { - if ( vinstr.imm_size ) - std::printf( "> 0x%x - 0x%x\n", vinstr.vm_handler, vinstr.operand ); - else - std::printf( "> 0x%x\n", vinstr.vm_handler ); + for ( const auto &vinstr : label.vinstrs ) + { + if ( vinstr.imm_size ) + std::printf( "> 0x%x - 0x%x\n", vinstr.vm_handler, vinstr.operand ); + else + std::printf( "> 0x%x\n", vinstr.vm_handler ); + } } // // encrypt virtual instructions... // - auto [ entry_rva, result_buffer ] = compiler.encrypt(); - std::printf( "[+] finished encrypting... encrypted instructions below...\n" ); - - if ( !entry_rva ) - { - std::printf( "[!] failed to encrypt virtual instructions...\n" ); - return -1; - } + auto compiled_labels = compiler.encrypt(); + std::printf( "[+] finished encrypting... encrypted labels below...\n" ); - std::printf( "> virtual instructions must be allocated at = 0x%p\n", entry_rva ); - std::printf( "> " ); + for ( const auto &label : compiled_labels ) { - auto idx = 0u; - for ( auto byte : *result_buffer ) + std::printf( "> %s must be allocated at = 0x%p\n", label.label_name.c_str(), label.alloc_rva ); + std::printf( "> " ); { - std::printf( "0x%x ", byte ); - if ( ++idx == 10 ) + auto idx = 0u; + for ( auto byte : label.vinstrs ) { - std::printf( "\n" ); - idx = 0u; + std::printf( "0x%x ", byte ); + if ( ++idx == 10 ) + { + std::printf( "\n" ); + idx = 0u; + } } } } std::printf( "\n" ); - generate_header( *result_buffer, argp.get< std::string >( "output" ) ); } \ No newline at end of file diff --git a/src/parser.cpp b/src/parser.cpp index 3d5df60..a22bf9b 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -12,22 +12,22 @@ auto parse_t::get_instance() -> parse_t * void parse_t::add_label( std::string label_name ) { - vinstrs.push_back( { label_name } ); + virt_labels.push_back( { label_name } ); } void parse_t::add_vinstr( std::string vinstr_name ) { - vinstrs.back().vinstrs.push_back( { vinstr_name, false, 0u } ); + virt_labels.back().vinstrs.push_back( { vinstr_name, false, 0u } ); } void parse_t::add_vinstr( std::string vinstr_name, std::uintptr_t imm_val ) { - vinstrs.back().vinstrs.push_back( { vinstr_name, true, imm_val } ); + virt_labels.back().vinstrs.push_back( { vinstr_name, true, imm_val } ); } bool parse_t::for_each( callback_t callback ) { - for ( auto &entry : vinstrs ) + for ( auto &entry : virt_labels ) if ( !callback( &entry ) ) return false; diff --git a/src/parser.h b/src/parser.h index e3a093d..173ff70 100644 --- a/src/parser.h +++ b/src/parser.h @@ -33,5 +33,5 @@ class parse_t private: parse_t(); - std::vector< _vlabel_meta > vinstrs; + std::vector< _vlabel_meta > virt_labels; }; \ No newline at end of file