vmemu recode is done, just need to make vmemu-lib and submodule it..

merge-requests/6/head
_xeroxz 3 years ago
parent 3f8fea77cf
commit abc22a3ca1

@ -1,11 +1,14 @@
#pragma once #pragma once
#include <nt/image.hpp>
#include <unicorn/unicorn.h> #include <unicorn/unicorn.h>
#include <nt/image.hpp>
#include <vmprofiler.hpp> #include <vmprofiler.hpp>
#define PAGE_4KB 0x1000 #define PAGE_4KB 0x1000
#define STACK_SIZE PAGE_4KB * 512 #define STACK_SIZE PAGE_4KB * 512
#define STACK_BASE 0xFFFF000000000000 #define STACK_BASE 0xFFFF000000000000
#define IAT_VECTOR_TABLE 0xFFFFF00000000000
namespace vm namespace vm
{ {
@ -26,7 +29,7 @@ namespace vm
}; };
public: public:
explicit emu_t( vm::ctx_t *g_vm_ctx ); explicit emu_t( vm::ctx_t *vm_ctx );
~emu_t(); ~emu_t();
bool init(); bool init();

@ -77,7 +77,10 @@ int __cdecl main( int argc, const char *argv[] )
} }
if ( !emu.get_trace( code_blocks ) ) if ( !emu.get_trace( code_blocks ) )
{
std::printf( "[!] something failed during tracing, review the console for more information...\n" ); std::printf( "[!] something failed during tracing, review the console for more information...\n" );
return -1;
}
std::printf( "> number of blocks = %d\n", code_blocks.size() ); std::printf( "> number of blocks = %d\n", code_blocks.size() );
@ -207,7 +210,7 @@ int __cdecl main( int argc, const char *argv[] )
if ( !emu.get_trace( new_code_blocks ) ) if ( !emu.get_trace( new_code_blocks ) )
{ {
std::printf( "[!] something failed during tracing, review the console for more information...\n" ); std::printf( "[!] something failed during tracing, review the console for more information...\n" );
return -1; continue;
} }
std::printf( "> number of blocks = %d\n", new_code_blocks.size() ); std::printf( "> number of blocks = %d\n", new_code_blocks.size() );

@ -2,8 +2,8 @@
namespace vm namespace vm
{ {
emu_t::emu_t( vm::ctx_t *g_vm_ctx ) emu_t::emu_t( vm::ctx_t *vm_ctx )
: g_vm_ctx( g_vm_ctx ), uc_ctx( nullptr ), img_base( g_vm_ctx->image_base ), img_size( g_vm_ctx->image_size ) : g_vm_ctx( vm_ctx ), uc_ctx( nullptr ), img_base( vm_ctx->image_base ), img_size( vm_ctx->image_size )
{ {
} }
@ -28,20 +28,21 @@ namespace vm
return false; return false;
} }
if ( ( err = uc_mem_map( uc_ctx, img_base, img_size, UC_PROT_ALL ) ) ) if ( ( err = uc_mem_map( uc_ctx, g_vm_ctx->module_base, img_size, UC_PROT_ALL ) ) )
{ {
std::printf( "> map memory failed, reason = %d\n", err ); std::printf( "> map memory failed, reason = %d\n", err );
return false; return false;
} }
if ( ( err = uc_mem_write( uc_ctx, img_base, reinterpret_cast< void * >( g_vm_ctx->module_base ), img_size ) ) ) if ( ( err = uc_mem_write( uc_ctx, g_vm_ctx->module_base, reinterpret_cast< void * >( g_vm_ctx->module_base ),
img_size ) ) )
{ {
std::printf( "> failed to write memory... reason = %d\n", err ); std::printf( "> failed to write memory... reason = %d\n", err );
return false; return false;
} }
if ( ( err = uc_hook_add( uc_ctx, &code_exec_hook, UC_HOOK_CODE, &vm::emu_t::code_exec_callback, this, img_base, if ( ( err = uc_hook_add( uc_ctx, &code_exec_hook, UC_HOOK_CODE, &vm::emu_t::code_exec_callback, this,
img_base + img_size ) ) ) g_vm_ctx->module_base, g_vm_ctx->module_base + img_size ) ) )
{ {
std::printf( "> uc_hook_add error, reason = %d\n", err ); std::printf( "> uc_hook_add error, reason = %d\n", err );
return false; return false;
@ -61,7 +62,7 @@ namespace vm
bool emu_t::get_trace( std::vector< vm::instrs::code_block_t > &entries ) bool emu_t::get_trace( std::vector< vm::instrs::code_block_t > &entries )
{ {
uc_err err; uc_err err;
std::uintptr_t rip = g_vm_ctx->vm_entry_rva + img_base, rsp = STACK_BASE + STACK_SIZE - PAGE_4KB; std::uintptr_t rip = g_vm_ctx->vm_entry_rva + g_vm_ctx->module_base, rsp = STACK_BASE + STACK_SIZE - PAGE_4KB;
if ( ( err = uc_reg_write( uc_ctx, UC_X86_REG_RSP, &rsp ) ) ) if ( ( err = uc_reg_write( uc_ctx, UC_X86_REG_RSP, &rsp ) ) )
{ {
@ -105,7 +106,8 @@ namespace vm
continue; continue;
std::uintptr_t rbp = 0ull; std::uintptr_t rbp = 0ull;
std::uint32_t branch_rva = _code_block.code_block.jcc.block_addr[ 1 ]; std::uint32_t branch_rva =
( _code_block.code_block.jcc.block_addr[ 1 ] - g_vm_ctx->module_base ) + g_vm_ctx->image_base;
// setup object globals so that the tracing will work... // setup object globals so that the tracing will work...
code_block_data_t branch_block{ { _code_block.cpu_ctx->rip }, nullptr, nullptr }; code_block_data_t branch_block{ { _code_block.cpu_ctx->rip }, nullptr, nullptr };
@ -160,7 +162,8 @@ namespace vm
continue; continue;
std::uintptr_t rbp = 0ull; std::uintptr_t rbp = 0ull;
std::uint32_t branch_rva = _code_block.code_block.jcc.block_addr[ 0 ]; std::uint32_t branch_rva =
( _code_block.code_block.jcc.block_addr[ 1 ] - g_vm_ctx->module_base ) + g_vm_ctx->image_base;
// setup object globals so that the tracing will work... // setup object globals so that the tracing will work...
code_block_data_t branch_block{ { _code_block.cpu_ctx->rip }, nullptr, nullptr }; code_block_data_t branch_block{ { _code_block.cpu_ctx->rip }, nullptr, nullptr };
@ -271,8 +274,8 @@ namespace vm
ZydisFormatterInit( &formatter, ZYDIS_FORMATTER_STYLE_INTEL ); ZydisFormatterInit( &formatter, ZYDIS_FORMATTER_STYLE_INTEL );
} }
auto instr_ptr = reinterpret_cast< void * >( obj->g_vm_ctx->module_base + ( address - obj->img_base ) ); if ( !ZYAN_SUCCESS(
if ( !ZYAN_SUCCESS( ZydisDecoderDecodeBuffer( &decoder, instr_ptr, PAGE_4KB, &instr ) ) ) ZydisDecoderDecodeBuffer( &decoder, reinterpret_cast< void * >( address ), PAGE_4KB, &instr ) ) )
{ {
std::printf( "> failed to decode instruction at = 0x%p\n", address ); std::printf( "> failed to decode instruction at = 0x%p\n", address );
if ( ( err = uc_emu_stop( uc ) ) ) if ( ( err = uc_emu_stop( uc ) ) )
@ -332,11 +335,9 @@ namespace vm
const auto &vm_handler = obj->g_vm_ctx->vm_handlers[ vm_handler_table_idx ]; const auto &vm_handler = obj->g_vm_ctx->vm_handlers[ vm_handler_table_idx ];
// quick check to ensure sanity... things can get crazy so this is good to check... if ( ( err = obj->create_entry( &vinstr_entry ) ) )
if ( vm_handler.address != vm_handler_addr )
{ {
std::printf( "> vm handler index (%d) does not match vm handler address (%p)...\n", vm_handler_table_idx, std::printf( "> failed to create vinstr entry... reason = %d\n", err );
vm_handler_addr );
if ( ( err = uc_emu_stop( uc ) ) ) if ( ( err = uc_emu_stop( uc ) ) )
{ {
std::printf( "> failed to stop emulation, exiting... reason = %d\n", err ); std::printf( "> failed to stop emulation, exiting... reason = %d\n", err );
@ -345,14 +346,20 @@ namespace vm
return false; return false;
} }
if ( ( err = obj->create_entry( &vinstr_entry ) ) ) // quick check to ensure sanity... things can get crazy so this is good to check...
if ( vm_handler.address != vm_handler_addr ||
vinstr_entry.vip >= obj->g_vm_ctx->module_base + obj->g_vm_ctx->image_size ||
vinstr_entry.vip < obj->g_vm_ctx->module_base )
{ {
std::printf( "> failed to create vinstr entry... reason = %d\n", err ); std::printf( "> vm handler index (%d) does not match vm handler address (%p)...\n", vm_handler_table_idx,
vm_handler_addr );
if ( ( err = uc_emu_stop( uc ) ) ) if ( ( err = uc_emu_stop( uc ) ) )
{ {
std::printf( "> failed to stop emulation, exiting... reason = %d\n", err ); std::printf( "> failed to stop emulation, exiting... reason = %d\n", err );
exit( 0 ); exit( 0 );
} }
return false; return false;
} }
@ -409,8 +416,9 @@ namespace vm
// optimize so that we dont need to create a new vm::ctx_t every single virtual JMP... // optimize so that we dont need to create a new vm::ctx_t every single virtual JMP...
if ( obj->vm_ctxs.find( vm_handler_addr ) == obj->vm_ctxs.end() ) if ( obj->vm_ctxs.find( vm_handler_addr ) == obj->vm_ctxs.end() )
{ {
obj->vm_ctxs[ vm_handler_addr ] = std::make_shared< vm::ctx_t >( obj->vm_ctxs[ vm_handler_addr ] =
obj->g_vm_ctx->module_base, obj->img_base, obj->img_size, vm_handler_addr - obj->img_base ); std::make_shared< vm::ctx_t >( obj->g_vm_ctx->module_base, obj->img_base, obj->img_size,
vm_handler_addr - obj->g_vm_ctx->module_base );
if ( !obj->vm_ctxs[ vm_handler_addr ]->init() ) if ( !obj->vm_ctxs[ vm_handler_addr ]->init() )
{ {

Loading…
Cancel
Save