diff --git a/include/vmp_rtn.hpp b/include/vmp_rtn.hpp index 05993b6..9ce80db 100644 --- a/include/vmp_rtn.hpp +++ b/include/vmp_rtn.hpp @@ -31,8 +31,15 @@ namespace vm std::shared_ptr< llvm::IRBuilder<> > ir_builder; llvm::AllocaInst *virtual_stack, *stack_ptr; + std::map< ZydisRegister, llvm::Constant * > native_registers; std::vector< llvm::AllocaInst * > virtual_registers; std::vector< llvm::BasicBlock * > llvm_code_blocks; std::vector< vm::instrs::code_block_t > vmp2_code_blocks; + + private: + void create_native_registers( void ); + void create_virtual_registers( void ); + void create_routine( void ); + void create_virtual_stack( void ); }; } // namespace vm \ No newline at end of file diff --git a/src/vmp_rtn.cpp b/src/vmp_rtn.cpp index 3760363..f567661 100644 --- a/src/vmp_rtn.cpp +++ b/src/vmp_rtn.cpp @@ -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; } }