added some source and a class for lifting...

colton
_xeroxz 3 years ago
parent 8841661c3b
commit 1bb5d7e399

@ -40,7 +40,16 @@ set(CMKR_TARGET vmdevirt)
set(vmdevirt_SOURCES "") set(vmdevirt_SOURCES "")
list(APPEND vmdevirt_SOURCES list(APPEND vmdevirt_SOURCES
"src/lifters/lconst.cpp"
"src/lifters/lreg.cpp"
"src/lifters/sreg.cpp"
"src/main.cpp" "src/main.cpp"
"src/vmp_rtn.cpp"
"src/lifters/lconst.cpp"
"src/lifters/lreg.cpp"
"src/lifters/sreg.cpp"
"include/vm_lifters.hpp"
"include/vmp_rtn.hpp"
) )
list(APPEND vmdevirt_SOURCES list(APPEND vmdevirt_SOURCES

@ -7,6 +7,7 @@ type = "executable"
sources = [ sources = [
"src/**.cpp", "src/**.cpp",
"src/lifters/**.cpp",
"include/**.hpp", "include/**.hpp",
] ]
include-directories = [ include-directories = [

Binary file not shown.

@ -0,0 +1,38 @@
#pragma once
#include <vmprofiler.hpp>
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/IRPrintingPasses.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/PassManager.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Verifier.h"
#include "llvm/Pass.h"
#include "llvm/Support/raw_ostream.h"
namespace vm
{
class vmp_rtn_t
{
public:
explicit vmp_rtn_t( llvm::LLVMContext *llvm_ctx, llvm::Module *llvm_module, std::uintptr_t rtn_begin,
std::vector< vm::instrs::code_block_t > vmp2_code_blocks );
llvm::Function *lift( void );
private:
llvm::LLVMContext *llvm_ctx;
llvm::Module *llvm_module;
std::uintptr_t rtn_begin;
std::shared_ptr< llvm::Function > llvm_fptr;
std::shared_ptr< llvm::IRBuilder<> > ir_builder;
std::vector< std::shared_ptr< llvm::BasicBlock > > llvm_code_blocks;
std::vector< vm::instrs::code_block_t > vmp2_code_blocks;
};
} // namespace vm

@ -1,5 +1,6 @@
#include <Windows.h> #include <Windows.h>
#include <cli-parser.hpp> #include <cli-parser.hpp>
#include <vmp_rtn.hpp>
#include <vmprofiler.hpp> #include <vmprofiler.hpp>
#include <xtils.hpp> #include <xtils.hpp>
@ -59,34 +60,23 @@ int main( int argc, const char *argv[] )
auto first_block = reinterpret_cast< vmp2::v3::code_block_t * >( reinterpret_cast< std::uintptr_t >( file_header ) + auto first_block = reinterpret_cast< vmp2::v3::code_block_t * >( reinterpret_cast< std::uintptr_t >( file_header ) +
file_header->code_block_offset ); file_header->code_block_offset );
std::vector< vm::instrs::code_block_t > vmp_code_blocks;
// convert code blocks back to vm::instrs::code_block_t form...
for ( auto [ code_block, code_block_num ] = std::tuple{ first_block, 0u }; for ( auto [ code_block, code_block_num ] = std::tuple{ first_block, 0u };
code_block_num < file_header->code_block_count; code_block_num < file_header->code_block_count;
code_block = reinterpret_cast< vmp2::v3::code_block_t * >( reinterpret_cast< std::uintptr_t >( code_block ) + code_block = reinterpret_cast< vmp2::v3::code_block_t * >( reinterpret_cast< std::uintptr_t >( code_block ) +
code_block->next_block_offset ), code_block->next_block_offset ),
++code_block_num ) ++code_block_num )
{ {
vm::instrs::code_block_t _code_block{ code_block->vip_begin, code_block->jcc };
std::for_each( code_block->vinstr, code_block->vinstr + code_block->vinstr_count,
[ & ]( const vm::instrs::virt_instr_t &vinstr ) { _code_block.vinstrs.push_back( vinstr ); } );
std::printf( "[code block #%d] begin = 0x%p, virtual instruction count = %d\n", code_block_num, vmp_code_blocks.push_back( _code_block );
ABS_TO_IMG( code_block->vip_begin, file_header->module_base, file_header->image_base ),
code_block->vinstr_count );
if ( code_block->jcc.has_jcc )
std::printf(
"\tcode block branches to 0x%p and 0x%p\n",
ABS_TO_IMG( code_block->jcc.block_addr[ 0 ], file_header->module_base, file_header->image_base ),
ABS_TO_IMG( code_block->jcc.block_addr[ 1 ], file_header->module_base, file_header->image_base ) );
} }
LLVMContext llvm_ctx; LLVMContext llvm_ctx;
Module llvm_module( "VMProtect 2 Static Devirtualizer", llvm_ctx ); Module llvm_module( "VMProtect 2 Static Devirtualizer", llvm_ctx );
IRBuilder<> ir_builder( llvm_ctx );
FunctionType *FT = FunctionType::get( Type::getVoidTy( llvm_ctx ), false );
Function *F = Function::Create( FT, Function::ExternalLinkage, "test_func", llvm_module );
F->setCallingConv( CallingConv::C );
auto basic_block = BasicBlock::Create( llvm_ctx, "test", F ); vm::vmp_rtn_t vmp_rtn( &llvm_ctx, &llvm_module, first_block->vip_begin, vmp_code_blocks );
ir_builder.SetInsertPoint( basic_block );
ir_builder.CreateRetVoid();
basic_block->print( outs() );
} }

@ -0,0 +1,28 @@
#include <vmp_rtn.hpp>
namespace vm
{
vmp_rtn_t::vmp_rtn_t( llvm::LLVMContext *llvm_ctx, llvm::Module *llvm_module, std::uintptr_t rtn_begin,
std::vector< vm::instrs::code_block_t > vmp2_code_blocks )
: llvm_ctx( llvm_ctx ), llvm_module( llvm_module ), rtn_begin( rtn_begin ), vmp2_code_blocks( vmp2_code_blocks )
{
// 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 ), false );
// convert the rtn_begin address to a hex string and prepend "rtn_" to it...
std::stringstream rtn_name;
rtn_name << "rtn_" << std::hex << rtn_begin;
const llvm::Twine rtn_twine( rtn_name.str() );
llvm_fptr = std::shared_ptr< llvm::Function >( llvm::Function::Create(
func_ty, llvm::GlobalValue::LinkageTypes::ExternalLinkage, rtn_twine, *llvm_module ) );
ir_builder = std::make_shared< llvm::IRBuilder<> >( *llvm_ctx );
}
llvm::Function *vmp_rtn_t::lift( void )
{
return {};
}
} // namespace vm
Loading…
Cancel
Save