added more lifters, added flags var, need to add code to update flags...

merge-requests/1/merge
_xeroxz 3 years ago
parent 7acee04ccd
commit 332f9e4d2e

@ -24,16 +24,25 @@ namespace vmp2::lifters
extern lifter_callback_t lconstq;
extern lifter_callback_t lconstdwsxq;
extern lifter_callback_t lconstwsxq;
extern lifter_callback_t pushvsp;
extern lifter_callback_t addq;
extern lifter_callback_t adddw;
extern lifter_callback_t addw;
extern lifter_callback_t sregq;
extern lifter_callback_t lregq;
extern lifter_callback_t readq;
inline std::map< vm::handler::mnemonic_t, lifter_callback_t * > lifters = {
{ vm::handler::LCONSTQ, &lconstq }, { vm::handler::LCONSTDWSXQ, &lconstdwsxq },
{ vm::handler::ADDQ, &addq }, { vm::handler::PUSHVSP, &pushvsp },
{ vm::handler::SREGQ, &sregq }, { vm::handler::LREGQ, &lregq } };
{ vm::handler::LCONSTQ, &lconstq }, { vm::handler::LCONSTDWSXQ, &lconstdwsxq },
{ vm::handler::LCONSTWSXQ, &lconstwsxq }, { vm::handler::ADDQ, &addq },
{ vm::handler::ADDDW, &adddw }, { vm::handler::ADDW, &addw },
{ vm::handler::PUSHVSP, &pushvsp }, { vm::handler::SREGQ, &sregq },
{ vm::handler::LREGQ, &lregq }, { vm::handler::READQ, &readq } };
inline bool lift( 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 )

@ -30,7 +30,7 @@ namespace vm
std::uintptr_t rtn_begin;
llvm::Function *llvm_fptr;
std::shared_ptr< llvm::IRBuilder<> > ir_builder;
llvm::AllocaInst *virtual_stack, *stack_ptr;
llvm::AllocaInst *virtual_stack, *stack_ptr, *flags;
std::map< ZydisRegister, llvm::GlobalVariable * > native_registers;
std::vector< llvm::AllocaInst * > virtual_registers;

@ -7,11 +7,44 @@ namespace vmp2::lifters
auto t1 = rtn->pop( 8 );
auto t2 = rtn->pop( 8 );
auto t3 = ir_builder->CreateAdd( t1, t2 );
rtn->push( 8, t1 );
rtn->push( 8, t3 );
// TODO: compute and update RFLAGS...
rtn->push( 8, rtn->load_value( 8, rtn->native_registers[ ZYDIS_REGISTER_RFLAGS ] ) );
// do the updating here on rtn->flags before we push it...
//
//
rtn->push( 8, rtn->load_value( 8, rtn->flags ) );
};
lifter_callback_t adddw = [ & ]( 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 t3 = ir_builder->CreateAdd( t1, t2 );
rtn->push( 4, t3 );
// TODO: compute and update RFLAGS...
// do the updating here on rtn->flags before we push it...
//
//
rtn->push( 8, rtn->load_value( 8, rtn->flags ) );
};
lifter_callback_t addw = [ & ]( 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( 2 );
auto t2 = rtn->pop( 2 );
auto t3 = ir_builder->CreateAdd( t1, t2 );
rtn->push( 2, t3 );
// TODO: compute and update RFLAGS...
// do the updating here on rtn->flags before we push it...
//
//
rtn->push( 8, rtn->load_value( 8, rtn->flags ) );
};
}
} // namespace vmp2::lifters

@ -11,4 +11,9 @@ namespace vmp2::lifters
const vm::instrs::virt_instr_t &vinstr, llvm::IRBuilder<> *ir_builder ) {
rtn->push( 8, llvm::ConstantInt::get( ir_builder->getInt64Ty(), vinstr.operand.imm.u ) );
};
lifter_callback_t lconstwsxq = [ & ]( 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( 8, llvm::ConstantInt::get( ir_builder->getInt64Ty(), vinstr.operand.imm.u ) );
};
} // namespace vmp2::lifters

@ -0,0 +1,12 @@
#include <vm_lifters.hpp>
namespace vmp2::lifters
{
lifter_callback_t readq = [ & ]( 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( 8 );
auto t2 = ir_builder->CreateIntToPtr( t1, llvm::PointerType::get( ir_builder->getInt64Ty(), 0ull ) );
auto t3 = ir_builder->CreateLoad( ir_builder->getInt64Ty(), t2 );
rtn->push( 8, t3 );
};
}

@ -9,6 +9,6 @@ namespace vmp2::lifters
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 );
ir_builder->CreateStore( t1, vreg )->setAlignment( llvm::Align( 8 ) );
};
} // namespace vmp2::lifters

@ -111,6 +111,7 @@ namespace vm
llvm_module->getOrInsertGlobal( "rflags", ir_builder->getInt64Ty() );
native_registers[ ZYDIS_REGISTER_RFLAGS ] = llvm_module->getGlobalVariable( "rflags" );
flags = ir_builder->CreateAlloca( ir_builder->getInt64Ty(), nullptr, "flags" );
}
void vmp_rtn_t::create_virtual_registers( void )
@ -147,11 +148,11 @@ namespace vm
void vmp_rtn_t::push( std::uint8_t byte_size, llvm::Value *input_value )
{
// Load the current stack index into a temporary variable
auto current_stack_index = ir_builder->CreateLoad( llvm::IntegerType::get( *llvm_ctx, 64 ), stack_ptr, false );
auto current_stack_index = ir_builder->CreateLoad( ir_builder->getInt64Ty(), stack_ptr, false );
// Subtract the input value size from the current stack index
auto new_stack_index = ir_builder->CreateSub(
current_stack_index, llvm::ConstantInt::get( llvm::IntegerType::get( *llvm_ctx, 64 ), byte_size ) );
auto new_stack_index =
ir_builder->CreateSub( current_stack_index, llvm::ConstantInt::get( ir_builder->getInt64Ty(), byte_size ) );
// Store the newly calculated stack index into VSP
ir_builder->CreateStore( new_stack_index, stack_ptr );
@ -178,67 +179,56 @@ namespace vm
llvm::Value *vmp_rtn_t::pop( std::uint8_t byte_size )
{
// Load the current stack index into a temporary variable
auto current_stack_index = ir_builder->CreateLoad( llvm::IntegerType::get( *llvm_ctx, 64 ), stack_ptr, false );
llvm::Value *output_value = nullptr;
auto current_spi = ir_builder->CreateLoad( ir_builder->getInt64Ty(), stack_ptr, false );
// Get a pointer to the top byte of the stack
llvm::Value *i64_zero = llvm::ConstantInt::get( *llvm_ctx, llvm::APInt( 64, 0 ) );
llvm::Value *indices[ 2 ] = { i64_zero, current_stack_index };
auto stack_ptr = ir_builder->CreateInBoundsGEP( virtual_stack, llvm::ArrayRef< llvm::Value * >( indices, 2 ) );
llvm::Value *indices[ 2 ] = { i64_zero, current_spi };
auto top_stack = ir_builder->CreateInBoundsGEP( virtual_stack, llvm::ArrayRef< llvm::Value * >( indices, 2 ) );
// Read the value at the top of the stack
llvm::Value *output_value = nullptr;
if ( byte_size == 1 )
{
output_value = ir_builder->CreateLoad( llvm::IntegerType::get( *llvm_ctx, 8 ), stack_ptr );
}
else
if ( byte_size > 1 )
{
// Cast the current stack pointer so the stack item width matches the width of the output value
auto casted_ptr = ir_builder->CreatePointerCast(
stack_ptr, llvm::PointerType::get( llvm::IntegerType::get( *llvm_ctx, byte_size * 8 ), 0 ) );
top_stack, llvm::PointerType::get( llvm::IntegerType::get( *llvm_ctx, byte_size * 8 ), 0 ) );
output_value = ir_builder->CreateLoad( llvm::IntegerType::get( *llvm_ctx, byte_size * 8 ), casted_ptr );
}
else
output_value = ir_builder->CreateLoad( ir_builder->getInt8Ty(), top_stack );
// Subtract the input value size from the current stack index
auto new_stack_index = ir_builder->CreateAdd(
current_stack_index, llvm::ConstantInt::get( llvm::IntegerType::get( *llvm_ctx, 64 ), byte_size ) );
current_spi, llvm::ConstantInt::get( llvm::IntegerType::get( *llvm_ctx, 64 ), byte_size ) );
// Store the newly calculated stack index into VSP
ir_builder->CreateStore( new_stack_index, this->stack_ptr );
ir_builder->CreateStore( new_stack_index, stack_ptr );
return output_value;
}
llvm::Value *vmp_rtn_t::peek( std::uint8_t byte_size, std::uint8_t byte_offset )
{
// Load the current stack index into a temporary variable
auto current_stack_index = ir_builder->CreateLoad( llvm::IntegerType::get( *llvm_ctx, 64 ), stack_ptr, false );
auto current_spi = ir_builder->CreateLoad( llvm::IntegerType::get( *llvm_ctx, 64 ), stack_ptr, false );
if ( byte_offset )
{
auto t1 = ir_builder->CreateAdd(
current_stack_index, llvm::ConstantInt::get( llvm::IntegerType::get( *llvm_ctx, 64 ), byte_offset ) );
current_spi, llvm::ConstantInt::get( llvm::IntegerType::get( *llvm_ctx, 64 ), byte_offset ) );
current_stack_index = ir_builder->CreateLoad( llvm::IntegerType::get( *llvm_ctx, 64 ), t1, false );
current_spi = ir_builder->CreateLoad( llvm::IntegerType::get( *llvm_ctx, 64 ), t1, false );
}
// Get a pointer to the top byte of the stack + byte_offset (if any)
llvm::Value *i64_zero = llvm::ConstantInt::get( *llvm_ctx, llvm::APInt( 64, 0 ) );
llvm::Value *indices[ 2 ] = { i64_zero, current_stack_index };
auto stack_ptr = ir_builder->CreateInBoundsGEP( virtual_stack, llvm::ArrayRef< llvm::Value * >( indices, 2 ) );
llvm::Value *indices[ 2 ] = { i64_zero, current_spi };
auto top_stack = ir_builder->CreateInBoundsGEP( virtual_stack, llvm::ArrayRef< llvm::Value * >( indices, 2 ) );
if ( byte_size != 1 )
if ( byte_size > 1 )
{
auto casted_ptr = ir_builder->CreatePointerCast(
stack_ptr, llvm::PointerType::get( llvm::IntegerType::get( *llvm_ctx, byte_size * 8 ), 0 ) );
top_stack, llvm::PointerType::get( llvm::IntegerType::get( *llvm_ctx, byte_size * 8 ), 0 ) );
return ir_builder->CreateLoad( llvm::IntegerType::get( *llvm_ctx, byte_size * 8 ), casted_ptr );
}
else
{
return ir_builder->CreateLoad( llvm::IntegerType::get( *llvm_ctx, byte_size * 8 ), stack_ptr );
return ir_builder->CreateLoad( llvm::IntegerType::get( *llvm_ctx, byte_size * 8 ), top_stack );
}
}

Loading…
Cancel
Save