|
|
|
@ -3,9 +3,10 @@
|
|
|
|
|
namespace vm
|
|
|
|
|
{
|
|
|
|
|
vmp_rtn_t::vmp_rtn_t( std::uintptr_t rtn_begin, std::vector< vm::instrs::code_block_t > vmp2_code_blocks,
|
|
|
|
|
std::shared_ptr< llvm::IRBuilder<> > &ir_builder, llvm::Module *llvm_module )
|
|
|
|
|
std::shared_ptr< llvm::IRBuilder<> > &ir_builder, llvm::Module *llvm_module,
|
|
|
|
|
vmp2::v4::file_header *vmp2_file )
|
|
|
|
|
: ir_builder( ir_builder ), vmp2_code_blocks( vmp2_code_blocks ), rtn_begin( rtn_begin ),
|
|
|
|
|
llvm_module( llvm_module )
|
|
|
|
|
llvm_module( llvm_module ), vmp2_file( vmp2_file )
|
|
|
|
|
{
|
|
|
|
|
create_routine();
|
|
|
|
|
// create virtual registers in the first code block...
|
|
|
|
@ -45,5 +46,53 @@ namespace vm
|
|
|
|
|
{ vmp2_code_block.vip_begin,
|
|
|
|
|
llvm::BasicBlock::Create( ir_builder->getContext(), blk_name.str().c_str(), llvm_fptr ) } );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
zydis_routine_t vm_enter;
|
|
|
|
|
auto vm_enter_addr = reinterpret_cast< std::uintptr_t >( vmp2_file ) + vmp2_file->module_offset +
|
|
|
|
|
( rtn_begin - vmp2_file->image_base );
|
|
|
|
|
|
|
|
|
|
vm::util::flatten( vm_enter, vm_enter_addr );
|
|
|
|
|
vm::util::deobfuscate( vm_enter );
|
|
|
|
|
|
|
|
|
|
std::string asm_str;
|
|
|
|
|
ZydisFormatter formatter;
|
|
|
|
|
ZydisFormatterInit( &formatter, ZYDIS_FORMATTER_STYLE_INTEL );
|
|
|
|
|
|
|
|
|
|
for ( const auto &instr_data : vm_enter )
|
|
|
|
|
{
|
|
|
|
|
if ( instr_data.instr.mnemonic == ZYDIS_MNEMONIC_PUSH )
|
|
|
|
|
{
|
|
|
|
|
if ( instr_data.instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY )
|
|
|
|
|
{
|
|
|
|
|
asm_str.append( "mov rax, 0x1000000000000000; push rax; mov rax, 0x1000000000000000; push rax; " );
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char buffer[ 256 ];
|
|
|
|
|
ZydisFormatterFormatInstruction( &formatter, &instr_data.instr, buffer, sizeof( buffer ), 0ull );
|
|
|
|
|
asm_str.append( buffer ).append( "; " );
|
|
|
|
|
}
|
|
|
|
|
else if ( instr_data.instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ )
|
|
|
|
|
{
|
|
|
|
|
asm_str.append( "pushfq; " );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rtn_name.str( "" );
|
|
|
|
|
asm_str.append( "mov rcx, rsp; sub rsp, 0xA00; " );
|
|
|
|
|
|
|
|
|
|
rtn_name << "vmenter_" << std::hex << rtn_begin;
|
|
|
|
|
auto entry_func = llvm::Function::Create( llvm::FunctionType::get( ir_builder->getVoidTy(), false ),
|
|
|
|
|
llvm::GlobalValue::LinkageTypes::ExternalLinkage,
|
|
|
|
|
rtn_name.str().c_str(), *llvm_module );
|
|
|
|
|
|
|
|
|
|
auto entry_block = llvm::BasicBlock::Create( ir_builder->getContext(), "", entry_func );
|
|
|
|
|
ir_builder->SetInsertPoint( entry_block );
|
|
|
|
|
|
|
|
|
|
auto entry_stub = llvm::InlineAsm::get( llvm::FunctionType::get( ir_builder->getVoidTy(), false ), asm_str, "",
|
|
|
|
|
false, false, llvm::InlineAsm::AD_Intel );
|
|
|
|
|
|
|
|
|
|
ir_builder->CreateCall( entry_stub );
|
|
|
|
|
ir_builder->CreateRetVoid();
|
|
|
|
|
}
|
|
|
|
|
} // namespace vm
|