added labels to the source code..

merge-requests/2/head
_xeroxz 3 years ago
parent 73654873ef
commit a371b2f00e

@ -50,10 +50,10 @@ namespace vm
{ {
for ( auto itr = vmctx->vm_handlers.begin(); itr != vmctx->vm_handlers.end(); ++itr ) 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 ) 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 } ); vinstr.imm, itr->profile->imm_size } );
break; break;
} }
@ -62,11 +62,12 @@ namespace vm
return true; return true;
} ); } );
return &vinstrs; return &virt_labels;
} }
std::vector< compiled_label_data > compiler_t::encrypt() 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; const auto end_of_module = vmctx->image_size + vmctx->image_base;
// decryption key starts off as the image // decryption key starts off as the image
@ -74,7 +75,7 @@ namespace vm
std::uintptr_t decrypt_key = end_of_module, start_addr; std::uintptr_t decrypt_key = end_of_module, start_addr;
if ( vmctx->exec_type == vmp2::exec_type_t::backward ) 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; ( ++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... // invert the encoded virtual instructions operands if vip advances backward...
if ( vmctx->exec_type == vmp2::exec_type_t::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... // 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; for ( auto &vinstr : label.vinstrs )
std::tie( vinstr.vm_handler, decrypt_key ) =
vm::instrs::encrypt_operand( calc_jmp_transforms, vinstr.vm_handler, decrypt_key );
if ( !vinstr.imm_size )
{ {
result_buffer.push_back( vinstr.vm_handler ); std::printf( "> decrypt key = 0x%p\n", decrypt_key );
continue;
}
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 ) = if ( !vinstr.imm_size )
vm::instrs::encrypt_operand( transforms, vinstr.operand, decrypt_key ); {
result.back().vinstrs.push_back( vinstr.vm_handler );
continue;
}
// operands must be backwards if VIP advances backward... auto transforms = vmctx->vm_handlers.at( vm_handler_idx ).transforms;
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 ] );
result_buffer.push_back( vinstr.vm_handler ); std::tie( vinstr.operand, decrypt_key ) =
} vm::instrs::encrypt_operand( transforms, vinstr.operand, decrypt_key );
else
{
result_buffer.push_back( vinstr.vm_handler );
for ( auto idx = 0u; idx < vinstr.imm_size / 8; ++idx ) // operands must be backwards if VIP advances backward...
result_buffer.push_back( reinterpret_cast< std::uint8_t * >( &vinstr.operand )[ idx ] ); 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 ) std::uint64_t compiler_t::encrypt_rva( std::uint64_t rva )

@ -32,7 +32,7 @@ namespace vm
struct compiled_label_data struct compiled_label_data
{ {
std::string label_name; std::string label_name;
std::uintptr_t enc_alloc_rva; std::uintptr_t alloc_rva, enc_alloc_rva;
std::vector< std::uint8_t > vinstrs; std::vector< std::uint8_t > vinstrs;
}; };
@ -44,9 +44,11 @@ namespace vm
std::vector< compiled_label_data > encrypt(); std::vector< compiled_label_data > encrypt();
private: private:
std::uint64_t encrypt_rva( std::uint64_t rva );
vm::ctx_t *vmctx; vm::ctx_t *vmctx;
transform::map_t calc_jmp_transforms; 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; std::vector< zydis_decoded_instr_t > encrypt_vinstrs_rva;
}; };
} // namespace vm } // namespace vm

@ -22,11 +22,6 @@ void yyerror( char *msg )
std::printf( "[!] parsing failure: %s\n", 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[] ) int __cdecl main( int argc, const char *argv[] )
{ {
argparse::argument_parser_t argp( "vmassembler", "virtual instruction assembler" ); argparse::argument_parser_t argp( "vmassembler", "virtual instruction assembler" );
@ -98,51 +93,44 @@ int __cdecl main( int argc, const char *argv[] )
// encode virtual instructions... // encode virtual instructions...
// //
auto [ encoded_success, vinstrs ] = compiler.encode(); auto virt_labels = compiler.encode();
std::printf( "[+] finished encoding... encoded instructions below...\n" ); std::printf( "[+] finished encoding... encoded instructions below...\n" );
if ( !encoded_success ) for ( auto &label : *virt_labels )
{
std::printf( "[!] failed to encode virtual instructions...\n" );
return -1;
}
for ( auto &vinstr : *vinstrs )
{ {
if ( vinstr.imm_size ) for ( const auto &vinstr : label.vinstrs )
std::printf( "> 0x%x - 0x%x\n", vinstr.vm_handler, vinstr.operand ); {
else if ( vinstr.imm_size )
std::printf( "> 0x%x\n", vinstr.vm_handler ); std::printf( "> 0x%x - 0x%x\n", vinstr.vm_handler, vinstr.operand );
else
std::printf( "> 0x%x\n", vinstr.vm_handler );
}
} }
// //
// encrypt virtual instructions... // encrypt virtual instructions...
// //
auto [ entry_rva, result_buffer ] = compiler.encrypt(); auto compiled_labels = compiler.encrypt();
std::printf( "[+] finished encrypting... encrypted instructions below...\n" ); std::printf( "[+] finished encrypting... encrypted labels below...\n" );
if ( !entry_rva )
{
std::printf( "[!] failed to encrypt virtual instructions...\n" );
return -1;
}
std::printf( "> virtual instructions must be allocated at = 0x%p\n", entry_rva ); for ( const auto &label : compiled_labels )
std::printf( "> " );
{ {
auto idx = 0u; std::printf( "> %s must be allocated at = 0x%p\n", label.label_name.c_str(), label.alloc_rva );
for ( auto byte : *result_buffer ) std::printf( "> " );
{ {
std::printf( "0x%x ", byte ); auto idx = 0u;
if ( ++idx == 10 ) for ( auto byte : label.vinstrs )
{ {
std::printf( "\n" ); std::printf( "0x%x ", byte );
idx = 0u; if ( ++idx == 10 )
{
std::printf( "\n" );
idx = 0u;
}
} }
} }
} }
std::printf( "\n" ); std::printf( "\n" );
generate_header( *result_buffer, argp.get< std::string >( "output" ) );
} }

@ -12,22 +12,22 @@ auto parse_t::get_instance() -> parse_t *
void parse_t::add_label( std::string label_name ) 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 ) 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 ) 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 ) bool parse_t::for_each( callback_t callback )
{ {
for ( auto &entry : vinstrs ) for ( auto &entry : virt_labels )
if ( !callback( &entry ) ) if ( !callback( &entry ) )
return false; return false;

@ -33,5 +33,5 @@ class parse_t
private: private:
parse_t(); parse_t();
std::vector< _vlabel_meta > vinstrs; std::vector< _vlabel_meta > virt_labels;
}; };
Loading…
Cancel
Save