fix issue with sreg handler

master
xtremegamer1 2 years ago
parent 71b1705804
commit 8eef5d9706

2
deps/vmprofiler vendored

@ -1 +1 @@
Subproject commit 343c7b95a4a18f119167a4f371a29cfa1624d404 Subproject commit fa64967bd77983b8fd3affc1de196a0d525adb52

@ -26,7 +26,7 @@ class emu_t {
~emu_t(); ~emu_t();
bool init(); bool init();
bool emulate(std::uint32_t vmenter_rva, vm::instrs::vrtn_t& vrtn); bool emulate(std::uint32_t vmenter_rva, vm::instrs::vrtn_t& vrtn);
const bool m_log_instructions = true; const bool m_log_instructions = false;
private: private:
uc_engine* uc; uc_engine* uc;

@ -285,15 +285,7 @@ bool emu_t::branch_pred_spec_exec(uc_engine* uc, uint64_t address,
// deobfuscate the instruction stream before profiling... // deobfuscate the instruction stream before profiling...
// makes it easier for profiles to be correct... // makes it easier for profiles to be correct...
vm::instrs::deobfuscate(obj->cc_trace); vm::instrs::deobfuscate(obj->cc_trace);
std::printf("> vsp = %s, vip = %s, address = %p (%p)\n", ZydisRegisterGetString(obj->cc_trace.m_vsp), ZydisRegisterGetString(obj->cc_trace.m_vip),
obj->cc_trace.m_begin, obj->cc_trace.m_begin - obj->m_vm->m_module_base + obj->m_vm->m_image_base);
zydis_rtn_t inst_stream;
std::for_each(obj->cc_trace.m_instrs.begin(),
obj->cc_trace.m_instrs.end(),
[&](vm::instrs::emu_instr_t& instr) {
inst_stream.push_back({instr.m_instr});
});
vm::utils::print(inst_stream);
/* // find the last MOV REG, DWORD PTR [VIP] in the instruction stream, then /* // find the last MOV REG, DWORD PTR [VIP] in the instruction stream, then
// remove any instructions from this instruction to the JMP/RET... // remove any instructions from this instruction to the JMP/RET...
const auto rva_fetch = std::find_if( const auto rva_fetch = std::find_if(
@ -318,7 +310,7 @@ bool emu_t::branch_pred_spec_exec(uc_engine* uc, uint64_t address,
} */ } */
const auto vinstr = vm::instrs::determine(obj->cc_trace); const auto vinstr = vm::instrs::determine(obj->cc_trace);
std::printf("instruction is: %d\n", vinstr.mnemonic);
// -- free the trace since we will start a new one... // -- free the trace since we will start a new one...
std::for_each(obj->cc_trace.m_instrs.begin(), obj->cc_trace.m_instrs.end(), std::for_each(obj->cc_trace.m_instrs.begin(), obj->cc_trace.m_instrs.end(),
[&](const vm::instrs::emu_instr_t& instr) { [&](const vm::instrs::emu_instr_t& instr) {
@ -328,12 +320,12 @@ bool emu_t::branch_pred_spec_exec(uc_engine* uc, uint64_t address,
obj->cc_trace.m_instrs.clear(); obj->cc_trace.m_instrs.clear();
if (vinstr.mnemonic != vm::instrs::mnemonic_t::jmp) { if (vinstr.mnemonic != vm::instrs::mnemonic_t::jmp) {
/* if (vinstr.mnemonic != vm::instrs::mnemonic_t::sreg) uc_emu_stop(uc); if (vinstr.mnemonic != vm::instrs::mnemonic_t::sreg) uc_emu_stop(uc);
if (!vinstr.imm.has_imm) uc_emu_stop(uc); if (!vinstr.imm.has_imm) uc_emu_stop(uc);
if (vinstr.imm.size != 8 || vinstr.imm.val > 8 * VIRTUAL_REGISTER_COUNT) if (vinstr.imm.size != 8 || vinstr.imm.val > 8 * VIRTUAL_REGISTER_COUNT)
uc_emu_stop(uc); */ uc_emu_stop(uc);
// stop if done or if instruction is invalid // stop if done or if instruction is invalid
if (vinstr.mnemonic == instrs::mnemonic_t::unknown) if (vinstr.mnemonic == instrs::mnemonic_t::unknown)
@ -496,7 +488,36 @@ bool emu_t::code_exec_callback(uc_engine* uc, uint64_t address, uint32_t size,
std::memcpy(obj->cc_blk->m_jmp.stack, obj->cc_trace.m_stack, std::memcpy(obj->cc_blk->m_jmp.stack, obj->cc_trace.m_stack,
STACK_SIZE); STACK_SIZE);
} }
if (vinstr.mnemonic == vm::instrs::mnemonic_t::vmexit)
{
int i = 0;
for (const auto& instr_it : obj->cc_trace.m_instrs)
{
if ((instr_it.m_instr.mnemonic == ZYDIS_MNEMONIC_POP ||
instr_it.m_instr.mnemonic == ZYDIS_MNEMONIC_POPFQ) &&
instr_it.m_instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER)
{
if (i >= 16)
{
std::printf("[!] failed to parse vmexit pops\n");
return false;
}
auto pushed_reg = instr_it.m_instr.operands[instr_it.m_instr.mnemonic == ZYDIS_MNEMONIC_POPFQ ? 2 : 0].reg.value;
if (std::find(obj->cc_blk->vmexit_pop_order.begin(), obj->cc_blk->vmexit_pop_order.begin() + i, pushed_reg)
!= obj->cc_blk->vmexit_pop_order.begin() + i)
{
std::printf("[!] failed to parse vmexit pops\n");
return false;
}
obj->cc_blk->vmexit_pop_order[i++] = pushed_reg;
}
}
if (i != 16)
{
std::printf("[!] failed to parse vmexit pops\n");
return false;
}
}
if (vinstr.mnemonic == vm::instrs::mnemonic_t::jmp || if (vinstr.mnemonic == vm::instrs::mnemonic_t::jmp ||
vinstr.mnemonic == vm::instrs::mnemonic_t::vmexit) vinstr.mnemonic == vm::instrs::mnemonic_t::vmexit)
uc_emu_stop(obj->uc); uc_emu_stop(obj->uc);

Loading…
Cancel
Save