From 856fa1815d9ec8d9ab506dc82cae6a7813a668fb Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Sun, 8 Aug 2021 01:46:20 -0700 Subject: [PATCH] added more lifters... --- CMakeLists.txt | 1 + dependencies/vmprofiler | 2 +- include/vm_lifters.hpp | 10 +++++--- include/vmp_rtn.hpp | 2 +- src/lifters/jmp.cpp | 54 +++++++++++++++++++++++++++++++++++++++++ src/lifters/lconst.cpp | 6 +++++ src/lifters/nand.cpp | 20 +++++++++++++++ src/vmp_rtn.cpp | 5 ++-- 8 files changed, 93 insertions(+), 7 deletions(-) create mode 100644 src/lifters/jmp.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 7f4b344..21c35b2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,6 +42,7 @@ set(vmdevirt_SOURCES "") list(APPEND vmdevirt_SOURCES "src/lifters/add.cpp" "src/lifters/div.cpp" + "src/lifters/jmp.cpp" "src/lifters/lconst.cpp" "src/lifters/lreg.cpp" "src/lifters/mul.cpp" diff --git a/dependencies/vmprofiler b/dependencies/vmprofiler index 16aeb2d..1f5fe9c 160000 --- a/dependencies/vmprofiler +++ b/dependencies/vmprofiler @@ -1 +1 @@ -Subproject commit 16aeb2d6d48c4822b89497ad660911eb0f5e54bd +Subproject commit 1f5fe9cd7b16ad2edd17ee8e13c672b3feeb9c08 diff --git a/include/vm_lifters.hpp b/include/vm_lifters.hpp index e8cd511..fedbd35 100644 --- a/include/vm_lifters.hpp +++ b/include/vm_lifters.hpp @@ -30,17 +30,19 @@ namespace vm 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 ) >; - static lifter_callback_t lconstq, lconstdwsxq, lconstwsxq, lconstbzxw, lconstbsxq; + static lifter_callback_t lconstq, lconstdwsxq, lconstwsxq, lconstbzxw, lconstbsxq, lconstdw; static lifter_callback_t addq, adddw, addw; static lifter_callback_t sregq, sregdw; static lifter_callback_t lregq, lregdw; static lifter_callback_t pushvsp; static lifter_callback_t readq; - static lifter_callback_t nandq; + static lifter_callback_t nandq, nanddw; static lifter_callback_t shrq; + static lifter_callback_t jmp; std::map< vm::handler::mnemonic_t, lifter_callback_t * > lifters = { { vm::handler::LCONSTQ, &lconstq }, + { vm::handler::LCONSTDW, &lconstdw }, { vm::handler::LCONSTDWSXQ, &lconstdwsxq }, { vm::handler::LCONSTWSXQ, &lconstwsxq }, { vm::handler::LCONSTBZXW, &lconstbzxw }, @@ -55,7 +57,9 @@ namespace vm { vm::handler::LREGQ, &lregq }, { vm::handler::LREGDW, &lregdw }, { vm::handler::READQ, &readq }, - { vm::handler::NANDQ, &nandq } }; + { vm::handler::NANDQ, &nandq }, + { vm::handler::NANDDW, &nanddw }, + { vm::handler::JMP, &jmp } }; static vm::llvm_value_t *add_flags( vm::vmp_rtn_t *rtn, std::uint8_t byte_size, vm::llvm_value_t *lhs, vm::llvm_value_t *rhs ); diff --git a/include/vmp_rtn.hpp b/include/vmp_rtn.hpp index 32d5afe..4d5f418 100644 --- a/include/vmp_rtn.hpp +++ b/include/vmp_rtn.hpp @@ -51,7 +51,7 @@ namespace vm std::map< zydis_register_t, llvm_global_value_t * > native_registers; std::vector< llvm_alloca_inst_t * > virtual_registers; - std::vector< llvm_basic_block_t * > llvm_code_blocks; + std::vector< std::pair< std::uintptr_t, llvm_basic_block_t * > > llvm_code_blocks; std::vector< vm::instrs::code_block_t > vmp2_code_blocks; void push( std::uint8_t byte_size, llvm::Value *input_val ); diff --git a/src/lifters/jmp.cpp b/src/lifters/jmp.cpp new file mode 100644 index 0000000..697d377 --- /dev/null +++ b/src/lifters/jmp.cpp @@ -0,0 +1,54 @@ +#include + +namespace vm +{ + lifters_t::lifter_callback_t lifters_t::jmp = [ & ]( 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 ) { + assert( vm_code_block.jcc.has_jcc, "[!] fatal error in vmemu... virtual block ending with jmp marked as" + " has_jcc = false... debug time!\n" ); + + if ( vm_code_block.jcc.type == vm::instrs::jcc_type::branching ) + { + auto rva = rtn->pop( 8 ); + auto b1 = vm_code_block.jcc.block_addr[ 0 ] & ~std::numeric_limits< std::uint32_t >::max(); + auto _const_b1 = llvm::ConstantInt::get( ir_builder->getInt64Ty(), b1 ); + auto cmp = ir_builder->CreateCmp( llvm::CmpInst::ICMP_EQ, rva, _const_b1 ); + + // find the first branch basic block... + auto bb1 = std::find_if( + rtn->llvm_code_blocks.begin(), rtn->llvm_code_blocks.end(), + [ & ]( const std::pair< std::uintptr_t, llvm_basic_block_t * > &block_data ) -> bool { + return block_data.first == ( vm_code_block.jcc.block_addr[ 0 ] - vinstr.trace_data.regs.r13 ); + } ); + + assert( bb1 != rtn->llvm_code_blocks.end(), + "[!] fatal error... unable to locate basic block for branching...\n" ); + + // find the second branch basic block... + auto bb2 = std::find_if( + rtn->llvm_code_blocks.begin(), rtn->llvm_code_blocks.end(), + [ & ]( const std::pair< std::uintptr_t, llvm_basic_block_t * > &block_data ) -> bool { + return block_data.first == ( vm_code_block.jcc.block_addr[ 1 ] - vinstr.trace_data.regs.r13 ); + } ); + + assert( bb2 != rtn->llvm_code_blocks.end(), + "[!] fatal error... unable to locate basic block for branching...\n" ); + + ir_builder->CreateCondBr( cmp, bb1->second, bb2->second ); + } + else + { + auto rva = rtn->pop( 8 ); + auto bb_data = std::find_if( + rtn->llvm_code_blocks.begin(), rtn->llvm_code_blocks.end(), + [ & ]( const std::pair< std::uintptr_t, llvm_basic_block_t * > &block_data ) -> bool { + return block_data.first == vm_code_block.jcc.block_addr[ 0 ] - vinstr.trace_data.regs.r13; + } ); + + assert( bb_data != rtn->llvm_code_blocks.end(), "[!] fatal error... unable to locate basic block...\n" ); + ir_builder->CreateBr( bb_data->second ); + } + }; +} \ No newline at end of file diff --git a/src/lifters/lconst.cpp b/src/lifters/lconst.cpp index cf65c49..8617061 100644 --- a/src/lifters/lconst.cpp +++ b/src/lifters/lconst.cpp @@ -26,6 +26,12 @@ namespace vm rtn->push( 8, llvm::ConstantInt::get( ir_builder->getInt64Ty(), vinstr.operand.imm.u ) ); }; + lifters_t::lifter_callback_t lifters_t::lconstdw = + [ & ]( 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 ) { + rtn->push( 4, llvm::ConstantInt::get( ir_builder->getInt32Ty(), vinstr.operand.imm.u ) ); + }; + lifters_t::lifter_callback_t lifters_t::lconstbzxw = [ & ]( 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 ) { diff --git a/src/lifters/nand.cpp b/src/lifters/nand.cpp index 76510f9..12d6d47 100644 --- a/src/lifters/nand.cpp +++ b/src/lifters/nand.cpp @@ -33,4 +33,24 @@ namespace vm ir_builder->CreateStore( flags, rtn->flags ); rtn->push( 8, rtn->load_value( 8, rtn->flags ) ); }; + + lifters_t::lifter_callback_t lifters_t::nanddw = + [ & ]( 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 t1 = rtn->pop( 4 ); + auto t2 = rtn->pop( 4 ); + + auto t1_not = ir_builder->CreateNot( t1 ); + auto t2_not = ir_builder->CreateNot( t2 ); + + auto t3 = ir_builder->CreateAnd( { t1_not, t2_not } ); + rtn->push( 4, t3 ); + + // TODO: fix code for and_flags... setting byte value to anything + // other than 8 causes asserts to fire due to different types... + // + // auto flags = and_flags( rtn, 4, t1, t2 ); + // ir_builder->CreateStore( flags, rtn->flags ); + rtn->push( 8, rtn->load_value( 8, rtn->flags ) ); + }; } // namespace vm \ No newline at end of file diff --git a/src/vmp_rtn.cpp b/src/vmp_rtn.cpp index 0538ee4..17bf48b 100644 --- a/src/vmp_rtn.cpp +++ b/src/vmp_rtn.cpp @@ -11,7 +11,7 @@ namespace vm // do not change the ordering of these function calls... create_routine(); ir_builder = std::make_shared< llvm_irbuilder_t >( *llvm_ctx ); - ir_builder->SetInsertPoint( llvm_code_blocks[ 0 ] ); + ir_builder->SetInsertPoint( llvm_code_blocks[ 0 ].second ); // do not change the ordering of these function calls... create_native_registers(); @@ -132,7 +132,8 @@ namespace vm // create basic block name... block_xxxxxxxx format... std::stringstream blk_name; 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 ) ); + llvm_code_blocks.push_back( { vmp2_code_block.vip_begin, + llvm::BasicBlock::Create( *llvm_ctx, blk_name.str().c_str(), llvm_fptr ) } ); } }