|
|
|
@ -6,6 +6,88 @@ namespace vm
|
|
|
|
|
vmp_rtn_t::vmp_rtn_t( llvm::LLVMContext *llvm_ctx, llvm::Module *llvm_module, std::uintptr_t rtn_begin,
|
|
|
|
|
std::vector< vm::instrs::code_block_t > vmp2_code_blocks )
|
|
|
|
|
: llvm_ctx( llvm_ctx ), llvm_module( llvm_module ), rtn_begin( rtn_begin ), vmp2_code_blocks( vmp2_code_blocks )
|
|
|
|
|
{
|
|
|
|
|
// create native registers...
|
|
|
|
|
create_native_registers();
|
|
|
|
|
|
|
|
|
|
// create llvm::Function and llvm::BasicBlock's...
|
|
|
|
|
create_routine();
|
|
|
|
|
|
|
|
|
|
// set the insert point to the first code block...
|
|
|
|
|
ir_builder = std::make_shared< llvm::IRBuilder<> >( *llvm_ctx );
|
|
|
|
|
ir_builder->SetInsertPoint( llvm_code_blocks[ 0 ] );
|
|
|
|
|
|
|
|
|
|
// create stack and stack pointer...
|
|
|
|
|
create_virtual_stack();
|
|
|
|
|
|
|
|
|
|
// create virtual registers...
|
|
|
|
|
create_virtual_registers();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void vmp_rtn_t::create_native_registers( void )
|
|
|
|
|
{
|
|
|
|
|
native_registers[ ZYDIS_REGISTER_RAX ] =
|
|
|
|
|
llvm_module->getOrInsertGlobal( "rax", llvm::IntegerType::get( *llvm_ctx, 64 ) );
|
|
|
|
|
|
|
|
|
|
native_registers[ ZYDIS_REGISTER_RBX ] =
|
|
|
|
|
llvm_module->getOrInsertGlobal( "rbx", llvm::IntegerType::get( *llvm_ctx, 64 ) );
|
|
|
|
|
|
|
|
|
|
native_registers[ ZYDIS_REGISTER_RCX ] =
|
|
|
|
|
llvm_module->getOrInsertGlobal( "rcx", llvm::IntegerType::get( *llvm_ctx, 64 ) );
|
|
|
|
|
|
|
|
|
|
native_registers[ ZYDIS_REGISTER_RDX ] =
|
|
|
|
|
llvm_module->getOrInsertGlobal( "rdx", llvm::IntegerType::get( *llvm_ctx, 64 ) );
|
|
|
|
|
|
|
|
|
|
native_registers[ ZYDIS_REGISTER_RSI ] =
|
|
|
|
|
llvm_module->getOrInsertGlobal( "rsi", llvm::IntegerType::get( *llvm_ctx, 64 ) );
|
|
|
|
|
|
|
|
|
|
native_registers[ ZYDIS_REGISTER_RDI ] =
|
|
|
|
|
llvm_module->getOrInsertGlobal( "rdi", llvm::IntegerType::get( *llvm_ctx, 64 ) );
|
|
|
|
|
|
|
|
|
|
native_registers[ ZYDIS_REGISTER_RBP ] =
|
|
|
|
|
llvm_module->getOrInsertGlobal( "rbp", llvm::IntegerType::get( *llvm_ctx, 64 ) );
|
|
|
|
|
|
|
|
|
|
native_registers[ ZYDIS_REGISTER_RSP ] =
|
|
|
|
|
llvm_module->getOrInsertGlobal( "rsp", llvm::IntegerType::get( *llvm_ctx, 64 ) );
|
|
|
|
|
|
|
|
|
|
native_registers[ ZYDIS_REGISTER_R8 ] =
|
|
|
|
|
llvm_module->getOrInsertGlobal( "r8", llvm::IntegerType::get( *llvm_ctx, 64 ) );
|
|
|
|
|
|
|
|
|
|
native_registers[ ZYDIS_REGISTER_R9 ] =
|
|
|
|
|
llvm_module->getOrInsertGlobal( "r9", llvm::IntegerType::get( *llvm_ctx, 64 ) );
|
|
|
|
|
|
|
|
|
|
native_registers[ ZYDIS_REGISTER_R10 ] =
|
|
|
|
|
llvm_module->getOrInsertGlobal( "r10", llvm::IntegerType::get( *llvm_ctx, 64 ) );
|
|
|
|
|
|
|
|
|
|
native_registers[ ZYDIS_REGISTER_R11 ] =
|
|
|
|
|
llvm_module->getOrInsertGlobal( "r11", llvm::IntegerType::get( *llvm_ctx, 64 ) );
|
|
|
|
|
|
|
|
|
|
native_registers[ ZYDIS_REGISTER_R12 ] =
|
|
|
|
|
llvm_module->getOrInsertGlobal( "r12", llvm::IntegerType::get( *llvm_ctx, 64 ) );
|
|
|
|
|
|
|
|
|
|
native_registers[ ZYDIS_REGISTER_R13 ] =
|
|
|
|
|
llvm_module->getOrInsertGlobal( "r13", llvm::IntegerType::get( *llvm_ctx, 64 ) );
|
|
|
|
|
|
|
|
|
|
native_registers[ ZYDIS_REGISTER_R14 ] =
|
|
|
|
|
llvm_module->getOrInsertGlobal( "r14", llvm::IntegerType::get( *llvm_ctx, 64 ) );
|
|
|
|
|
|
|
|
|
|
native_registers[ ZYDIS_REGISTER_R15 ] =
|
|
|
|
|
llvm_module->getOrInsertGlobal( "r15", llvm::IntegerType::get( *llvm_ctx, 64 ) );
|
|
|
|
|
|
|
|
|
|
native_registers[ ZYDIS_REGISTER_RFLAGS ] =
|
|
|
|
|
llvm_module->getOrInsertGlobal( "rflags", llvm::IntegerType::get( *llvm_ctx, 64 ) );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void vmp_rtn_t::create_virtual_registers( void )
|
|
|
|
|
{
|
|
|
|
|
for ( auto idx = 0u; idx < 24; ++idx )
|
|
|
|
|
// allocate virtual register space...
|
|
|
|
|
virtual_registers.push_back(
|
|
|
|
|
ir_builder->CreateAlloca( llvm::IntegerType::get( *llvm_ctx, 64 ), nullptr,
|
|
|
|
|
( std::string( "vreg" ) + std::to_string( idx ) ).c_str() ) );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void vmp_rtn_t::create_routine( void )
|
|
|
|
|
{
|
|
|
|
|
// function has no arguments and returns void... maybe change this in the future as i learn
|
|
|
|
|
// more and more LLVM...
|
|
|
|
@ -25,17 +107,10 @@ namespace vm
|
|
|
|
|
blk_name << "blk_" << std::hex << vmp2_code_block.vip_begin;
|
|
|
|
|
llvm_code_blocks.push_back( llvm::BasicBlock::Create( *llvm_ctx, blk_name.str().c_str(), llvm_fptr ) );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// set the insert point to the first code block...
|
|
|
|
|
ir_builder = std::make_shared< llvm::IRBuilder<> >( *llvm_ctx );
|
|
|
|
|
ir_builder->SetInsertPoint( llvm_code_blocks[ 0 ] );
|
|
|
|
|
|
|
|
|
|
for ( auto idx = 0u; idx < 24; ++idx )
|
|
|
|
|
// allocate virtual register space...
|
|
|
|
|
virtual_registers.push_back(
|
|
|
|
|
ir_builder->CreateAlloca( llvm::IntegerType::get( *llvm_ctx, 64 ), nullptr,
|
|
|
|
|
( std::string( "vreg" ) + std::to_string( idx ) ).c_str() ) );
|
|
|
|
|
|
|
|
|
|
void vmp_rtn_t::create_virtual_stack( void )
|
|
|
|
|
{
|
|
|
|
|
// allocate stack space...
|
|
|
|
|
virtual_stack = ir_builder->CreateAlloca( llvm::ArrayType::get( llvm::IntegerType::get( *llvm_ctx, 8 ), 1024 ),
|
|
|
|
|
nullptr, "stack" );
|
|
|
|
@ -59,7 +134,7 @@ namespace vm
|
|
|
|
|
std::printf( "> failed to devirtualize virtual instruction with vm handler index = %d\n",
|
|
|
|
|
vinstr.opcode );
|
|
|
|
|
|
|
|
|
|
llvm_fptr->print( llvm::outs() );
|
|
|
|
|
llvm_module->print( llvm::outs(), nullptr );
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|