I don't understand how to use git

pull/1/head
xtremegamer1 2 years ago
parent 09fbfbdd31
commit c56fd3f6da

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <unicorn/unicorn.h> #include <unicorn/unicorn.h>
#include <array>
#include <atomic> #include <atomic>
#include <functional> #include <functional>
#include <linuxpe> #include <linuxpe>
@ -14,12 +15,19 @@
#define STACK_BASE 0xFFFF000000000000 #define STACK_BASE 0xFFFF000000000000
namespace vm { namespace vm {
namespace reg_names
{
const std::array<std::string, 8> prefixes = {{"Red", "Blue", "Pink", "Green", "Orange", "Yellow", "Black", "White"}};
const std::array<std::string, 4> suffixes = {{"Crewmate", "Engineer", "Imposter", "Shapeshifter"}};
}
class emu_t { class emu_t {
public: public:
explicit emu_t(vm::vmctx_t* vm_ctx, bool log);
explicit emu_t(vm::vmctx_t* vm_ctx); explicit emu_t(vm::vmctx_t* vm_ctx);
~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);
std::vector<uint8_t>& get_il_bytecode();
private: private:
uc_engine* uc; uc_engine* uc;
@ -51,6 +59,11 @@ class emu_t {
/// </summary> /// </summary>
uc_hook code_exec_hook, invalid_mem_hook, int_hook, branch_pred_hook; uc_hook code_exec_hook, invalid_mem_hook, int_hook, branch_pred_hook;
bool log_bytecode;
// Logged bytecode for lifting
std::vector<uint8_t> il_bytecode;
/// <summary> /// <summary>
/// code execution callback for executable memory ranges of the vmprotect'ed /// code execution callback for executable memory ranges of the vmprotect'ed
/// module... essentially used to single step the processor over virtual /// module... essentially used to single step the processor over virtual
@ -61,7 +74,9 @@ 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, uint64_t address, uint32_t size, static bool code_exec_callback(uc_engine* uc,
uint64_t address,
uint32_t size,
emu_t* obj); emu_t* obj);
/// <summary> /// <summary>
@ -74,8 +89,10 @@ 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, uint64_t address, static bool branch_pred_spec_exec(uc_engine* uc,
uint32_t size, emu_t* obj); uint64_t address,
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
@ -88,8 +105,12 @@ 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, uc_mem_type type, uint64_t address, static void invalid_mem(uc_engine* uc,
int size, int64_t value, emu_t* obj); uc_mem_type type,
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,8 +1,9 @@
#include <string> #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, bool log) : m_vm(vm_ctx),
log_bytecode(log) {}
emu_t::emu_t(vm::vmctx_t* vm_ctx) : m_vm(vm_ctx) {};
emu_t::~emu_t() { emu_t::~emu_t() {
if (uc) uc_close(uc); if (uc) uc_close(uc);
@ -86,14 +87,14 @@ bool emu_t::emulate(std::uint32_t vmenter_rva, vm::instrs::vrtn_t& vrtn) {
cc_trace.m_vip = cc_blk->m_vm.vip; cc_trace.m_vip = cc_blk->m_vm.vip;
cc_trace.m_vsp = cc_blk->m_vm.vsp; cc_trace.m_vsp = cc_blk->m_vm.vsp;
std::printf("> beginning execution at = %p\n", rip); std::printf("> beginning execution at = %p (%p)\n", rip, rip - m_vm->m_module_base + m_vm->m_image_base);
if ((err = uc_emu_start(uc, rip, 0ull, 0ull, 0ull))) { if ((err = uc_emu_start(uc, rip, 0ull, 0ull, 0ull))) {
std::printf("> error starting emu... reason = %d\n", err); std::printf("> error starting emu... reason = %d\n", err);
return false; return false;
} }
extract_branch_data(); extract_branch_data();
std::printf("> emulated blk_%p\n\n", cc_blk->m_vip.img_base); std::printf("> emulated blk_%p\n\n", cc_blk->m_vip.img_based);
// keep track of the emulated blocks... by their addresses... // keep track of the emulated blocks... by their addresses...
std::vector<std::uintptr_t> blk_addrs; std::vector<std::uintptr_t> blk_addrs;
@ -124,14 +125,14 @@ bool emu_t::emulate(std::uint32_t vmenter_rva, vm::instrs::vrtn_t& vrtn) {
// emulate the branch... // emulate the branch...
uc_mem_write(uc, vsp, &br, sizeof br); uc_mem_write(uc, vsp, &br, sizeof br);
std::printf("> beginning execution at = %p\n", blk.m_jmp.rip); std::printf("> beginning execution at = %p (%p)\n", rip, rip - m_vm->m_module_base + m_vm->m_image_base);
if ((err = uc_emu_start(uc, blk.m_jmp.rip, 0ull, 0ull, 0ull))) { if ((err = uc_emu_start(uc, blk.m_jmp.rip, 0ull, 0ull, 0ull))) {
std::printf("> error starting emu... reason = %d\n", err); std::printf("> error starting emu... reason = %d\n", err);
return false; return false;
} }
extract_branch_data(); extract_branch_data();
std::printf("> emulated blk_%p\n", cc_blk->m_vip.img_base); std::printf("> emulated blk_%p\n", cc_blk->m_vip.img_based);
} }
} }
} }
@ -373,7 +374,7 @@ bool emu_t::code_exec_callback(uc_engine* uc, uint64_t address, uint32_t size,
obj->cc_trace.m_instrs.end()); obj->cc_trace.m_instrs.end());
// set the virtual code block vip address information... // set the virtual code block vip address information...
if (!obj->cc_blk->m_vip.rva || !obj->cc_blk->m_vip.img_base) { if (!obj->cc_blk->m_vip.rva || !obj->cc_blk->m_vip.img_based) {
// 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(),
@ -393,14 +394,35 @@ bool emu_t::code_exec_callback(uc_engine* uc, uint64_t address, uint32_t size,
uc_reg_read(uc, vm::instrs::reg_map[obj->cc_trace.m_vip], &vip_addr); uc_reg_read(uc, vm::instrs::reg_map[obj->cc_trace.m_vip], &vip_addr);
obj->cc_blk->m_vip.rva = vip_addr -= obj->m_vm->m_module_base; obj->cc_blk->m_vip.rva = vip_addr -= obj->m_vm->m_module_base;
obj->cc_blk->m_vip.img_base = vip_addr += obj->m_vm->m_image_base; obj->cc_blk->m_vip.img_based = vip_addr += obj->m_vm->m_image_base;
uc_context_restore(uc, backup); uc_context_restore(uc, backup);
uc_context_free(backup); uc_context_free(backup);
} else { } else {
const auto vinstr = vm::instrs::determine(obj->cc_trace); const auto vinstr = vm::instrs::determine(obj->cc_trace);
if (vinstr.mnemonic != vm::instrs::mnemonic_t::unknown) { if (vinstr.mnemonic != vm::instrs::mnemonic_t::unknown) {
if (obj->log_bytecode)
{
obj->il_bytecode.emplace_back(static_cast<uint8_t>(vinstr.mnemonic));
if (vinstr.imm.has_imm)
{
obj->il_bytecode.emplace_back(vinstr.imm.size);
for(int i = 0; i < (vinstr.imm.size / 8); ++i)
{
obj->il_bytecode.emplace_back(*(reinterpret_cast<const uint8_t*>(&vinstr.imm.val) + i));
}
}
else
obj->il_bytecode.emplace_back<uint8_t>(0);
}
std::printf("%p: ", obj->cc_trace.m_begin + obj->m_vm->m_image_base - obj->m_vm->m_module_base);
if (vinstr.imm.has_imm) if (vinstr.imm.has_imm)
if (vinstr.mnemonic == instrs::mnemonic_t::lreg || vinstr.mnemonic == instrs::mnemonic_t::sreg)
std::printf("> %s %s_%s\n",
vm::instrs::get_profile(vinstr.mnemonic)->name.c_str(),
vm::reg_names::prefixes[(vinstr.imm.val / 8) % 8].c_str(),
vm::reg_names::suffixes[(vinstr.imm.val / 8) / 8].c_str());
else
std::printf("> %s %p\n", std::printf("> %s %p\n",
vm::instrs::get_profile(vinstr.mnemonic)->name.c_str(), vm::instrs::get_profile(vinstr.mnemonic)->name.c_str(),
vinstr.imm.val); vinstr.imm.val);
@ -592,4 +614,9 @@ std::optional<std::pair<std::uintptr_t, std::uintptr_t>> emu_t::could_have_jcc(
return {{lconst1->imm.val, lconst2->imm.val}}; return {{lconst1->imm.val, lconst2->imm.val}};
} }
std::vector<uint8_t>& emu_t::get_il_bytecode()
{
return il_bytecode;
}
} // namespace vm } // namespace vm
Loading…
Cancel
Save