#pragma once #include namespace vm::instrs { /// /// mnemonic representation of supported virtual instructions... /// enum class mnemonic_t { unknown, sreg, lreg, lconst, add, div, idiv, mul, imul, nand, read, write, shl, shld, shr, shrd, lvsp, svsp, writecr3, readcr3, writecr8, readcr8, cpuid, rdtsc, call, jmp, vmexit }; /// /// the main virtual instruction structure which is returned by profilers... /// struct vinstr_t { /// /// mnemonic of the virtual instruction... /// mnemonic_t mnemonic; /// /// size varient of the virtual instruction... I.E SREGQ would have a value of /// "64" here...where the SREGDW varient would have a "32" here... /// u8 size; struct { /// /// true if the virtual instruction has an imm false if not... /// bool has_imm; /// /// size in bits of the imm... 8, 16, 32, 64... /// u8 size; /// /// imm value... /// u64 val; } imm; }; /// /// matcher function which returns true if an instruction matches a desired /// one... /// using matcher_t = std::function; /// /// virtual instruction structure generator... this can update the vip and vsp /// argument... it cannot update the instruction stream (hndlr)... /// using vinstr_gen_t = std::function(zydis_reg_t& vip, zydis_reg_t& vsp, zydis_rtn_t& hndlr)>; /// /// each virtual instruction has its own profiler_t structure which can generate /// all varients of the virtual instruction for each size... /// struct profiler_t { /// /// string name of the virtual instruction that this profile generates for... /// std::string name; /// /// mnemonic representation of the virtual instruction... /// mnemonic_t mnemonic; /// /// vector of matcher lambda's which return true if a given instruction /// matches... /// std::vector matchers; /// /// generates a virtual instruction structure... /// vinstr_gen_t generate; }; extern profiler_t jmp; inline std::vector profiles = {&jmp}; inline vinstr_t determine(zydis_reg_t& vip, zydis_reg_t& vsp, zydis_rtn_t& hndlr) { const auto profile = std::find_if( profiles.begin(), profiles.end(), [&](profiler_t* profile) -> bool { for (auto& matcher : profile->matchers) { const auto matched = std::find_if(hndlr.begin(), hndlr.end(), [&](zydis_instr_t& instr) -> bool { const auto& i = instr.instr; return matcher(vip, vsp, i); }); if (matched == hndlr.end()) return false; } return true; }); if (profile == profiles.end()) return vinstr_t{mnemonic_t::unknown}; auto result = (*profile)->generate(vip, vsp, hndlr); return result.has_value() ? result.value() : vinstr_t{mnemonic_t::unknown}; } } // namespace vm::instrs