Merge branch '_xeroxz' into 'master'

i updated a bunch, too much to type lol

See merge request vmp2/vmdevirt!5
merge-requests/6/merge
_xeroxz 3 years ago
commit 1128607429

@ -1 +1 @@
Subproject commit c2319117a07d95794f54db970aa7f72e8726349a Subproject commit f06bf5f6b72b1d52a6156d6828675c77ceaee7e2

@ -30,7 +30,9 @@ namespace vm
std::function< void( vm::vmp_rtn_t *rtn, const vm::instrs::code_block_t &vm_code_block, 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 ) >; 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 addq, adddw, addw;
static lifter_callback_t sregq, sregdw; static lifter_callback_t sregq, sregdw;
static lifter_callback_t lregq, lregdw; static lifter_callback_t lregq, lregdw;
@ -50,6 +52,7 @@ namespace vm
{ vm::handler::LCONSTBZXW, &lconstbzxw }, { vm::handler::LCONSTBZXW, &lconstbzxw },
{ vm::handler::LCONSTBSXQ, &lconstbsxq }, { vm::handler::LCONSTBSXQ, &lconstbsxq },
{ vm::handler::LCONSTWSXDW, &lconstwsxdw }, { vm::handler::LCONSTWSXDW, &lconstwsxdw },
{ vm::handler::LCONSTBSXDW, &lconstbsxdw },
{ vm::handler::ADDQ, &addq }, { vm::handler::ADDQ, &addq },
{ vm::handler::ADDDW, &adddw }, { vm::handler::ADDDW, &adddw },
{ vm::handler::ADDW, &addw }, { vm::handler::ADDW, &addw },
@ -90,4 +93,4 @@ namespace vm
return true; return true;
} }
}; };
} // namespace vm } // namespace vm

@ -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 *virtual_stack, *stack_ptr, *flags; llvm_alloca_inst_t *flags, *stack;
vm::ctx_t *vm_ctx; vm::ctx_t *vm_ctx;
std::uintptr_t rtn_begin; 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 *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 );
}; };

@ -38,6 +38,12 @@ namespace vm
rtn->push( 4, llvm::ConstantInt::get( ir_builder->getInt32Ty(), vinstr.operand.imm.u ) ); 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 = lifters_t::lifter_callback_t lifters_t::lconstbzxw =
[ & ]( 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 ) {

@ -5,16 +5,8 @@ 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 current_spi = auto stack = ir_builder->CreateLoad( rtn->stack );
ir_builder->CreateLoad( llvm::IntegerType::get( *rtn->llvm_ctx, 64 ), rtn->stack_ptr, false ); auto stack_ptr = ir_builder->CreatePtrToInt( stack, ir_builder->getInt64Ty() );
rtn->push( 8, stack_ptr );
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 )->setAlignment( llvm::Align( 1 ) ); ir_builder->CreateStore( t1, vreg );
}; };
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 )->setAlignment( llvm::Align( 1 ) ); ir_builder->CreateStore( t1, vregdw );
}; };
} // namespace vm } // namespace vm

@ -5,4 +5,4 @@ namespace vm
lifters_t::lifter_callback_t lifters_t::vmexit = lifters_t::lifter_callback_t lifters_t::vmexit =
[ & ]( 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 ) { ir_builder->CreateRetVoid(); }; const vm::instrs::virt_instr_t &vinstr, llvm::IRBuilder<> *ir_builder ) { ir_builder->CreateRetVoid(); };
} }

@ -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 ); 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 );
} }

@ -13,14 +13,9 @@ 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" );
create_virtual_stack(); ir_builder->CreateStore( llvm_fptr->getArg( 0 ), 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 );
}
create_virtual_registers(); create_virtual_registers();
} }
@ -35,11 +30,10 @@ namespace vm
void vmp_rtn_t::create_routine( void ) void vmp_rtn_t::create_routine( void )
{ {
std::vector< llvm::Type * > arg_types; // function has no arguments and returns void... maybe change this in the future as i learn
for ( auto idx = 0u; idx < 21; ++idx ) // more and more LLVM...
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 ),
{ llvm::PointerType::getInt8PtrTy( *llvm_ctx ) }, false );
auto func_ty = llvm::FunctionType::get( llvm::Type::getVoidTy( *llvm_ctx ), arg_types, 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;
@ -47,7 +41,6 @@ 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...
@ -60,53 +53,36 @@ 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 )
{ {
auto spi = ir_builder->CreateLoad( ir_builder->getInt64Ty(), stack_ptr, false ); // sub rsp, num_bytes
spi->setAlignment( llvm::Align( 1 ) ); auto rsp_addr = ir_builder->CreateLoad( stack );
auto rsp_i64 = ir_builder->CreatePtrToInt( rsp_addr, ir_builder->getInt64Ty() );
auto new_spi = ir_builder->CreateSub( spi, llvm::ConstantInt::get( ir_builder->getInt64Ty(), num_bytes ) ); auto sub_rsp_val = ir_builder->CreateSub( rsp_i64, ir_builder->getInt64( num_bytes ) );
ir_builder->CreateStore( new_spi, stack_ptr )->setAlignment( llvm::Align( 1 ) ); ir_builder->CreateStore(
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 ) );
llvm_value_t *indices[ 2 ] = { i64_zero, new_spi }; // mov [rsp], val
auto stack_ptr = ir_builder->CreateInBoundsGEP( virtual_stack, llvm::ArrayRef< llvm_value_t * >( indices, 2 ) ); rsp_addr = ir_builder->CreateLoad( stack );
auto rsp_cast_ptr = ir_builder->CreatePointerCast(
if ( num_bytes > 1 ) rsp_addr, llvm::PointerType::get( llvm::IntegerType::get( *llvm_ctx, num_bytes * 8 ), false ) );
{ 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 )
{ {
llvm_value_t *output_value = nullptr; // mov rax, [rsp]
auto current_spi = ir_builder->CreateLoad( ir_builder->getInt64Ty(), stack_ptr, false ); auto rsp_addr = ir_builder->CreateLoad( stack );
current_spi->setAlignment( llvm::Align( 1 ) ); auto rsp_cast_ptr = ir_builder->CreatePointerCast(
rsp_addr, llvm::PointerType::get( llvm::IntegerType::get( *llvm_ctx, num_bytes * 8 ), false ) );
llvm_value_t *i64_zero = llvm::ConstantInt::get( *llvm_ctx, llvm::APInt( 64, 0 ) ); auto pop_val = ir_builder->CreateLoad( rsp_cast_ptr );
llvm_value_t *indices[ 2 ] = { i64_zero, current_spi };
auto top_stack = ir_builder->CreateInBoundsGEP( virtual_stack, llvm::ArrayRef< llvm::Value * >( indices, 2 ) ); // add rsp, num_bytes
auto rsp_i64 = ir_builder->CreatePtrToInt( rsp_addr, ir_builder->getInt64Ty() );
if ( num_bytes > 1 ) auto sub_rsp_val = ir_builder->CreateAdd( rsp_i64, ir_builder->getInt64( num_bytes ) );
{ auto sub_rsp_val_ptr =
auto casted_ptr = ir_builder->CreatePointerCast( ir_builder->CreateIntToPtr( sub_rsp_val, llvm::PointerType::get( ir_builder->getInt8Ty(), 0ull ) );
top_stack, llvm::PointerType::get( llvm::IntegerType::get( *llvm_ctx, num_bytes * 8 ), 0 ) );
ir_builder->CreateStore( sub_rsp_val_ptr, stack );
output_value = ir_builder->CreateLoad( llvm::IntegerType::get( *llvm_ctx, num_bytes * 8 ), casted_ptr ); return pop_val;
}
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 )
@ -116,13 +92,9 @@ 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 ) );
auto result = ir_builder->CreateLoad( llvm::IntegerType::get( *llvm_ctx, byte_size * 8 ), cast_ptr ); return ir_builder->CreateLoad( llvm::IntegerType::get( *llvm_ctx, byte_size * 8 ), cast_ptr );
result->setAlignment( llvm::Align( 1 ) );
return result;
} }
auto result = ir_builder->CreateLoad( llvm::IntegerType::get( *llvm_ctx, byte_size * 8 ), var ); return 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 )
@ -132,14 +104,9 @@ 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 ) );
auto result = ir_builder->CreateLoad( llvm::IntegerType::get( *llvm_ctx, byte_size * 8 ), cast_ptr ); return 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 )
@ -164,18 +131,6 @@ 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