#pragma once #include #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, vm::ctx_t *vm_ctx, std::uintptr_t rtn_begin, std::vector< vm::instrs::code_block_t > vmp2_code_blocks ); llvm::Function *lift( void ); llvm::LLVMContext *llvm_ctx; vm::ctx_t *vm_ctx; llvm::Module *llvm_module; std::uintptr_t rtn_begin; llvm::Function *llvm_fptr; std::shared_ptr< llvm::IRBuilder<> > ir_builder; llvm::AllocaInst *virtual_stack, *stack_ptr, *flags; std::map< ZydisRegister, llvm::GlobalVariable * > native_registers; std::vector< llvm::AllocaInst * > virtual_registers; std::vector< llvm::BasicBlock * > llvm_code_blocks; std::vector< vm::instrs::code_block_t > vmp2_code_blocks; void push( std::uint8_t byte_size, llvm::Value *input_val ); llvm::Value *pop( std::uint8_t byte_size ); llvm::Value *peek( std::uint8_t byte_size, std::uint8_t byte_offset = 0u ); llvm::Value *load_value( std::uint8_t byte_size, llvm::GlobalValue *global ); llvm::Value *load_value( std::uint8_t byte_size, llvm::AllocaInst *var ); private: void create_native_registers( void ); void create_virtual_registers( void ); void create_routine( void ); void create_virtual_stack( void ); void lift_vm_entry( void ); }; } // namespace vm