From 4fe8c63f4914012b380882235c974ea28603f284 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Sun, 29 Aug 2021 15:49:55 -0700 Subject: [PATCH 01/12] added more lifters... updated vmprofiler dep... --- CMakeLists.txt | 1 + dependencies/vmprofiler | 2 +- include/vm_lifters.hpp | 8 ++++++-- src/lifters/imul.cpp | 22 ++++++++++++++++++++++ src/lifters/jmp.cpp | 18 +++++++++++++++--- src/lifters/mul.cpp | 6 ++++++ src/lifters/read.cpp | 18 ++++++++++++++---- src/lifters/write.cpp | 9 +++++++++ 8 files changed, 74 insertions(+), 10 deletions(-) create mode 100644 src/lifters/imul.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index ac51295..fd8c7af 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,6 +44,7 @@ list(APPEND vmdevirt_SOURCES "src/devirt_utils.cpp" "src/lifters/add.cpp" "src/lifters/div.cpp" + "src/lifters/imul.cpp" "src/lifters/jmp.cpp" "src/lifters/lconst.cpp" "src/lifters/lflags.cpp" diff --git a/dependencies/vmprofiler b/dependencies/vmprofiler index 7b1f815..1b6875d 160000 --- a/dependencies/vmprofiler +++ b/dependencies/vmprofiler @@ -1 +1 @@ -Subproject commit 7b1f815a73096ac33f41133b63d991019622de49 +Subproject commit 1b6875d18825529907289bc87990fed5d99e7f96 diff --git a/include/vm_lifters.hpp b/include/vm_lifters.hpp index cb6dc90..241fb08 100644 --- a/include/vm_lifters.hpp +++ b/include/vm_lifters.hpp @@ -35,10 +35,11 @@ namespace vm static lifter_callback_t sregq, sregdw, sregb; static lifter_callback_t lregq, lregdw; + static lifter_callback_t imulq; static lifter_callback_t pushvsp; static lifter_callback_t popvsp; - static lifter_callback_t writeq; - static lifter_callback_t readq, readdw; + static lifter_callback_t writeq, writedw; + static lifter_callback_t readq, readdw, readb; static lifter_callback_t nandq, nanddw, nandb; static lifter_callback_t shrq; static lifter_callback_t jmp; @@ -57,6 +58,7 @@ namespace vm { vm::handler::ADDDW, &adddw }, { vm::handler::ADDW, &addw }, { vm::handler::SHRQ, &shrq }, + { vm::handler::IMULQ, &imulq }, { vm::handler::PUSHVSP, &pushvsp }, { vm::handler::POPVSP, &popvsp }, { vm::handler::SREGQ, &sregq }, @@ -66,7 +68,9 @@ namespace vm { vm::handler::LREGDW, &lregdw }, { vm::handler::READQ, &readq }, { vm::handler::READDW, &readdw }, + { vm::handler::READB, &readb }, { vm::handler::WRITEQ, &writeq }, + { vm::handler::WRITEDW, &writedw }, { vm::handler::NANDQ, &nandq }, { vm::handler::NANDDW, &nanddw }, { vm::handler::NANDB, &nandb }, diff --git a/src/lifters/imul.cpp b/src/lifters/imul.cpp new file mode 100644 index 0000000..ec13813 --- /dev/null +++ b/src/lifters/imul.cpp @@ -0,0 +1,22 @@ +#include + +// https://lists.llvm.org/pipermail/llvm-dev/2014-July/074685.html +// credit to James Courtier-Dutton for asking this question in 2014... +namespace vm +{ + lifters_t::lifter_callback_t lifters_t::imulq = + [ & ]( vm::devirt_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 = rtn->pop( 8 ); + auto t3 = ir_builder->CreateMul( t1, t2 ); + auto t4 = ir_builder->CreateAShr( t3, llvm::APInt( 64, 32 ) ); + auto t5 = ir_builder->CreateAnd( t3, 0xFFFFFFFF00000000 ); + rtn->push( 8, t4 ); + rtn->push( 8, t5 ); + + // TODO: compute flags for IMULQ + auto &vmp_rtn = rtn->vmp_rtns.back(); + rtn->push( 8, rtn->load_value( 8, vmp_rtn->flags ) ); + }; +} \ No newline at end of file diff --git a/src/lifters/jmp.cpp b/src/lifters/jmp.cpp index 43464ad..ba9325e 100644 --- a/src/lifters/jmp.cpp +++ b/src/lifters/jmp.cpp @@ -9,7 +9,9 @@ namespace vm " has_jcc = false... debug time!\n" ); auto &vmp_rtn = rtn->vmp_rtns.back(); - if ( vm_code_block.jcc.type == vm::instrs::jcc_type::branching ) + switch ( vm_code_block.jcc.type ) + { + case vm::instrs::jcc_type::branching: { auto rva = rtn->pop( 8 ); auto b1 = vm_code_block.jcc.block_addr[ 0 ] & std::numeric_limits< std::uint32_t >::max(); @@ -38,8 +40,9 @@ namespace vm "[!] fatal error... unable to locate basic block for branching...\n" ); ir_builder->CreateCondBr( cmp, bb1->second, bb2->second ); + break; } - else + case vm::instrs::jcc_type::absolute: { auto rva = rtn->pop( 8 ); auto bb_data = @@ -52,6 +55,15 @@ namespace vm "[!] fatal error... unable to locate basic block...\n" ); ir_builder->CreateBr( bb_data->second ); + break; + } + case vm::instrs::jcc_type::switch_case: + { + // TODO: add switch case support here... + break; + } + default: + break; } }; -} \ No newline at end of file +} // namespace vm \ No newline at end of file diff --git a/src/lifters/mul.cpp b/src/lifters/mul.cpp index e69de29..7fa5903 100644 --- a/src/lifters/mul.cpp +++ b/src/lifters/mul.cpp @@ -0,0 +1,6 @@ +#include + +namespace vm +{ + +} \ No newline at end of file diff --git a/src/lifters/read.cpp b/src/lifters/read.cpp index b92f53d..7dbea1e 100644 --- a/src/lifters/read.cpp +++ b/src/lifters/read.cpp @@ -3,8 +3,8 @@ namespace vm { lifters_t::lifter_callback_t lifters_t::readq = - [ & ]( vm::devirt_t *rtn, const vm::instrs::code_block_t &vm_code_block, - const vm::instrs::virt_instr_t &vinstr, llvm::IRBuilder<> *ir_builder ) { + [ & ]( vm::devirt_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 ); @@ -12,11 +12,21 @@ namespace vm }; lifters_t::lifter_callback_t lifters_t::readdw = - [ & ]( vm::devirt_t *rtn, const vm::instrs::code_block_t &vm_code_block, - const vm::instrs::virt_instr_t &vinstr, llvm::IRBuilder<> *ir_builder ) { + [ & ]( vm::devirt_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->getInt32Ty(), 0ull ) ); auto t3 = ir_builder->CreateLoad( ir_builder->getInt32Ty(), t2 ); rtn->push( 4, t3 ); }; + + lifters_t::lifter_callback_t lifters_t::readb = + [ & ]( vm::devirt_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->getInt8Ty(), 0ull ) ); + auto t3 = ir_builder->CreateLoad( ir_builder->getInt8Ty(), t2 ); + auto t4 = ir_builder->CreateIntCast( t3, ir_builder->getInt16Ty(), false ); + rtn->push( 2, t4 ); + }; } // namespace vm \ No newline at end of file diff --git a/src/lifters/write.cpp b/src/lifters/write.cpp index d2e00f7..037b878 100644 --- a/src/lifters/write.cpp +++ b/src/lifters/write.cpp @@ -10,4 +10,13 @@ namespace vm auto t3 = ir_builder->CreateIntToPtr( t1, llvm::PointerType::get( ir_builder->getInt64Ty(), 0ull ) ); ir_builder->CreateStore( t2, t3 ); }; + + lifters_t::lifter_callback_t lifters_t::writedw = + [ & ]( vm::devirt_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 = rtn->pop( 4 ); + auto t3 = ir_builder->CreateIntToPtr( t1, llvm::PointerType::get( ir_builder->getInt32Ty(), 0ull ) ); + ir_builder->CreateStore( t2, t3 ); + }; } // namespace vm \ No newline at end of file From 93402767a98d8c75875b551cc6192a1c54c7c2fa Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Sun, 29 Aug 2021 20:16:35 -0700 Subject: [PATCH 02/12] added more lifters... --- CMakeLists.txt | 1 + include/vm_lifters.hpp | 15 ++++++++++----- src/lifters/read.cpp | 9 +++++++++ src/lifters/readcr8.cpp | 26 ++++++++++++++++++++++++++ src/lifters/shl.cpp | 19 +++++++++++++++++++ src/lifters/shr.cpp | 27 ++++++++++++++++++++------- 6 files changed, 85 insertions(+), 12 deletions(-) create mode 100644 src/lifters/readcr8.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index fd8c7af..ddd557c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -54,6 +54,7 @@ list(APPEND vmdevirt_SOURCES "src/lifters/popvsp.cpp" "src/lifters/pushvsp.cpp" "src/lifters/read.cpp" + "src/lifters/readcr8.cpp" "src/lifters/sflags.cpp" "src/lifters/shl.cpp" "src/lifters/shr.cpp" diff --git a/include/vm_lifters.hpp b/include/vm_lifters.hpp index 241fb08..9b81957 100644 --- a/include/vm_lifters.hpp +++ b/include/vm_lifters.hpp @@ -34,17 +34,18 @@ namespace vm static lifter_callback_t addq, adddw, addw; static lifter_callback_t sregq, sregdw, sregb; static lifter_callback_t lregq, lregdw; - static lifter_callback_t imulq; static lifter_callback_t pushvsp; static lifter_callback_t popvsp; static lifter_callback_t writeq, writedw; - static lifter_callback_t readq, readdw, readb; + static lifter_callback_t readq, readdw, readw, readb; static lifter_callback_t nandq, nanddw, nandb; - static lifter_callback_t shrq; + static lifter_callback_t shrq, shrdw; + static lifter_callback_t shlq; static lifter_callback_t jmp; static lifter_callback_t lflagsq; static lifter_callback_t vmexit; + static lifter_callback_t readcr8; std::map< vm::handler::mnemonic_t, lifter_callback_t * > lifters = { { vm::handler::LCONSTQ, &lconstq }, { vm::handler::LCONSTDW, &lconstdw }, @@ -58,9 +59,11 @@ namespace vm { vm::handler::ADDDW, &adddw }, { vm::handler::ADDW, &addw }, { vm::handler::SHRQ, &shrq }, + { vm::handler::SHRDW, &shrdw }, + { vm::handler::SHLQ, &shlq }, { vm::handler::IMULQ, &imulq }, - { vm::handler::PUSHVSP, &pushvsp }, - { vm::handler::POPVSP, &popvsp }, + { vm::handler::PUSHVSPQ, &pushvsp }, + { vm::handler::POPVSPQ, &popvsp }, { vm::handler::SREGQ, &sregq }, { vm::handler::SREGDW, &sregdw }, { vm::handler::SREGB, &sregb }, @@ -68,6 +71,7 @@ namespace vm { vm::handler::LREGDW, &lregdw }, { vm::handler::READQ, &readq }, { vm::handler::READDW, &readdw }, + { vm::handler::READW, &readw }, { vm::handler::READB, &readb }, { vm::handler::WRITEQ, &writeq }, { vm::handler::WRITEDW, &writedw }, @@ -75,6 +79,7 @@ namespace vm { vm::handler::NANDDW, &nanddw }, { vm::handler::NANDB, &nandb }, { vm::handler::LFLAGSQ, &lflagsq }, + { vm::handler::READCR8, &readcr8 }, { vm::handler::JMP, &jmp }, { vm::handler::VMEXIT, &vmexit } }; diff --git a/src/lifters/read.cpp b/src/lifters/read.cpp index 7dbea1e..6bf602a 100644 --- a/src/lifters/read.cpp +++ b/src/lifters/read.cpp @@ -20,6 +20,15 @@ namespace vm rtn->push( 4, t3 ); }; + lifters_t::lifter_callback_t lifters_t::readw = + [ & ]( vm::devirt_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->getInt16Ty(), 0ull ) ); + auto t3 = ir_builder->CreateLoad( ir_builder->getInt16Ty(), t2 ); + rtn->push( 2, t3 ); + }; + lifters_t::lifter_callback_t lifters_t::readb = [ & ]( vm::devirt_t *rtn, const vm::instrs::code_block_t &vm_code_block, const vm::instrs::virt_instr_t &vinstr, llvm::IRBuilder<> *ir_builder ) { diff --git a/src/lifters/readcr8.cpp b/src/lifters/readcr8.cpp new file mode 100644 index 0000000..a69063b --- /dev/null +++ b/src/lifters/readcr8.cpp @@ -0,0 +1,26 @@ +#include + +namespace vm +{ + lifters_t::lifter_callback_t lifters_t::readcr8 = + [ & ]( vm::devirt_t *rtn, const vm::instrs::code_block_t &vm_code_block, const vm::instrs::virt_instr_t &vinstr, + llvm::IRBuilder<> *ir_builder ) { + llvm::Function *readcr8_intrin = nullptr; + if ( !( readcr8_intrin = rtn->llvm_module->getFunction( "readcr8" ) ) ) + { + readcr8_intrin = llvm::Function::Create( llvm::FunctionType::get( ir_builder->getInt64Ty(), false ), + llvm::GlobalValue::LinkageTypes::ExternalLinkage ); + + auto entry_block = llvm::BasicBlock::Create( ir_builder->getContext(), "", readcr8_intrin ); + auto ib = ir_builder->GetInsertBlock(); + ir_builder->SetInsertPoint( entry_block ); + auto intrin = llvm::InlineAsm::get( llvm::FunctionType::get( ir_builder->getVoidTy(), false ), + "mov rax, cr8; ret", "", false, false, llvm::InlineAsm::AD_Intel ); + ir_builder->CreateCall( intrin ); + ir_builder->CreateRetVoid(); // TODO: dont return VOID here... + ir_builder->SetInsertPoint( ib ); + } + auto t1 = ir_builder->CreateCall( readcr8_intrin ); + rtn->push( 8, t1 ); + }; +} \ No newline at end of file diff --git a/src/lifters/shl.cpp b/src/lifters/shl.cpp index e69de29..60ce8f5 100644 --- a/src/lifters/shl.cpp +++ b/src/lifters/shl.cpp @@ -0,0 +1,19 @@ +#include + +namespace vm +{ + lifters_t::lifter_callback_t lifters_t::shlq = + [ & ]( vm::devirt_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 = rtn->pop( 2 ); + auto t3 = ir_builder->CreateIntCast( t2, llvm::IntegerType::get( *rtn->llvm_ctx, 64 ), false ); + auto t4 = ir_builder->CreateShl( t1, t3 ); + + auto &vmp_rtn = rtn->vmp_rtns.back(); + // TODO: update rflags... + + rtn->push( 8, t4 ); + rtn->push( 8, rtn->load_value( 8, vmp_rtn->flags ) ); + }; +} \ No newline at end of file diff --git a/src/lifters/shr.cpp b/src/lifters/shr.cpp index 03a74f6..32800ff 100644 --- a/src/lifters/shr.cpp +++ b/src/lifters/shr.cpp @@ -2,7 +2,6 @@ namespace vm { - // our undefined behavior is that we don't model cases where the shift count is zero... llvm::Value *lifters_t::shr_flags( vm::devirt_t *rtn, std::uint8_t byte_size, llvm::Value *lhs, llvm::Value *rhs, llvm::Value *result ) { @@ -10,19 +9,18 @@ namespace vm auto msb = rtn->ir_builder->CreateLShr( lhs, ( byte_size * 8 ) - 1 ); auto cf = rtn->ir_builder->CreateZExt( msb, llvm::IntegerType::get( *rtn->llvm_ctx, 64 ) ); - auto of = - rtn->sf( byte_size, lhs ); // we reuse the compute_sf helper since the flag expression is the same + auto of = rtn->sf( byte_size, lhs ); auto sf = rtn->sf( byte_size, result ); auto zf = rtn->zf( byte_size, result ); auto pf = llvm::ConstantInt::get( llvm::IntegerType::get( *rtn->llvm_ctx, 64 ), 0 ); - return rtn->flags( cf, pf, llvm::ConstantInt::get( llvm::IntegerType::get( *rtn->llvm_ctx, 64 ), 0 ), - zf, sf, of ); + return rtn->flags( cf, pf, llvm::ConstantInt::get( llvm::IntegerType::get( *rtn->llvm_ctx, 64 ), 0 ), zf, sf, + of ); } lifters_t::lifter_callback_t lifters_t::shrq = - [ & ]( vm::devirt_t *rtn, const vm::instrs::code_block_t &vm_code_block, - const vm::instrs::virt_instr_t &vinstr, llvm::IRBuilder<> *ir_builder ) { + [ & ]( vm::devirt_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 = rtn->pop( 2 ); auto t3 = ir_builder->CreateIntCast( t2, llvm::IntegerType::get( *rtn->llvm_ctx, 64 ), false ); @@ -34,4 +32,19 @@ namespace vm rtn->push( 8, t4 ); rtn->push( 8, rtn->load_value( 8, vmp_rtn->flags ) ); }; + + lifters_t::lifter_callback_t lifters_t::shrdw = + [ & ]( vm::devirt_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( 2 ); + auto t3 = ir_builder->CreateIntCast( t2, llvm::IntegerType::get( *rtn->llvm_ctx, 32 ), false ); + auto t4 = ir_builder->CreateLShr( t1, t3 ); + + auto &vmp_rtn = rtn->vmp_rtns.back(); + auto flags = lifters_t::shr_flags( rtn, 4, t1, t3, t4 ); + ir_builder->CreateStore( flags, vmp_rtn->flags ); + rtn->push( 4, t4 ); + rtn->push( 8, rtn->load_value( 8, vmp_rtn->flags ) ); + }; } // namespace vm \ No newline at end of file From ea078d98477419179498a7fe038c2fc5597875e9 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Tue, 31 Aug 2021 19:04:21 -0700 Subject: [PATCH 03/12] added more lifters --- CMakeLists.txt | 1 + include/vm_lifters.hpp | 14 ++++++++++---- src/lifters/add.cpp | 34 ++++++++++++++++++++++++++-------- src/lifters/imul.cpp | 23 ++++++++++++++++++++++- src/lifters/nand.cpp | 18 ++++++++++++++++++ src/lifters/readcr8.cpp | 12 ++++++++---- src/lifters/readgs.cpp | 32 ++++++++++++++++++++++++++++++++ src/lifters/write.cpp | 10 ++++++++++ 8 files changed, 127 insertions(+), 17 deletions(-) create mode 100644 src/lifters/readgs.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index ddd557c..8216de0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,6 +55,7 @@ list(APPEND vmdevirt_SOURCES "src/lifters/pushvsp.cpp" "src/lifters/read.cpp" "src/lifters/readcr8.cpp" + "src/lifters/readgs.cpp" "src/lifters/sflags.cpp" "src/lifters/shl.cpp" "src/lifters/shr.cpp" diff --git a/include/vm_lifters.hpp b/include/vm_lifters.hpp index 9b81957..e829453 100644 --- a/include/vm_lifters.hpp +++ b/include/vm_lifters.hpp @@ -31,21 +31,22 @@ namespace vm static lifter_callback_t lconstq, lconstdwsxq, lconstwsxq, lconstbzxw, lconstbsxq, lconstwsxdw, lconstdw, lconstbsxdw; - static lifter_callback_t addq, adddw, addw; + static lifter_callback_t addq, adddw, addw, addb; static lifter_callback_t sregq, sregdw, sregb; static lifter_callback_t lregq, lregdw; - static lifter_callback_t imulq; + static lifter_callback_t imulq, imuldw; static lifter_callback_t pushvsp; static lifter_callback_t popvsp; - static lifter_callback_t writeq, writedw; + static lifter_callback_t writeq, writedw, writeb; static lifter_callback_t readq, readdw, readw, readb; - static lifter_callback_t nandq, nanddw, nandb; + static lifter_callback_t nandq, nanddw, nandw, nandb; static lifter_callback_t shrq, shrdw; static lifter_callback_t shlq; static lifter_callback_t jmp; static lifter_callback_t lflagsq; static lifter_callback_t vmexit; static lifter_callback_t readcr8; + static lifter_callback_t readgsq; std::map< vm::handler::mnemonic_t, lifter_callback_t * > lifters = { { vm::handler::LCONSTQ, &lconstq }, { vm::handler::LCONSTDW, &lconstdw }, @@ -58,10 +59,12 @@ namespace vm { vm::handler::ADDQ, &addq }, { vm::handler::ADDDW, &adddw }, { vm::handler::ADDW, &addw }, + { vm::handler::ADDB, &addb }, { vm::handler::SHRQ, &shrq }, { vm::handler::SHRDW, &shrdw }, { vm::handler::SHLQ, &shlq }, { vm::handler::IMULQ, &imulq }, + { vm::handler::IMULDW, &imuldw }, { vm::handler::PUSHVSPQ, &pushvsp }, { vm::handler::POPVSPQ, &popvsp }, { vm::handler::SREGQ, &sregq }, @@ -75,11 +78,14 @@ namespace vm { vm::handler::READB, &readb }, { vm::handler::WRITEQ, &writeq }, { vm::handler::WRITEDW, &writedw }, + { vm::handler::WRITEB, &writeb }, { vm::handler::NANDQ, &nandq }, { vm::handler::NANDDW, &nanddw }, + { vm::handler::NANDW, &nandw }, { vm::handler::NANDB, &nandb }, { vm::handler::LFLAGSQ, &lflagsq }, { vm::handler::READCR8, &readcr8 }, + { vm::handler::READGSQ, &readgsq }, { vm::handler::JMP, &jmp }, { vm::handler::VMEXIT, &vmexit } }; diff --git a/src/lifters/add.cpp b/src/lifters/add.cpp index 9060c1d..0da5cd3 100644 --- a/src/lifters/add.cpp +++ b/src/lifters/add.cpp @@ -29,15 +29,15 @@ namespace vm auto pf = llvm::ConstantInt::get( llvm::IntegerType::get( *rtn->llvm_ctx, 64 ), 0 ); // TODO make clean PF bit computation... - auto flags_calc = rtn->flags( - cf, pf, llvm::ConstantInt::get( llvm::IntegerType::get( *rtn->llvm_ctx, 64 ), 0 ), zf, sf, of ); + auto flags_calc = + rtn->flags( cf, pf, llvm::ConstantInt::get( llvm::IntegerType::get( *rtn->llvm_ctx, 64 ), 0 ), zf, sf, of ); return flags_calc; } lifters_t::lifter_callback_t lifters_t::addq = - [ & ]( vm::devirt_t *rtn, const vm::instrs::code_block_t &vm_code_block, - const vm::instrs::virt_instr_t &vinstr, llvm::IRBuilder<> *ir_builder ) { + [ & ]( vm::devirt_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 = rtn->pop( 8 ); auto t3 = ir_builder->CreateAdd( t1, t2 ); @@ -50,8 +50,8 @@ namespace vm }; lifters_t::lifter_callback_t lifters_t::adddw = - [ & ]( vm::devirt_t *rtn, const vm::instrs::code_block_t &vm_code_block, - const vm::instrs::virt_instr_t &vinstr, llvm::IRBuilder<> *ir_builder ) { + [ & ]( vm::devirt_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 ); @@ -64,8 +64,8 @@ namespace vm }; lifters_t::lifter_callback_t lifters_t::addw = - [ & ]( vm::devirt_t *rtn, const vm::instrs::code_block_t &vm_code_block, - const vm::instrs::virt_instr_t &vinstr, llvm::IRBuilder<> *ir_builder ) { + [ & ]( vm::devirt_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 ); @@ -77,4 +77,22 @@ namespace vm rtn->push( 8, rtn->load_value( 8, vmp_rtn->flags ) ); }; + lifters_t::lifter_callback_t lifters_t::addb = + [ & ]( vm::devirt_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->CreateIntCast( t1, ir_builder->getInt8Ty(), false ); + auto t4 = ir_builder->CreateIntCast( t2, ir_builder->getInt8Ty(), false ); + + auto t5 = ir_builder->CreateAdd( t3, t4 ); + rtn->push( 2, ir_builder->CreateIntCast( t5, ir_builder->getInt16Ty(), false ) ); + + auto &vmp_rtn = rtn->vmp_rtns.back(); + auto flags = lifters_t::add_flags( rtn, 1, t3, t4 ); + ir_builder->CreateStore( flags, vmp_rtn->flags ); + rtn->push( 8, rtn->load_value( 8, vmp_rtn->flags ) ); + }; + } // namespace vm \ No newline at end of file diff --git a/src/lifters/imul.cpp b/src/lifters/imul.cpp index ec13813..74d60c2 100644 --- a/src/lifters/imul.cpp +++ b/src/lifters/imul.cpp @@ -19,4 +19,25 @@ namespace vm auto &vmp_rtn = rtn->vmp_rtns.back(); rtn->push( 8, rtn->load_value( 8, vmp_rtn->flags ) ); }; -} \ No newline at end of file + + lifters_t::lifter_callback_t lifters_t::imuldw = + [ & ]( vm::devirt_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->CreateIntCast( t1, ir_builder->getInt64Ty(), false ); + auto t4 = ir_builder->CreateIntCast( t2, ir_builder->getInt64Ty(), false ); + + auto t5 = ir_builder->CreateMul( t3, t4 ); + auto t6 = ir_builder->CreateAShr( t5, llvm::APInt( 64, 32 ) ); + auto t7 = ir_builder->CreateAnd( t5, 0xFFFFFFFF00000000 ); + + rtn->push( 8, t6 ); + rtn->push( 8, t7 ); + + // TODO: compute flags for IMULQ + auto &vmp_rtn = rtn->vmp_rtns.back(); + rtn->push( 8, rtn->load_value( 8, vmp_rtn->flags ) ); + }; +} // namespace vm \ No newline at end of file diff --git a/src/lifters/nand.cpp b/src/lifters/nand.cpp index 58d1a6f..5640872 100644 --- a/src/lifters/nand.cpp +++ b/src/lifters/nand.cpp @@ -51,6 +51,24 @@ namespace vm rtn->push( 8, rtn->load_value( 8, vmp_rtn->flags ) ); }; + lifters_t::lifter_callback_t lifters_t::nandw = + [ & ]( vm::devirt_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 t1_not = ir_builder->CreateNot( t1 ); + auto t2_not = ir_builder->CreateNot( t2 ); + + auto t3 = ir_builder->CreateAnd( { t1_not, t2_not } ); + rtn->push( 2, t3 ); + + auto &vmp_rtn = rtn->vmp_rtns.back(); + auto flags = and_flags( rtn, 2, t3 ); + ir_builder->CreateStore( flags, vmp_rtn->flags ); + rtn->push( 8, rtn->load_value( 8, vmp_rtn->flags ) ); + }; + lifters_t::lifter_callback_t lifters_t::nandb = [ & ]( vm::devirt_t *rtn, const vm::instrs::code_block_t &vm_code_block, const vm::instrs::virt_instr_t &vinstr, llvm::IRBuilder<> *ir_builder ) { diff --git a/src/lifters/readcr8.cpp b/src/lifters/readcr8.cpp index a69063b..ac82132 100644 --- a/src/lifters/readcr8.cpp +++ b/src/lifters/readcr8.cpp @@ -9,15 +9,19 @@ namespace vm if ( !( readcr8_intrin = rtn->llvm_module->getFunction( "readcr8" ) ) ) { readcr8_intrin = llvm::Function::Create( llvm::FunctionType::get( ir_builder->getInt64Ty(), false ), - llvm::GlobalValue::LinkageTypes::ExternalLinkage ); + llvm::GlobalValue::LinkageTypes::ExternalLinkage, "readcr8", + *rtn->llvm_module ); auto entry_block = llvm::BasicBlock::Create( ir_builder->getContext(), "", readcr8_intrin ); auto ib = ir_builder->GetInsertBlock(); ir_builder->SetInsertPoint( entry_block ); - auto intrin = llvm::InlineAsm::get( llvm::FunctionType::get( ir_builder->getVoidTy(), false ), - "mov rax, cr8; ret", "", false, false, llvm::InlineAsm::AD_Intel ); + + std::string asm_str( "mov rax, cr8; ret" ); + auto intrin = llvm::InlineAsm::get( llvm::FunctionType::get( ir_builder->getVoidTy(), false ), asm_str, + "", false, false, llvm::InlineAsm::AD_Intel ); + ir_builder->CreateCall( intrin ); - ir_builder->CreateRetVoid(); // TODO: dont return VOID here... + ir_builder->CreateRet( llvm::ConstantInt::get( *rtn->llvm_ctx, llvm::APInt( 64, 0 ) ) ); ir_builder->SetInsertPoint( ib ); } auto t1 = ir_builder->CreateCall( readcr8_intrin ); diff --git a/src/lifters/readgs.cpp b/src/lifters/readgs.cpp new file mode 100644 index 0000000..ada1ea5 --- /dev/null +++ b/src/lifters/readgs.cpp @@ -0,0 +1,32 @@ +#include + +namespace vm +{ + lifters_t::lifter_callback_t lifters_t::readgsq = + [ & ]( vm::devirt_t *rtn, const vm::instrs::code_block_t &vm_code_block, const vm::instrs::virt_instr_t &vinstr, + llvm::IRBuilder<> *ir_builder ) { + llvm::Function *readgs_intrin = nullptr; + if ( !( readgs_intrin = rtn->llvm_module->getFunction( "readgs" ) ) ) + { + readgs_intrin = llvm::Function::Create( + llvm::FunctionType::get( ir_builder->getInt64Ty(), { ir_builder->getInt64Ty() }, false ), + llvm::GlobalValue::LinkageTypes::ExternalLinkage, "readgs", *rtn->llvm_module ); + + auto entry_block = llvm::BasicBlock::Create( ir_builder->getContext(), "", readgs_intrin ); + auto ib = ir_builder->GetInsertBlock(); + ir_builder->SetInsertPoint( entry_block ); + + std::string asm_str( "mov rax, gs:[rcx]; ret" ); + auto intrin = llvm::InlineAsm::get( llvm::FunctionType::get( ir_builder->getVoidTy(), false ), asm_str, + "", false, false, llvm::InlineAsm::AD_Intel ); + + ir_builder->CreateCall( intrin ); + ir_builder->CreateRet( llvm::ConstantInt::get( *rtn->llvm_ctx, llvm::APInt( 64, 0 ) ) ); + ir_builder->SetInsertPoint( ib ); + } + + auto t1 = rtn->pop( 8 ); + auto t2 = ir_builder->CreateCall( readgs_intrin, { t1 } ); + rtn->push( 8, t2 ); + }; +} // namespace vm \ No newline at end of file diff --git a/src/lifters/write.cpp b/src/lifters/write.cpp index 037b878..89e61de 100644 --- a/src/lifters/write.cpp +++ b/src/lifters/write.cpp @@ -19,4 +19,14 @@ namespace vm auto t3 = ir_builder->CreateIntToPtr( t1, llvm::PointerType::get( ir_builder->getInt32Ty(), 0ull ) ); ir_builder->CreateStore( t2, t3 ); }; + + lifters_t::lifter_callback_t lifters_t::writeb = + [ & ]( vm::devirt_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 = rtn->pop( 2 ); + auto t3 = ir_builder->CreateIntToPtr( t1, llvm::PointerType::get( ir_builder->getInt8Ty(), 0ull ) ); + auto t4 = ir_builder->CreateIntCast( t2, ir_builder->getInt8Ty(), false ); + ir_builder->CreateStore( t4, t3 ); + }; } // namespace vm \ No newline at end of file From 65ae6ebe0280ae677e6903d114ba7eff3a807f0b Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Tue, 31 Aug 2021 19:46:36 -0700 Subject: [PATCH 04/12] added more lifters :yawn: --- include/vm_lifters.hpp | 9 ++++++--- src/lifters/shl.cpp | 17 ++++++++++++++++- src/lifters/shld.cpp | 0 src/lifters/sreg.cpp | 11 +++++++++++ src/lifters/write.cpp | 9 +++++++++ 5 files changed, 42 insertions(+), 4 deletions(-) create mode 100644 src/lifters/shld.cpp diff --git a/include/vm_lifters.hpp b/include/vm_lifters.hpp index e829453..b8cd77c 100644 --- a/include/vm_lifters.hpp +++ b/include/vm_lifters.hpp @@ -32,16 +32,16 @@ namespace vm lconstbsxdw; static lifter_callback_t addq, adddw, addw, addb; - static lifter_callback_t sregq, sregdw, sregb; + static lifter_callback_t sregq, sregdw, sregw, sregb; static lifter_callback_t lregq, lregdw; static lifter_callback_t imulq, imuldw; static lifter_callback_t pushvsp; static lifter_callback_t popvsp; - static lifter_callback_t writeq, writedw, writeb; + static lifter_callback_t writeq, writedw, writew, writeb; static lifter_callback_t readq, readdw, readw, readb; static lifter_callback_t nandq, nanddw, nandw, nandb; static lifter_callback_t shrq, shrdw; - static lifter_callback_t shlq; + static lifter_callback_t shlq, shldw; static lifter_callback_t jmp; static lifter_callback_t lflagsq; static lifter_callback_t vmexit; @@ -63,12 +63,14 @@ namespace vm { vm::handler::SHRQ, &shrq }, { vm::handler::SHRDW, &shrdw }, { vm::handler::SHLQ, &shlq }, + { vm::handler::SHLDW, &shldw }, { vm::handler::IMULQ, &imulq }, { vm::handler::IMULDW, &imuldw }, { vm::handler::PUSHVSPQ, &pushvsp }, { vm::handler::POPVSPQ, &popvsp }, { vm::handler::SREGQ, &sregq }, { vm::handler::SREGDW, &sregdw }, + { vm::handler::SREGW, &sregw }, { vm::handler::SREGB, &sregb }, { vm::handler::LREGQ, &lregq }, { vm::handler::LREGDW, &lregdw }, @@ -78,6 +80,7 @@ namespace vm { vm::handler::READB, &readb }, { vm::handler::WRITEQ, &writeq }, { vm::handler::WRITEDW, &writedw }, + { vm::handler::WRITEW, &writew }, { vm::handler::WRITEB, &writeb }, { vm::handler::NANDQ, &nandq }, { vm::handler::NANDDW, &nanddw }, diff --git a/src/lifters/shl.cpp b/src/lifters/shl.cpp index 60ce8f5..fa34a94 100644 --- a/src/lifters/shl.cpp +++ b/src/lifters/shl.cpp @@ -16,4 +16,19 @@ namespace vm rtn->push( 8, t4 ); rtn->push( 8, rtn->load_value( 8, vmp_rtn->flags ) ); }; -} \ No newline at end of file + + lifters_t::lifter_callback_t lifters_t::shldw = + [ & ]( vm::devirt_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( 2 ); + auto t3 = ir_builder->CreateIntCast( t2, llvm::IntegerType::get( *rtn->llvm_ctx, 32 ), false ); + auto t4 = ir_builder->CreateShl( t1, t3 ); + + auto &vmp_rtn = rtn->vmp_rtns.back(); + // TODO: update rflags... + + rtn->push( 4, t4 ); + rtn->push( 8, rtn->load_value( 8, vmp_rtn->flags ) ); + }; +} // namespace vm \ No newline at end of file diff --git a/src/lifters/shld.cpp b/src/lifters/shld.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/lifters/sreg.cpp b/src/lifters/sreg.cpp index 97e6c9e..46e1502 100644 --- a/src/lifters/sreg.cpp +++ b/src/lifters/sreg.cpp @@ -20,6 +20,17 @@ namespace vm ir_builder->CreateStore( ir_builder->CreateIntCast( t1, ir_builder->getInt64Ty(), false ), vreg ); }; + lifters_t::lifter_callback_t lifters_t::sregw = + [ & ]( vm::devirt_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 &vmp_rtn = rtn->vmp_rtns.back(); + auto vreg = vmp_rtn->virtual_registers[ vinstr.operand.imm.u ? vinstr.operand.imm.u / 8 : 0 ]; + ir_builder->CreateStore( + ir_builder->CreateIntCast( t1, ir_builder->getInt16Ty(), false ), + ir_builder->CreatePointerCast( vreg, llvm::PointerType::get( ir_builder->getInt16Ty(), 0ull ) ) ); + }; + lifters_t::lifter_callback_t lifters_t::sregb = [ & ]( vm::devirt_t *rtn, const vm::instrs::code_block_t &vm_code_block, const vm::instrs::virt_instr_t &vinstr, llvm::IRBuilder<> *ir_builder ) { diff --git a/src/lifters/write.cpp b/src/lifters/write.cpp index 89e61de..9097ff8 100644 --- a/src/lifters/write.cpp +++ b/src/lifters/write.cpp @@ -20,6 +20,15 @@ namespace vm ir_builder->CreateStore( t2, t3 ); }; + lifters_t::lifter_callback_t lifters_t::writew = + [ & ]( vm::devirt_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 = rtn->pop( 2 ); + auto t3 = ir_builder->CreateIntToPtr( t1, llvm::PointerType::get( ir_builder->getInt16Ty(), 0ull ) ); + ir_builder->CreateStore( t2, t3 ); + }; + lifters_t::lifter_callback_t lifters_t::writeb = [ & ]( vm::devirt_t *rtn, const vm::instrs::code_block_t &vm_code_block, const vm::instrs::virt_instr_t &vinstr, llvm::IRBuilder<> *ir_builder ) { From 014c1a08cd3bb85dabcd1052b08b75efec7551aa Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Tue, 31 Aug 2021 21:17:32 -0700 Subject: [PATCH 05/12] added more lifters... --- CMakeLists.txt | 2 ++ include/vm_lifters.hpp | 10 ++++++++-- src/lifters/lconst.cpp | 6 ++++++ src/lifters/shld.cpp | 21 +++++++++++++++++++++ src/lifters/shr.cpp | 15 +++++++++++++++ src/lifters/shrd.cpp | 21 +++++++++++++++++++++ 6 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 src/lifters/shrd.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 8216de0..40cb428 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -58,7 +58,9 @@ list(APPEND vmdevirt_SOURCES "src/lifters/readgs.cpp" "src/lifters/sflags.cpp" "src/lifters/shl.cpp" + "src/lifters/shld.cpp" "src/lifters/shr.cpp" + "src/lifters/shrd.cpp" "src/lifters/sreg.cpp" "src/lifters/vmexit.cpp" "src/lifters/write.cpp" diff --git a/include/vm_lifters.hpp b/include/vm_lifters.hpp index b8cd77c..7e37a80 100644 --- a/include/vm_lifters.hpp +++ b/include/vm_lifters.hpp @@ -29,7 +29,7 @@ namespace vm const vm::instrs::virt_instr_t &vinstr, llvm::IRBuilder<> *ir_builder ) >; static lifter_callback_t lconstq, lconstdwsxq, lconstwsxq, lconstbzxw, lconstbsxq, lconstwsxdw, lconstdw, - lconstbsxdw; + lconstw, lconstbsxdw; static lifter_callback_t addq, adddw, addw, addb; static lifter_callback_t sregq, sregdw, sregw, sregb; @@ -40,8 +40,10 @@ namespace vm static lifter_callback_t writeq, writedw, writew, writeb; static lifter_callback_t readq, readdw, readw, readb; static lifter_callback_t nandq, nanddw, nandw, nandb; - static lifter_callback_t shrq, shrdw; + static lifter_callback_t shrq, shrdw, shrw; static lifter_callback_t shlq, shldw; + static lifter_callback_t shlddw; + static lifter_callback_t shrdq; static lifter_callback_t jmp; static lifter_callback_t lflagsq; static lifter_callback_t vmexit; @@ -50,6 +52,7 @@ namespace vm std::map< vm::handler::mnemonic_t, lifter_callback_t * > lifters = { { vm::handler::LCONSTQ, &lconstq }, { vm::handler::LCONSTDW, &lconstdw }, + { vm::handler::LCONSTW, &lconstw }, { vm::handler::LCONSTDWSXQ, &lconstdwsxq }, { vm::handler::LCONSTWSXQ, &lconstwsxq }, { vm::handler::LCONSTBZXW, &lconstbzxw }, @@ -62,8 +65,11 @@ namespace vm { vm::handler::ADDB, &addb }, { vm::handler::SHRQ, &shrq }, { vm::handler::SHRDW, &shrdw }, + { vm::handler::SHRW, &shrw }, { vm::handler::SHLQ, &shlq }, { vm::handler::SHLDW, &shldw }, + { vm::handler::SHLDDW, &shlddw }, + { vm::handler::SHRDQ, &shrdq }, { vm::handler::IMULQ, &imulq }, { vm::handler::IMULDW, &imuldw }, { vm::handler::PUSHVSPQ, &pushvsp }, diff --git a/src/lifters/lconst.cpp b/src/lifters/lconst.cpp index 1e7d32e..4d5e81e 100644 --- a/src/lifters/lconst.cpp +++ b/src/lifters/lconst.cpp @@ -32,6 +32,12 @@ namespace vm rtn->push( 4, llvm::ConstantInt::get( ir_builder->getInt32Ty(), vinstr.operand.imm.u ) ); }; + lifters_t::lifter_callback_t lifters_t::lconstw = + [ & ]( vm::devirt_t *rtn, const vm::instrs::code_block_t &vm_code_block, const vm::instrs::virt_instr_t &vinstr, + llvm::IRBuilder<> *ir_builder ) { + rtn->push( 2, llvm::ConstantInt::get( ir_builder->getInt16Ty(), vinstr.operand.imm.u ) ); + }; + lifters_t::lifter_callback_t lifters_t::lconstwsxdw = [ & ]( vm::devirt_t *rtn, const vm::instrs::code_block_t &vm_code_block, const vm::instrs::virt_instr_t &vinstr, llvm::IRBuilder<> *ir_builder ) { diff --git a/src/lifters/shld.cpp b/src/lifters/shld.cpp index e69de29..f1b1567 100644 --- a/src/lifters/shld.cpp +++ b/src/lifters/shld.cpp @@ -0,0 +1,21 @@ +#include + +namespace vm +{ + lifters_t::lifter_callback_t lifters_t::shlddw = + [ & ]( vm::devirt_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 = rtn->pop( 2 ); + + // TODO: this is wrong - replace with more logic! + auto t4 = ir_builder->CreateShl( t1, ir_builder->CreateIntCast( t3, ir_builder->getInt32Ty(), false ) ); + + rtn->push( 4, t4 ); + auto &vmp_rtn = rtn->vmp_rtns.back(); + + // TODO: update rflags... + rtn->push( 8, rtn->load_value( 8, vmp_rtn->flags ) ); + }; +} \ No newline at end of file diff --git a/src/lifters/shr.cpp b/src/lifters/shr.cpp index 32800ff..d5d8a22 100644 --- a/src/lifters/shr.cpp +++ b/src/lifters/shr.cpp @@ -47,4 +47,19 @@ namespace vm rtn->push( 4, t4 ); rtn->push( 8, rtn->load_value( 8, vmp_rtn->flags ) ); }; + + lifters_t::lifter_callback_t lifters_t::shrw = + [ & ]( vm::devirt_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->CreateIntCast( t2, llvm::IntegerType::get( *rtn->llvm_ctx, 16 ), false ); + auto t4 = ir_builder->CreateLShr( t1, t3 ); + + auto &vmp_rtn = rtn->vmp_rtns.back(); + auto flags = lifters_t::shr_flags( rtn, 2, t1, t3, t4 ); + ir_builder->CreateStore( flags, vmp_rtn->flags ); + rtn->push( 2, t4 ); + rtn->push( 8, rtn->load_value( 8, vmp_rtn->flags ) ); + }; } // namespace vm \ No newline at end of file diff --git a/src/lifters/shrd.cpp b/src/lifters/shrd.cpp new file mode 100644 index 0000000..758ee04 --- /dev/null +++ b/src/lifters/shrd.cpp @@ -0,0 +1,21 @@ +#include + +namespace vm +{ + lifters_t::lifter_callback_t lifters_t::shrdq = + [ & ]( vm::devirt_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 = rtn->pop( 8 ); + auto t3 = rtn->pop( 2 ); + + // TODO: this is wrong - replace with more logic! + auto t4 = ir_builder->CreateLShr( t1, ir_builder->CreateIntCast( t3, ir_builder->getInt64Ty(), false ) ); + + rtn->push( 8, t4 ); + auto &vmp_rtn = rtn->vmp_rtns.back(); + + // TODO: update rflags... + rtn->push( 8, rtn->load_value( 8, vmp_rtn->flags ) ); + }; +} \ No newline at end of file From d2da38cad1547afa3a227040999fbd5bf9710622 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Tue, 31 Aug 2021 22:08:09 -0700 Subject: [PATCH 06/12] added more lifters... --- include/vm_lifters.hpp | 4 ++++ src/lifters/div.cpp | 19 +++++++++++++++++++ src/lifters/imul.cpp | 2 ++ src/lifters/mul.cpp | 16 ++++++++++++++++ src/main.cpp | 5 +++++ 5 files changed, 46 insertions(+) diff --git a/include/vm_lifters.hpp b/include/vm_lifters.hpp index 7e37a80..835d2e1 100644 --- a/include/vm_lifters.hpp +++ b/include/vm_lifters.hpp @@ -35,6 +35,7 @@ namespace vm static lifter_callback_t sregq, sregdw, sregw, sregb; static lifter_callback_t lregq, lregdw; static lifter_callback_t imulq, imuldw; + static lifter_callback_t mulq; static lifter_callback_t pushvsp; static lifter_callback_t popvsp; static lifter_callback_t writeq, writedw, writew, writeb; @@ -49,6 +50,7 @@ namespace vm static lifter_callback_t vmexit; static lifter_callback_t readcr8; static lifter_callback_t readgsq; + static lifter_callback_t divdw; std::map< vm::handler::mnemonic_t, lifter_callback_t * > lifters = { { vm::handler::LCONSTQ, &lconstq }, { vm::handler::LCONSTDW, &lconstdw }, @@ -59,6 +61,7 @@ namespace vm { vm::handler::LCONSTBSXQ, &lconstbsxq }, { vm::handler::LCONSTWSXDW, &lconstwsxdw }, { vm::handler::LCONSTBSXDW, &lconstbsxdw }, + { vm::handler::DIVDW, &divdw }, { vm::handler::ADDQ, &addq }, { vm::handler::ADDDW, &adddw }, { vm::handler::ADDW, &addw }, @@ -72,6 +75,7 @@ namespace vm { vm::handler::SHRDQ, &shrdq }, { vm::handler::IMULQ, &imulq }, { vm::handler::IMULDW, &imuldw }, + { vm::handler::MULQ, &mulq }, { vm::handler::PUSHVSPQ, &pushvsp }, { vm::handler::POPVSPQ, &popvsp }, { vm::handler::SREGQ, &sregq }, diff --git a/src/lifters/div.cpp b/src/lifters/div.cpp index e69de29..72cf65f 100644 --- a/src/lifters/div.cpp +++ b/src/lifters/div.cpp @@ -0,0 +1,19 @@ +#include + +namespace vm +{ + lifters_t::lifter_callback_t lifters_t::divdw = + [ & ]( vm::devirt_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 = rtn->pop( 4 ); + ir_builder->CreateUDiv( t2, t3 ); + rtn->push( 4, t1 ); + rtn->push( 4, t2 ); + + auto &vmp_rtn = rtn->vmp_rtns.back(); + // TODO: compute flags... + rtn->push( 8, rtn->load_value( 8, vmp_rtn->flags ) ); + }; +} \ No newline at end of file diff --git a/src/lifters/imul.cpp b/src/lifters/imul.cpp index 74d60c2..506f54e 100644 --- a/src/lifters/imul.cpp +++ b/src/lifters/imul.cpp @@ -9,6 +9,8 @@ namespace vm llvm::IRBuilder<> *ir_builder ) { auto t1 = rtn->pop( 8 ); auto t2 = rtn->pop( 8 ); + + // TODO: this is wrong... still need to do some more research into this... auto t3 = ir_builder->CreateMul( t1, t2 ); auto t4 = ir_builder->CreateAShr( t3, llvm::APInt( 64, 32 ) ); auto t5 = ir_builder->CreateAnd( t3, 0xFFFFFFFF00000000 ); diff --git a/src/lifters/mul.cpp b/src/lifters/mul.cpp index 7fa5903..32f6618 100644 --- a/src/lifters/mul.cpp +++ b/src/lifters/mul.cpp @@ -2,5 +2,21 @@ namespace vm { + lifters_t::lifter_callback_t lifters_t::mulq = + [ & ]( vm::devirt_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 = rtn->pop( 8 ); + // TODO: this is wrong... still need to do some more research into this... + auto t3 = ir_builder->CreateMul( t1, t2 ); + auto t4 = ir_builder->CreateAShr( t3, llvm::APInt( 64, 32 ) ); + auto t5 = ir_builder->CreateAnd( t3, 0xFFFFFFFF00000000 ); + rtn->push( 8, t4 ); + rtn->push( 8, t5 ); + + // TODO: compute flags for IMULQ + auto &vmp_rtn = rtn->vmp_rtns.back(); + rtn->push( 8, rtn->load_value( 8, vmp_rtn->flags ) ); + }; } \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 89f8f81..60f0e3c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -60,6 +60,9 @@ int main( int argc, const char *argv[] ) for ( auto &[ vm_enter_offset, vmp2_code_blocks ] : virt_rtns ) { + if ( vmp2_code_blocks.empty() ) + continue; + if ( !vmp_devirt.lift( vm_enter_offset + file_header->image_base, vmp2_code_blocks ) ) { std::printf( "[!] failed to lift rtn_0x%p, please review the console...\n", @@ -67,6 +70,8 @@ int main( int argc, const char *argv[] ) return -1; } + + std::printf( "> lifted rtn_0x%p\n", vm_enter_offset + file_header->image_base ); } llvm::LLVMInitializeX86TargetInfo(); From b82072e2ed02730d16f4eb45af0326155a6ee935 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Tue, 31 Aug 2021 23:23:08 -0700 Subject: [PATCH 07/12] added more lifters... --- CMakeLists.txt | 3 +++ include/vm_lifters.hpp | 9 ++++++++- src/lifters/idiv.cpp | 20 ++++++++++++++++++++ src/lifters/readcr3.cpp | 30 ++++++++++++++++++++++++++++++ src/lifters/shrd.cpp | 19 ++++++++++++++++++- src/lifters/writecr3.cpp | 31 +++++++++++++++++++++++++++++++ 6 files changed, 110 insertions(+), 2 deletions(-) create mode 100644 src/lifters/idiv.cpp create mode 100644 src/lifters/readcr3.cpp create mode 100644 src/lifters/writecr3.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 40cb428..1196e8c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,6 +44,7 @@ list(APPEND vmdevirt_SOURCES "src/devirt_utils.cpp" "src/lifters/add.cpp" "src/lifters/div.cpp" + "src/lifters/idiv.cpp" "src/lifters/imul.cpp" "src/lifters/jmp.cpp" "src/lifters/lconst.cpp" @@ -54,6 +55,7 @@ list(APPEND vmdevirt_SOURCES "src/lifters/popvsp.cpp" "src/lifters/pushvsp.cpp" "src/lifters/read.cpp" + "src/lifters/readcr3.cpp" "src/lifters/readcr8.cpp" "src/lifters/readgs.cpp" "src/lifters/sflags.cpp" @@ -64,6 +66,7 @@ list(APPEND vmdevirt_SOURCES "src/lifters/sreg.cpp" "src/lifters/vmexit.cpp" "src/lifters/write.cpp" + "src/lifters/writecr3.cpp" "src/main.cpp" "src/vmp_rtn_t.cpp" "include/devirt_t.hpp" diff --git a/include/vm_lifters.hpp b/include/vm_lifters.hpp index 835d2e1..c7d07d3 100644 --- a/include/vm_lifters.hpp +++ b/include/vm_lifters.hpp @@ -44,13 +44,16 @@ namespace vm static lifter_callback_t shrq, shrdw, shrw; static lifter_callback_t shlq, shldw; static lifter_callback_t shlddw; - static lifter_callback_t shrdq; + static lifter_callback_t shrdq, shrddw; static lifter_callback_t jmp; static lifter_callback_t lflagsq; static lifter_callback_t vmexit; static lifter_callback_t readcr8; + static lifter_callback_t readcr3; + static lifter_callback_t writecr3; static lifter_callback_t readgsq; static lifter_callback_t divdw; + static lifter_callback_t idivdw; std::map< vm::handler::mnemonic_t, lifter_callback_t * > lifters = { { vm::handler::LCONSTQ, &lconstq }, { vm::handler::LCONSTDW, &lconstdw }, @@ -62,6 +65,7 @@ namespace vm { vm::handler::LCONSTWSXDW, &lconstwsxdw }, { vm::handler::LCONSTBSXDW, &lconstbsxdw }, { vm::handler::DIVDW, &divdw }, + { vm::handler::IDIVDW, &idivdw }, { vm::handler::ADDQ, &addq }, { vm::handler::ADDDW, &adddw }, { vm::handler::ADDW, &addw }, @@ -73,6 +77,7 @@ namespace vm { vm::handler::SHLDW, &shldw }, { vm::handler::SHLDDW, &shlddw }, { vm::handler::SHRDQ, &shrdq }, + { vm::handler::SHRDDW, &shrddw }, { vm::handler::IMULQ, &imulq }, { vm::handler::IMULDW, &imuldw }, { vm::handler::MULQ, &mulq }, @@ -98,6 +103,8 @@ namespace vm { vm::handler::NANDB, &nandb }, { vm::handler::LFLAGSQ, &lflagsq }, { vm::handler::READCR8, &readcr8 }, + { vm::handler::READCR3, &readcr3 }, + { vm::handler::WRITECR3, &writecr3 }, { vm::handler::READGSQ, &readgsq }, { vm::handler::JMP, &jmp }, { vm::handler::VMEXIT, &vmexit } }; diff --git a/src/lifters/idiv.cpp b/src/lifters/idiv.cpp new file mode 100644 index 0000000..ff00c8c --- /dev/null +++ b/src/lifters/idiv.cpp @@ -0,0 +1,20 @@ +#include + +namespace vm +{ + lifters_t::lifter_callback_t lifters_t::idivdw = + [ & ]( vm::devirt_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 ); + + // TODO: this is wrong... + ir_builder->CreateUDiv( t1, t2 ); + rtn->push( 4, t1 ); + rtn->push( 4, t2 ); + + auto &vmp_rtn = rtn->vmp_rtns.back(); + // TODO: compute flags... + rtn->push( 8, rtn->load_value( 8, vmp_rtn->flags ) ); + }; +} \ No newline at end of file diff --git a/src/lifters/readcr3.cpp b/src/lifters/readcr3.cpp new file mode 100644 index 0000000..15ec784 --- /dev/null +++ b/src/lifters/readcr3.cpp @@ -0,0 +1,30 @@ +#include + +namespace vm +{ + lifters_t::lifter_callback_t lifters_t::readcr3 = + [ & ]( vm::devirt_t *rtn, const vm::instrs::code_block_t &vm_code_block, const vm::instrs::virt_instr_t &vinstr, + llvm::IRBuilder<> *ir_builder ) { + llvm::Function *readcr3_intrin = nullptr; + if ( !( readcr3_intrin = rtn->llvm_module->getFunction( "readcr3" ) ) ) + { + readcr3_intrin = llvm::Function::Create( llvm::FunctionType::get( ir_builder->getInt64Ty(), false ), + llvm::GlobalValue::LinkageTypes::ExternalLinkage, "readcr3", + *rtn->llvm_module ); + + auto entry_block = llvm::BasicBlock::Create( ir_builder->getContext(), "", readcr3_intrin ); + auto ib = ir_builder->GetInsertBlock(); + ir_builder->SetInsertPoint( entry_block ); + + std::string asm_str( "mov rax, cr3; ret" ); + auto intrin = llvm::InlineAsm::get( llvm::FunctionType::get( ir_builder->getVoidTy(), false ), asm_str, + "", false, false, llvm::InlineAsm::AD_Intel ); + + ir_builder->CreateCall( intrin ); + ir_builder->CreateRet( llvm::ConstantInt::get( *rtn->llvm_ctx, llvm::APInt( 64, 0 ) ) ); + ir_builder->SetInsertPoint( ib ); + } + auto t1 = ir_builder->CreateCall( readcr3_intrin ); + rtn->push( 8, t1 ); + }; +} \ No newline at end of file diff --git a/src/lifters/shrd.cpp b/src/lifters/shrd.cpp index 758ee04..36f88d6 100644 --- a/src/lifters/shrd.cpp +++ b/src/lifters/shrd.cpp @@ -18,4 +18,21 @@ namespace vm // TODO: update rflags... rtn->push( 8, rtn->load_value( 8, vmp_rtn->flags ) ); }; -} \ No newline at end of file + + lifters_t::lifter_callback_t lifters_t::shrddw = + [ & ]( vm::devirt_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 = rtn->pop( 2 ); + + // TODO: this is wrong - replace with more logic! + auto t4 = ir_builder->CreateLShr( t1, ir_builder->CreateIntCast( t3, ir_builder->getInt32Ty(), false ) ); + + rtn->push( 4, t4 ); + auto &vmp_rtn = rtn->vmp_rtns.back(); + + // TODO: update rflags... + rtn->push( 8, rtn->load_value( 8, vmp_rtn->flags ) ); + }; +} // namespace vm \ No newline at end of file diff --git a/src/lifters/writecr3.cpp b/src/lifters/writecr3.cpp new file mode 100644 index 0000000..4568e08 --- /dev/null +++ b/src/lifters/writecr3.cpp @@ -0,0 +1,31 @@ +#include + +namespace vm +{ + lifters_t::lifter_callback_t lifters_t::writecr3 = + [ & ]( vm::devirt_t *rtn, const vm::instrs::code_block_t &vm_code_block, const vm::instrs::virt_instr_t &vinstr, + llvm::IRBuilder<> *ir_builder ) { + llvm::Function *writecr3_intrin = nullptr; + if ( !( writecr3_intrin = rtn->llvm_module->getFunction( "writecr3" ) ) ) + { + writecr3_intrin = llvm::Function::Create( + llvm::FunctionType::get( ir_builder->getVoidTy(), { ir_builder->getInt64Ty() }, false ), + llvm::GlobalValue::LinkageTypes::ExternalLinkage, "writecr3", *rtn->llvm_module ); + + auto entry_block = llvm::BasicBlock::Create( ir_builder->getContext(), "", writecr3_intrin ); + auto ib = ir_builder->GetInsertBlock(); + ir_builder->SetInsertPoint( entry_block ); + + std::string asm_str( "mov cr3, rcx; ret" ); + auto intrin = llvm::InlineAsm::get( + llvm::FunctionType::get( ir_builder->getVoidTy(), false ), asm_str, + "", false, false, llvm::InlineAsm::AD_Intel ); + + ir_builder->CreateCall( intrin ); + ir_builder->CreateRetVoid(); + ir_builder->SetInsertPoint( ib ); + } + auto t1 = rtn->pop( 8 ); + ir_builder->CreateCall( writecr3_intrin, { t1 } ); + }; +} \ No newline at end of file From aaf0e9defe5868d51842a720b9c97449903b3d1a Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Wed, 1 Sep 2021 00:03:15 -0700 Subject: [PATCH 08/12] added more lifters... --- include/vm_lifters.hpp | 8 +++++--- src/lifters/mul.cpp | 18 ++++++++++++++++++ src/lifters/shr.cpp | 23 +++++++++++++++++++---- 3 files changed, 42 insertions(+), 7 deletions(-) diff --git a/include/vm_lifters.hpp b/include/vm_lifters.hpp index c7d07d3..b93d565 100644 --- a/include/vm_lifters.hpp +++ b/include/vm_lifters.hpp @@ -35,13 +35,13 @@ namespace vm static lifter_callback_t sregq, sregdw, sregw, sregb; static lifter_callback_t lregq, lregdw; static lifter_callback_t imulq, imuldw; - static lifter_callback_t mulq; + static lifter_callback_t mulq, muldw; static lifter_callback_t pushvsp; static lifter_callback_t popvsp; static lifter_callback_t writeq, writedw, writew, writeb; static lifter_callback_t readq, readdw, readw, readb; static lifter_callback_t nandq, nanddw, nandw, nandb; - static lifter_callback_t shrq, shrdw, shrw; + static lifter_callback_t shrq, shrdw, shrw, shrb; static lifter_callback_t shlq, shldw; static lifter_callback_t shlddw; static lifter_callback_t shrdq, shrddw; @@ -73,6 +73,7 @@ namespace vm { vm::handler::SHRQ, &shrq }, { vm::handler::SHRDW, &shrdw }, { vm::handler::SHRW, &shrw }, + { vm::handler::SHRB, &shrb }, { vm::handler::SHLQ, &shlq }, { vm::handler::SHLDW, &shldw }, { vm::handler::SHLDDW, &shlddw }, @@ -81,6 +82,7 @@ namespace vm { vm::handler::IMULQ, &imulq }, { vm::handler::IMULDW, &imuldw }, { vm::handler::MULQ, &mulq }, + { vm::handler::MULDW, &muldw }, { vm::handler::PUSHVSPQ, &pushvsp }, { vm::handler::POPVSPQ, &popvsp }, { vm::handler::SREGQ, &sregq }, @@ -131,4 +133,4 @@ namespace vm return true; } }; -} // namespace vm +} // namespace vm \ No newline at end of file diff --git a/src/lifters/mul.cpp b/src/lifters/mul.cpp index 32f6618..a47789f 100644 --- a/src/lifters/mul.cpp +++ b/src/lifters/mul.cpp @@ -15,6 +15,24 @@ namespace vm rtn->push( 8, t4 ); rtn->push( 8, t5 ); + // TODO: compute flags for IMULQ + auto &vmp_rtn = rtn->vmp_rtns.back(); + rtn->push( 8, rtn->load_value( 8, vmp_rtn->flags ) ); + }; + + lifters_t::lifter_callback_t lifters_t::muldw = + [ & ]( vm::devirt_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 ); + + // TODO: this is wrong... still need to do some more research into this... + auto t3 = ir_builder->CreateMul( t1, t2 ); + auto t4 = ir_builder->CreateAShr( t3, llvm::APInt( 32, 16 ) ); + auto t5 = ir_builder->CreateAnd( t3, 0xFFFF0000 ); + rtn->push( 4, t4 ); + rtn->push( 4, t5 ); + // TODO: compute flags for IMULQ auto &vmp_rtn = rtn->vmp_rtns.back(); rtn->push( 8, rtn->load_value( 8, vmp_rtn->flags ) ); diff --git a/src/lifters/shr.cpp b/src/lifters/shr.cpp index d5d8a22..50c3874 100644 --- a/src/lifters/shr.cpp +++ b/src/lifters/shr.cpp @@ -53,13 +53,28 @@ namespace vm llvm::IRBuilder<> *ir_builder ) { auto t1 = rtn->pop( 2 ); auto t2 = rtn->pop( 2 ); - auto t3 = ir_builder->CreateIntCast( t2, llvm::IntegerType::get( *rtn->llvm_ctx, 16 ), false ); - auto t4 = ir_builder->CreateLShr( t1, t3 ); + auto t3 = ir_builder->CreateLShr( t1, t2 ); + + auto &vmp_rtn = rtn->vmp_rtns.back(); + auto flags = lifters_t::shr_flags( rtn, 2, t1, t2, t3 ); + ir_builder->CreateStore( flags, vmp_rtn->flags ); + rtn->push( 2, t3 ); + rtn->push( 8, rtn->load_value( 8, vmp_rtn->flags ) ); + }; + + lifters_t::lifter_callback_t lifters_t::shrb = + [ & ]( vm::devirt_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->CreateIntCast( t1, ir_builder->getInt8Ty(), false ); + auto t4 = ir_builder->CreateIntCast( t2, ir_builder->getInt8Ty(), false ); + auto t5 = ir_builder->CreateLShr( t3, t4 ); auto &vmp_rtn = rtn->vmp_rtns.back(); - auto flags = lifters_t::shr_flags( rtn, 2, t1, t3, t4 ); + auto flags = lifters_t::shr_flags( rtn, 1, t3, t4, t5 ); ir_builder->CreateStore( flags, vmp_rtn->flags ); - rtn->push( 2, t4 ); + rtn->push( 2, ir_builder->CreateIntCast( t5, ir_builder->getInt16Ty(), false ) ); rtn->push( 8, rtn->load_value( 8, vmp_rtn->flags ) ); }; } // namespace vm \ No newline at end of file From 5775d5ae65b3834b9be54d411f4824a5c02e94e1 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Wed, 1 Sep 2021 13:45:26 -0700 Subject: [PATCH 09/12] added more lifters... --- include/vm_lifters.hpp | 8 +++++--- src/devirt_utils.cpp | 24 ------------------------ src/lifters/pushvsp.cpp | 13 +++++++++++-- src/lifters/shld.cpp | 19 ++++++++++++++++++- 4 files changed, 34 insertions(+), 30 deletions(-) diff --git a/include/vm_lifters.hpp b/include/vm_lifters.hpp index b93d565..94e87ec 100644 --- a/include/vm_lifters.hpp +++ b/include/vm_lifters.hpp @@ -36,14 +36,14 @@ namespace vm static lifter_callback_t lregq, lregdw; static lifter_callback_t imulq, imuldw; static lifter_callback_t mulq, muldw; - static lifter_callback_t pushvsp; + static lifter_callback_t pushvspq, pushvspdw; static lifter_callback_t popvsp; static lifter_callback_t writeq, writedw, writew, writeb; static lifter_callback_t readq, readdw, readw, readb; static lifter_callback_t nandq, nanddw, nandw, nandb; static lifter_callback_t shrq, shrdw, shrw, shrb; static lifter_callback_t shlq, shldw; - static lifter_callback_t shlddw; + static lifter_callback_t shldq, shlddw; static lifter_callback_t shrdq, shrddw; static lifter_callback_t jmp; static lifter_callback_t lflagsq; @@ -76,6 +76,7 @@ namespace vm { vm::handler::SHRB, &shrb }, { vm::handler::SHLQ, &shlq }, { vm::handler::SHLDW, &shldw }, + { vm::handler::SHLDQ, &shldq }, { vm::handler::SHLDDW, &shlddw }, { vm::handler::SHRDQ, &shrdq }, { vm::handler::SHRDDW, &shrddw }, @@ -83,7 +84,8 @@ namespace vm { vm::handler::IMULDW, &imuldw }, { vm::handler::MULQ, &mulq }, { vm::handler::MULDW, &muldw }, - { vm::handler::PUSHVSPQ, &pushvsp }, + { vm::handler::PUSHVSPQ, &pushvspq }, + { vm::handler::PUSHVSPDW, &pushvspdw }, { vm::handler::POPVSPQ, &popvsp }, { vm::handler::SREGQ, &sregq }, { vm::handler::SREGDW, &sregdw }, diff --git a/src/devirt_utils.cpp b/src/devirt_utils.cpp index ff8d310..255d97f 100644 --- a/src/devirt_utils.cpp +++ b/src/devirt_utils.cpp @@ -193,30 +193,6 @@ namespace devirt } } ); - auto resize_cnt = new_relocs.size() * ( sizeof( win::reloc_entry_t ) + sizeof( win::reloc_block_t ) ); - map_buff.resize( map_img->get_nt_headers()->optional_header.size_image += resize_cnt ); - - map_img = reinterpret_cast< win::image_t<> * >( map_buff.data() ); - auto basereloc_dir = map_img->get_directory( win::directory_id::directory_entry_basereloc ); - auto reloc_dir = reinterpret_cast< win::reloc_directory_t * >( basereloc_dir->rva + map_buff.data() ); - - basereloc_dir->size += resize_cnt; - for ( const auto &[ reloc_rva, reloc_offset ] : new_relocs ) - { - win::reloc_block_t *reloc_block = &reloc_dir->first_block; - while ( reloc_block->base_rva && reloc_block->size_block ) - reloc_block = reloc_block->next(); - - reloc_block->base_rva = reloc_rva; - reloc_block->size_block = sizeof( win::reloc_entry_t ) + sizeof uint64_t; - - reloc_block->next()->base_rva = 0ull; - reloc_block->next()->size_block = 0ull; - - reloc_block->entries[ 0 ].type = win::reloc_type_id::rel_based_dir64; - reloc_block->entries[ 0 ].offset = reloc_offset; - } - // replace bin vector with map_buff vector... bin.clear(); bin.insert( bin.begin(), map_buff.begin(), map_buff.end() ); diff --git a/src/lifters/pushvsp.cpp b/src/lifters/pushvsp.cpp index 0b91ba8..0e50fb4 100644 --- a/src/lifters/pushvsp.cpp +++ b/src/lifters/pushvsp.cpp @@ -2,7 +2,7 @@ namespace vm { - lifters_t::lifter_callback_t lifters_t::pushvsp = + lifters_t::lifter_callback_t lifters_t::pushvspq = [ & ]( vm::devirt_t *rtn, const vm::instrs::code_block_t &vm_code_block, const vm::instrs::virt_instr_t &vinstr, llvm::IRBuilder<> *ir_builder ) { auto &vmp_rtn = rtn->vmp_rtns.back(); @@ -10,4 +10,13 @@ namespace vm auto stack_ptr = ir_builder->CreatePtrToInt( stack, ir_builder->getInt64Ty() ); rtn->push( 8, stack_ptr ); }; -} \ No newline at end of file + + lifters_t::lifter_callback_t lifters_t::pushvspdw = + [ & ]( vm::devirt_t *rtn, const vm::instrs::code_block_t &vm_code_block, const vm::instrs::virt_instr_t &vinstr, + llvm::IRBuilder<> *ir_builder ) { + auto &vmp_rtn = rtn->vmp_rtns.back(); + auto stack = ir_builder->CreateLoad( vmp_rtn->stack ); + auto stack_ptr = ir_builder->CreatePtrToInt( stack, ir_builder->getInt32Ty() ); + rtn->push( 4, stack_ptr ); + }; +} // namespace vm \ No newline at end of file diff --git a/src/lifters/shld.cpp b/src/lifters/shld.cpp index f1b1567..ca14358 100644 --- a/src/lifters/shld.cpp +++ b/src/lifters/shld.cpp @@ -2,6 +2,23 @@ namespace vm { + lifters_t::lifter_callback_t lifters_t::shldq = + [ & ]( vm::devirt_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 = rtn->pop( 8 ); + auto t3 = rtn->pop( 2 ); + + // TODO: this is wrong - replace with more logic! + auto t4 = ir_builder->CreateShl( t1, ir_builder->CreateIntCast( t3, ir_builder->getInt64Ty(), false ) ); + + rtn->push( 8, t4 ); + auto &vmp_rtn = rtn->vmp_rtns.back(); + + // TODO: update rflags... + rtn->push( 8, rtn->load_value( 8, vmp_rtn->flags ) ); + }; + lifters_t::lifter_callback_t lifters_t::shlddw = [ & ]( vm::devirt_t *rtn, const vm::instrs::code_block_t &vm_code_block, const vm::instrs::virt_instr_t &vinstr, llvm::IRBuilder<> *ir_builder ) { @@ -18,4 +35,4 @@ namespace vm // TODO: update rflags... rtn->push( 8, rtn->load_value( 8, vmp_rtn->flags ) ); }; -} \ No newline at end of file +} // namespace vm \ No newline at end of file From 8a5bf9e8abe26d9851773665b977bafc34965b50 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Wed, 1 Sep 2021 17:45:18 -0700 Subject: [PATCH 10/12] added more lifters --- CMakeLists.txt | 1 + include/vm_lifters.hpp | 8 ++++++-- src/devirt_t.cpp | 3 +++ src/lifters/div.cpp | 17 ++++++++++++++++- src/lifters/jmp.cpp | 4 ++-- src/lifters/rdtsc.cpp | 32 ++++++++++++++++++++++++++++++++ src/lifters/shl.cpp | 16 ++++++++++++++++ 7 files changed, 76 insertions(+), 5 deletions(-) create mode 100644 src/lifters/rdtsc.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 1196e8c..34c833c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -54,6 +54,7 @@ list(APPEND vmdevirt_SOURCES "src/lifters/nand.cpp" "src/lifters/popvsp.cpp" "src/lifters/pushvsp.cpp" + "src/lifters/rdtsc.cpp" "src/lifters/read.cpp" "src/lifters/readcr3.cpp" "src/lifters/readcr8.cpp" diff --git a/include/vm_lifters.hpp b/include/vm_lifters.hpp index 94e87ec..5ce6e32 100644 --- a/include/vm_lifters.hpp +++ b/include/vm_lifters.hpp @@ -42,7 +42,7 @@ namespace vm static lifter_callback_t readq, readdw, readw, readb; static lifter_callback_t nandq, nanddw, nandw, nandb; static lifter_callback_t shrq, shrdw, shrw, shrb; - static lifter_callback_t shlq, shldw; + static lifter_callback_t shlq, shldw, shlb; static lifter_callback_t shldq, shlddw; static lifter_callback_t shrdq, shrddw; static lifter_callback_t jmp; @@ -51,8 +51,9 @@ namespace vm static lifter_callback_t readcr8; static lifter_callback_t readcr3; static lifter_callback_t writecr3; + static lifter_callback_t rdtsc; static lifter_callback_t readgsq; - static lifter_callback_t divdw; + static lifter_callback_t divq, divdw; static lifter_callback_t idivdw; std::map< vm::handler::mnemonic_t, lifter_callback_t * > lifters = { { vm::handler::LCONSTQ, &lconstq }, @@ -64,6 +65,7 @@ namespace vm { vm::handler::LCONSTBSXQ, &lconstbsxq }, { vm::handler::LCONSTWSXDW, &lconstwsxdw }, { vm::handler::LCONSTBSXDW, &lconstbsxdw }, + { vm::handler::DIVQ, &divq }, { vm::handler::DIVDW, &divdw }, { vm::handler::IDIVDW, &idivdw }, { vm::handler::ADDQ, &addq }, @@ -76,6 +78,7 @@ namespace vm { vm::handler::SHRB, &shrb }, { vm::handler::SHLQ, &shlq }, { vm::handler::SHLDW, &shldw }, + { vm::handler::SHLB, &shlb }, { vm::handler::SHLDQ, &shldq }, { vm::handler::SHLDDW, &shlddw }, { vm::handler::SHRDQ, &shrdq }, @@ -109,6 +112,7 @@ namespace vm { vm::handler::READCR8, &readcr8 }, { vm::handler::READCR3, &readcr3 }, { vm::handler::WRITECR3, &writecr3 }, + { vm::handler::RDTSC, &rdtsc }, { vm::handler::READGSQ, &readgsq }, { vm::handler::JMP, &jmp }, { vm::handler::VMEXIT, &vmexit } }; diff --git a/src/devirt_t.cpp b/src/devirt_t.cpp index 478f3e5..5e1dad3 100644 --- a/src/devirt_t.cpp +++ b/src/devirt_t.cpp @@ -115,6 +115,9 @@ namespace vm for ( auto idx = 0u; idx < vmp_rtn->vmp2_code_blocks.size(); ++idx ) { + if ( vmp_rtn->vmp2_code_blocks[ idx ].vinstrs.size() < 35 ) + continue; + ir_builder->SetInsertPoint( vmp_rtn->llvm_code_blocks[ idx ].second ); for ( auto &vinstr : vmp_rtn->vmp2_code_blocks[ idx ].vinstrs ) { diff --git a/src/lifters/div.cpp b/src/lifters/div.cpp index 72cf65f..f13e8e0 100644 --- a/src/lifters/div.cpp +++ b/src/lifters/div.cpp @@ -2,6 +2,21 @@ namespace vm { + lifters_t::lifter_callback_t lifters_t::divq = + [ & ]( vm::devirt_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 = rtn->pop( 8 ); + auto t3 = rtn->pop( 8 ); + ir_builder->CreateUDiv( t2, t3 ); + rtn->push( 8, t1 ); + rtn->push( 8, t2 ); + + auto &vmp_rtn = rtn->vmp_rtns.back(); + // TODO: compute flags... + rtn->push( 8, rtn->load_value( 8, vmp_rtn->flags ) ); + }; + lifters_t::lifter_callback_t lifters_t::divdw = [ & ]( vm::devirt_t *rtn, const vm::instrs::code_block_t &vm_code_block, const vm::instrs::virt_instr_t &vinstr, llvm::IRBuilder<> *ir_builder ) { @@ -16,4 +31,4 @@ namespace vm // TODO: compute flags... rtn->push( 8, rtn->load_value( 8, vmp_rtn->flags ) ); }; -} \ No newline at end of file +} // namespace vm \ No newline at end of file diff --git a/src/lifters/jmp.cpp b/src/lifters/jmp.cpp index ba9325e..385bbb0 100644 --- a/src/lifters/jmp.cpp +++ b/src/lifters/jmp.cpp @@ -5,8 +5,8 @@ namespace vm lifters_t::lifter_callback_t lifters_t::jmp = [ & ]( vm::devirt_t *rtn, const vm::instrs::code_block_t &vm_code_block, const vm::instrs::virt_instr_t &vinstr, llvm::IRBuilder<> *ir_builder ) { - assert( vm_code_block.jcc.has_jcc, "[!] fatal error in vmemu... virtual block ending with jmp marked as" - " has_jcc = false... debug time!\n" ); + if ( !vm_code_block.jcc.has_jcc ) + return; auto &vmp_rtn = rtn->vmp_rtns.back(); switch ( vm_code_block.jcc.type ) diff --git a/src/lifters/rdtsc.cpp b/src/lifters/rdtsc.cpp new file mode 100644 index 0000000..c456ff5 --- /dev/null +++ b/src/lifters/rdtsc.cpp @@ -0,0 +1,32 @@ +#include + +namespace vm +{ + lifters_t::lifter_callback_t lifters_t::rdtsc = + [ & ]( vm::devirt_t *rtn, const vm::instrs::code_block_t &vm_code_block, const vm::instrs::virt_instr_t &vinstr, + llvm::IRBuilder<> *ir_builder ) { + llvm::Function *rdtsc_intrin = nullptr; + if ( !( rdtsc_intrin = rtn->llvm_module->getFunction( "rdtsc" ) ) ) + { + rdtsc_intrin = llvm::Function::Create( + llvm::FunctionType::get( ir_builder->getVoidTy(), + { llvm::PointerType::get( ir_builder->getInt8Ty(), 0ull ) }, false ), + llvm::GlobalValue::LinkageTypes::ExternalLinkage, "rdtsc", *rtn->llvm_module ); + + auto entry_block = llvm::BasicBlock::Create( ir_builder->getContext(), "", rdtsc_intrin ); + auto ib = ir_builder->GetInsertBlock(); + ir_builder->SetInsertPoint( entry_block ); + + std::string asm_str( "rdtsc; sub rbp, 0x08; mov [rcx], edx; mov [rcx+0x04], eax; ret" ); + auto intrin = llvm::InlineAsm::get( llvm::FunctionType::get( ir_builder->getVoidTy(), false ), asm_str, + "", false, false, llvm::InlineAsm::AD_Intel ); + + ir_builder->CreateCall( intrin ); + ir_builder->CreateRetVoid(); + ir_builder->SetInsertPoint( ib ); + } + + auto &vmp_rtn = rtn->vmp_rtns.back(); + ir_builder->CreateCall( rdtsc_intrin, { vmp_rtn->stack } ); + }; +} \ No newline at end of file diff --git a/src/lifters/shl.cpp b/src/lifters/shl.cpp index fa34a94..d2c6ecd 100644 --- a/src/lifters/shl.cpp +++ b/src/lifters/shl.cpp @@ -31,4 +31,20 @@ namespace vm rtn->push( 4, t4 ); rtn->push( 8, rtn->load_value( 8, vmp_rtn->flags ) ); }; + + lifters_t::lifter_callback_t lifters_t::shlb = + [ & ]( vm::devirt_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->CreateIntCast( t1, ir_builder->getInt8Ty(), false ); + auto t4 = ir_builder->CreateIntCast( t2, ir_builder->getInt8Ty(), false ); + auto t5 = ir_builder->CreateShl( t3, t4 ); + + auto &vmp_rtn = rtn->vmp_rtns.back(); + // TODO: update rflags... + + rtn->push( 2, ir_builder->CreateIntCast( t5, ir_builder->getInt16Ty(), false ) ); + rtn->push( 8, rtn->load_value( 8, vmp_rtn->flags ) ); + }; } // namespace vm \ No newline at end of file From a8fef83c95cecf72b56b2b16f65e382a58bc2b4e Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Wed, 1 Sep 2021 23:39:06 -0700 Subject: [PATCH 11/12] preparing for release... --- src/devirt_t.cpp | 13 +++++++++++++ src/lifters/rdtsc.cpp | 14 +++++--------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/devirt_t.cpp b/src/devirt_t.cpp index 5e1dad3..20c3d18 100644 --- a/src/devirt_t.cpp +++ b/src/devirt_t.cpp @@ -85,6 +85,19 @@ namespace vm bool devirt_t::compile( std::vector< std::uint8_t > &obj ) { + llvm::legacy::FunctionPassManager pass_mgr( llvm_module ); + pass_mgr.add( llvm::createPromoteMemoryToRegisterPass() ); + pass_mgr.add( llvm::createNewGVNPass() ); + pass_mgr.add( llvm::createReassociatePass() ); + pass_mgr.add( llvm::createDeadCodeEliminationPass() ); + pass_mgr.add( llvm::createInstructionCombiningPass() ); + + for ( auto vmp_rtn : vmp_rtns ) + { + pass_mgr.run( *vmp_rtn->llvm_fptr ); + std::printf( "> opt rtn_0x%p\n", vmp_rtn->rtn_begin ); + } + llvm::TargetOptions opt; llvm::SmallVector< char, 128 > buff; llvm::raw_svector_ostream dest( buff ); diff --git a/src/lifters/rdtsc.cpp b/src/lifters/rdtsc.cpp index c456ff5..4f9b660 100644 --- a/src/lifters/rdtsc.cpp +++ b/src/lifters/rdtsc.cpp @@ -8,25 +8,21 @@ namespace vm llvm::Function *rdtsc_intrin = nullptr; if ( !( rdtsc_intrin = rtn->llvm_module->getFunction( "rdtsc" ) ) ) { - rdtsc_intrin = llvm::Function::Create( - llvm::FunctionType::get( ir_builder->getVoidTy(), - { llvm::PointerType::get( ir_builder->getInt8Ty(), 0ull ) }, false ), - llvm::GlobalValue::LinkageTypes::ExternalLinkage, "rdtsc", *rtn->llvm_module ); + rdtsc_intrin = llvm::Function::Create( llvm::FunctionType::get( ir_builder->getVoidTy(), false ), + llvm::GlobalValue::LinkageTypes::ExternalLinkage, "rdtsc", + *rtn->llvm_module ); auto entry_block = llvm::BasicBlock::Create( ir_builder->getContext(), "", rdtsc_intrin ); auto ib = ir_builder->GetInsertBlock(); ir_builder->SetInsertPoint( entry_block ); - std::string asm_str( "rdtsc; sub rbp, 0x08; mov [rcx], edx; mov [rcx+0x04], eax; ret" ); - auto intrin = llvm::InlineAsm::get( llvm::FunctionType::get( ir_builder->getVoidTy(), false ), asm_str, - "", false, false, llvm::InlineAsm::AD_Intel ); + // TODO: put RDTSC code here... - ir_builder->CreateCall( intrin ); ir_builder->CreateRetVoid(); ir_builder->SetInsertPoint( ib ); } auto &vmp_rtn = rtn->vmp_rtns.back(); - ir_builder->CreateCall( rdtsc_intrin, { vmp_rtn->stack } ); + ir_builder->CreateCall( rdtsc_intrin ); }; } \ No newline at end of file From 64e4838d6d4bb33f4aa43cd16ead6cbbf2dd1f81 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Thu, 2 Sep 2021 09:05:58 -0700 Subject: [PATCH 12/12] finished version 0.1... --- src/devirt_t.cpp | 5 ++++- src/lifters/jmp.cpp | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/devirt_t.cpp b/src/devirt_t.cpp index 20c3d18..75805e6 100644 --- a/src/devirt_t.cpp +++ b/src/devirt_t.cpp @@ -128,10 +128,13 @@ namespace vm for ( auto idx = 0u; idx < vmp_rtn->vmp2_code_blocks.size(); ++idx ) { + ir_builder->SetInsertPoint( vmp_rtn->llvm_code_blocks[ idx ].second ); if ( vmp_rtn->vmp2_code_blocks[ idx ].vinstrs.size() < 35 ) + { + ir_builder->CreateRetVoid(); continue; + } - ir_builder->SetInsertPoint( vmp_rtn->llvm_code_blocks[ idx ].second ); for ( auto &vinstr : vmp_rtn->vmp2_code_blocks[ idx ].vinstrs ) { if ( !lifters->lift( this, vmp_rtn->vmp2_code_blocks[ idx ], vinstr, ir_builder.get() ) ) diff --git a/src/lifters/jmp.cpp b/src/lifters/jmp.cpp index 385bbb0..d23f62b 100644 --- a/src/lifters/jmp.cpp +++ b/src/lifters/jmp.cpp @@ -6,7 +6,10 @@ namespace vm [ & ]( vm::devirt_t *rtn, const vm::instrs::code_block_t &vm_code_block, const vm::instrs::virt_instr_t &vinstr, llvm::IRBuilder<> *ir_builder ) { if ( !vm_code_block.jcc.has_jcc ) + { + ir_builder->CreateRetVoid(); return; + } auto &vmp_rtn = rtn->vmp_rtns.back(); switch ( vm_code_block.jcc.type )