|
|
@ -1,7 +1,9 @@
|
|
|
|
|
|
|
|
#define NOMINMAX
|
|
|
|
#include <Windows.h>
|
|
|
|
#include <Windows.h>
|
|
|
|
#include <filesystem>
|
|
|
|
#include <filesystem>
|
|
|
|
#include <fstream>
|
|
|
|
#include <fstream>
|
|
|
|
#include <iostream>
|
|
|
|
#include <iostream>
|
|
|
|
|
|
|
|
#include <vtil/vtil>
|
|
|
|
|
|
|
|
|
|
|
|
#include <ZydisExportConfig.h>
|
|
|
|
#include <ZydisExportConfig.h>
|
|
|
|
#include <cli-parser.hpp>
|
|
|
|
#include <cli-parser.hpp>
|
|
|
@ -24,6 +26,9 @@ int __cdecl main( int argc, const char *argv[] )
|
|
|
|
.name( "--showblockinstrs" )
|
|
|
|
.name( "--showblockinstrs" )
|
|
|
|
.description( "show the virtual instructions of a specific code block..." );
|
|
|
|
.description( "show the virtual instructions of a specific code block..." );
|
|
|
|
parser.add_argument().name( "--showallblocks" ).description( "shows all information for all code blocks..." );
|
|
|
|
parser.add_argument().name( "--showallblocks" ).description( "shows all information for all code blocks..." );
|
|
|
|
|
|
|
|
parser.add_argument()
|
|
|
|
|
|
|
|
.name( "--devirt" )
|
|
|
|
|
|
|
|
.description( "lift to VTIL IR and apply optimizations, then display the output..." );
|
|
|
|
|
|
|
|
|
|
|
|
parser.enable_help();
|
|
|
|
parser.enable_help();
|
|
|
|
auto err = parser.parse( argc, argv );
|
|
|
|
auto err = parser.parse( argc, argv );
|
|
|
@ -180,6 +185,61 @@ int __cdecl main( int argc, const char *argv[] )
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ( parser.exists( "devirt" ) )
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
vtil::basic_block *rtn = nullptr;
|
|
|
|
|
|
|
|
for ( auto [ code_block, code_block_num ] = std::tuple{ first_block, 0u };
|
|
|
|
|
|
|
|
code_block_num < file_header->code_block_count;
|
|
|
|
|
|
|
|
code_block = reinterpret_cast< vmp2::v3::code_block_t * >(
|
|
|
|
|
|
|
|
reinterpret_cast< std::uintptr_t >( code_block ) + code_block->next_block_offset ),
|
|
|
|
|
|
|
|
++code_block_num )
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
rtn = rtn ? rtn->fork(
|
|
|
|
|
|
|
|
ABS_TO_IMG( code_block->vip_begin, file_header->module_base, file_header->image_base ) )
|
|
|
|
|
|
|
|
: vtil::basic_block::begin(
|
|
|
|
|
|
|
|
ABS_TO_IMG( code_block->vip_begin, file_header->module_base, file_header->image_base ) );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for ( auto idx = 0u; idx < code_block->vinstr_count; ++idx )
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
auto vinstr = &code_block->vinstr[ idx ];
|
|
|
|
|
|
|
|
if ( vinstr->mnemonic_t == vm::handler::INVALID )
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
std::printf(
|
|
|
|
|
|
|
|
"> unable to lift to VTIL... unknown virtual instruction handler #%d... "
|
|
|
|
|
|
|
|
"please define a vm handler profile for this virtual instruction and try again..."
|
|
|
|
|
|
|
|
" you can also create your first contribution to this open source project by submitting"
|
|
|
|
|
|
|
|
" a merge request with your changes! :)\n",
|
|
|
|
|
|
|
|
vinstr->opcode );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const auto result = std::find_if(
|
|
|
|
|
|
|
|
vm::lifters::all.begin(), vm::lifters::all.end(),
|
|
|
|
|
|
|
|
[ & ]( vm::lifters::lifter_t *lifter ) -> bool { return lifter->first == vinstr->mnemonic_t; } );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ( result == vm::lifters::all.end() )
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
std::printf(
|
|
|
|
|
|
|
|
"> unable to lift to VTIL... unknown virtual instruction handler lifter for #%d... "
|
|
|
|
|
|
|
|
"please define a vm handler lifter for this vm handler and try again..."
|
|
|
|
|
|
|
|
" you can also create your first contribution to this open source project by submitting"
|
|
|
|
|
|
|
|
" a merge request with your changes! :)\n",
|
|
|
|
|
|
|
|
vinstr->opcode );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// lift the virtual instruction...
|
|
|
|
|
|
|
|
( *result )->second( rtn, vinstr );
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vtil::optimizer::apply_all( rtn );
|
|
|
|
|
|
|
|
vtil::debug::dump( rtn );
|
|
|
|
|
|
|
|
return {};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if ( parser.exists( "showblockinstrs" ) )
|
|
|
|
if ( parser.exists( "showblockinstrs" ) )
|
|
|
|
{
|
|
|
|
{
|
|
|
|
const auto block_img_addr = parser.get< std::string >( "showblockinstrs" );
|
|
|
|
const auto block_img_addr = parser.get< std::string >( "showblockinstrs" );
|
|
|
|