|
|
|
@ -7,7 +7,7 @@ namespace vm
|
|
|
|
|
{
|
|
|
|
|
using instr_callback_t = bool(*)(const zydis_decoded_instr_t& instr);
|
|
|
|
|
|
|
|
|
|
enum VM_MNEMONIC
|
|
|
|
|
enum mnemonic_t
|
|
|
|
|
{
|
|
|
|
|
INVALID,
|
|
|
|
|
|
|
|
|
@ -28,7 +28,11 @@ namespace vm
|
|
|
|
|
PUSHVSP,
|
|
|
|
|
|
|
|
|
|
ADDQ,
|
|
|
|
|
ADDDW
|
|
|
|
|
ADDDW,
|
|
|
|
|
|
|
|
|
|
NANDQ,
|
|
|
|
|
|
|
|
|
|
VMEXIT
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
enum extention_t
|
|
|
|
@ -41,7 +45,7 @@ namespace vm
|
|
|
|
|
struct profile_t
|
|
|
|
|
{
|
|
|
|
|
const char* name;
|
|
|
|
|
VM_MNEMONIC mnemonic;
|
|
|
|
|
mnemonic_t mnemonic;
|
|
|
|
|
u8 imm_size;
|
|
|
|
|
std::vector<instr_callback_t> signature;
|
|
|
|
|
extention_t extention;
|
|
|
|
@ -559,6 +563,113 @@ namespace vm
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
inline vm::handler::profile_t nandq =
|
|
|
|
|
{
|
|
|
|
|
// MOV RAX, [RBP]
|
|
|
|
|
// MOV RDX, [RBP+8]
|
|
|
|
|
// NOT RAX
|
|
|
|
|
// NOT RDX
|
|
|
|
|
// AND RAX, RDX
|
|
|
|
|
// MOV [RBP], RAX
|
|
|
|
|
// PUSHFQ
|
|
|
|
|
// POP [RBP]
|
|
|
|
|
"NANDQ", NANDQ, NULL,
|
|
|
|
|
{
|
|
|
|
|
{
|
|
|
|
|
// MOV RAX, [RBP]
|
|
|
|
|
[](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_RAX &&
|
|
|
|
|
instr.operands[1].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
|
|
|
|
instr.operands[1].mem.base == ZYDIS_REGISTER_RBP;
|
|
|
|
|
},
|
|
|
|
|
// MOV RDX, [RBP+8]
|
|
|
|
|
[](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_RDX &&
|
|
|
|
|
instr.operands[1].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
|
|
|
|
instr.operands[1].mem.base == ZYDIS_REGISTER_RBP &&
|
|
|
|
|
instr.operands[1].mem.index == 0x8;
|
|
|
|
|
},
|
|
|
|
|
// NOT RAX
|
|
|
|
|
[](const zydis_decoded_instr_t& instr) -> bool
|
|
|
|
|
{
|
|
|
|
|
return instr.mnemonic == ZYDIS_MNEMONIC_NOT &&
|
|
|
|
|
instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
|
|
|
|
instr.operands[0].reg.value == ZYDIS_REGISTER_RAX;
|
|
|
|
|
},
|
|
|
|
|
// NOT RDX
|
|
|
|
|
[](const zydis_decoded_instr_t& instr) -> bool
|
|
|
|
|
{
|
|
|
|
|
return instr.mnemonic == ZYDIS_MNEMONIC_NOT &&
|
|
|
|
|
instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
|
|
|
|
instr.operands[0].reg.value == ZYDIS_REGISTER_RDX;
|
|
|
|
|
},
|
|
|
|
|
// AND RAX, RDX
|
|
|
|
|
[](const zydis_decoded_instr_t& instr) -> bool
|
|
|
|
|
{
|
|
|
|
|
return instr.mnemonic == ZYDIS_MNEMONIC_AND &&
|
|
|
|
|
instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
|
|
|
|
instr.operands[0].reg.value == ZYDIS_REGISTER_RAX &&
|
|
|
|
|
instr.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
|
|
|
|
instr.operands[1].reg.value == ZYDIS_REGISTER_RDX;
|
|
|
|
|
},
|
|
|
|
|
// MOV [RBP], RAX
|
|
|
|
|
[](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 == ZYDIS_REGISTER_RBP &&
|
|
|
|
|
instr.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
|
|
|
|
instr.operands[1].reg.value == ZYDIS_REGISTER_RAX;
|
|
|
|
|
},
|
|
|
|
|
// PUSHFQ
|
|
|
|
|
[](const zydis_decoded_instr_t& instr) -> bool
|
|
|
|
|
{
|
|
|
|
|
return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ;
|
|
|
|
|
},
|
|
|
|
|
// POP [RBP]
|
|
|
|
|
[](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 == ZYDIS_REGISTER_RBP;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
inline vm::handler::profile_t vmexit =
|
|
|
|
|
{
|
|
|
|
|
// MOV RAX, RBP
|
|
|
|
|
// POPFQ
|
|
|
|
|
// RET
|
|
|
|
|
"VMEXIT", VMEXIT, NULL,
|
|
|
|
|
{
|
|
|
|
|
{
|
|
|
|
|
// MOV RAX, RBP
|
|
|
|
|
[](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_RAX &&
|
|
|
|
|
instr.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
|
|
|
|
instr.operands[1].reg.value == ZYDIS_REGISTER_RBP;
|
|
|
|
|
},
|
|
|
|
|
// POPFQ
|
|
|
|
|
[](const zydis_decoded_instr_t& instr) -> bool
|
|
|
|
|
{ return instr.mnemonic == ZYDIS_MNEMONIC_POPFQ; },
|
|
|
|
|
// RET
|
|
|
|
|
[](const zydis_decoded_instr_t& instr) -> bool
|
|
|
|
|
{ return instr.mnemonic == ZYDIS_MNEMONIC_RET; }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
inline std::vector<vm::handler::profile_t*> all =
|
|
|
|
|
{
|
|
|
|
|
&sregq, &sregdw, &sregw,
|
|
|
|
@ -569,7 +680,11 @@ namespace vm
|
|
|
|
|
|
|
|
|
|
&pushvsp,
|
|
|
|
|
|
|
|
|
|
&addq, &adddw
|
|
|
|
|
&addq, &adddw,
|
|
|
|
|
|
|
|
|
|
&nandq,
|
|
|
|
|
|
|
|
|
|
&vmexit
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|