updated vmprofiler dep and fixed compile issues on linux

master
IDontCode 3 years ago
parent 4d3bb60489
commit a23c46ee56

2
deps/vmprofiler vendored

@ -1 +1 @@
Subproject commit 1b2b79e3e91916da08179663d672634db7c35d4c Subproject commit b7330ad02f6735ab7fe391022165f767058bdcc7

@ -1,8 +1,9 @@
#pragma once #pragma once
#include <unicorn/unicorn.h> #include <unicorn/unicorn.h>
#include <atomic> #include <atomic>
#include <functional> #include <functional>
#include <nt/image.hpp> #include <linuxpe>
#include <numeric> #include <numeric>
#include <string> #include <string>
#include <vmctx.hpp> #include <vmctx.hpp>
@ -60,9 +61,7 @@ class emu_t {
/// <param name="size"></param> /// <param name="size"></param>
/// <param name="obj"></param> /// <param name="obj"></param>
/// <returns></returns> /// <returns></returns>
static bool code_exec_callback(uc_engine* uc, static bool code_exec_callback(uc_engine* uc, uint64_t address, uint32_t size,
uint64_t address,
uint32_t size,
emu_t* obj); emu_t* obj);
/// <summary> /// <summary>
@ -75,10 +74,8 @@ class emu_t {
/// <param name="size"></param> /// <param name="size"></param>
/// <param name="obj"></param> /// <param name="obj"></param>
/// <returns></returns> /// <returns></returns>
static bool branch_pred_spec_exec(uc_engine* uc, static bool branch_pred_spec_exec(uc_engine* uc, uint64_t address,
uint64_t address, uint32_t size, emu_t* obj);
uint32_t size,
emu_t* obj);
/// <summary> /// <summary>
/// invalid memory access handler. no runtime values can possibly effect the /// invalid memory access handler. no runtime values can possibly effect the
@ -91,12 +88,8 @@ class emu_t {
/// <param name="size">size of the memory access...</param> /// <param name="size">size of the memory access...</param>
/// <param name="value">value being read...</param> /// <param name="value">value being read...</param>
/// <param name="obj">emu_t object pointer...</param> /// <param name="obj">emu_t object pointer...</param>
static void invalid_mem(uc_engine* uc, static void invalid_mem(uc_engine* uc, uc_mem_type type, uint64_t address,
uc_mem_type type, int size, int64_t value, emu_t* obj);
uint64_t address,
int size,
int64_t value,
emu_t* obj);
/// <summary> /// <summary>
/// interrupt callback for unicorn engine. this is used to advance rip over /// interrupt callback for unicorn engine. this is used to advance rip over

@ -1,11 +1,11 @@
#include <string>
#include <vmemu_t.hpp> #include <vmemu_t.hpp>
namespace vm { namespace vm {
emu_t::emu_t(vm::vmctx_t* vm_ctx) : m_vm(vm_ctx) {} emu_t::emu_t(vm::vmctx_t* vm_ctx) : m_vm(vm_ctx) {}
emu_t::~emu_t() { emu_t::~emu_t() {
if (uc) if (uc) uc_close(uc);
uc_close(uc);
} }
bool emu_t::init() { bool emu_t::init() {
@ -139,11 +139,9 @@ bool emu_t::emulate(std::uint32_t vmenter_rva, vm::instrs::vrtn_t& vrtn) {
// free all virtual code block virtual jmp information... // free all virtual code block virtual jmp information...
std::for_each(vrtn.m_blks.begin(), vrtn.m_blks.end(), std::for_each(vrtn.m_blks.begin(), vrtn.m_blks.end(),
[&](vm::instrs::vblk_t& blk) { [&](vm::instrs::vblk_t& blk) {
if (blk.m_jmp.ctx) if (blk.m_jmp.ctx) uc_context_free(blk.m_jmp.ctx);
uc_context_free(blk.m_jmp.ctx);
if (blk.m_jmp.stack) if (blk.m_jmp.stack) delete[] blk.m_jmp.stack;
delete[] blk.m_jmp.stack;
}); });
return true; return true;
@ -239,10 +237,8 @@ void emu_t::int_callback(uc_engine* uc, std::uint32_t intno, emu_t* obj) {
} }
} }
bool emu_t::branch_pred_spec_exec(uc_engine* uc, bool emu_t::branch_pred_spec_exec(uc_engine* uc, uint64_t address,
uint64_t address, uint32_t size, emu_t* obj) {
uint32_t size,
emu_t* obj) {
uc_err err; uc_err err;
static thread_local zydis_decoded_instr_t instr; static thread_local zydis_decoded_instr_t instr;
if (!ZYAN_SUCCESS(ZydisDecoderDecodeBuffer(vm::utils::g_decoder.get(), if (!ZYAN_SUCCESS(ZydisDecoderDecodeBuffer(vm::utils::g_decoder.get(),
@ -256,8 +252,7 @@ bool emu_t::branch_pred_spec_exec(uc_engine* uc,
return false; return false;
} }
if (instr.mnemonic == ZYDIS_MNEMONIC_INVALID) if (instr.mnemonic == ZYDIS_MNEMONIC_INVALID) return false;
return false;
uc_context* ctx; uc_context* ctx;
uc_context_alloc(uc, &ctx); uc_context_alloc(uc, &ctx);
@ -283,7 +278,7 @@ bool emu_t::branch_pred_spec_exec(uc_engine* uc,
// 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(
obj->cc_trace.m_instrs.rbegin(), obj->cc_trace.m_instrs.rend(), obj->cc_trace.m_instrs.rbegin(), obj->cc_trace.m_instrs.rend(),
[&vip = obj->cc_trace.m_vip]( [& vip = obj->cc_trace.m_vip](
const vm::instrs::emu_instr_t& instr) -> bool { const vm::instrs::emu_instr_t& instr) -> bool {
const auto& i = instr.m_instr; const auto& i = instr.m_instr;
return i.mnemonic == ZYDIS_MNEMONIC_MOV && return i.mnemonic == ZYDIS_MNEMONIC_MOV &&
@ -308,26 +303,21 @@ bool emu_t::branch_pred_spec_exec(uc_engine* uc,
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) if (vinstr.mnemonic != vm::instrs::mnemonic_t::sreg) uc_emu_stop(uc);
uc_emu_stop(uc);
if (!vinstr.imm.has_imm) if (!vinstr.imm.has_imm) uc_emu_stop(uc);
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 after 10 legit SREG's... // -- stop after 10 legit SREG's...
if (++obj->m_sreg_cnt == 10) if (++obj->m_sreg_cnt == 10) uc_emu_stop(uc);
uc_emu_stop(uc);
} }
} }
return true; return true;
} }
bool emu_t::code_exec_callback(uc_engine* uc, bool emu_t::code_exec_callback(uc_engine* uc, uint64_t address, uint32_t size,
uint64_t address,
uint32_t size,
emu_t* obj) { emu_t* obj) {
uc_err err; uc_err err;
static thread_local zydis_decoded_instr_t instr; static thread_local zydis_decoded_instr_t instr;
@ -342,8 +332,7 @@ bool emu_t::code_exec_callback(uc_engine* uc,
return false; return false;
} }
if (instr.mnemonic == ZYDIS_MNEMONIC_INVALID) if (instr.mnemonic == ZYDIS_MNEMONIC_INVALID) return false;
return false;
uc_context* ctx; uc_context* ctx;
uc_context_alloc(uc, &ctx); uc_context_alloc(uc, &ctx);
@ -370,7 +359,7 @@ bool emu_t::code_exec_callback(uc_engine* uc,
// 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(
obj->cc_trace.m_instrs.rbegin(), obj->cc_trace.m_instrs.rend(), obj->cc_trace.m_instrs.rbegin(), obj->cc_trace.m_instrs.rend(),
[&vip = obj->cc_trace.m_vip]( [& vip = obj->cc_trace.m_vip](
const vm::instrs::emu_instr_t& instr) -> bool { const vm::instrs::emu_instr_t& instr) -> bool {
const auto& i = instr.m_instr; const auto& i = instr.m_instr;
return i.mnemonic == ZYDIS_MNEMONIC_MOV && return i.mnemonic == ZYDIS_MNEMONIC_MOV &&
@ -388,7 +377,8 @@ bool emu_t::code_exec_callback(uc_engine* uc,
// find the last write done to VIP... // find the last write done to VIP...
auto vip_write = std::find_if( auto vip_write = std::find_if(
obj->cc_trace.m_instrs.rbegin(), obj->cc_trace.m_instrs.rend(), obj->cc_trace.m_instrs.rbegin(), obj->cc_trace.m_instrs.rend(),
[&vip = obj->cc_trace.m_vip](vm::instrs::emu_instr_t& instr) -> bool { [& vip =
obj->cc_trace.m_vip](vm::instrs::emu_instr_t& instr) -> bool {
const auto& i = instr.m_instr; const auto& i = instr.m_instr;
return i.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && return i.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER &&
i.operands[0].reg.value == vip; i.operands[0].reg.value == vip;
@ -481,12 +471,8 @@ bool emu_t::code_exec_callback(uc_engine* uc,
return true; return true;
} }
void emu_t::invalid_mem(uc_engine* uc, void emu_t::invalid_mem(uc_engine* uc, uc_mem_type type, uint64_t address,
uc_mem_type type, int size, int64_t value, emu_t* obj) {
uint64_t address,
int size,
int64_t value,
emu_t* obj) {
switch (type) { switch (type) {
case UC_MEM_READ_UNMAPPED: { case UC_MEM_READ_UNMAPPED: {
uc_mem_map(uc, address & ~0xFFFull, PAGE_4KB, UC_PROT_ALL); uc_mem_map(uc, address & ~0xFFFull, PAGE_4KB, UC_PROT_ALL);
@ -560,8 +546,7 @@ bool emu_t::legit_branch(vm::instrs::vblk_t& vblk, std::uintptr_t branch_addr) {
std::optional<std::pair<std::uintptr_t, std::uintptr_t>> emu_t::could_have_jcc( std::optional<std::pair<std::uintptr_t, std::uintptr_t>> emu_t::could_have_jcc(
std::vector<vm::instrs::vinstr_t>& vinstrs) { std::vector<vm::instrs::vinstr_t>& vinstrs) {
if (vinstrs.back().mnemonic == vm::instrs::mnemonic_t::vmexit) if (vinstrs.back().mnemonic == vm::instrs::mnemonic_t::vmexit) return {};
return {};
// check to see if there is at least 3 LCONST %i64's // check to see if there is at least 3 LCONST %i64's
if (std::accumulate( if (std::accumulate(
@ -582,13 +567,11 @@ std::optional<std::pair<std::uintptr_t, std::uintptr_t>> emu_t::could_have_jcc(
const auto lconst1 = const auto lconst1 =
std::find_if(vinstrs.rbegin(), vinstrs.rend(), lconst64_chk); std::find_if(vinstrs.rbegin(), vinstrs.rend(), lconst64_chk);
if (lconst1 == vinstrs.rend()) if (lconst1 == vinstrs.rend()) return {};
return {};
const auto lconst2 = std::find_if(lconst1 + 1, vinstrs.rend(), lconst64_chk); const auto lconst2 = std::find_if(lconst1 + 1, vinstrs.rend(), lconst64_chk);
if (lconst2 == vinstrs.rend()) if (lconst2 == vinstrs.rend()) return {};
return {};
// check to see if the imm val is inside of the image... // check to see if the imm val is inside of the image...
if (lconst1->imm.val > m_vm->m_image_base + m_vm->m_image_size || if (lconst1->imm.val > m_vm->m_image_base + m_vm->m_image_size ||

Loading…
Cancel
Save