reverted back to making a local stack, made alignment 1...

merge-requests/3/head
_xeroxz 3 years ago
parent 9ff8014de8
commit 77ae31b1b6

@ -54,6 +54,7 @@ list(APPEND vmdevirt_SOURCES
"src/lifters/shl.cpp" "src/lifters/shl.cpp"
"src/lifters/shr.cpp" "src/lifters/shr.cpp"
"src/lifters/sreg.cpp" "src/lifters/sreg.cpp"
"src/lifters/vmexit.cpp"
"src/main.cpp" "src/main.cpp"
"src/vmp_rtn.cpp" "src/vmp_rtn.cpp"
"include/vm_lifters.hpp" "include/vm_lifters.hpp"

@ -41,6 +41,7 @@ namespace vm
static lifter_callback_t shrq; static lifter_callback_t shrq;
static lifter_callback_t jmp; static lifter_callback_t jmp;
static lifter_callback_t lflagsq; static lifter_callback_t lflagsq;
static lifter_callback_t vmexit;
std::map< vm::handler::mnemonic_t, lifter_callback_t * > lifters = { { vm::handler::LCONSTQ, &lconstq }, std::map< vm::handler::mnemonic_t, lifter_callback_t * > lifters = { { vm::handler::LCONSTQ, &lconstq },
{ vm::handler::LCONSTDW, &lconstdw }, { vm::handler::LCONSTDW, &lconstdw },
@ -63,7 +64,8 @@ namespace vm
{ vm::handler::NANDQ, &nandq }, { vm::handler::NANDQ, &nandq },
{ vm::handler::NANDDW, &nanddw }, { vm::handler::NANDDW, &nanddw },
{ vm::handler::LFLAGSQ, &lflagsq }, { vm::handler::LFLAGSQ, &lflagsq },
{ vm::handler::JMP, &jmp } }; { vm::handler::JMP, &jmp },
{ vm::handler::VMEXIT, &vmexit } };
static vm::llvm_value_t *and_flags( vm::vmp_rtn_t *rtn, std::uint8_t byte_size, vm::llvm_value_t *result ); static vm::llvm_value_t *and_flags( vm::vmp_rtn_t *rtn, std::uint8_t byte_size, vm::llvm_value_t *result );
static vm::llvm_value_t *add_flags( vm::vmp_rtn_t *rtn, std::uint8_t byte_size, vm::llvm_value_t *lhs, static vm::llvm_value_t *add_flags( vm::vmp_rtn_t *rtn, std::uint8_t byte_size, vm::llvm_value_t *lhs,

@ -43,7 +43,7 @@ namespace vm
llvm_context_t *llvm_ctx; llvm_context_t *llvm_ctx;
llvm_module_t *llvm_module; llvm_module_t *llvm_module;
llvm_function_t *llvm_fptr; llvm_function_t *llvm_fptr;
llvm_alloca_inst_t *flags, *stack; llvm_alloca_inst_t *virtual_stack, *stack_ptr, *flags;
vm::ctx_t *vm_ctx; vm::ctx_t *vm_ctx;
std::uintptr_t rtn_begin; std::uintptr_t rtn_begin;
@ -65,6 +65,7 @@ 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 *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 ); llvm_value_t *sf, llvm_value_t *of );
void create_virtual_stack( void );
void create_virtual_registers( void ); void create_virtual_registers( void );
void create_routine( void ); void create_routine( void );
}; };

@ -5,8 +5,16 @@ namespace vm
lifters_t::lifter_callback_t lifters_t::pushvsp = lifters_t::lifter_callback_t lifters_t::pushvsp =
[ & ]( vm::vmp_rtn_t *rtn, const vm::instrs::code_block_t &vm_code_block, [ & ]( 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 ) { const vm::instrs::virt_instr_t &vinstr, llvm::IRBuilder<> *ir_builder ) {
auto sp = rtn->pop( 8 ); auto current_spi =
auto sp_ptr = ir_builder->CreateIntToPtr( sp, llvm::PointerType::get( ir_builder->getInt8Ty(), 0ull ) ); ir_builder->CreateLoad( llvm::IntegerType::get( *rtn->llvm_ctx, 64 ), rtn->stack_ptr, false );
ir_builder->CreateStore( sp_ptr, rtn->stack );
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 );
}; };
} }

@ -7,7 +7,7 @@ namespace vm
const vm::instrs::virt_instr_t &vinstr, llvm::IRBuilder<> *ir_builder ) { const vm::instrs::virt_instr_t &vinstr, llvm::IRBuilder<> *ir_builder ) {
auto t1 = rtn->pop( 8 ); auto t1 = rtn->pop( 8 );
auto vreg = rtn->virtual_registers[ vinstr.operand.imm.u ? vinstr.operand.imm.u / 8 : 0 ]; auto vreg = rtn->virtual_registers[ vinstr.operand.imm.u ? vinstr.operand.imm.u / 8 : 0 ];
ir_builder->CreateStore( t1, vreg ); ir_builder->CreateStore( t1, vreg )->setAlignment( llvm::Align( 1 ) );
}; };
lifters_t::lifter_callback_t lifters_t::sregdw = 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 vreg = rtn->virtual_registers[ vinstr.operand.imm.u ? vinstr.operand.imm.u / 8 : 0 ];
auto vregdw = ir_builder->CreatePointerCast( auto vregdw = ir_builder->CreatePointerCast(
vreg, llvm::PointerType::get( llvm::IntegerType::get( *rtn->llvm_ctx, 32 ), 0 ) ); vreg, llvm::PointerType::get( llvm::IntegerType::get( *rtn->llvm_ctx, 32 ), 0 ) );
ir_builder->CreateStore( t1, vregdw ); ir_builder->CreateStore( t1, vregdw )->setAlignment( llvm::Align( 1 ) );
}; };
} // namespace vm } // namespace vm

@ -13,9 +13,10 @@ namespace vm
ir_builder = std::make_shared< llvm_irbuilder_t >( *llvm_ctx ); ir_builder = std::make_shared< llvm_irbuilder_t >( *llvm_ctx );
ir_builder->SetInsertPoint( llvm_code_blocks[ 0 ].second ); ir_builder->SetInsertPoint( llvm_code_blocks[ 0 ].second );
flags = ir_builder->CreateAlloca( ir_builder->getInt64Ty(), nullptr, "flags" ); flags = ir_builder->CreateAlloca( ir_builder->getInt64Ty(), nullptr, "flags" );
stack = ir_builder->CreateAlloca( llvm::PointerType::get( ir_builder->getInt8Ty(), 0ull ), nullptr, "sp" );
ir_builder->CreateStore( llvm_fptr->getArg( 0 ), stack ); create_virtual_stack();
// TODO: copy arg1 (array) onto the local stack...
// ir_builder->CreateMemCpy(...
create_virtual_registers(); create_virtual_registers();
} }
@ -32,8 +33,9 @@ namespace vm
{ {
// function has no arguments and returns void... maybe change this in the future as i learn // function has no arguments and returns void... maybe change this in the future as i learn
// more and more LLVM... // more and more LLVM...
auto func_ty = llvm::FunctionType::get( llvm::Type::getVoidTy( *llvm_ctx ), auto func_ty =
{ llvm::PointerType::getInt8PtrTy( *llvm_ctx ) }, false ); llvm::FunctionType::get( llvm::Type::getVoidTy( *llvm_ctx ),
{ llvm::ArrayType::get( llvm::IntegerType::get( *llvm_ctx, 64 ), 21 ) }, false );
// convert the rtn_begin address to a hex string and prepend "rtn_" to it... // convert the rtn_begin address to a hex string and prepend "rtn_" to it...
std::stringstream rtn_name; std::stringstream rtn_name;
@ -41,6 +43,7 @@ namespace vm
llvm_fptr = llvm::Function::Create( func_ty, llvm::GlobalValue::LinkageTypes::ExternalLinkage, llvm_fptr = llvm::Function::Create( func_ty, llvm::GlobalValue::LinkageTypes::ExternalLinkage,
rtn_name.str().c_str(), *llvm_module ); rtn_name.str().c_str(), *llvm_module );
llvm_fptr->setCallingConv( llvm::CallingConv::X86_FastCall );
for ( const auto &vmp2_code_block : vmp2_code_blocks ) for ( const auto &vmp2_code_block : vmp2_code_blocks )
{ {
// create basic block name... block_xxxxxxxx format... // create basic block name... block_xxxxxxxx format...
@ -53,36 +56,53 @@ namespace vm
void vmp_rtn_t::push( std::uint8_t num_bytes, llvm_value_t *val ) void vmp_rtn_t::push( std::uint8_t num_bytes, llvm_value_t *val )
{ {
// sub rsp, num_bytes auto spi = ir_builder->CreateLoad( ir_builder->getInt64Ty(), stack_ptr, false );
auto rsp_addr = ir_builder->CreateLoad( stack ); spi->setAlignment( llvm::Align( 1 ) );
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 ) ); auto new_spi = ir_builder->CreateSub( spi, llvm::ConstantInt::get( ir_builder->getInt64Ty(), num_bytes ) );
ir_builder->CreateStore( ir_builder->CreateStore( new_spi, stack_ptr )->setAlignment( llvm::Align( 1 ) );
ir_builder->CreateIntToPtr( sub_rsp_val, llvm::PointerType::get( ir_builder->getInt8Ty(), 0ull ) ), stack );
auto *i64_zero = llvm::ConstantInt::get( *llvm_ctx, llvm::APInt( 64, 0 ) );
// mov [rsp], val llvm_value_t *indices[ 2 ] = { i64_zero, new_spi };
rsp_addr = ir_builder->CreateLoad( stack ); auto stack_ptr = ir_builder->CreateInBoundsGEP( virtual_stack, llvm::ArrayRef< llvm_value_t * >( indices, 2 ) );
auto rsp_cast_ptr = ir_builder->CreatePointerCast(
rsp_addr, llvm::PointerType::get( llvm::IntegerType::get( *llvm_ctx, num_bytes * 8 ), false ) ); if ( num_bytes > 1 )
ir_builder->CreateStore( val, rsp_cast_ptr ); {
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 ) );
} }
llvm_value_t *vmp_rtn_t::pop( std::uint8_t num_bytes ) llvm_value_t *vmp_rtn_t::pop( std::uint8_t num_bytes )
{ {
// mov rax, [rsp] llvm_value_t *output_value = nullptr;
auto rsp_addr = ir_builder->CreateLoad( stack ); auto current_spi = ir_builder->CreateLoad( ir_builder->getInt64Ty(), stack_ptr, false );
auto rsp_cast_ptr = ir_builder->CreatePointerCast( current_spi->setAlignment( llvm::Align( 1 ) );
rsp_addr, llvm::PointerType::get( llvm::IntegerType::get( *llvm_ctx, num_bytes * 8 ), false ) );
auto pop_val = ir_builder->CreateLoad( rsp_cast_ptr ); llvm_value_t *i64_zero = llvm::ConstantInt::get( *llvm_ctx, llvm::APInt( 64, 0 ) );
llvm_value_t *indices[ 2 ] = { i64_zero, current_spi };
// add rsp, num_bytes auto top_stack = ir_builder->CreateInBoundsGEP( virtual_stack, llvm::ArrayRef< llvm::Value * >( indices, 2 ) );
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 ) ); if ( num_bytes > 1 )
auto sub_rsp_val_ptr = {
ir_builder->CreateIntToPtr( sub_rsp_val, llvm::PointerType::get( ir_builder->getInt8Ty(), 0ull ) ); auto casted_ptr = ir_builder->CreatePointerCast(
top_stack, llvm::PointerType::get( llvm::IntegerType::get( *llvm_ctx, num_bytes * 8 ), 0 ) );
ir_builder->CreateStore( sub_rsp_val_ptr, stack );
return pop_val; 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;
} }
llvm_value_t *vmp_rtn_t::load_value( std::uint8_t byte_size, llvm_global_value_t *var ) llvm_value_t *vmp_rtn_t::load_value( std::uint8_t byte_size, llvm_global_value_t *var )
@ -92,9 +112,13 @@ namespace vm
auto cast_ptr = ir_builder->CreatePointerCast( auto cast_ptr = ir_builder->CreatePointerCast(
var, llvm::PointerType::get( llvm::IntegerType::get( *llvm_ctx, byte_size * 8 ), 0 ) ); var, llvm::PointerType::get( llvm::IntegerType::get( *llvm_ctx, byte_size * 8 ), 0 ) );
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 ), cast_ptr );
result->setAlignment( llvm::Align( 1 ) );
return result;
} }
return ir_builder->CreateLoad( llvm::IntegerType::get( *llvm_ctx, byte_size * 8 ), var ); auto result = ir_builder->CreateLoad( llvm::IntegerType::get( *llvm_ctx, byte_size * 8 ), var );
result->setAlignment( llvm::Align( 1 ) );
return result;
} }
llvm_value_t *vmp_rtn_t::load_value( std::uint8_t byte_size, llvm_alloca_inst_t *var ) llvm_value_t *vmp_rtn_t::load_value( std::uint8_t byte_size, llvm_alloca_inst_t *var )
@ -104,9 +128,14 @@ namespace vm
auto cast_ptr = ir_builder->CreatePointerCast( auto cast_ptr = ir_builder->CreatePointerCast(
var, llvm::PointerType::get( llvm::IntegerType::get( *llvm_ctx, byte_size * 8 ), 0 ) ); var, llvm::PointerType::get( llvm::IntegerType::get( *llvm_ctx, byte_size * 8 ), 0 ) );
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 ), cast_ptr );
result->setAlignment( llvm::Align( 1 ) );
return result;
} }
return ir_builder->CreateLoad( llvm::IntegerType::get( *llvm_ctx, byte_size * 8 ), var );
auto result = ir_builder->CreateLoad( llvm::IntegerType::get( *llvm_ctx, byte_size * 8 ), var );
result->setAlignment( llvm::Align( 1 ) );
return result;
} }
llvm_function_t *vmp_rtn_t::lift( void ) llvm_function_t *vmp_rtn_t::lift( void )
@ -131,6 +160,18 @@ namespace vm
return llvm_fptr; 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 ) 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 ); auto op_size = llvm::IntegerType::get( *llvm_ctx, byte_size * 8 );

Loading…
Cancel
Save