removed capture from lambdas in profiles... compiles on linux now. added readme for vm_entry_test...

main
IDontCode 3 years ago
parent 1b2b79e3e9
commit b7330ad02f

@ -1,5 +1,6 @@
#pragma once #pragma once
#include <unicorn/unicorn.h> #include <unicorn/unicorn.h>
#include <vmutils.hpp> #include <vmutils.hpp>
#define VIRTUAL_REGISTER_COUNT 24 #define VIRTUAL_REGISTER_COUNT 24
@ -239,18 +240,16 @@ struct hndlr_trace_t {
/// matcher function which returns true if an instruction matches a desired /// matcher function which returns true if an instruction matches a desired
/// one... /// one...
/// </summary> /// </summary>
using matcher_t = std::function<bool(const zydis_reg_t vip, using matcher_t =
const zydis_reg_t vsp, std::function<bool(const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr)>; const zydis_decoded_instr_t& instr)>;
/// <summary> /// <summary>
/// virtual instruction structure generator... this can update the vip and vsp /// virtual instruction structure generator... this can update the vip and vsp
/// argument... it cannot update the instruction stream (hndlr)... /// argument... it cannot update the instruction stream (hndlr)...
/// </summary> /// </summary>
using vinstr_gen_t = using vinstr_gen_t = std::function<std::optional<vinstr_t>(
std::function<std::optional<vinstr_t>(zydis_reg_t& vip, zydis_reg_t& vip, zydis_reg_t& vsp, hndlr_trace_t& hndlr)>;
zydis_reg_t& vsp,
hndlr_trace_t& hndlr)>;
/// <summary> /// <summary>
/// each virtual instruction has its own profiler_t structure which can generate /// each virtual instruction has its own profiler_t structure which can generate
@ -412,7 +411,7 @@ profiler_t* get_profile(mnemonic_t mnemonic);
// MOV REG, [VIP] // MOV REG, [VIP]
#define IMM_FETCH \ #define IMM_FETCH \
[&](const zydis_reg_t vip, const zydis_reg_t vsp, \ [](const zydis_reg_t vip, const zydis_reg_t vsp, \
const zydis_decoded_instr_t& instr) -> bool { \ const zydis_decoded_instr_t& instr) -> bool { \
return vm::utils::is_mov(instr) && \ return vm::utils::is_mov(instr) && \
instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && \ instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && \
@ -422,7 +421,7 @@ profiler_t* get_profile(mnemonic_t mnemonic);
// MOV [VSP], REG // MOV [VSP], REG
#define STR_VALUE \ #define STR_VALUE \
[&](const zydis_reg_t vip, const zydis_reg_t vsp, \ [](const zydis_reg_t vip, const zydis_reg_t vsp, \
const zydis_decoded_instr_t& instr) -> bool { \ const zydis_decoded_instr_t& instr) -> bool { \
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && \ return instr.mnemonic == ZYDIS_MNEMONIC_MOV && \
instr.operands[0].type == ZYDIS_OPERAND_TYPE_MEMORY && \ instr.operands[0].type == ZYDIS_OPERAND_TYPE_MEMORY && \
@ -432,7 +431,7 @@ profiler_t* get_profile(mnemonic_t mnemonic);
// MOV REG, [VSP] // MOV REG, [VSP]
#define LOAD_VALUE \ #define LOAD_VALUE \
[&](const zydis_reg_t vip, const zydis_reg_t vsp, \ [](const zydis_reg_t vip, const zydis_reg_t vsp, \
const zydis_decoded_instr_t& instr) -> bool { \ const zydis_decoded_instr_t& instr) -> bool { \
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && \ return instr.mnemonic == ZYDIS_MNEMONIC_MOV && \
instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && \ instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && \
@ -442,7 +441,7 @@ profiler_t* get_profile(mnemonic_t mnemonic);
// SUB VSP, OFFSET // SUB VSP, OFFSET
#define SUB_VSP \ #define SUB_VSP \
[&](const zydis_reg_t vip, const zydis_reg_t vsp, \ [](const zydis_reg_t vip, const zydis_reg_t vsp, \
const zydis_decoded_instr_t& instr) -> bool { \ const zydis_decoded_instr_t& instr) -> bool { \
return instr.mnemonic == ZYDIS_MNEMONIC_SUB && \ return instr.mnemonic == ZYDIS_MNEMONIC_SUB && \
instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && \ instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && \

@ -17,9 +17,7 @@ struct vm_enter_t {
std::uint32_t encrypted_rva; std::uint32_t encrypted_rva;
}; };
std::uintptr_t sigscan(void* base, std::uintptr_t sigscan(void* base, std::uint32_t size, const char* pattern,
std::uint32_t size,
const char* pattern,
const char* mask); const char* mask);
std::vector<vm_enter_t> get_vm_entries(std::uintptr_t module_base, std::vector<vm_enter_t> get_vm_entries(std::uintptr_t module_base,

@ -1,5 +1,7 @@
#pragma once #pragma once
#include <Zydis/Zydis.h>
#include <vmctx.hpp> #include <vmctx.hpp>
#include <vminstrs.hpp>
#include <vmlocate.hpp> #include <vmlocate.hpp>
#include <vmutils.hpp> #include <vmutils.hpp>
#include <vminstrs.hpp>

@ -1,9 +1,12 @@
#pragma once #pragma once
#include <Zydis/Zydis.h> #include <Zydis/Zydis.h>
#include <algorithm> #include <algorithm>
#include <atomic>
#include <cstdint> #include <cstdint>
#include <fstream> #include <fstream>
#include <functional> #include <functional>
#include <memory>
#include <nt/image.hpp> #include <nt/image.hpp>
#include <optional> #include <optional>
#include <vector> #include <vector>
@ -46,8 +49,7 @@ inline void init() {
inline bool open_binary_file(const std::string& file, inline bool open_binary_file(const std::string& file,
std::vector<uint8_t>& data) { std::vector<uint8_t>& data) {
std::ifstream fstr(file, std::ios::binary); std::ifstream fstr(file, std::ios::binary);
if (!fstr.is_open()) if (!fstr.is_open()) return false;
return false;
fstr.unsetf(std::ios::skipws); fstr.unsetf(std::ios::skipws);
fstr.seekg(0, std::ios::end); fstr.seekg(0, std::ios::end);
@ -117,10 +119,8 @@ bool compare(zydis_reg_t a, zydis_reg_t b);
/// from...</param> <param name="keep_jmps">keep JCC's in the flattened /// from...</param> <param name="keep_jmps">keep JCC's in the flattened
/// instruction stream...</param> <returns>returns true if flattened was /// instruction stream...</param> <returns>returns true if flattened was
/// successful...</returns> /// successful...</returns>
bool flatten(zydis_rtn_t& routine, bool flatten(zydis_rtn_t& routine, std::uintptr_t routine_addr,
std::uintptr_t routine_addr, bool keep_jmps = false, std::uint32_t max_instrs = 500,
bool keep_jmps = false,
std::uint32_t max_instrs = 500,
std::uintptr_t module_base = 0ull); std::uintptr_t module_base = 0ull);
/// <summary> /// <summary>

@ -1,15 +1,13 @@
#include <string>
#include <vmlocate.hpp> #include <vmlocate.hpp>
namespace vm::locate { namespace vm::locate {
std::uintptr_t sigscan(void* base, std::uintptr_t sigscan(void* base, std::uint32_t size, const char* pattern,
std::uint32_t size,
const char* pattern,
const char* mask) { const char* mask) {
static const auto check_mask = [&](const char* base, const char* pattern, static const auto check_mask = [&](const char* base, const char* pattern,
const char* mask) -> bool { const char* mask) -> bool {
for (; *mask; ++base, ++pattern, ++mask) for (; *mask; ++base, ++pattern, ++mask)
if (*mask == 'x' && *base != *pattern) if (*mask == 'x' && *base != *pattern) return false;
return false;
return true; return true;
}; };
@ -39,8 +37,7 @@ std::vector<vm_enter_t> get_vm_entries(std::uintptr_t module_base,
}); });
// skip RSP push... // skip RSP push...
if (res == rtn.end() && reg != ZYDIS_REGISTER_RSP) if (res == rtn.end() && reg != ZYDIS_REGISTER_RSP) return false;
return false;
} }
return true; return true;
}; };
@ -50,11 +47,9 @@ std::vector<vm_enter_t> get_vm_entries(std::uintptr_t module_base,
PUSH_4B_IMM, PUSH_4B_MASK); PUSH_4B_IMM, PUSH_4B_MASK);
zydis_rtn_t rtn; zydis_rtn_t rtn;
if (!vm::utils::scn::executable(module_base, result)) if (!vm::utils::scn::executable(module_base, result)) continue;
continue;
if (!vm::utils::flatten(rtn, result, false, 500, module_base)) if (!vm::utils::flatten(rtn, result, false, 500, module_base)) continue;
continue;
// the last instruction in the stream should be a JMP to a register or a // the last instruction in the stream should be a JMP to a register or a
// return instruction... // return instruction...
@ -93,8 +88,7 @@ std::vector<vm_enter_t> get_vm_entries(std::uintptr_t module_base,
> 0x7a53 : push rbx > 0x7a53 : push rbx
> 0x500d : push r15 > 0x500d : push r15
*/ */
if (num_pushs != 1) if (num_pushs != 1) continue;
continue;
// check for a pushfq... // check for a pushfq...
// > 0x4926 : pushfq <--- // > 0x4926 : pushfq <---
@ -123,8 +117,7 @@ std::vector<vm_enter_t> get_vm_entries(std::uintptr_t module_base,
> 0x7a53 : push rbx > 0x7a53 : push rbx
> 0x500d : push r15 > 0x500d : push r15
*/ */
if (!push_regs(rtn)) if (!push_regs(rtn)) continue;
continue;
// check for a mov reg, rsp // check for a mov reg, rsp
if (!vm::locate::find(rtn, [&](const zydis_instr_t& instr) -> bool { if (!vm::locate::find(rtn, [&](const zydis_instr_t& instr) -> bool {

@ -7,8 +7,7 @@ profiler_t add = {
{{// MOV REG, [VSP] {{// MOV REG, [VSP]
LOAD_VALUE, LOAD_VALUE,
// MOV REG, [VSP+OFFSET] // MOV REG, [VSP+OFFSET]
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER &&
@ -17,16 +16,14 @@ profiler_t add = {
instr.operands[1].mem.disp.has_displacement; instr.operands[1].mem.disp.has_displacement;
}, },
// ADD REG, REG // ADD REG, REG
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_ADD && return instr.mnemonic == ZYDIS_MNEMONIC_ADD &&
instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER; instr.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER;
}, },
// MOV [VSP+OFFSET], REG // MOV [VSP+OFFSET], REG
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[0].type == ZYDIS_OPERAND_TYPE_MEMORY && instr.operands[0].type == ZYDIS_OPERAND_TYPE_MEMORY &&
@ -35,21 +32,18 @@ profiler_t add = {
instr.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER; instr.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER;
}, },
// PUSHFQ // PUSHFQ
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ; return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ;
}, },
// POP [VSP] // POP [VSP]
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_POP && return instr.mnemonic == ZYDIS_MNEMONIC_POP &&
instr.operands[0].type == ZYDIS_OPERAND_TYPE_MEMORY && instr.operands[0].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[0].mem.base == vsp; instr.operands[0].mem.base == vsp;
}}}, }}},
[&](zydis_reg_t& vip, [](zydis_reg_t& vip, zydis_reg_t& vsp,
zydis_reg_t& vsp,
hndlr_trace_t& hndlr) -> std::optional<vinstr_t> { hndlr_trace_t& hndlr) -> std::optional<vinstr_t> {
vinstr_t res{mnemonic_t::add}; vinstr_t res{mnemonic_t::add};

@ -7,8 +7,7 @@ profiler_t imul = {
{{// MOV REG, [VSP] {{// MOV REG, [VSP]
LOAD_VALUE, LOAD_VALUE,
// MOV REG, [VSP+OFFSET] // MOV REG, [VSP+OFFSET]
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER &&
@ -17,15 +16,13 @@ profiler_t imul = {
instr.operands[1].mem.disp.has_displacement; instr.operands[1].mem.disp.has_displacement;
}, },
// IMUL REG // IMUL REG
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_IMUL && return instr.mnemonic == ZYDIS_MNEMONIC_IMUL &&
instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER; instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER;
}, },
// MOV [VSP+OFFSET], REG // MOV [VSP+OFFSET], REG
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[0].type == ZYDIS_OPERAND_TYPE_MEMORY && instr.operands[0].type == ZYDIS_OPERAND_TYPE_MEMORY &&
@ -34,21 +31,18 @@ profiler_t imul = {
instr.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER; instr.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER;
}, },
// PUSHFQ // PUSHFQ
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ; return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ;
}, },
// POP [VSP] // POP [VSP]
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_POP && return instr.mnemonic == ZYDIS_MNEMONIC_POP &&
instr.operands[0].type == ZYDIS_OPERAND_TYPE_MEMORY && instr.operands[0].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[0].mem.base == vsp; instr.operands[0].mem.base == vsp;
}}}, }}},
[&](zydis_reg_t& vip, [](zydis_reg_t& vip, zydis_reg_t& vsp,
zydis_reg_t& vsp,
hndlr_trace_t& hndlr) -> std::optional<vinstr_t> { hndlr_trace_t& hndlr) -> std::optional<vinstr_t> {
vinstr_t res{mnemonic_t::imul}; vinstr_t res{mnemonic_t::imul};
res.imm.has_imm = false; res.imm.has_imm = false;

@ -7,8 +7,7 @@ profiler_t jmp = {
{{// MOV REG, [VSP] {{// MOV REG, [VSP]
LOAD_VALUE, LOAD_VALUE,
// ADD VSP, 8 // ADD VSP, 8
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_ADD && return instr.mnemonic == ZYDIS_MNEMONIC_ADD &&
instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER &&
@ -17,8 +16,7 @@ profiler_t jmp = {
instr.operands[1].imm.value.u == 8; instr.operands[1].imm.value.u == 8;
}, },
// MOV REG, IMM_64 // MOV REG, IMM_64
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER &&
@ -26,8 +24,7 @@ profiler_t jmp = {
instr.operands[1].size == 64; instr.operands[1].size == 64;
}, },
// LEA REG, [0x0] ; disp is -7... // LEA REG, [0x0] ; disp is -7...
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_LEA && return instr.mnemonic == ZYDIS_MNEMONIC_LEA &&
instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER &&
@ -35,8 +32,7 @@ profiler_t jmp = {
instr.operands[1].mem.disp.has_displacement && instr.operands[1].mem.disp.has_displacement &&
instr.operands[1].mem.disp.value == -7; instr.operands[1].mem.disp.value == -7;
}}}, }}},
[&](zydis_reg_t& vip, [](zydis_reg_t& vip, zydis_reg_t& vsp,
zydis_reg_t& vsp,
hndlr_trace_t& hndlr) -> std::optional<vinstr_t> { hndlr_trace_t& hndlr) -> std::optional<vinstr_t> {
const auto& instrs = hndlr.m_instrs; const auto& instrs = hndlr.m_instrs;
const auto xchg = std::find_if( const auto xchg = std::find_if(
@ -76,8 +72,7 @@ profiler_t jmp = {
i.operands[1].reg.value == write_dep; i.operands[1].reg.value == write_dep;
}); });
if (mov_reg_write_dep == instrs.end()) if (mov_reg_write_dep == instrs.end()) return {};
return {};
vsp = mov_reg_write_dep->m_instr.operands[0].reg.value; vsp = mov_reg_write_dep->m_instr.operands[0].reg.value;
} else { } else {
@ -92,8 +87,7 @@ profiler_t jmp = {
i.operands[1].mem.base == vsp; i.operands[1].mem.base == vsp;
}); });
if (mov_reg_deref_vsp == instrs.end()) if (mov_reg_deref_vsp == instrs.end()) return {};
return {};
// find the MOV REG, mov_reg_deref_vsp->operands[0].reg.value // find the MOV REG, mov_reg_deref_vsp->operands[0].reg.value
const auto mov_vip_reg = std::find_if( const auto mov_vip_reg = std::find_if(
@ -107,8 +101,7 @@ profiler_t jmp = {
mov_reg_deref_vsp->m_instr.operands[0].reg.value; mov_reg_deref_vsp->m_instr.operands[0].reg.value;
}); });
if (mov_vip_reg == instrs.end()) if (mov_vip_reg == instrs.end()) return {};
return {};
vip = mov_vip_reg->m_instr.operands[0].reg.value; vip = mov_vip_reg->m_instr.operands[0].reg.value;
@ -128,8 +121,8 @@ profiler_t jmp = {
} }
vinstr_t res; vinstr_t res;
memset(&res, NULL, sizeof vinstr_t);
res.mnemonic = mnemonic_t::jmp; res.mnemonic = mnemonic_t::jmp;
res.imm.has_imm = false;
return res; return res;
}}; }};
} }

@ -10,8 +10,7 @@ profiler_t lconst = {
SUB_VSP, SUB_VSP,
// MOV [VSP], REG // MOV [VSP], REG
STR_VALUE}}, STR_VALUE}},
[&](zydis_reg_t& vip, [](zydis_reg_t& vip, zydis_reg_t& vsp,
zydis_reg_t& vsp,
hndlr_trace_t& hndlr) -> std::optional<vinstr_t> { hndlr_trace_t& hndlr) -> std::optional<vinstr_t> {
vinstr_t res; vinstr_t res;
res.mnemonic = mnemonic_t::lconst; res.mnemonic = mnemonic_t::lconst;

@ -7,8 +7,7 @@ profiler_t lreg = {
{{// MOV REG, [VIP] {{// MOV REG, [VIP]
IMM_FETCH, IMM_FETCH,
// MOV REG, [RSP+REG] // MOV REG, [RSP+REG]
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER &&
@ -20,11 +19,9 @@ profiler_t lreg = {
SUB_VSP, SUB_VSP,
// MOV [VSP], REG // MOV [VSP], REG
STR_VALUE}}, STR_VALUE}},
[&](zydis_reg_t& vip, [](zydis_reg_t& vip, zydis_reg_t& vsp,
zydis_reg_t& vsp,
hndlr_trace_t& hndlr) -> std::optional<vinstr_t> { hndlr_trace_t& hndlr) -> std::optional<vinstr_t> {
vinstr_t res; vinstr_t res;
memset(&res, NULL, sizeof res);
res.mnemonic = mnemonic_t::lreg; res.mnemonic = mnemonic_t::lreg;
res.imm.has_imm = true; res.imm.has_imm = true;
res.imm.size = 8; res.imm.size = 8;

@ -5,8 +5,7 @@ profiler_t lvsp = {
"LVSP", "LVSP",
mnemonic_t::lvsp, mnemonic_t::lvsp,
{{// MOV VSP, [VSP] {{// MOV VSP, [VSP]
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER &&
@ -14,8 +13,7 @@ profiler_t lvsp = {
instr.operands[1].type == ZYDIS_OPERAND_TYPE_MEMORY && instr.operands[1].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[1].mem.base == vsp; instr.operands[1].mem.base == vsp;
}}}, }}},
[&](zydis_reg_t& vip, [](zydis_reg_t& vip, zydis_reg_t& vsp,
zydis_reg_t& vsp,
hndlr_trace_t& hndlr) -> std::optional<vinstr_t> { hndlr_trace_t& hndlr) -> std::optional<vinstr_t> {
vinstr_t res{mnemonic_t::svsp}; vinstr_t res{mnemonic_t::svsp};
res.imm.has_imm = false; res.imm.has_imm = false;

@ -7,8 +7,7 @@ profiler_t nand = {
{{// MOV REG, [VSP] {{// MOV REG, [VSP]
LOAD_VALUE, LOAD_VALUE,
// MOV REG, [VSP+OFFSET] // MOV REG, [VSP+OFFSET]
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER &&
@ -17,23 +16,20 @@ profiler_t nand = {
instr.operands[1].mem.disp.has_displacement; instr.operands[1].mem.disp.has_displacement;
}, },
// NOT REG // NOT REG
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_NOT && return instr.mnemonic == ZYDIS_MNEMONIC_NOT &&
instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER; instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER;
}, },
// AND REG, REG // AND REG, REG
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_AND && return instr.mnemonic == ZYDIS_MNEMONIC_AND &&
instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER; instr.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER;
}, },
// MOV [VSP+OFFSET], REG // MOV [VSP+OFFSET], REG
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[0].type == ZYDIS_OPERAND_TYPE_MEMORY && instr.operands[0].type == ZYDIS_OPERAND_TYPE_MEMORY &&
@ -42,21 +38,18 @@ profiler_t nand = {
instr.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER; instr.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER;
}, },
// PUSHFQ // PUSHFQ
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ; return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ;
}, },
// POP [VSP] // POP [VSP]
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_POP && return instr.mnemonic == ZYDIS_MNEMONIC_POP &&
instr.operands[0].type == ZYDIS_OPERAND_TYPE_MEMORY && instr.operands[0].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[0].mem.base == vsp; instr.operands[0].mem.base == vsp;
}}}, }}},
[&](zydis_reg_t& vip, [](zydis_reg_t& vip, zydis_reg_t& vsp,
zydis_reg_t& vsp,
hndlr_trace_t& hndlr) -> std::optional<vinstr_t> { hndlr_trace_t& hndlr) -> std::optional<vinstr_t> {
vinstr_t res{mnemonic_t::nand}; vinstr_t res{mnemonic_t::nand};
res.imm.has_imm = false; res.imm.has_imm = false;

@ -5,8 +5,7 @@ profiler_t nop = {
"NOP", "NOP",
mnemonic_t::nop, mnemonic_t::nop,
{{// LEA REG, [0x0] ; disp is -7... {{// LEA REG, [0x0] ; disp is -7...
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_LEA && return instr.mnemonic == ZYDIS_MNEMONIC_LEA &&
instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER &&
@ -14,8 +13,7 @@ profiler_t nop = {
instr.operands[1].mem.disp.has_displacement && instr.operands[1].mem.disp.has_displacement &&
instr.operands[1].mem.disp.value == -7; instr.operands[1].mem.disp.value == -7;
}}}, }}},
[&](zydis_reg_t& vip, [](zydis_reg_t& vip, zydis_reg_t& vsp,
zydis_reg_t& vsp,
hndlr_trace_t& hndlr) -> std::optional<vinstr_t> { hndlr_trace_t& hndlr) -> std::optional<vinstr_t> {
vinstr_t res; vinstr_t res;
res.mnemonic = mnemonic_t::nop; res.mnemonic = mnemonic_t::nop;

@ -7,8 +7,7 @@ profiler_t nor = {
{{// MOV REG, [VSP] {{// MOV REG, [VSP]
LOAD_VALUE, LOAD_VALUE,
// MOV REG, [VSP+OFFSET] // MOV REG, [VSP+OFFSET]
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER &&
@ -17,23 +16,20 @@ profiler_t nor = {
instr.operands[1].mem.disp.has_displacement; instr.operands[1].mem.disp.has_displacement;
}, },
// NOT REG // NOT REG
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_NOT && return instr.mnemonic == ZYDIS_MNEMONIC_NOT &&
instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER; instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER;
}, },
// OR REG, REG // OR REG, REG
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_OR && return instr.mnemonic == ZYDIS_MNEMONIC_OR &&
instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER; instr.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER;
}, },
// MOV [VSP+OFFSET], REG // MOV [VSP+OFFSET], REG
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[0].type == ZYDIS_OPERAND_TYPE_MEMORY && instr.operands[0].type == ZYDIS_OPERAND_TYPE_MEMORY &&
@ -42,21 +38,18 @@ profiler_t nor = {
instr.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER; instr.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER;
}, },
// PUSHFQ // PUSHFQ
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ; return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ;
}, },
// POP [VSP] // POP [VSP]
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_POP && return instr.mnemonic == ZYDIS_MNEMONIC_POP &&
instr.operands[0].type == ZYDIS_OPERAND_TYPE_MEMORY && instr.operands[0].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[0].mem.base == vsp; instr.operands[0].mem.base == vsp;
}}}, }}},
[&](zydis_reg_t& vip, [](zydis_reg_t& vip, zydis_reg_t& vsp,
zydis_reg_t& vsp,
hndlr_trace_t& hndlr) -> std::optional<vinstr_t> { hndlr_trace_t& hndlr) -> std::optional<vinstr_t> {
vinstr_t res{mnemonic_t::nand}; vinstr_t res{mnemonic_t::nand};
res.imm.has_imm = false; res.imm.has_imm = false;

@ -7,8 +7,7 @@ profiler_t read = {
{{// MOV REG, [VSP] {{// MOV REG, [VSP]
LOAD_VALUE, LOAD_VALUE,
// MOV REG, [REG] // MOV REG, [REG]
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER &&
@ -17,8 +16,7 @@ profiler_t read = {
}, },
// MOV [VSP], REG // MOV [VSP], REG
STR_VALUE}}, STR_VALUE}},
[&](zydis_reg_t& vip, [](zydis_reg_t& vip, zydis_reg_t& vsp,
zydis_reg_t& vsp,
hndlr_trace_t& hndlr) -> std::optional<vinstr_t> { hndlr_trace_t& hndlr) -> std::optional<vinstr_t> {
vinstr_t res{mnemonic_t::read}; vinstr_t res{mnemonic_t::read};
res.imm.has_imm = false; res.imm.has_imm = false;

@ -7,8 +7,7 @@ profiler_t shr = {
{{// MOV REG, [VSP] {{// MOV REG, [VSP]
LOAD_VALUE, LOAD_VALUE,
// MOV REG, [VSP+OFFSET] // MOV REG, [VSP+OFFSET]
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER &&
@ -17,16 +16,14 @@ profiler_t shr = {
instr.operands[1].mem.disp.has_displacement; instr.operands[1].mem.disp.has_displacement;
}, },
// SHR REG, REG // SHR REG, REG
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_SHR && return instr.mnemonic == ZYDIS_MNEMONIC_SHR &&
instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER; instr.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER;
}, },
// MOV [VSP+OFFSET], REG // MOV [VSP+OFFSET], REG
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[0].type == ZYDIS_OPERAND_TYPE_MEMORY && instr.operands[0].type == ZYDIS_OPERAND_TYPE_MEMORY &&
@ -35,21 +32,18 @@ profiler_t shr = {
instr.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER; instr.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER;
}, },
// PUSHFQ // PUSHFQ
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ; return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ;
}, },
// POP [VSP] // POP [VSP]
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_POP && return instr.mnemonic == ZYDIS_MNEMONIC_POP &&
instr.operands[0].type == ZYDIS_OPERAND_TYPE_MEMORY && instr.operands[0].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[0].mem.base == vsp; instr.operands[0].mem.base == vsp;
}}}, }}},
[&](zydis_reg_t& vip, [](zydis_reg_t& vip, zydis_reg_t& vsp,
zydis_reg_t& vsp,
hndlr_trace_t& hndlr) -> std::optional<vinstr_t> { hndlr_trace_t& hndlr) -> std::optional<vinstr_t> {
vinstr_t res{mnemonic_t::shr}; vinstr_t res{mnemonic_t::shr};
res.imm.has_imm = false; res.imm.has_imm = false;

@ -7,8 +7,7 @@ profiler_t sreg = {
{{// MOV REG, [VSP] {{// MOV REG, [VSP]
LOAD_VALUE, LOAD_VALUE,
// ADD VSP, OFFSET // ADD VSP, OFFSET
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_ADD && return instr.mnemonic == ZYDIS_MNEMONIC_ADD &&
instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER &&
@ -18,8 +17,7 @@ profiler_t sreg = {
// MOV REG, [VIP] // MOV REG, [VIP]
IMM_FETCH, IMM_FETCH,
// MOV [RSP+REG], REG // MOV [RSP+REG], REG
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[0].type == ZYDIS_OPERAND_TYPE_MEMORY && instr.operands[0].type == ZYDIS_OPERAND_TYPE_MEMORY &&
@ -27,11 +25,9 @@ profiler_t sreg = {
instr.operands[0].mem.index != ZYDIS_REGISTER_NONE && instr.operands[0].mem.index != ZYDIS_REGISTER_NONE &&
instr.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER; instr.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER;
}}}, }}},
[&](zydis_reg_t& vip, [](zydis_reg_t& vip, zydis_reg_t& vsp,
zydis_reg_t& vsp,
hndlr_trace_t& hndlr) -> std::optional<vinstr_t> { hndlr_trace_t& hndlr) -> std::optional<vinstr_t> {
vinstr_t res; vinstr_t res;
memset(&res, NULL, sizeof res);
res.mnemonic = mnemonic_t::sreg; res.mnemonic = mnemonic_t::sreg;
res.imm.has_imm = true; res.imm.has_imm = true;
res.imm.size = 8; res.imm.size = 8;

@ -5,8 +5,7 @@ profiler_t svsp = {
"SVSP", "SVSP",
mnemonic_t::svsp, mnemonic_t::svsp,
{{// MOV REG, VSP {{// MOV REG, VSP
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER &&
@ -14,8 +13,7 @@ profiler_t svsp = {
instr.operands[1].reg.value == vsp; instr.operands[1].reg.value == vsp;
}, },
// SUB VSP, OFFSET // SUB VSP, OFFSET
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_SUB && return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER &&
@ -23,8 +21,7 @@ profiler_t svsp = {
instr.operands[1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE; instr.operands[1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE;
}, },
// MOV [VSP], REG // MOV [VSP], REG
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[0].type == ZYDIS_OPERAND_TYPE_MEMORY && instr.operands[0].type == ZYDIS_OPERAND_TYPE_MEMORY &&
@ -32,8 +29,7 @@ profiler_t svsp = {
instr.operands[0].mem.disp.has_displacement == false && instr.operands[0].mem.disp.has_displacement == false &&
instr.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER; instr.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER;
}}}, }}},
[&](zydis_reg_t& vip, [](zydis_reg_t& vip, zydis_reg_t& vsp,
zydis_reg_t& vsp,
hndlr_trace_t& hndlr) -> std::optional<vinstr_t> { hndlr_trace_t& hndlr) -> std::optional<vinstr_t> {
vinstr_t res{mnemonic_t::lvsp}; vinstr_t res{mnemonic_t::lvsp};
const auto sub_vsp = std::find_if( const auto sub_vsp = std::find_if(

@ -5,8 +5,7 @@ profiler_t vmexit = {
"VMEXIT", "VMEXIT",
mnemonic_t::vmexit, mnemonic_t::vmexit,
{{// MOV RSP, VSP {{// MOV RSP, VSP
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER &&
@ -15,129 +14,113 @@ profiler_t vmexit = {
instr.operands[1].reg.value == vsp; instr.operands[1].reg.value == vsp;
}, },
// POP R13 // POP R13
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_POP && return instr.mnemonic == ZYDIS_MNEMONIC_POP &&
instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[0].reg.value == ZYDIS_REGISTER_R13; instr.operands[0].reg.value == ZYDIS_REGISTER_R13;
}, },
// POP RCX // POP RCX
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_POP && return instr.mnemonic == ZYDIS_MNEMONIC_POP &&
instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[0].reg.value == ZYDIS_REGISTER_RCX; instr.operands[0].reg.value == ZYDIS_REGISTER_RCX;
}, },
// POP RBP // POP RBP
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_POP && return instr.mnemonic == ZYDIS_MNEMONIC_POP &&
instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[0].reg.value == ZYDIS_REGISTER_RBP; instr.operands[0].reg.value == ZYDIS_REGISTER_RBP;
}, },
// POP R8 // POP R8
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_POP && return instr.mnemonic == ZYDIS_MNEMONIC_POP &&
instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[0].reg.value == ZYDIS_REGISTER_R8; instr.operands[0].reg.value == ZYDIS_REGISTER_R8;
}, },
// POP R15 // POP R15
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_POP && return instr.mnemonic == ZYDIS_MNEMONIC_POP &&
instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[0].reg.value == ZYDIS_REGISTER_R15; instr.operands[0].reg.value == ZYDIS_REGISTER_R15;
}, },
// POP RDX // POP RDX
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_POP && return instr.mnemonic == ZYDIS_MNEMONIC_POP &&
instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[0].reg.value == ZYDIS_REGISTER_RDX; instr.operands[0].reg.value == ZYDIS_REGISTER_RDX;
}, },
// POP RDI // POP RDI
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_POP && return instr.mnemonic == ZYDIS_MNEMONIC_POP &&
instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[0].reg.value == ZYDIS_REGISTER_RDI; instr.operands[0].reg.value == ZYDIS_REGISTER_RDI;
}, },
// POP R11 // POP R11
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_POP && return instr.mnemonic == ZYDIS_MNEMONIC_POP &&
instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[0].reg.value == ZYDIS_REGISTER_R11; instr.operands[0].reg.value == ZYDIS_REGISTER_R11;
}, },
// POP RAX // POP RAX
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_POP && return instr.mnemonic == ZYDIS_MNEMONIC_POP &&
instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[0].reg.value == ZYDIS_REGISTER_RAX; instr.operands[0].reg.value == ZYDIS_REGISTER_RAX;
}, },
// POP R9 // POP R9
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_POP && return instr.mnemonic == ZYDIS_MNEMONIC_POP &&
instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[0].reg.value == ZYDIS_REGISTER_R9; instr.operands[0].reg.value == ZYDIS_REGISTER_R9;
}, },
// POP RSI // POP RSI
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_POP && return instr.mnemonic == ZYDIS_MNEMONIC_POP &&
instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[0].reg.value == ZYDIS_REGISTER_RSI; instr.operands[0].reg.value == ZYDIS_REGISTER_RSI;
}, },
// POP R14 // POP R14
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_POP && return instr.mnemonic == ZYDIS_MNEMONIC_POP &&
instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[0].reg.value == ZYDIS_REGISTER_R14; instr.operands[0].reg.value == ZYDIS_REGISTER_R14;
}, },
// POP R12 // POP R12
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_POP && return instr.mnemonic == ZYDIS_MNEMONIC_POP &&
instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[0].reg.value == ZYDIS_REGISTER_R12; instr.operands[0].reg.value == ZYDIS_REGISTER_R12;
}, },
// POP R11 // POP R11
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_POP && return instr.mnemonic == ZYDIS_MNEMONIC_POP &&
instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[0].reg.value == ZYDIS_REGISTER_R11; instr.operands[0].reg.value == ZYDIS_REGISTER_R11;
}, },
// POPFQ // POPFQ
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_POPFQ; return instr.mnemonic == ZYDIS_MNEMONIC_POPFQ;
}, },
// RET // RET
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_RET; return instr.mnemonic == ZYDIS_MNEMONIC_RET;
}}}, }}},
[&](zydis_reg_t& vip, zydis_reg_t& vsp, hndlr_trace_t& hndlr) [](zydis_reg_t& vip, zydis_reg_t& vsp, hndlr_trace_t& hndlr)
-> std::optional<vinstr_t> { return vinstr_t{mnemonic_t::vmexit}; }}; -> std::optional<vinstr_t> { return vinstr_t{mnemonic_t::vmexit}; }};
} }

@ -7,8 +7,7 @@ profiler_t write = {
{{// MOV REG, [VSP] {{// MOV REG, [VSP]
LOAD_VALUE, LOAD_VALUE,
// MOV REG, [VSP+OFFSET] // MOV REG, [VSP+OFFSET]
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER &&
@ -17,8 +16,7 @@ profiler_t write = {
instr.operands[1].mem.disp.has_displacement; instr.operands[1].mem.disp.has_displacement;
}, },
// ADD VSP, OFFSET // ADD VSP, OFFSET
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_ADD && return instr.mnemonic == ZYDIS_MNEMONIC_ADD &&
instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER &&
@ -26,8 +24,7 @@ profiler_t write = {
instr.operands[1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE; instr.operands[1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE;
}, },
// MOV [REG], REG // MOV [REG], REG
[&](const zydis_reg_t vip, [](const zydis_reg_t vip, const zydis_reg_t vsp,
const zydis_reg_t vsp,
const zydis_decoded_instr_t& instr) -> bool { const zydis_decoded_instr_t& instr) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[0].type == ZYDIS_OPERAND_TYPE_MEMORY && instr.operands[0].type == ZYDIS_OPERAND_TYPE_MEMORY &&
@ -35,8 +32,7 @@ profiler_t write = {
instr.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER && instr.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[1].reg.value != vsp; instr.operands[1].reg.value != vsp;
}}}, }}},
[&](zydis_reg_t& vip, [](zydis_reg_t& vip, zydis_reg_t& vsp,
zydis_reg_t& vsp,
hndlr_trace_t& hndlr) -> std::optional<vinstr_t> { hndlr_trace_t& hndlr) -> std::optional<vinstr_t> {
vinstr_t res{mnemonic_t::write}; vinstr_t res{mnemonic_t::write};
res.imm.has_imm = false; res.imm.has_imm = false;

@ -0,0 +1,54 @@
# Example Output
```
> 0x7f4bd5fc8f8d push 0x6CBB0520
> 0x7f4bd5ed96a3 push r8
> 0x7f4bd5ed96ad push r9
> 0x7f4bd5f22602 push rdx
> 0x7f4bd5f22605 push r12
> 0x7f4bd5f2260c push r11
> 0x7f4bd5f22610 push rcx
> 0x7f4bd5f22619 push r10
> 0x7f4bd5fa22d2 push rsi
> 0x7f4bd5fa22d6 push r15
> 0x7f4bd5fa22de push rbp
> 0x7f4bd5fa22e8 push r13
> 0x7f4bd5fa22f2 push rdi
> 0x7f4bd5fa22f3 push rbx
> 0x7f4bd5f17ade push r14
> 0x7f4bd5f17ae6 push rax
> 0x7f4bd5f17aea pushfq
> 0x7f4bd5f786f3 mov r11, 0x7F4A95C90000
> 0x7f4bd5f786fd push r11
> 0x7f4bd5f78707 mov r8, [rsp+0x90]
> 0x7f4bd5f7870f not r8d
> 0x7f4bd5f78719 rol r8d, 0x01
> 0x7f4bd5f78722 bswap r8d
> 0x7f4bd5f78725 not r8d
> 0x7f4bd5f7872f lea r8, [r8+r11*1]
> 0x7f4bd5f78733 mov r11, 0x100000000
> 0x7f4bd5f7873f add r8, r11
> 0x7f4bd5f7874d mov r9, rsp
> 0x7f4bd5f78753 sub rsp, 0x180
> 0x7f4bd5f78763 and rsp, 0xFFFFFFFFFFFFFFF0
> 0x7f4bd5f7876c mov rbx, r8
> 0x7f4bd5f78775 mov rdx, 0x7F4A95C90000
> 0x7f4bd5f7877f sub rbx, rdx
> 0x7f4bd5f78782 lea rbp, [0x00007F4BD5F78782]
> 0x7f4bd5f7878e sub r8, 0x04
> 0x7f4bd5f7879a mov edx, [r8]
> 0x7f4bd5f787a1 xor edx, ebx
> 0x7f4bd5f50bcd inc edx
> 0x7f4bd5f50bd0 rol edx, 0x01
> 0x7f4bd5f50bda add edx, 0x50DE102C
> 0x7f4bd5f50be0 rol edx, 0x03
> 0x7f4bd5f50be4 push rbx
> 0x7f4bd5f50bee xor [rsp], edx
> 0x7f4bd5f50bf4 pop rbx
> 0x7f4bd5f50bf9 movsxd rdx, edx
> 0x7f4bd5f50c00 add rbp, rdx
> 0x7f4bd5ebab8f jmp rbp
> Starting Virtual Instruction Pointer Register: r8
> Starting Virtual Stack Pointer Register: r9
```
Loading…
Cancel
Save