From e3ecef4d4af080d4998767fdff235e6d30481f11 Mon Sep 17 00:00:00 2001 From: xtremegamer1 Date: Sat, 8 Oct 2022 00:37:53 -0600 Subject: [PATCH 01/35] I still dont't understand git please help --- include/vminstrs.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/vminstrs.hpp b/include/vminstrs.hpp index 8eaa05c..38c131f 100644 --- a/include/vminstrs.hpp +++ b/include/vminstrs.hpp @@ -10,7 +10,7 @@ namespace vm::instrs { /// /// mnemonic representation of supported virtual instructions... /// -enum class mnemonic_t { +enum class mnemonic_t : uint8_t { unknown, sreg, lreg, @@ -117,7 +117,7 @@ struct vblk_t { /// /// image based relative virtual address... /// - std::uintptr_t img_base; + std::uintptr_t img_based; } m_vip; /// -- 2.36.3 From 48eaabf52622d24aad465fbde0f70f42f53f08dd Mon Sep 17 00:00:00 2001 From: xtremegamer1 Date: Sun, 9 Oct 2022 19:12:23 -0600 Subject: [PATCH 02/35] trying to fix submodule fuckup --- deps/linux-pe | 2 +- deps/unicorn | 2 +- deps/zydis | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/deps/linux-pe b/deps/linux-pe index 9b87640..4f83eae 160000 --- a/deps/linux-pe +++ b/deps/linux-pe @@ -1 +1 @@ -Subproject commit 9b8764004a284fefe599c407f4ebbdf5a8aa4b0a +Subproject commit 4f83eae434696201f5075d65b11bf8329c6d218a diff --git a/deps/unicorn b/deps/unicorn index 63a445c..99dc84c 160000 --- a/deps/unicorn +++ b/deps/unicorn @@ -1 +1 @@ -Subproject commit 63a445cbba18bf1313ac3699b5d25462b5d529f4 +Subproject commit 99dc84ca226e72c9e7d5845d73fa271e3e707ead diff --git a/deps/zydis b/deps/zydis index ce4a42f..b865df9 160000 --- a/deps/zydis +++ b/deps/zydis @@ -1 +1 @@ -Subproject commit ce4a42ffaffe4a5ff615665e05177c4c69eb4683 +Subproject commit b865df986ca39235a17715d04987e0258163d01c -- 2.36.3 From a19d9c6fb8d0fa34634dbd5ef39d0ed15606b80d Mon Sep 17 00:00:00 2001 From: xtremegamer1 Date: Sun, 9 Oct 2022 23:52:27 -0600 Subject: [PATCH 03/35] trying to fix submodule fuckup --- deps/linux-pe | 2 +- deps/unicorn | 2 +- deps/zydis | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/deps/linux-pe b/deps/linux-pe index 9b87640..4f83eae 160000 --- a/deps/linux-pe +++ b/deps/linux-pe @@ -1 +1 @@ -Subproject commit 9b8764004a284fefe599c407f4ebbdf5a8aa4b0a +Subproject commit 4f83eae434696201f5075d65b11bf8329c6d218a diff --git a/deps/unicorn b/deps/unicorn index 63a445c..6c1cbef 160000 --- a/deps/unicorn +++ b/deps/unicorn @@ -1 +1 @@ -Subproject commit 63a445cbba18bf1313ac3699b5d25462b5d529f4 +Subproject commit 6c1cbef6ac505d355033aef1176b684d02e1eb3a diff --git a/deps/zydis b/deps/zydis index ce4a42f..2a9f9c6 160000 --- a/deps/zydis +++ b/deps/zydis @@ -1 +1 @@ -Subproject commit ce4a42ffaffe4a5ff615665e05177c4c69eb4683 +Subproject commit 2a9f9c66775a4ac3d56bb163c85563df3cea7547 -- 2.36.3 From 4b80be1bdfd4cdcc4efab319fafbdd145bf3e2b2 Mon Sep 17 00:00:00 2001 From: xtremegamer1 Date: Sun, 9 Oct 2022 23:52:42 -0600 Subject: [PATCH 04/35] Ok this should work now.... --- deps/unicorn | 2 +- deps/zydis | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/deps/unicorn b/deps/unicorn index 99dc84c..6c1cbef 160000 --- a/deps/unicorn +++ b/deps/unicorn @@ -1 +1 @@ -Subproject commit 99dc84ca226e72c9e7d5845d73fa271e3e707ead +Subproject commit 6c1cbef6ac505d355033aef1176b684d02e1eb3a diff --git a/deps/zydis b/deps/zydis index b865df9..2a9f9c6 160000 --- a/deps/zydis +++ b/deps/zydis @@ -1 +1 @@ -Subproject commit b865df986ca39235a17715d04987e0258163d01c +Subproject commit 2a9f9c66775a4ac3d56bb163c85563df3cea7547 -- 2.36.3 From c39b783af858b6f4cbe1b0d456ce90f375542f5d Mon Sep 17 00:00:00 2001 From: xtremegamer1 Date: Mon, 10 Oct 2022 00:58:10 -0600 Subject: [PATCH 05/35] removed profanity from commit message --- deps/zydis | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/zydis b/deps/zydis index 2a9f9c6..ce4a42f 160000 --- a/deps/zydis +++ b/deps/zydis @@ -1 +1 @@ -Subproject commit 2a9f9c66775a4ac3d56bb163c85563df3cea7547 +Subproject commit ce4a42ffaffe4a5ff615665e05177c4c69eb4683 -- 2.36.3 From 0a8964d3abef4f94c5dbf92a8eeccffeca3c40ff Mon Sep 17 00:00:00 2001 From: xtremegamer1 Date: Wed, 12 Oct 2022 14:42:57 -0600 Subject: [PATCH 06/35] Added some new vmprofiles --- include/vminstrs.hpp | 10 ++++- src/vmprofiles/readbzxw.cpp | 40 ++++++++++++++++++++ src/vmprofiles/shl.cpp | 63 ++++++++++++++++++++++++++++++++ src/vmprofiles/shld.cpp | 73 +++++++++++++++++++++++++++++++++++++ src/vmprofiles/shrd.cpp | 73 +++++++++++++++++++++++++++++++++++++ 5 files changed, 257 insertions(+), 2 deletions(-) create mode 100644 src/vmprofiles/readbzxw.cpp create mode 100644 src/vmprofiles/shl.cpp create mode 100644 src/vmprofiles/shld.cpp create mode 100644 src/vmprofiles/shrd.cpp diff --git a/include/vminstrs.hpp b/include/vminstrs.hpp index 38c131f..f96e0e6 100644 --- a/include/vminstrs.hpp +++ b/include/vminstrs.hpp @@ -24,6 +24,7 @@ enum class mnemonic_t : uint8_t { nop, nor, read, + readbzxw, //Read byte zero extend to word write, shl, shld, @@ -292,17 +293,22 @@ extern profiler_t nand; extern profiler_t nop; extern profiler_t nor; extern profiler_t read; +extern profiler_t readbzxw; extern profiler_t write; extern profiler_t imul; +extern profiler_t shl; +extern profiler_t shld; extern profiler_t shr; +extern profiler_t shrd; +extern profiler_t shrd; extern profiler_t vmexit; /// /// unsorted vector of profiles... they get sorted once at runtime... /// inline std::vector profiles = { - &vmexit, &shr, &imul, &nor, &write, &svsp, &read, &nand, - &lvsp, &add, &jmp, &sreg, &lreg, &lconst, &nop}; + &vmexit, &shl, &shld, &shr, &shrd, &imul, &nor, &write, &svsp, &read, &readbzxw, + &nand, &lvsp, &add, &jmp, &sreg, &lreg, &lconst, &nop}; /// /// no i did not make this by hand, you cannot clown upon me! diff --git a/src/vmprofiles/readbzxw.cpp b/src/vmprofiles/readbzxw.cpp new file mode 100644 index 0000000..609acbe --- /dev/null +++ b/src/vmprofiles/readbzxw.cpp @@ -0,0 +1,40 @@ +#include + +namespace vm::instrs { +profiler_t readbzxw = { + "READ", + mnemonic_t::readbzxw, + {{// MOV REG, [VSP] + LOAD_VALUE, + // MOVZX REG, [REG] + [](const zydis_reg_t vip, const zydis_reg_t vsp, + const zydis_decoded_instr_t& instr) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_MOVZX && + instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[0].size == 16 && + instr.operands[1].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr.operands[1].size == 8 && + instr.operands[1].mem.base != vsp; + }, + // MOV [VSP], REG + STR_VALUE}}, + [](zydis_reg_t& vip, zydis_reg_t& vsp, + hndlr_trace_t& hndlr) -> std::optional { + vinstr_t res{mnemonic_t::read}; + res.imm.has_imm = false; + + // MOV REG, [REG] + const auto mov_reg_reg = std::find_if( + hndlr.m_instrs.begin(), hndlr.m_instrs.end(), + [&](emu_instr_t& instr) -> bool { + const auto& i = instr.m_instr; + return i.mnemonic == ZYDIS_MNEMONIC_MOVZX && + i.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && + i.operands[1].type == ZYDIS_OPERAND_TYPE_MEMORY && + i.operands[1].mem.base != vsp; + }); + + res.stack_size = mov_reg_reg->m_instr.operands[0].size; + return res; + }}; +} \ No newline at end of file diff --git a/src/vmprofiles/shl.cpp b/src/vmprofiles/shl.cpp new file mode 100644 index 0000000..d5ae9b1 --- /dev/null +++ b/src/vmprofiles/shl.cpp @@ -0,0 +1,63 @@ +#include + +namespace vm::instrs { +profiler_t shl = { + "SHR", + mnemonic_t::shl, + {{// MOV REG, [VSP] + LOAD_VALUE, + // MOV REG, [VSP+OFFSET] + [](const zydis_reg_t vip, const zydis_reg_t vsp, + const zydis_decoded_instr_t& instr) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_MOV && + instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[1].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr.operands[1].mem.base == vsp && + instr.operands[1].mem.disp.has_displacement; + }, + // SHL REG, REG + [](const zydis_reg_t vip, const zydis_reg_t vsp, + const zydis_decoded_instr_t& instr) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_SHL && + instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER; + }, + // MOV [VSP+OFFSET], REG + [](const zydis_reg_t vip, const zydis_reg_t vsp, + const zydis_decoded_instr_t& instr) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_MOV && + instr.operands[0].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr.operands[0].mem.base == vsp && + instr.operands[0].mem.disp.has_displacement && + instr.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER; + }, + // PUSHFQ + [](const zydis_reg_t vip, const zydis_reg_t vsp, + const zydis_decoded_instr_t& instr) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ; + }, + // POP [VSP] + [](const zydis_reg_t vip, const zydis_reg_t vsp, + const zydis_decoded_instr_t& instr) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_POP && + instr.operands[0].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr.operands[0].mem.base == vsp; + }}}, + [](zydis_reg_t& vip, zydis_reg_t& vsp, + hndlr_trace_t& hndlr) -> std::optional { + vinstr_t res{mnemonic_t::shr}; + res.imm.has_imm = false; + + const auto shr_reg = std::find_if( + hndlr.m_instrs.begin(), hndlr.m_instrs.end(), + [&](emu_instr_t& instr) -> bool { + const auto& i = instr.m_instr; + return i.mnemonic == ZYDIS_MNEMONIC_SHL && + i.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && + i.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER; + }); + + res.stack_size = shr_reg->m_instr.operands[0].size; + return res; + }}; +} \ No newline at end of file diff --git a/src/vmprofiles/shld.cpp b/src/vmprofiles/shld.cpp new file mode 100644 index 0000000..14a01e9 --- /dev/null +++ b/src/vmprofiles/shld.cpp @@ -0,0 +1,73 @@ +#include + +namespace vm::instrs { +profiler_t shld = { + "SHR", + mnemonic_t::shld, + {{// MOV REG, [VSP] + LOAD_VALUE, + // MOV REG, [VSP+OFFSET] + [](const zydis_reg_t vip, const zydis_reg_t vsp, + const zydis_decoded_instr_t& instr) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_MOV && + instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[1].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr.operands[1].mem.base == vsp && + instr.operands[1].mem.disp.has_displacement; + }, + // MOV REG, [VSP+OFFSET] + [](const zydis_reg_t vip, const zydis_reg_t vsp, + const zydis_decoded_instr_t& instr) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_MOV && + instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[1].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr.operands[1].mem.base == vsp && + instr.operands[1].mem.disp.has_displacement; + }, + // SHL REG, REG + [](const zydis_reg_t vip, const zydis_reg_t vsp, + const zydis_decoded_instr_t& instr) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_SHLD && + instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER; + }, + // MOV [VSP+OFFSET], REG + [](const zydis_reg_t vip, const zydis_reg_t vsp, + const zydis_decoded_instr_t& instr) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_MOV && + instr.operands[0].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr.operands[0].mem.base == vsp && + instr.operands[0].mem.disp.has_displacement && + instr.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER; + }, + // PUSHFQ + [](const zydis_reg_t vip, const zydis_reg_t vsp, + const zydis_decoded_instr_t& instr) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ; + }, + // POP [VSP] + [](const zydis_reg_t vip, const zydis_reg_t vsp, + const zydis_decoded_instr_t& instr) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_POP && + instr.operands[0].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr.operands[0].mem.base == vsp; + }}}, + [](zydis_reg_t& vip, zydis_reg_t& vsp, + hndlr_trace_t& hndlr) -> std::optional { + vinstr_t res{mnemonic_t::shr}; + res.imm.has_imm = false; + + const auto shr_reg = std::find_if( + hndlr.m_instrs.begin(), hndlr.m_instrs.end(), + [&](emu_instr_t& instr) -> bool { + const auto& i = instr.m_instr; + return i.mnemonic == ZYDIS_MNEMONIC_SHLD && + i.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && + i.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER; + }); + + res.stack_size = shr_reg->m_instr.operands[0].size; + return res; + }}; + +} \ No newline at end of file diff --git a/src/vmprofiles/shrd.cpp b/src/vmprofiles/shrd.cpp new file mode 100644 index 0000000..73d4aad --- /dev/null +++ b/src/vmprofiles/shrd.cpp @@ -0,0 +1,73 @@ +#include + +namespace vm::instrs { +profiler_t shrd = { + "SHR", + mnemonic_t::shrd, + {{// MOV REG, [VSP] + LOAD_VALUE, + // MOV REG, [VSP+OFFSET] + [](const zydis_reg_t vip, const zydis_reg_t vsp, + const zydis_decoded_instr_t& instr) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_MOV && + instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[1].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr.operands[1].mem.base == vsp && + instr.operands[1].mem.disp.has_displacement; + }, + // MOV REG, [VSP+OFFSET] + [](const zydis_reg_t vip, const zydis_reg_t vsp, + const zydis_decoded_instr_t& instr) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_MOV && + instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[1].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr.operands[1].mem.base == vsp && + instr.operands[1].mem.disp.has_displacement; + }, + // SHR REG, REG + [](const zydis_reg_t vip, const zydis_reg_t vsp, + const zydis_decoded_instr_t& instr) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_SHRD && + instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER; + }, + // MOV [VSP+OFFSET], REG + [](const zydis_reg_t vip, const zydis_reg_t vsp, + const zydis_decoded_instr_t& instr) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_MOV && + instr.operands[0].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr.operands[0].mem.base == vsp && + instr.operands[0].mem.disp.has_displacement && + instr.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER; + }, + // PUSHFQ + [](const zydis_reg_t vip, const zydis_reg_t vsp, + const zydis_decoded_instr_t& instr) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ; + }, + // POP [VSP] + [](const zydis_reg_t vip, const zydis_reg_t vsp, + const zydis_decoded_instr_t& instr) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_POP && + instr.operands[0].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr.operands[0].mem.base == vsp; + }}}, + [](zydis_reg_t& vip, zydis_reg_t& vsp, + hndlr_trace_t& hndlr) -> std::optional { + vinstr_t res{mnemonic_t::shr}; + res.imm.has_imm = false; + + const auto shr_reg = std::find_if( + hndlr.m_instrs.begin(), hndlr.m_instrs.end(), + [&](emu_instr_t& instr) -> bool { + const auto& i = instr.m_instr; + return i.mnemonic == ZYDIS_MNEMONIC_SHRD && + i.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && + i.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER; + }); + + res.stack_size = shr_reg->m_instr.operands[0].size; + return res; + }}; + +} \ No newline at end of file -- 2.36.3 From ddd58c2a989d260f504745f30d0d72eb1c788087 Mon Sep 17 00:00:00 2001 From: xtremegamer1 Date: Wed, 12 Oct 2022 14:50:09 -0600 Subject: [PATCH 07/35] Added some vmprofiles --- CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6669c8a..74834ba 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -65,7 +65,11 @@ list(APPEND vmprofiler_SOURCES "src/vmprofiles/nop.cpp" "src/vmprofiles/nor.cpp" "src/vmprofiles/read.cpp" + "src/vmprofiles/readbzxw.cpp" "src/vmprofiles/shr.cpp" + "src/vmprofiles/shrd.cpp" + "src/vmprofiles/shl.cpp" + "src/vmprofiles/shld.cpp" "src/vmprofiles/sreg.cpp" "src/vmprofiles/svsp.cpp" "src/vmprofiles/vmexit.cpp" -- 2.36.3 From 0be31ec97770dc333a1d9677407968fa9da850eb Mon Sep 17 00:00:00 2001 From: xtremegamer1 Date: Thu, 13 Oct 2022 19:03:43 -0600 Subject: [PATCH 08/35] Added an extremely simple memory leak tracker --- include/uc_allocation_tracker.hpp | 6 ++++++ src/uc_allocation_tracker.cpp | 15 +++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 include/uc_allocation_tracker.hpp create mode 100644 src/uc_allocation_tracker.cpp diff --git a/include/uc_allocation_tracker.hpp b/include/uc_allocation_tracker.hpp new file mode 100644 index 0000000..8dd1aa2 --- /dev/null +++ b/include/uc_allocation_tracker.hpp @@ -0,0 +1,6 @@ +#include + +extern int g_allocation_tracker; + +uc_err uct_context_alloc(uc_engine *uc, uc_context **context); +uc_err uct_context_free(uc_context *context); \ No newline at end of file diff --git a/src/uc_allocation_tracker.cpp b/src/uc_allocation_tracker.cpp new file mode 100644 index 0000000..076c208 --- /dev/null +++ b/src/uc_allocation_tracker.cpp @@ -0,0 +1,15 @@ +#include +#include + +int g_allocation_tracker; + +uc_err uct_context_alloc(uc_engine *uc, uc_context **context) +{ + std::printf("Allocations: %p\n", ++g_allocation_tracker); + return uc_context_alloc(uc, context); +} +uc_err uct_context_free(uc_context *context) +{ + std::printf("Allocations: %p\n", --g_allocation_tracker); + return uc_context_free(context); +} \ No newline at end of file -- 2.36.3 From 7b13df4bf69127c24fb0358d8f0a4978a8dec703 Mon Sep 17 00:00:00 2001 From: xtremegamer1 Date: Thu, 13 Oct 2022 19:04:39 -0600 Subject: [PATCH 09/35] Added writedr7 instruction --- include/vminstrs.hpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/include/vminstrs.hpp b/include/vminstrs.hpp index f96e0e6..6de4707 100644 --- a/include/vminstrs.hpp +++ b/include/vminstrs.hpp @@ -40,7 +40,8 @@ enum class mnemonic_t : uint8_t { rdtsc, call, jmp, - vmexit + vmexit, + writedr7 }; /// @@ -295,6 +296,7 @@ extern profiler_t nor; extern profiler_t read; extern profiler_t readbzxw; extern profiler_t write; +extern profiler_t writedr7; extern profiler_t imul; extern profiler_t shl; extern profiler_t shld; @@ -307,8 +309,8 @@ extern profiler_t vmexit; /// unsorted vector of profiles... they get sorted once at runtime... /// inline std::vector profiles = { - &vmexit, &shl, &shld, &shr, &shrd, &imul, &nor, &write, &svsp, &read, &readbzxw, - &nand, &lvsp, &add, &jmp, &sreg, &lreg, &lconst, &nop}; + &vmexit, &shl, &shld, &shr, &shrd, &imul, &nor, &write, &svsp, &read, &readbzxw, + &nand, &lvsp, &add, &jmp, &sreg, &lreg, &lconst, &nop, &writedr7}; /// /// no i did not make this by hand, you cannot clown upon me! -- 2.36.3 From 70d797420c496c21314e6242c7acb9f7422ae450 Mon Sep 17 00:00:00 2001 From: xtremegamer1 Date: Thu, 13 Oct 2022 19:04:59 -0600 Subject: [PATCH 10/35] updated source files --- CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 74834ba..e315a30 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -74,7 +74,10 @@ list(APPEND vmprofiler_SOURCES "src/vmprofiles/svsp.cpp" "src/vmprofiles/vmexit.cpp" "src/vmprofiles/write.cpp" + "src/vmprofiles/writedr7.cpp" "src/vmutils.cpp" + "include/uc_allocation_tracker.hpp" + "src/uc_allocation_tracker.cpp" "include/vmctx.hpp" "include/vminstrs.hpp" "include/vmlocate.hpp" -- 2.36.3 From f253e88ec117e9cf23a0da12c0b0e31832599d5e Mon Sep 17 00:00:00 2001 From: xtremegamer1 Date: Thu, 13 Oct 2022 19:05:14 -0600 Subject: [PATCH 11/35] Added allocation tracker --- include/vmprofiler.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/vmprofiler.hpp b/include/vmprofiler.hpp index 9ec68aa..bf854ef 100644 --- a/include/vmprofiler.hpp +++ b/include/vmprofiler.hpp @@ -4,4 +4,5 @@ #include #include #include -#include \ No newline at end of file +#include +#include \ No newline at end of file -- 2.36.3 From b0126f6f48d19646f47ef4acf0058d58fb9b2a15 Mon Sep 17 00:00:00 2001 From: xtremegamer1 Date: Thu, 13 Oct 2022 19:07:05 -0600 Subject: [PATCH 12/35] Fixed handlers, added writedr7, fixed names --- src/vmprofiles/jmp.cpp | 13 ++++++++----- src/vmprofiles/shl.cpp | 2 +- src/vmprofiles/shld.cpp | 2 +- src/vmprofiles/shr.cpp | 2 +- src/vmprofiles/shrd.cpp | 2 +- src/vmprofiles/writedr7.cpp | 35 +++++++++++++++++++++++++++++++++++ 6 files changed, 47 insertions(+), 9 deletions(-) create mode 100644 src/vmprofiles/writedr7.cpp diff --git a/src/vmprofiles/jmp.cpp b/src/vmprofiles/jmp.cpp index e5385fb..07c399f 100644 --- a/src/vmprofiles/jmp.cpp +++ b/src/vmprofiles/jmp.cpp @@ -72,9 +72,10 @@ profiler_t jmp = { i.operands[1].reg.value == write_dep; }); - if (mov_reg_write_dep == instrs.end()) return {}; - - vsp = mov_reg_write_dep->m_instr.operands[0].reg.value; + if (mov_reg_write_dep == instrs.end()) + vsp = write_dep; + else + vsp = mov_reg_write_dep->m_instr.operands[0].reg.value; } else { // find the MOV REG, [VSP] instruction... const auto mov_reg_deref_vsp = std::find_if( @@ -87,7 +88,8 @@ profiler_t jmp = { i.operands[1].mem.base == vsp; }); - if (mov_reg_deref_vsp == instrs.end()) return {}; + if (mov_reg_deref_vsp == instrs.end()) + return {}; // find the MOV REG, mov_reg_deref_vsp->operands[0].reg.value const auto mov_vip_reg = std::find_if( @@ -101,7 +103,8 @@ profiler_t jmp = { mov_reg_deref_vsp->m_instr.operands[0].reg.value; }); - if (mov_vip_reg == instrs.end()) return {}; + if (mov_vip_reg == instrs.end()) + return {}; vip = mov_vip_reg->m_instr.operands[0].reg.value; diff --git a/src/vmprofiles/shl.cpp b/src/vmprofiles/shl.cpp index d5ae9b1..25b8c41 100644 --- a/src/vmprofiles/shl.cpp +++ b/src/vmprofiles/shl.cpp @@ -2,7 +2,7 @@ namespace vm::instrs { profiler_t shl = { - "SHR", + "SHL", mnemonic_t::shl, {{// MOV REG, [VSP] LOAD_VALUE, diff --git a/src/vmprofiles/shld.cpp b/src/vmprofiles/shld.cpp index 14a01e9..2e30622 100644 --- a/src/vmprofiles/shld.cpp +++ b/src/vmprofiles/shld.cpp @@ -2,7 +2,7 @@ namespace vm::instrs { profiler_t shld = { - "SHR", + "SHLD", mnemonic_t::shld, {{// MOV REG, [VSP] LOAD_VALUE, diff --git a/src/vmprofiles/shr.cpp b/src/vmprofiles/shr.cpp index 5b54a8e..4a456c5 100644 --- a/src/vmprofiles/shr.cpp +++ b/src/vmprofiles/shr.cpp @@ -2,7 +2,7 @@ namespace vm::instrs { profiler_t shr = { - "SHR", + "SHRD", mnemonic_t::shr, {{// MOV REG, [VSP] LOAD_VALUE, diff --git a/src/vmprofiles/shrd.cpp b/src/vmprofiles/shrd.cpp index 73d4aad..14204c4 100644 --- a/src/vmprofiles/shrd.cpp +++ b/src/vmprofiles/shrd.cpp @@ -2,7 +2,7 @@ namespace vm::instrs { profiler_t shrd = { - "SHR", + "SHRD", mnemonic_t::shrd, {{// MOV REG, [VSP] LOAD_VALUE, diff --git a/src/vmprofiles/writedr7.cpp b/src/vmprofiles/writedr7.cpp new file mode 100644 index 0000000..2bdddd1 --- /dev/null +++ b/src/vmprofiles/writedr7.cpp @@ -0,0 +1,35 @@ +#include + +namespace vm::instrs { +profiler_t writedr7 = { + "WRITEDR7", + mnemonic_t::writedr7, + { + // MOV REG, [VSP+OFFSET] + LOAD_VALUE, + // ADD VSP, OFFSET + [](const zydis_reg_t vip, const zydis_reg_t vsp, + const zydis_decoded_instr_t& instr) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_ADD && + instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[0].reg.value == vsp && + instr.operands[1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE; + }, + // MOV DR7, REG + [](const zydis_reg_t vip, const zydis_reg_t vsp, + const zydis_decoded_instr_t& instr) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_MOV && + instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[0].reg.value == ZYDIS_REGISTER_DR7 && + instr.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[1].reg.value != vsp; + } + }, + [](zydis_reg_t& vip, zydis_reg_t& vsp, + hndlr_trace_t& hndlr) -> std::optional { + vinstr_t res{mnemonic_t::write}; + res.imm.has_imm = false; + return res; + } +}; +} -- 2.36.3 From 88c167bb67e4a6ee863457cd4d4fa026a2d66849 Mon Sep 17 00:00:00 2001 From: xtremegamer1 Date: Fri, 14 Oct 2022 07:10:52 -0600 Subject: [PATCH 13/35] FIxed handlers --- src/vmprofiles/lcr0.cpp | 44 +++++++++++++++++++++++++++++++++++++ src/vmprofiles/read.cpp | 4 ++-- src/vmprofiles/readbzxw.cpp | 40 --------------------------------- src/vmprofiles/shl.cpp | 6 ++--- src/vmprofiles/shld.cpp | 6 ++--- src/vmprofiles/shrd.cpp | 6 ++--- 6 files changed, 55 insertions(+), 51 deletions(-) create mode 100644 src/vmprofiles/lcr0.cpp delete mode 100644 src/vmprofiles/readbzxw.cpp diff --git a/src/vmprofiles/lcr0.cpp b/src/vmprofiles/lcr0.cpp new file mode 100644 index 0000000..d3964a2 --- /dev/null +++ b/src/vmprofiles/lcr0.cpp @@ -0,0 +1,44 @@ +#include + +//Loads CR0 onto the stack +namespace vm::instrs { +profiler_t lcr0 = { + "LCR0", + mnemonic_t::lcr0, + { + // MOV REG, CR0 + [](const zydis_reg_t vip, const zydis_reg_t vsp, + const zydis_decoded_instr_t& instr) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_MOV && + instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[1].reg.value == ZYDIS_REGISTER_CR0; + }, + // SUB VSP, OFFSET + [](const zydis_reg_t vip, const zydis_reg_t vsp, + const zydis_decoded_instr_t& instr) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_SUB && + instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[0].reg.value == vsp && + instr.operands[1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE; + }, + // MOV [VSP], REG + [](const zydis_reg_t vip, const zydis_reg_t vsp, + const zydis_decoded_instr_t& instr) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_MOV && + instr.operands[0].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr.operands[0].mem.base == vsp && + instr.operands[0].mem.index == ZYDIS_REGISTER_NONE && + instr.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[1].reg.value != vsp; + } + }, + [](zydis_reg_t& vip, zydis_reg_t& vsp, + hndlr_trace_t& hndlr) -> std::optional { + vinstr_t res{mnemonic_t::lcr0}; + res.imm.has_imm = false; + res.stack_size = 64; + return res; + } +}; +} diff --git a/src/vmprofiles/read.cpp b/src/vmprofiles/read.cpp index 3bf26dc..8c61eca 100644 --- a/src/vmprofiles/read.cpp +++ b/src/vmprofiles/read.cpp @@ -26,13 +26,13 @@ profiler_t read = { hndlr.m_instrs.begin(), hndlr.m_instrs.end(), [&](emu_instr_t& instr) -> bool { const auto& i = instr.m_instr; - return i.mnemonic == ZYDIS_MNEMONIC_MOV && + return i.mnemonic == ZYDIS_MNEMONIC_MOV || i.mnemonic == ZYDIS_MNEMONIC_MOVZX && i.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && i.operands[1].type == ZYDIS_OPERAND_TYPE_MEMORY && i.operands[1].mem.base != vsp; }); - res.stack_size = mov_reg_reg->m_instr.operands[0].size; + res.stack_size = mov_reg_reg->m_instr.operands[1].size; return res; }}; } \ No newline at end of file diff --git a/src/vmprofiles/readbzxw.cpp b/src/vmprofiles/readbzxw.cpp deleted file mode 100644 index 609acbe..0000000 --- a/src/vmprofiles/readbzxw.cpp +++ /dev/null @@ -1,40 +0,0 @@ -#include - -namespace vm::instrs { -profiler_t readbzxw = { - "READ", - mnemonic_t::readbzxw, - {{// MOV REG, [VSP] - LOAD_VALUE, - // MOVZX REG, [REG] - [](const zydis_reg_t vip, const zydis_reg_t vsp, - const zydis_decoded_instr_t& instr) -> bool { - return instr.mnemonic == ZYDIS_MNEMONIC_MOVZX && - instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && - instr.operands[0].size == 16 && - instr.operands[1].type == ZYDIS_OPERAND_TYPE_MEMORY && - instr.operands[1].size == 8 && - instr.operands[1].mem.base != vsp; - }, - // MOV [VSP], REG - STR_VALUE}}, - [](zydis_reg_t& vip, zydis_reg_t& vsp, - hndlr_trace_t& hndlr) -> std::optional { - vinstr_t res{mnemonic_t::read}; - res.imm.has_imm = false; - - // MOV REG, [REG] - const auto mov_reg_reg = std::find_if( - hndlr.m_instrs.begin(), hndlr.m_instrs.end(), - [&](emu_instr_t& instr) -> bool { - const auto& i = instr.m_instr; - return i.mnemonic == ZYDIS_MNEMONIC_MOVZX && - i.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && - i.operands[1].type == ZYDIS_OPERAND_TYPE_MEMORY && - i.operands[1].mem.base != vsp; - }); - - res.stack_size = mov_reg_reg->m_instr.operands[0].size; - return res; - }}; -} \ No newline at end of file diff --git a/src/vmprofiles/shl.cpp b/src/vmprofiles/shl.cpp index 25b8c41..bb8cc87 100644 --- a/src/vmprofiles/shl.cpp +++ b/src/vmprofiles/shl.cpp @@ -45,10 +45,10 @@ profiler_t shl = { }}}, [](zydis_reg_t& vip, zydis_reg_t& vsp, hndlr_trace_t& hndlr) -> std::optional { - vinstr_t res{mnemonic_t::shr}; + vinstr_t res{mnemonic_t::shl}; res.imm.has_imm = false; - const auto shr_reg = std::find_if( + const auto shl_reg = std::find_if( hndlr.m_instrs.begin(), hndlr.m_instrs.end(), [&](emu_instr_t& instr) -> bool { const auto& i = instr.m_instr; @@ -57,7 +57,7 @@ profiler_t shl = { i.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER; }); - res.stack_size = shr_reg->m_instr.operands[0].size; + res.stack_size = shl_reg->m_instr.operands[0].size; return res; }}; } \ No newline at end of file diff --git a/src/vmprofiles/shld.cpp b/src/vmprofiles/shld.cpp index 2e30622..54c1624 100644 --- a/src/vmprofiles/shld.cpp +++ b/src/vmprofiles/shld.cpp @@ -54,10 +54,10 @@ profiler_t shld = { }}}, [](zydis_reg_t& vip, zydis_reg_t& vsp, hndlr_trace_t& hndlr) -> std::optional { - vinstr_t res{mnemonic_t::shr}; + vinstr_t res{mnemonic_t::shld}; res.imm.has_imm = false; - const auto shr_reg = std::find_if( + const auto shld_reg = std::find_if( hndlr.m_instrs.begin(), hndlr.m_instrs.end(), [&](emu_instr_t& instr) -> bool { const auto& i = instr.m_instr; @@ -66,7 +66,7 @@ profiler_t shld = { i.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER; }); - res.stack_size = shr_reg->m_instr.operands[0].size; + res.stack_size = shld_reg->m_instr.operands[0].size; return res; }}; diff --git a/src/vmprofiles/shrd.cpp b/src/vmprofiles/shrd.cpp index 14204c4..94000c2 100644 --- a/src/vmprofiles/shrd.cpp +++ b/src/vmprofiles/shrd.cpp @@ -54,10 +54,10 @@ profiler_t shrd = { }}}, [](zydis_reg_t& vip, zydis_reg_t& vsp, hndlr_trace_t& hndlr) -> std::optional { - vinstr_t res{mnemonic_t::shr}; + vinstr_t res{mnemonic_t::shrd}; res.imm.has_imm = false; - const auto shr_reg = std::find_if( + const auto shrd_reg = std::find_if( hndlr.m_instrs.begin(), hndlr.m_instrs.end(), [&](emu_instr_t& instr) -> bool { const auto& i = instr.m_instr; @@ -66,7 +66,7 @@ profiler_t shrd = { i.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER; }); - res.stack_size = shr_reg->m_instr.operands[0].size; + res.stack_size = shrd_reg->m_instr.operands[0].size; return res; }}; -- 2.36.3 From da7292eb3139b762a10125ca7bf7f7152cc8f945 Mon Sep 17 00:00:00 2001 From: xtremegamer1 Date: Fri, 14 Oct 2022 07:11:08 -0600 Subject: [PATCH 14/35] Added handlers --- src/vmprofiles/and.cpp | 61 +++++++++++++++++++++++++++++++++++++ src/vmprofiles/writedr7.cpp | 4 ++- 2 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 src/vmprofiles/and.cpp diff --git a/src/vmprofiles/and.cpp b/src/vmprofiles/and.cpp new file mode 100644 index 0000000..f6ac147 --- /dev/null +++ b/src/vmprofiles/and.cpp @@ -0,0 +1,61 @@ +#include + +namespace vm::instrs { +profiler_t _and = { + "AND", + mnemonic_t::_and, + {{// MOV REG, [VSP] + LOAD_VALUE, + // MOV REG, [VSP+OFFSET] + [](const zydis_reg_t vip, const zydis_reg_t vsp, + const zydis_decoded_instr_t& instr) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_MOV && + instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[1].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr.operands[1].mem.base == vsp && + instr.operands[1].mem.disp.has_displacement; + }, + // AND [REG], REG + [](const zydis_reg_t vip, const zydis_reg_t vsp, + const zydis_decoded_instr_t& instr) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_AND && + instr.operands[0].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr.operands[0].mem.base != ZYDIS_REGISTER_NONE && + instr.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER; + }, + // PUSHFQ + [](const zydis_reg_t vip, const zydis_reg_t vsp, + const zydis_decoded_instr_t& instr) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ; + }, + // POP [VSP] + [](const zydis_reg_t vip, const zydis_reg_t vsp, + const zydis_decoded_instr_t& instr) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_POP && + instr.operands[0].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr.operands[0].mem.base == vsp; + }}}, + [](zydis_reg_t& vip, zydis_reg_t& vsp, + hndlr_trace_t& hndlr) -> std::optional { + vinstr_t res{mnemonic_t::_and}; + res.imm.has_imm = false; + + // MOV REG [VSP+OFFSET] + const auto mov_vsp_offset = std::find_if( + hndlr.m_instrs.begin(), hndlr.m_instrs.end(), + [&](emu_instr_t& instr) -> bool { + const auto& i = instr.m_instr; + return + i.mnemonic == ZYDIS_MNEMONIC_MOV && + i.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && + i.operands[1].type == ZYDIS_OPERAND_TYPE_MEMORY && + i.operands[1].mem.base == vsp && + i.operands[1].mem.disp.has_displacement; + }); + if (mov_vsp_offset == hndlr.m_instrs.end()) + return std::nullopt; + + res.stack_size = mov_vsp_offset->m_instr.operands[0].size; + return res; + }}; +} \ No newline at end of file diff --git a/src/vmprofiles/writedr7.cpp b/src/vmprofiles/writedr7.cpp index 2bdddd1..6218abf 100644 --- a/src/vmprofiles/writedr7.cpp +++ b/src/vmprofiles/writedr7.cpp @@ -1,5 +1,6 @@ #include +//Write value on top of stack to dr7 namespace vm::instrs { profiler_t writedr7 = { "WRITEDR7", @@ -27,7 +28,8 @@ profiler_t writedr7 = { }, [](zydis_reg_t& vip, zydis_reg_t& vsp, hndlr_trace_t& hndlr) -> std::optional { - vinstr_t res{mnemonic_t::write}; + vinstr_t res{mnemonic_t::writedr7}; + res.stack_size == 64; res.imm.has_imm = false; return res; } -- 2.36.3 From 10c39981cc1cf0a777ca4b8c879c2a071ba2baf8 Mon Sep 17 00:00:00 2001 From: xtremegamer1 Date: Fri, 14 Oct 2022 07:12:07 -0600 Subject: [PATCH 15/35] =?UTF-8?q?Hi=20besties=20=F0=9F=98=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e315a30..d5c4bf1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -65,7 +65,6 @@ list(APPEND vmprofiler_SOURCES "src/vmprofiles/nop.cpp" "src/vmprofiles/nor.cpp" "src/vmprofiles/read.cpp" - "src/vmprofiles/readbzxw.cpp" "src/vmprofiles/shr.cpp" "src/vmprofiles/shrd.cpp" "src/vmprofiles/shl.cpp" @@ -74,6 +73,8 @@ list(APPEND vmprofiler_SOURCES "src/vmprofiles/svsp.cpp" "src/vmprofiles/vmexit.cpp" "src/vmprofiles/write.cpp" + "src/vmprofiles/lcr0.cpp" + "src/vmprofiles/and.cpp" "src/vmprofiles/writedr7.cpp" "src/vmutils.cpp" "include/uc_allocation_tracker.hpp" -- 2.36.3 From 512b19292ccaa27d340820ac48e561c95a84b090 Mon Sep 17 00:00:00 2001 From: xtremegamer1 Date: Fri, 14 Oct 2022 07:12:59 -0600 Subject: [PATCH 16/35] Fixed the awful generator --- src/vmprofiles/jmp.cpp | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/vmprofiles/jmp.cpp b/src/vmprofiles/jmp.cpp index 07c399f..8fe7d6f 100644 --- a/src/vmprofiles/jmp.cpp +++ b/src/vmprofiles/jmp.cpp @@ -102,11 +102,27 @@ profiler_t jmp = { i.operands[1].reg.value == mov_reg_deref_vsp->m_instr.operands[0].reg.value; }); + //It is possible that mov_vip_reg is actually updating the rolling key, if so use original vip + const auto load_handler_rva = std::find_if( + mov_vip_reg, instrs.end(), + [&](const emu_instr_t& instr) -> bool { + const auto& i = instr.m_instr; + return i.mnemonic == ZYDIS_MNEMONIC_MOV && + i.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && + vm::utils::is_32_bit_gp(i.operands[0].reg.value) && + i.operands[1].type == ZYDIS_OPERAND_TYPE_MEMORY && + i.operands[1].mem.base == + mov_vip_reg->m_instr.operands[0].reg.value; + }); if (mov_vip_reg == instrs.end()) return {}; - vip = mov_vip_reg->m_instr.operands[0].reg.value; + vip = (load_handler_rva != instrs.end()) ? + mov_vip_reg->m_instr.operands[0].reg.value : + mov_vip_reg->m_instr.operands[1].reg.value; + //Ok so basically mov_vip_reg, despite its name, isn't guaranteed to be + //mov vip, reg, and can in fact be mov rkey, vip. // see if VSP gets updated as well... const auto mov_reg_vsp = std::find_if( -- 2.36.3 From 25c3008dc26213d52fcb248cb918bd160bd6c2ba Mon Sep 17 00:00:00 2001 From: xtremegamer1 Date: Fri, 14 Oct 2022 07:13:23 -0600 Subject: [PATCH 17/35] added my new instructions --- include/vminstrs.hpp | 12 +++++++----- src/vminstrs.cpp | 5 ++++- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/include/vminstrs.hpp b/include/vminstrs.hpp index 6de4707..e8b61d6 100644 --- a/include/vminstrs.hpp +++ b/include/vminstrs.hpp @@ -16,6 +16,7 @@ enum class mnemonic_t : uint8_t { lreg, lconst, add, + _and, //The fucking idiots who wrote the standard thought reserving the word "and" was appropriate div, idiv, mul, @@ -24,7 +25,6 @@ enum class mnemonic_t : uint8_t { nop, nor, read, - readbzxw, //Read byte zero extend to word write, shl, shld, @@ -32,6 +32,7 @@ enum class mnemonic_t : uint8_t { shrd, lvsp, svsp, + lcr0, writecr3, readcr3, writecr8, @@ -288,14 +289,15 @@ extern profiler_t sreg; extern profiler_t lreg; extern profiler_t lconst; extern profiler_t add; +extern profiler_t _and; extern profiler_t lvsp; extern profiler_t svsp; extern profiler_t nand; extern profiler_t nop; extern profiler_t nor; extern profiler_t read; -extern profiler_t readbzxw; extern profiler_t write; +extern profiler_t lcr0; extern profiler_t writedr7; extern profiler_t imul; extern profiler_t shl; @@ -309,10 +311,10 @@ extern profiler_t vmexit; /// unsorted vector of profiles... they get sorted once at runtime... /// inline std::vector profiles = { - &vmexit, &shl, &shld, &shr, &shrd, &imul, &nor, &write, &svsp, &read, &readbzxw, - &nand, &lvsp, &add, &jmp, &sreg, &lreg, &lconst, &nop, &writedr7}; + &vmexit, &shl, &shld, &shr, &shrd, &imul, &nor, &write, &svsp, &read, + &nand, &lvsp, &add, &jmp, &_and, &sreg, &lreg, &lcr0, &lconst, &nop, &writedr7}; -/// +/// /// no i did not make this by hand, you cannot clown upon me! /// inline std::map reg_map = { diff --git a/src/vminstrs.cpp b/src/vminstrs.cpp index 4b25806..feee8f2 100644 --- a/src/vminstrs.cpp +++ b/src/vminstrs.cpp @@ -1,5 +1,5 @@ #include - +#include namespace vm::instrs { void deobfuscate(hndlr_trace_t& trace) { static const auto _uses_reg = [](zydis_decoded_operand_t& op, @@ -64,11 +64,13 @@ void deobfuscate(hndlr_trace_t& trace) { if (std::find(blacklist.begin(), blacklist.end(), itr->m_instr.mnemonic) != blacklist.end()) { + uct_context_free(itr->m_cpu); trace.m_instrs.erase(itr); break; } if (vm::utils::is_jmp(itr->m_instr)) { + uct_context_free(itr->m_cpu); trace.m_instrs.erase(itr); break; } @@ -111,6 +113,7 @@ void deobfuscate(hndlr_trace_t& trace) { _writes(read_result->m_instr, reg)) continue; + uct_context_free(itr->m_cpu); trace.m_instrs.erase(itr); break; } -- 2.36.3 From ff1790ae22fe8acb77f60e1617115b8ba7257487 Mon Sep 17 00:00:00 2001 From: xtremegamer1 Date: Fri, 14 Oct 2022 07:13:44 -0600 Subject: [PATCH 18/35] removed prints now that the memory leaks are gone --- include/uc_allocation_tracker.hpp | 3 ++- src/uc_allocation_tracker.cpp | 11 +++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/include/uc_allocation_tracker.hpp b/include/uc_allocation_tracker.hpp index 8dd1aa2..ac50d6b 100644 --- a/include/uc_allocation_tracker.hpp +++ b/include/uc_allocation_tracker.hpp @@ -3,4 +3,5 @@ extern int g_allocation_tracker; uc_err uct_context_alloc(uc_engine *uc, uc_context **context); -uc_err uct_context_free(uc_context *context); \ No newline at end of file +uc_err uct_context_free(uc_context *context); +void print_allocation_number(); \ No newline at end of file diff --git a/src/uc_allocation_tracker.cpp b/src/uc_allocation_tracker.cpp index 076c208..95fc2a4 100644 --- a/src/uc_allocation_tracker.cpp +++ b/src/uc_allocation_tracker.cpp @@ -5,11 +5,18 @@ int g_allocation_tracker; uc_err uct_context_alloc(uc_engine *uc, uc_context **context) { - std::printf("Allocations: %p\n", ++g_allocation_tracker); + ++g_allocation_tracker; + //std::printf("Allocations: %p\n", g_allocation_tracker); return uc_context_alloc(uc, context); } uc_err uct_context_free(uc_context *context) { - std::printf("Allocations: %p\n", --g_allocation_tracker); + +g_allocation_tracker--; + //std::printf("Allocations: %p\n", g_allocation_tracker); return uc_context_free(context); +} + +void print_allocation_number() +{ + std::printf("uc_context allocations: %p\n", g_allocation_tracker); } \ No newline at end of file -- 2.36.3 From dd3aeabbb08a80ea279f8a380a597e09ff4a75bc Mon Sep 17 00:00:00 2001 From: xtremegamer1 Date: Fri, 14 Oct 2022 07:14:48 -0600 Subject: [PATCH 19/35] Added a function to determine if a register is 32-bit general purpose --- include/vmutils.hpp | 2 ++ src/vmutils.cpp | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/include/vmutils.hpp b/include/vmutils.hpp index 14af5ab..d66d7dc 100644 --- a/include/vmutils.hpp +++ b/include/vmutils.hpp @@ -70,6 +70,8 @@ inline bool open_binary_file(const std::string& file, /// bool is_jmp(const zydis_decoded_instr_t& instr); +bool is_32_bit_gp(const ZydisRegister reg); + /// /// used by profiles to see if an instruction is a MOV/SX/ZX... /// diff --git a/src/vmutils.cpp b/src/vmutils.cpp index 73e917c..f6b9ce3 100644 --- a/src/vmutils.cpp +++ b/src/vmutils.cpp @@ -28,6 +28,11 @@ bool is_mov(const zydis_decoded_instr_t& instr) { instr.mnemonic == ZYDIS_MNEMONIC_MOVZX; } +bool is_32_bit_gp(const ZydisRegister reg) +{ + return reg >= ZYDIS_REGISTER_EAX && reg <= ZYDIS_REGISTER_R15D; +} + bool flatten(zydis_rtn_t& routine, std::uintptr_t routine_addr, bool keep_jmps, -- 2.36.3 From 885f987d04491b4bbf93b0e7bde94a44a09b229b Mon Sep 17 00:00:00 2001 From: xtremegamer1 Date: Sat, 15 Oct 2022 00:38:58 -0600 Subject: [PATCH 20/35] Fixed vmenter location --- src/vmlocate.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/vmlocate.cpp b/src/vmlocate.cpp index 49e3ff8..a6c0700 100644 --- a/src/vmlocate.cpp +++ b/src/vmlocate.cpp @@ -49,6 +49,18 @@ std::vector get_vm_entries(std::uintptr_t module_base, zydis_rtn_t rtn; if (!vm::utils::scn::executable(module_base, result)) continue; + // Make sure that the form of the vmenter is a jmp immediately followed by a call imm + ZydisDecodedInstruction after_push; + if (ZYAN_SUCCESS(ZydisDecoderDecodeBuffer(vm::utils::g_decoder.get(), + (void*)(result + 5), 5, &after_push))) + { + if (after_push.mnemonic != ZYDIS_MNEMONIC_CALL || + after_push.operands[0].type != ZYDIS_OPERAND_TYPE_IMMEDIATE) + continue; + } + else + continue; + if (!vm::utils::flatten(rtn, result, false, 500, module_base)) continue; // the last instruction in the stream should be a JMP to a register or a -- 2.36.3 From e74f291d564ca656d3f388abafb7b54d3371f70f Mon Sep 17 00:00:00 2001 From: xtremegamer1 Date: Sat, 15 Oct 2022 00:39:33 -0600 Subject: [PATCH 21/35] Added or virtual instruction --- CMakeLists.txt | 1 + include/vminstrs.hpp | 4 ++- src/vmprofiles/or.cpp | 61 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 src/vmprofiles/or.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index d5c4bf1..e7dd2b4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -75,6 +75,7 @@ list(APPEND vmprofiler_SOURCES "src/vmprofiles/write.cpp" "src/vmprofiles/lcr0.cpp" "src/vmprofiles/and.cpp" + "src/vmprofiles/or.cpp" "src/vmprofiles/writedr7.cpp" "src/vmutils.cpp" "include/uc_allocation_tracker.hpp" diff --git a/include/vminstrs.hpp b/include/vminstrs.hpp index e8b61d6..7a3f327 100644 --- a/include/vminstrs.hpp +++ b/include/vminstrs.hpp @@ -16,6 +16,7 @@ enum class mnemonic_t : uint8_t { lreg, lconst, add, + _or, _and, //The fucking idiots who wrote the standard thought reserving the word "and" was appropriate div, idiv, @@ -289,6 +290,7 @@ extern profiler_t sreg; extern profiler_t lreg; extern profiler_t lconst; extern profiler_t add; +extern profiler_t _or; extern profiler_t _and; extern profiler_t lvsp; extern profiler_t svsp; @@ -312,7 +314,7 @@ extern profiler_t vmexit; /// inline std::vector profiles = { &vmexit, &shl, &shld, &shr, &shrd, &imul, &nor, &write, &svsp, &read, - &nand, &lvsp, &add, &jmp, &_and, &sreg, &lreg, &lcr0, &lconst, &nop, &writedr7}; + &nand, &lvsp, &add, &jmp, &_or, &_and, &sreg, &lreg, &lcr0, &lconst, &nop, &writedr7}; /// /// no i did not make this by hand, you cannot clown upon me! diff --git a/src/vmprofiles/or.cpp b/src/vmprofiles/or.cpp new file mode 100644 index 0000000..57a6911 --- /dev/null +++ b/src/vmprofiles/or.cpp @@ -0,0 +1,61 @@ +#include + +namespace vm::instrs { +profiler_t _or = { + "OR", + mnemonic_t::_or, + {{// MOV REG, [VSP] + LOAD_VALUE, + // MOV REG, [VSP+OFFSET] + [](const zydis_reg_t vip, const zydis_reg_t vsp, + const zydis_decoded_instr_t& instr) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_MOV && + instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[1].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr.operands[1].mem.base == vsp && + instr.operands[1].mem.disp.has_displacement; + }, + // OR [REG], REG + [](const zydis_reg_t vip, const zydis_reg_t vsp, + const zydis_decoded_instr_t& instr) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_OR && + instr.operands[0].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr.operands[0].mem.base != ZYDIS_REGISTER_NONE && + instr.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER; + }, + // PUSHFQ + [](const zydis_reg_t vip, const zydis_reg_t vsp, + const zydis_decoded_instr_t& instr) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ; + }, + // POP [VSP] + [](const zydis_reg_t vip, const zydis_reg_t vsp, + const zydis_decoded_instr_t& instr) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_POP && + instr.operands[0].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr.operands[0].mem.base == vsp; + }}}, + [](zydis_reg_t& vip, zydis_reg_t& vsp, + hndlr_trace_t& hndlr) -> std::optional { + vinstr_t res{mnemonic_t::_or}; + res.imm.has_imm = false; + + // MOV REG [VSP+OFFSET] + const auto reg_vsp_offset = std::find_if( + hndlr.m_instrs.begin(), hndlr.m_instrs.end(), + [&](emu_instr_t& instr) -> bool { + const auto& i = instr.m_instr; + return + i.mnemonic == ZYDIS_MNEMONIC_MOV && + i.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && + i.operands[1].type == ZYDIS_OPERAND_TYPE_MEMORY && + i.operands[1].mem.base == vsp && + i.operands[1].mem.disp.has_displacement; + }); + if (reg_vsp_offset == hndlr.m_instrs.end()) + return std::nullopt; + + res.stack_size = reg_vsp_offset->m_instr.operands[0].size; + return res; + }}; +} \ No newline at end of file -- 2.36.3 From 462157b22c3d99ba78ca3ed3f82be7e320f255a9 Mon Sep 17 00:00:00 2001 From: xtremegamer1 Date: Sun, 16 Oct 2022 04:37:04 -0600 Subject: [PATCH 22/35] Added load delta and push order These are necessary for lifting --- include/vmctx.hpp | 7 ++++++- src/vmctx.cpp | 41 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/include/vmctx.hpp b/include/vmctx.hpp index 0941aaf..42d2870 100644 --- a/include/vmctx.hpp +++ b/include/vmctx.hpp @@ -1,6 +1,7 @@ #pragma once #include #include +#include namespace vm { class vmctx_t { @@ -11,12 +12,13 @@ class vmctx_t { std::uintptr_t vm_entry_rva); bool init(); const std::uintptr_t m_module_base, m_image_base, m_vm_entry_rva, - m_image_size; + m_image_size, m_image_load_delta; zydis_reg_t get_vip() const { return m_vip; } zydis_reg_t get_vsp() const { return m_vsp; } zydis_rtn_t get_vm_enter() const { return m_vm_entry; } + const std::array& get_vmentry_push_order() const; private: /// /// m_vip and m_vsp are set to the native registers used for them by the vm @@ -29,5 +31,8 @@ class vmctx_t { /// the virtual machine enter flattened and deobfuscated... /// zydis_rtn_t m_vm_entry; + + //using array container instead of c-style array in order to pass by reference. + std::array vmentry_push_order; }; } // namespace vm \ No newline at end of file diff --git a/src/vmctx.cpp b/src/vmctx.cpp index fd5eaaa..a8aa73e 100644 --- a/src/vmctx.cpp +++ b/src/vmctx.cpp @@ -8,7 +8,8 @@ vmctx_t::vmctx_t(std::uintptr_t module_base, : m_module_base(module_base), m_image_base(image_base), m_vm_entry_rva(vm_entry_rva), - m_image_size(image_size) {} + m_image_size(image_size), + m_image_load_delta(m_module_base - m_image_base) {} bool vmctx_t::init() { vm::utils::init(); @@ -20,6 +21,40 @@ bool vmctx_t::init() { vm::utils::deobfuscate(m_vm_entry); + //Get the order in which native registers are pushed + int push_index = 0; + for (const auto& instr : m_vm_entry) + { + if (instr.instr.mnemonic == ZYDIS_MNEMONIC_PUSH && + instr.instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && + vm::utils::is_64_bit_gp(instr.instr.operands[0].reg.value)) + { + if (std::find(vmentry_push_order.begin(), vmentry_push_order.begin() + push_index, + instr.instr.operands[0].reg.value) != vmentry_push_order.begin() + push_index) + { + //Every register should only be pushed once + std::printf("Error initializing vmctx_t: vmenter pushes could not be parsed.\n"); + vm::utils::print(m_vm_entry); + return false; + } + vmentry_push_order[push_index++] = instr.instr.operands[0].reg.value; + } + else if (instr.instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ) + { + if (std::find(vmentry_push_order.begin(), vmentry_push_order.begin() + push_index, + instr.instr.operands[0].reg.value) != vmentry_push_order.begin() + push_index) + { + // Same shit + std::printf("Error initializing vmctx_t: vmenter pushes could not be parsed.\n"); + vm::utils::print(m_vm_entry); + return false; + } + vmentry_push_order[push_index++] = ZYDIS_REGISTER_RFLAGS; + } + if (push_index == 16) + break; + } + // find mov reg, [rsp+0x90]. this register will be VIP... const auto vip_fetch = std::find_if( m_vm_entry.begin(), m_vm_entry.end(), @@ -53,4 +88,8 @@ bool vmctx_t::init() { m_vsp = vsp_fetch->instr.operands[0].reg.value; return true; } +const std::array& vm::vmctx_t::get_vmentry_push_order() const +{ + return vmentry_push_order; +} } // namespace vm \ No newline at end of file -- 2.36.3 From f40579dc0ce72fcf42ae0cda7a6ec54603e41aa9 Mon Sep 17 00:00:00 2001 From: xtremegamer1 Date: Sun, 16 Oct 2022 04:37:23 -0600 Subject: [PATCH 23/35] Check for 64 bit GP --- include/vmutils.hpp | 2 ++ src/vmutils.cpp | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/include/vmutils.hpp b/include/vmutils.hpp index d66d7dc..e0bd3bd 100644 --- a/include/vmutils.hpp +++ b/include/vmutils.hpp @@ -72,6 +72,8 @@ bool is_jmp(const zydis_decoded_instr_t& instr); bool is_32_bit_gp(const ZydisRegister reg); +bool is_64_bit_gp(const ZydisRegister reg); + /// /// used by profiles to see if an instruction is a MOV/SX/ZX... /// diff --git a/src/vmutils.cpp b/src/vmutils.cpp index f6b9ce3..06cfff7 100644 --- a/src/vmutils.cpp +++ b/src/vmutils.cpp @@ -33,6 +33,11 @@ bool is_32_bit_gp(const ZydisRegister reg) return reg >= ZYDIS_REGISTER_EAX && reg <= ZYDIS_REGISTER_R15D; } +bool is_64_bit_gp(const ZydisRegister reg) +{ + return reg >= ZYDIS_REGISTER_RAX && reg <= ZYDIS_REGISTER_R15; +} + bool flatten(zydis_rtn_t& routine, std::uintptr_t routine_addr, bool keep_jmps, -- 2.36.3 From 1d685efa0cc0460cc9e30ad7c668b1d54c8eed18 Mon Sep 17 00:00:00 2001 From: xtremegamer1 Date: Sun, 16 Oct 2022 04:54:11 -0600 Subject: [PATCH 24/35] =?UTF-8?q?deleted=20a=20single=20line=20?= =?UTF-8?q?=F0=9F=98=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/vmprofiles/or.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/vmprofiles/or.cpp b/src/vmprofiles/or.cpp index 57a6911..95fbb5c 100644 --- a/src/vmprofiles/or.cpp +++ b/src/vmprofiles/or.cpp @@ -54,7 +54,6 @@ profiler_t _or = { }); if (reg_vsp_offset == hndlr.m_instrs.end()) return std::nullopt; - res.stack_size = reg_vsp_offset->m_instr.operands[0].size; return res; }}; -- 2.36.3 From c8695100e65b56a3a162431ab365b4e7e1b02557 Mon Sep 17 00:00:00 2001 From: xtremegamer1 Date: Mon, 31 Oct 2022 03:32:01 -0600 Subject: [PATCH 25/35] Fixed typo and fixed nor vs nand fuckup --- src/vmprofiles/nand.cpp | 4 ++-- src/vmprofiles/nor.cpp | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/vmprofiles/nand.cpp b/src/vmprofiles/nand.cpp index 0638a5a..16553f5 100644 --- a/src/vmprofiles/nand.cpp +++ b/src/vmprofiles/nand.cpp @@ -21,10 +21,10 @@ profiler_t nand = { return instr.mnemonic == ZYDIS_MNEMONIC_NOT && instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER; }, - // AND REG, REG + // OR REG, REG [](const zydis_reg_t vip, const zydis_reg_t vsp, const zydis_decoded_instr_t& instr) -> bool { - return instr.mnemonic == ZYDIS_MNEMONIC_AND && + return instr.mnemonic == ZYDIS_MNEMONIC_OR && instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && instr.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER; }, diff --git a/src/vmprofiles/nor.cpp b/src/vmprofiles/nor.cpp index 53bedbb..fd04544 100644 --- a/src/vmprofiles/nor.cpp +++ b/src/vmprofiles/nor.cpp @@ -21,10 +21,10 @@ profiler_t nor = { return instr.mnemonic == ZYDIS_MNEMONIC_NOT && instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER; }, - // OR REG, REG + // AND REG, REG [](const zydis_reg_t vip, const zydis_reg_t vsp, const zydis_decoded_instr_t& instr) -> bool { - return instr.mnemonic == ZYDIS_MNEMONIC_OR && + return instr.mnemonic == ZYDIS_MNEMONIC_AND && instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && instr.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER; }, @@ -51,7 +51,7 @@ profiler_t nor = { }}}, [](zydis_reg_t& vip, zydis_reg_t& vsp, hndlr_trace_t& hndlr) -> std::optional { - vinstr_t res{mnemonic_t::nand}; + vinstr_t res{mnemonic_t::nor}; res.imm.has_imm = false; // MOV [VSP+OFFSET], REG -- 2.36.3 From 8d124ec8282382c577c7b81e50d94547b78576ca Mon Sep 17 00:00:00 2001 From: xtremegamer1 Date: Tue, 1 Nov 2022 02:39:01 -0600 Subject: [PATCH 26/35] Corrected typos --- src/vmprofiles/add.cpp | 2 +- src/vmprofiles/shld.cpp | 2 +- src/vmprofiles/shr.cpp | 2 +- src/vmprofiles/shrd.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/vmprofiles/add.cpp b/src/vmprofiles/add.cpp index e02e66c..56b4dcc 100644 --- a/src/vmprofiles/add.cpp +++ b/src/vmprofiles/add.cpp @@ -46,6 +46,7 @@ profiler_t add = { [](zydis_reg_t& vip, zydis_reg_t& vsp, hndlr_trace_t& hndlr) -> std::optional { vinstr_t res{mnemonic_t::add}; + res.imm.has_imm = false; // MOV REG, [VSP] const auto mov_reg_vsp = std::find_if( @@ -71,7 +72,6 @@ profiler_t add = { }); res.stack_size = mov_vsp_offset->m_instr.operands[1].size; - res.imm.size = mov_reg_vsp->m_instr.operands[1].size; return res; }}; } \ No newline at end of file diff --git a/src/vmprofiles/shld.cpp b/src/vmprofiles/shld.cpp index 54c1624..edbc98b 100644 --- a/src/vmprofiles/shld.cpp +++ b/src/vmprofiles/shld.cpp @@ -24,7 +24,7 @@ profiler_t shld = { instr.operands[1].mem.base == vsp && instr.operands[1].mem.disp.has_displacement; }, - // SHL REG, REG + // SHLD REG, REG [](const zydis_reg_t vip, const zydis_reg_t vsp, const zydis_decoded_instr_t& instr) -> bool { return instr.mnemonic == ZYDIS_MNEMONIC_SHLD && diff --git a/src/vmprofiles/shr.cpp b/src/vmprofiles/shr.cpp index 4a456c5..5b54a8e 100644 --- a/src/vmprofiles/shr.cpp +++ b/src/vmprofiles/shr.cpp @@ -2,7 +2,7 @@ namespace vm::instrs { profiler_t shr = { - "SHRD", + "SHR", mnemonic_t::shr, {{// MOV REG, [VSP] LOAD_VALUE, diff --git a/src/vmprofiles/shrd.cpp b/src/vmprofiles/shrd.cpp index 94000c2..77268b4 100644 --- a/src/vmprofiles/shrd.cpp +++ b/src/vmprofiles/shrd.cpp @@ -24,7 +24,7 @@ profiler_t shrd = { instr.operands[1].mem.base == vsp && instr.operands[1].mem.disp.has_displacement; }, - // SHR REG, REG + // SHRD REG, REG [](const zydis_reg_t vip, const zydis_reg_t vsp, const zydis_decoded_instr_t& instr) -> bool { return instr.mnemonic == ZYDIS_MNEMONIC_SHRD && -- 2.36.3 From 0c1b62b2ca96cc76c76325eddf398c97f12eb35d Mon Sep 17 00:00:00 2001 From: xtremegamer1 Date: Sun, 30 Oct 2022 10:08:07 -0600 Subject: [PATCH 27/35] minor fixes --- src/uc_allocation_tracker.cpp | 2 +- src/vmprofiles/and.cpp | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/uc_allocation_tracker.cpp b/src/uc_allocation_tracker.cpp index 95fc2a4..16b8d31 100644 --- a/src/uc_allocation_tracker.cpp +++ b/src/uc_allocation_tracker.cpp @@ -11,7 +11,7 @@ uc_err uct_context_alloc(uc_engine *uc, uc_context **context) } uc_err uct_context_free(uc_context *context) { - +g_allocation_tracker--; + --g_allocation_tracker; //std::printf("Allocations: %p\n", g_allocation_tracker); return uc_context_free(context); } diff --git a/src/vmprofiles/and.cpp b/src/vmprofiles/and.cpp index f6ac147..fed4203 100644 --- a/src/vmprofiles/and.cpp +++ b/src/vmprofiles/and.cpp @@ -1,19 +1,21 @@ #include +// Loads an address and value from the stack, ands the derefed address with the value namespace vm::instrs { profiler_t _and = { "AND", mnemonic_t::_and, - {{// MOV REG, [VSP] + {{// MOV REG, [VSP] This is the address LOAD_VALUE, - // MOV REG, [VSP+OFFSET] + // MOV REG, [VSP+8] [](const zydis_reg_t vip, const zydis_reg_t vsp, const zydis_decoded_instr_t& instr) -> bool { return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && instr.operands[1].type == ZYDIS_OPERAND_TYPE_MEMORY && instr.operands[1].mem.base == vsp && - instr.operands[1].mem.disp.has_displacement; + instr.operands[1].mem.disp.has_displacement, + instr.operands[1].mem.disp.value == 8; }, // AND [REG], REG [](const zydis_reg_t vip, const zydis_reg_t vsp, -- 2.36.3 From b6aaaaeef42bd93249a0a41a503864bab01cb825 Mon Sep 17 00:00:00 2001 From: xtremegamer1 Date: Tue, 1 Nov 2022 18:45:45 -0600 Subject: [PATCH 28/35] added pragma once --- include/uc_allocation_tracker.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/include/uc_allocation_tracker.hpp b/include/uc_allocation_tracker.hpp index ac50d6b..00093a4 100644 --- a/include/uc_allocation_tracker.hpp +++ b/include/uc_allocation_tracker.hpp @@ -1,3 +1,4 @@ +#pragma once #include extern int g_allocation_tracker; -- 2.36.3 From 09b4e52f3a4fd58849bdd78886212d03d882e0fd Mon Sep 17 00:00:00 2001 From: xtremegamer1 Date: Thu, 3 Nov 2022 21:42:59 -0600 Subject: [PATCH 29/35] ok so basicallt i --- src/vmprofiles/jmp.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vmprofiles/jmp.cpp b/src/vmprofiles/jmp.cpp index 8fe7d6f..3e15e36 100644 --- a/src/vmprofiles/jmp.cpp +++ b/src/vmprofiles/jmp.cpp @@ -142,6 +142,7 @@ profiler_t jmp = { vinstr_t res; res.mnemonic = mnemonic_t::jmp; res.imm.has_imm = false; + res.stack_size = 64; return res; }}; } \ No newline at end of file -- 2.36.3 From adff58848c639d483eb4b36614a1ed7815dfb516 Mon Sep 17 00:00:00 2001 From: xtremegamer1 Date: Sat, 12 Nov 2022 04:24:10 -0700 Subject: [PATCH 30/35] basically added a bool and stuff --- include/vminstrs.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/vminstrs.hpp b/include/vminstrs.hpp index 7a3f327..4d5fa5f 100644 --- a/include/vminstrs.hpp +++ b/include/vminstrs.hpp @@ -109,6 +109,8 @@ enum class vbranch_type { /// virtual code block /// struct vblk_t { + bool is_branch; + /// /// start address VIP of this basic block... /// -- 2.36.3 From e62c872fbe208e27b43f393daa2eed2a2a1134f8 Mon Sep 17 00:00:00 2001 From: xtremegamer1 Date: Sun, 4 Dec 2022 08:08:45 -0700 Subject: [PATCH 31/35] fixed svsp.cpp --- src/vmprofiles/svsp.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/vmprofiles/svsp.cpp b/src/vmprofiles/svsp.cpp index 7175fcf..bd565d0 100644 --- a/src/vmprofiles/svsp.cpp +++ b/src/vmprofiles/svsp.cpp @@ -31,19 +31,20 @@ profiler_t svsp = { }}}, [](zydis_reg_t& vip, zydis_reg_t& vsp, hndlr_trace_t& hndlr) -> std::optional { - vinstr_t res{mnemonic_t::lvsp}; - const auto sub_vsp = std::find_if( + vinstr_t res{mnemonic_t::svsp}; + const auto mov_vsp_reg = std::find_if( hndlr.m_instrs.begin(), hndlr.m_instrs.end(), [&](emu_instr_t& instr) -> bool { const auto& i = instr.m_instr; - return i.mnemonic == ZYDIS_MNEMONIC_SUB && - i.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && - i.operands[0].reg.value == vsp && - i.operands[1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE; + return i.mnemonic == ZYDIS_MNEMONIC_MOV && + i.operands[0].type == ZYDIS_OPERAND_TYPE_MEMORY && + i.operands[0].mem.base == vsp && + i.operands[0].mem.disp.has_displacement == false && + i.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER; }); res.imm.has_imm = false; - res.stack_size = sub_vsp->m_instr.operands[1].imm.value.u; + res.stack_size = mov_vsp_reg->m_instr.operands[1].size; return res; }}; } \ No newline at end of file -- 2.36.3 From f35a70749f4f4033c8f2d0e9e6394f10c98c4a18 Mon Sep 17 00:00:00 2001 From: xtremegamer1 Date: Fri, 9 Dec 2022 18:36:03 -0700 Subject: [PATCH 32/35] changed deobfuscation to keep register jumps --- src/vminstrs.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vminstrs.cpp b/src/vminstrs.cpp index feee8f2..329408b 100644 --- a/src/vminstrs.cpp +++ b/src/vminstrs.cpp @@ -69,7 +69,7 @@ void deobfuscate(hndlr_trace_t& trace) { break; } - if (vm::utils::is_jmp(itr->m_instr)) { + if (vm::utils::is_jmp(itr->m_instr) && itr->m_instr.operands[0].type != ZYDIS_OPERAND_TYPE_REGISTER) { uct_context_free(itr->m_cpu); trace.m_instrs.erase(itr); break; -- 2.36.3 From 343c7b95a4a18f119167a4f371a29cfa1624d404 Mon Sep 17 00:00:00 2001 From: xtremegamer1 Date: Sun, 11 Dec 2022 21:44:14 -0700 Subject: [PATCH 33/35] fixed this fucking bullshit --- src/vmprofiles/lvsp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vmprofiles/lvsp.cpp b/src/vmprofiles/lvsp.cpp index 5beece4..6eff169 100644 --- a/src/vmprofiles/lvsp.cpp +++ b/src/vmprofiles/lvsp.cpp @@ -15,7 +15,7 @@ profiler_t lvsp = { }}}, [](zydis_reg_t& vip, zydis_reg_t& vsp, hndlr_trace_t& hndlr) -> std::optional { - vinstr_t res{mnemonic_t::svsp}; + vinstr_t res{mnemonic_t::lvsp}; res.imm.has_imm = false; const auto load_vsp = std::find_if( -- 2.36.3 From 122120b65f6eb702de9d36cefc9b84cf2afddc02 Mon Sep 17 00:00:00 2001 From: xtremegamer1 Date: Mon, 12 Dec 2022 02:09:01 -0700 Subject: [PATCH 34/35] Improved instruction profiling --- src/vminstrs.cpp | 43 ++++++++++++++++++++++++++++++++++++---- src/vmprofiles/write.cpp | 2 ++ 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/src/vminstrs.cpp b/src/vminstrs.cpp index 329408b..53db713 100644 --- a/src/vminstrs.cpp +++ b/src/vminstrs.cpp @@ -131,8 +131,42 @@ void init() { } vinstr_t determine(hndlr_trace_t& hndlr) { - const auto& instrs = hndlr.m_instrs; - const auto profile = std::find_if( + std::vector trimmed_instrs = hndlr.m_instrs; + // find the last MOV REG, DWORD PTR [VIP] in the instruction stream, then + // remove any instructions from this instruction to the JMP/RET... + const auto rva_fetch = std::find_if( + trimmed_instrs.rbegin(), trimmed_instrs.rend(), + [& vip = hndlr.m_vip]( + const vm::instrs::emu_instr_t& instr) -> bool { + const auto& i = instr.m_instr; + return i.mnemonic == ZYDIS_MNEMONIC_MOV && + i.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && + i.operands[1].type == ZYDIS_OPERAND_TYPE_MEMORY && + i.operands[1].mem.base == vip && i.operands[1].size == 32; + }); + + if (rva_fetch != trimmed_instrs.rend()) + trimmed_instrs.erase((rva_fetch + 1).base(), trimmed_instrs.end()); + auto profile = std::find_if( + profiles.begin(), profiles.end(), [&](profiler_t* profile) -> bool { + for (auto& matcher : profile->matchers) { + const auto matched = + std::find_if(trimmed_instrs.begin(), trimmed_instrs.end(), + [&](const emu_instr_t& instr) -> bool { + const auto& i = instr.m_instr; + return matcher(hndlr.m_vip, hndlr.m_vsp, i); + }); + if (matched == trimmed_instrs.end()) + return false; + } + return true; + }); + + if (profile == profiles.end()) + { + const auto& instrs = hndlr.m_instrs; + // Try again with original instruction stream including those after the last MOV REG, DWORD PTR [VIP] just to be sure + profile = std::find_if( profiles.begin(), profiles.end(), [&](profiler_t* profile) -> bool { for (auto& matcher : profile->matchers) { const auto matched = @@ -144,8 +178,9 @@ vinstr_t determine(hndlr_trace_t& hndlr) { if (matched == instrs.end()) return false; } - return true; - }); + return true; + }); + } if (profile == profiles.end()) return vinstr_t{mnemonic_t::unknown}; diff --git a/src/vmprofiles/write.cpp b/src/vmprofiles/write.cpp index 8a6a686..e12f411 100644 --- a/src/vmprofiles/write.cpp +++ b/src/vmprofiles/write.cpp @@ -29,6 +29,8 @@ profiler_t write = { return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[0].type == ZYDIS_OPERAND_TYPE_MEMORY && instr.operands[0].mem.base != vsp && + instr.operands[0].mem.base != ZYDIS_REGISTER_RSP && + //!instr.operands[0].mem.disp.has_displacement && instr.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER && instr.operands[1].reg.value != vsp; }}}, -- 2.36.3 From fa64967bd77983b8fd3affc1de196a0d525adb52 Mon Sep 17 00:00:00 2001 From: xtremegamer1 Date: Thu, 15 Dec 2022 01:59:42 -0700 Subject: [PATCH 35/35] fixed vmexit pop order --- include/vminstrs.hpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/vminstrs.hpp b/include/vminstrs.hpp index 4d5fa5f..f5cdfa2 100644 --- a/include/vminstrs.hpp +++ b/include/vminstrs.hpp @@ -2,6 +2,7 @@ #include #include +#include #define VIRTUAL_REGISTER_COUNT 24 #define VIRTUAL_SEH_REGISTER 24 @@ -158,6 +159,8 @@ struct vblk_t { std::uintptr_t rip; } m_jmp; + std::array vmexit_pop_order; + /// /// vector of virtual instructions for this basic block... /// -- 2.36.3