diff --git a/dependencies/vmprofiler b/dependencies/vmprofiler index 647eeef..ef9e9c1 160000 --- a/dependencies/vmprofiler +++ b/dependencies/vmprofiler @@ -1 +1 @@ -Subproject commit 647eeef8face8101523452e93f21312b64ef20fb +Subproject commit ef9e9c1cb2f69abfc5ea070db71ef57b4316bb87 diff --git a/include/vm_lifters.hpp b/include/vm_lifters.hpp index 94c7808..1063bba 100644 --- a/include/vm_lifters.hpp +++ b/include/vm_lifters.hpp @@ -1,4 +1,5 @@ #pragma once +#include #include #include @@ -17,6 +18,20 @@ namespace vmp2::lifters { - bool lift( vm::vmp_rtn_t *rtn, const vm::instrs::code_block_t &vm_code_block, const vm::instrs::virt_instr_t &vinstr, - llvm::IRBuilder<> *ir_builder ); -} \ No newline at end of file + using lifter_callback_t = + std::function< void( vm::vmp_rtn_t *rtn, const vm::instrs::code_block_t &vm_code_block, + const vm::instrs::virt_instr_t &vinstr, llvm::IRBuilder<> *ir_builder ) >; + + extern lifter_callback_t lconstq; + inline std::map< vm::handler::mnemonic_t, lifter_callback_t * > lifters = { { vm::handler::LCONSTQ, &lconstq } }; + + inline bool lift( vm::vmp_rtn_t *rtn, const vm::instrs::code_block_t &vm_code_block, + const vm::instrs::virt_instr_t &vinstr, llvm::IRBuilder<> *ir_builder ) + { + if ( vinstr.mnemonic_t == vm::handler::INVALID || lifters.find( vinstr.mnemonic_t ) == lifters.end() ) + return false; + + ( *( lifters[ vinstr.mnemonic_t ] ) )( rtn, vm_code_block, vinstr, ir_builder ); + return true; + } +} // namespace vmp2::lifters \ No newline at end of file diff --git a/include/vmp_rtn.hpp b/include/vmp_rtn.hpp index 4a08eb5..fa88dc4 100644 --- a/include/vmp_rtn.hpp +++ b/include/vmp_rtn.hpp @@ -23,17 +23,14 @@ namespace vm explicit 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 ); - ~vmp_rtn_t(); llvm::Function *lift( void ); - - private: llvm::LLVMContext *llvm_ctx; llvm::Module *llvm_module; - + private: std::uintptr_t rtn_begin; - llvm::Function* llvm_fptr; + llvm::Function *llvm_fptr; std::shared_ptr< llvm::IRBuilder<> > ir_builder; - llvm::AllocaInst *virutal_registers; + llvm::AllocaInst *virutal_registers, *virtual_stack; std::vector< llvm::BasicBlock * > llvm_code_blocks; std::vector< vm::instrs::code_block_t > vmp2_code_blocks; }; diff --git a/src/lifters/lconst.cpp b/src/lifters/lconst.cpp index e69de29..55e6b4c 100644 --- a/src/lifters/lconst.cpp +++ b/src/lifters/lconst.cpp @@ -0,0 +1,9 @@ +#include + +namespace vmp2::lifters +{ + lifter_callback_t lconstq = [ & ]( vm::vmp_rtn_t *rtn, const vm::instrs::code_block_t &vm_code_block, + const vm::instrs::virt_instr_t &vinstr, llvm::IRBuilder<> *ir_builder ) { + auto push_val = llvm::ConstantInt::get( llvm::IntegerType::getInt64Ty( *rtn->llvm_ctx ), vinstr.operand.imm.u ); + }; +} \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 7fde48e..66d17f1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -65,4 +65,5 @@ int main( int argc, const char *argv[] ) Module llvm_module( "VMProtect 2 Static Devirtualizer", llvm_ctx ); vm::vmp_rtn_t vmp_rtn( &llvm_ctx, &llvm_module, first_block->vip_begin, vmp_code_blocks ); + vmp_rtn.lift(); } \ No newline at end of file diff --git a/src/vmp_rtn.cpp b/src/vmp_rtn.cpp index fa8938d..ee8f895 100644 --- a/src/vmp_rtn.cpp +++ b/src/vmp_rtn.cpp @@ -34,15 +34,28 @@ namespace vm virutal_registers = ir_builder->CreateAlloca( llvm::ArrayType::get( llvm::IntegerType::get( *llvm_ctx, 64 ), 24 ), nullptr, "vregs" ); - llvm_fptr->print( llvm::outs() ); - } - - vmp_rtn_t::~vmp_rtn_t() - { + // allocate stack space... + virtual_stack = ir_builder->CreateAlloca( llvm::ArrayType::get( llvm::IntegerType::get( *llvm_ctx, 8 ), 1024 ), + nullptr, "stack" ); } llvm::Function *vmp_rtn_t::lift( void ) { - return {}; + auto &code_blocks = llvm_fptr->getBasicBlockList(); + for ( auto idx = 0u; idx < code_blocks.size(); ++idx ) + { + for ( auto &vinstr : vmp2_code_blocks[ idx ].vinstrs ) + { + if ( !vmp2::lifters::lift( this, vmp2_code_blocks[ idx ], vinstr, ir_builder.get() ) ) + { + std::printf( "> failed to devirtualize virtual instruction with vm handler index = %d\n", + vinstr.opcode ); + + llvm_fptr->print( llvm::outs() ); + return nullptr; + } + } + } + return llvm_fptr; } } // namespace vm \ No newline at end of file