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,
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
} // namespace vm

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

@ -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 ) {

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

@ -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

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

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

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

Loading…
Cancel
Save