diff --git a/dependencies/vmprofiler b/dependencies/vmprofiler index c231911..f06bf5f 160000 --- a/dependencies/vmprofiler +++ b/dependencies/vmprofiler @@ -1 +1 @@ -Subproject commit c2319117a07d95794f54db970aa7f72e8726349a +Subproject commit f06bf5f6b72b1d52a6156d6828675c77ceaee7e2 diff --git a/include/vm_lifters.hpp b/include/vm_lifters.hpp index 3bc7f01..1bbaec2 100644 --- a/include/vm_lifters.hpp +++ b/include/vm_lifters.hpp @@ -30,7 +30,9 @@ 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, lconstwsxdw, lconstdw; + static lifter_callback_t lconstq, lconstdwsxq, lconstwsxq, lconstbzxw, lconstbsxq, lconstwsxdw, lconstdw, + lconstbsxdw; + static lifter_callback_t addq, adddw, addw; static lifter_callback_t sregq, sregdw; static lifter_callback_t lregq, lregdw; @@ -50,6 +52,7 @@ namespace vm { vm::handler::LCONSTBZXW, &lconstbzxw }, { vm::handler::LCONSTBSXQ, &lconstbsxq }, { vm::handler::LCONSTWSXDW, &lconstwsxdw }, + { vm::handler::LCONSTBSXDW, &lconstbsxdw }, { vm::handler::ADDQ, &addq }, { vm::handler::ADDDW, &adddw }, { vm::handler::ADDW, &addw }, @@ -90,4 +93,4 @@ namespace vm return true; } }; -} // namespace vm \ No newline at end of file +} // namespace vm diff --git a/include/vmp_rtn.hpp b/include/vmp_rtn.hpp index abd4328..c309fc6 100644 --- a/include/vmp_rtn.hpp +++ b/include/vmp_rtn.hpp @@ -43,7 +43,7 @@ namespace vm llvm_context_t *llvm_ctx; llvm_module_t *llvm_module; llvm_function_t *llvm_fptr; - llvm_alloca_inst_t *virtual_stack, *stack_ptr, *flags; + llvm_alloca_inst_t *flags, *stack; vm::ctx_t *vm_ctx; std::uintptr_t rtn_begin; @@ -65,7 +65,6 @@ namespace vm llvm_value_t *combine_flags( llvm_value_t *cf, llvm_value_t *pf, llvm_value_t *af, llvm_value_t *zf, llvm_value_t *sf, llvm_value_t *of ); - void create_virtual_stack( void ); void create_virtual_registers( void ); void create_routine( void ); }; diff --git a/src/lifters/lconst.cpp b/src/lifters/lconst.cpp index e6a8815..0856610 100644 --- a/src/lifters/lconst.cpp +++ b/src/lifters/lconst.cpp @@ -38,6 +38,12 @@ namespace vm rtn->push( 4, llvm::ConstantInt::get( ir_builder->getInt32Ty(), vinstr.operand.imm.u ) ); }; + lifters_t::lifter_callback_t lifters_t::lconstbsxdw = + [ & ]( 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/pushvsp.cpp b/src/lifters/pushvsp.cpp index c1b29d2..38c6f2f 100644 --- a/src/lifters/pushvsp.cpp +++ b/src/lifters/pushvsp.cpp @@ -5,16 +5,8 @@ namespace vm lifters_t::lifter_callback_t lifters_t::pushvsp = [ & ]( 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 current_spi = - ir_builder->CreateLoad( llvm::IntegerType::get( *rtn->llvm_ctx, 64 ), rtn->stack_ptr, false ); - - auto *i64_zero = llvm::ConstantInt::get( *rtn->llvm_ctx, llvm::APInt( 64, 0 ) ); - llvm_value_t *indices[ 2 ] = { i64_zero, current_spi }; - auto stack_ptr = - ir_builder->CreateInBoundsGEP( rtn->virtual_stack, llvm::ArrayRef< llvm::Value * >( indices, 2 ) ); - - auto stack_ptr_val = ir_builder->CreatePtrToInt( stack_ptr, ir_builder->getInt64Ty() ); - rtn->push( 8, stack_ptr_val ); - + auto stack = ir_builder->CreateLoad( rtn->stack ); + auto stack_ptr = ir_builder->CreatePtrToInt( stack, ir_builder->getInt64Ty() ); + rtn->push( 8, stack_ptr ); }; } \ No newline at end of file diff --git a/src/lifters/sreg.cpp b/src/lifters/sreg.cpp index b2d3abf..6e2ae98 100644 --- a/src/lifters/sreg.cpp +++ b/src/lifters/sreg.cpp @@ -7,7 +7,7 @@ namespace vm const vm::instrs::virt_instr_t &vinstr, llvm::IRBuilder<> *ir_builder ) { auto t1 = rtn->pop( 8 ); auto vreg = rtn->virtual_registers[ vinstr.operand.imm.u ? vinstr.operand.imm.u / 8 : 0 ]; - ir_builder->CreateStore( t1, vreg )->setAlignment( llvm::Align( 1 ) ); + ir_builder->CreateStore( t1, vreg ); }; lifters_t::lifter_callback_t lifters_t::sregdw = @@ -17,6 +17,6 @@ namespace vm auto vreg = rtn->virtual_registers[ vinstr.operand.imm.u ? vinstr.operand.imm.u / 8 : 0 ]; auto vregdw = ir_builder->CreatePointerCast( vreg, llvm::PointerType::get( llvm::IntegerType::get( *rtn->llvm_ctx, 32 ), 0 ) ); - ir_builder->CreateStore( t1, vregdw )->setAlignment( llvm::Align( 1 ) ); + ir_builder->CreateStore( t1, vregdw ); }; } // namespace vm \ No newline at end of file diff --git a/src/lifters/vmexit.cpp b/src/lifters/vmexit.cpp index 2b758b7..ee1bb99 100644 --- a/src/lifters/vmexit.cpp +++ b/src/lifters/vmexit.cpp @@ -5,4 +5,4 @@ namespace vm lifters_t::lifter_callback_t lifters_t::vmexit = [ & ]( 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 ) { ir_builder->CreateRetVoid(); }; -} \ No newline at end of file +} diff --git a/src/main.cpp b/src/main.cpp index e0652fe..77043ad 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -76,5 +76,6 @@ int main( int argc, const char *argv[] ) } vm::vmp_rtn_t vmp_rtn( &llvm_ctx, &llvm_module, &vm_ctx, first_block->vip_begin, vmp_code_blocks ); - vmp_rtn.lift(); + auto func = vmp_rtn.lift(); + func->print( llvm::outs(), nullptr ); } \ No newline at end of file diff --git a/src/vmp_rtn.cpp b/src/vmp_rtn.cpp index 1e1520e..a14f127 100644 --- a/src/vmp_rtn.cpp +++ b/src/vmp_rtn.cpp @@ -13,14 +13,9 @@ namespace vm ir_builder = std::make_shared< llvm_irbuilder_t >( *llvm_ctx ); ir_builder->SetInsertPoint( llvm_code_blocks[ 0 ].second ); flags = ir_builder->CreateAlloca( ir_builder->getInt64Ty(), nullptr, "flags" ); + stack = ir_builder->CreateAlloca( llvm::PointerType::get( ir_builder->getInt8Ty(), 0ull ), nullptr, "sp" ); - create_virtual_stack(); - for ( auto idx = 0u; idx < 21; ++idx ) - { - auto val = ir_builder->CreateLoad( llvm_fptr->getArg( idx ) ); - val->setAlignment( llvm::Align( 1 ) ); - push( 8, val ); - } + ir_builder->CreateStore( llvm_fptr->getArg( 0 ), stack ); create_virtual_registers(); } @@ -35,11 +30,10 @@ namespace vm void vmp_rtn_t::create_routine( void ) { - std::vector< llvm::Type * > arg_types; - for ( auto idx = 0u; idx < 21; ++idx ) - arg_types.push_back( llvm::PointerType::get( llvm::IntegerType::get( *llvm_ctx, 64 ), 0ull ) ); - - auto func_ty = llvm::FunctionType::get( llvm::Type::getVoidTy( *llvm_ctx ), arg_types, false ); + // function has no arguments and returns void... maybe change this in the future as i learn + // more and more LLVM... + auto func_ty = llvm::FunctionType::get( llvm::Type::getVoidTy( *llvm_ctx ), + { llvm::PointerType::getInt8PtrTy( *llvm_ctx ) }, false ); // convert the rtn_begin address to a hex string and prepend "rtn_" to it... std::stringstream rtn_name; @@ -47,7 +41,6 @@ namespace vm llvm_fptr = llvm::Function::Create( func_ty, llvm::GlobalValue::LinkageTypes::ExternalLinkage, rtn_name.str().c_str(), *llvm_module ); - llvm_fptr->setCallingConv( llvm::CallingConv::X86_FastCall ); for ( const auto &vmp2_code_block : vmp2_code_blocks ) { // create basic block name... block_xxxxxxxx format... @@ -60,53 +53,36 @@ namespace vm void vmp_rtn_t::push( std::uint8_t num_bytes, llvm_value_t *val ) { - auto spi = ir_builder->CreateLoad( ir_builder->getInt64Ty(), stack_ptr, false ); - spi->setAlignment( llvm::Align( 1 ) ); - - auto new_spi = ir_builder->CreateSub( spi, llvm::ConstantInt::get( ir_builder->getInt64Ty(), num_bytes ) ); - ir_builder->CreateStore( new_spi, stack_ptr )->setAlignment( llvm::Align( 1 ) ); - - auto *i64_zero = llvm::ConstantInt::get( *llvm_ctx, llvm::APInt( 64, 0 ) ); - llvm_value_t *indices[ 2 ] = { i64_zero, new_spi }; - auto stack_ptr = ir_builder->CreateInBoundsGEP( virtual_stack, llvm::ArrayRef< llvm_value_t * >( indices, 2 ) ); - - if ( num_bytes > 1 ) - { - auto casted_ptr = ir_builder->CreatePointerCast( - stack_ptr, llvm::PointerType::get( llvm::IntegerType::get( *llvm_ctx, num_bytes * 8 ), 0 ) ); - - ir_builder->CreateStore( val, casted_ptr )->setAlignment( llvm::Align( 1 ) ); - } - else - ir_builder->CreateStore( val, stack_ptr )->setAlignment( llvm::Align( 1 ) ); + // sub rsp, num_bytes + auto rsp_addr = ir_builder->CreateLoad( stack ); + auto rsp_i64 = ir_builder->CreatePtrToInt( rsp_addr, ir_builder->getInt64Ty() ); + auto sub_rsp_val = ir_builder->CreateSub( rsp_i64, ir_builder->getInt64( num_bytes ) ); + ir_builder->CreateStore( + ir_builder->CreateIntToPtr( sub_rsp_val, llvm::PointerType::get( ir_builder->getInt8Ty(), 0ull ) ), stack ); + + // mov [rsp], val + rsp_addr = ir_builder->CreateLoad( stack ); + auto rsp_cast_ptr = ir_builder->CreatePointerCast( + rsp_addr, llvm::PointerType::get( llvm::IntegerType::get( *llvm_ctx, num_bytes * 8 ), false ) ); + ir_builder->CreateStore( val, rsp_cast_ptr ); } llvm_value_t *vmp_rtn_t::pop( std::uint8_t num_bytes ) { - llvm_value_t *output_value = nullptr; - auto current_spi = ir_builder->CreateLoad( ir_builder->getInt64Ty(), stack_ptr, false ); - current_spi->setAlignment( llvm::Align( 1 ) ); - - llvm_value_t *i64_zero = llvm::ConstantInt::get( *llvm_ctx, llvm::APInt( 64, 0 ) ); - llvm_value_t *indices[ 2 ] = { i64_zero, current_spi }; - auto top_stack = ir_builder->CreateInBoundsGEP( virtual_stack, llvm::ArrayRef< llvm::Value * >( indices, 2 ) ); - - if ( num_bytes > 1 ) - { - auto casted_ptr = ir_builder->CreatePointerCast( - top_stack, llvm::PointerType::get( llvm::IntegerType::get( *llvm_ctx, num_bytes * 8 ), 0 ) ); - - output_value = ir_builder->CreateLoad( llvm::IntegerType::get( *llvm_ctx, num_bytes * 8 ), casted_ptr ); - } - else - output_value = ir_builder->CreateLoad( ir_builder->getInt8Ty(), top_stack ); - - static_cast< llvm::LoadInst * >( output_value )->setAlignment( llvm::Align( 1 ) ); - auto new_spi = ir_builder->CreateAdd( - current_spi, llvm::ConstantInt::get( llvm::IntegerType::get( *llvm_ctx, 64 ), num_bytes ) ); - - ir_builder->CreateStore( new_spi, stack_ptr )->setAlignment( llvm::Align( 1 ) ); - return output_value; + // mov rax, [rsp] + auto rsp_addr = ir_builder->CreateLoad( stack ); + auto rsp_cast_ptr = ir_builder->CreatePointerCast( + rsp_addr, llvm::PointerType::get( llvm::IntegerType::get( *llvm_ctx, num_bytes * 8 ), false ) ); + auto pop_val = ir_builder->CreateLoad( rsp_cast_ptr ); + + // add rsp, num_bytes + auto rsp_i64 = ir_builder->CreatePtrToInt( rsp_addr, ir_builder->getInt64Ty() ); + auto sub_rsp_val = ir_builder->CreateAdd( rsp_i64, ir_builder->getInt64( num_bytes ) ); + auto sub_rsp_val_ptr = + ir_builder->CreateIntToPtr( sub_rsp_val, llvm::PointerType::get( ir_builder->getInt8Ty(), 0ull ) ); + + ir_builder->CreateStore( sub_rsp_val_ptr, stack ); + return pop_val; } llvm_value_t *vmp_rtn_t::load_value( std::uint8_t byte_size, llvm_global_value_t *var ) @@ -116,13 +92,9 @@ namespace vm auto cast_ptr = ir_builder->CreatePointerCast( var, llvm::PointerType::get( llvm::IntegerType::get( *llvm_ctx, byte_size * 8 ), 0 ) ); - auto result = ir_builder->CreateLoad( llvm::IntegerType::get( *llvm_ctx, byte_size * 8 ), cast_ptr ); - result->setAlignment( llvm::Align( 1 ) ); - return result; + return ir_builder->CreateLoad( llvm::IntegerType::get( *llvm_ctx, byte_size * 8 ), cast_ptr ); } - auto result = ir_builder->CreateLoad( llvm::IntegerType::get( *llvm_ctx, byte_size * 8 ), var ); - result->setAlignment( llvm::Align( 1 ) ); - return result; + return ir_builder->CreateLoad( llvm::IntegerType::get( *llvm_ctx, byte_size * 8 ), var ); } llvm_value_t *vmp_rtn_t::load_value( std::uint8_t byte_size, llvm_alloca_inst_t *var ) @@ -132,14 +104,9 @@ namespace vm auto cast_ptr = ir_builder->CreatePointerCast( var, llvm::PointerType::get( llvm::IntegerType::get( *llvm_ctx, byte_size * 8 ), 0 ) ); - auto result = ir_builder->CreateLoad( llvm::IntegerType::get( *llvm_ctx, byte_size * 8 ), cast_ptr ); - result->setAlignment( llvm::Align( 1 ) ); - return result; + return ir_builder->CreateLoad( llvm::IntegerType::get( *llvm_ctx, byte_size * 8 ), cast_ptr ); } - - auto result = ir_builder->CreateLoad( llvm::IntegerType::get( *llvm_ctx, byte_size * 8 ), var ); - result->setAlignment( llvm::Align( 1 ) ); - return result; + return ir_builder->CreateLoad( llvm::IntegerType::get( *llvm_ctx, byte_size * 8 ), var ); } llvm_function_t *vmp_rtn_t::lift( void ) @@ -164,18 +131,6 @@ namespace vm return llvm_fptr; } - 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" ); - - // allocate stack pointer... - stack_ptr = ir_builder->CreateAlloca( llvm::IntegerType::get( *llvm_ctx, 64 ), nullptr, "sp" ); - ir_builder->CreateStore( llvm::ConstantInt::get( llvm::IntegerType::getInt64Ty( *llvm_ctx ), 1024 ), - stack_ptr ); - } - llvm_value_t *vmp_rtn_t::compute_sf( std::uint8_t byte_size, llvm_value_t *val ) { auto op_size = llvm::IntegerType::get( *llvm_ctx, byte_size * 8 );