mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-28 23:41:03 +00:00
prepare 32bit support with name and class inheritance modifications
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
|
||||
#include "../emulator_utils.hpp"
|
||||
|
||||
#include <x64_emulator.hpp>
|
||||
#include <arch_emulator.hpp>
|
||||
|
||||
#include <utils/io.hpp>
|
||||
#include <utils/compression.hpp>
|
||||
@@ -14,7 +14,7 @@ namespace apiset
|
||||
{
|
||||
namespace
|
||||
{
|
||||
uint64_t copy_string(x64_emulator& emu, emulator_allocator& allocator, const void* base_ptr,
|
||||
uint64_t copy_string(x86_64_emulator& emu, emulator_allocator& allocator, const void* base_ptr,
|
||||
const uint64_t offset, const size_t length)
|
||||
{
|
||||
if (!length)
|
||||
@@ -29,7 +29,7 @@ namespace apiset
|
||||
return str_obj;
|
||||
}
|
||||
|
||||
ULONG copy_string_as_relative(x64_emulator& emu, emulator_allocator& allocator, const uint64_t result_base,
|
||||
ULONG copy_string_as_relative(x86_64_emulator& emu, emulator_allocator& allocator, const uint64_t result_base,
|
||||
const void* base_ptr, const uint64_t offset, const size_t length)
|
||||
{
|
||||
const auto address = copy_string(emu, allocator, base_ptr, offset, length);
|
||||
@@ -115,13 +115,13 @@ namespace apiset
|
||||
return obtain(apiset_loc, root);
|
||||
}
|
||||
|
||||
emulator_object<API_SET_NAMESPACE> clone(x64_emulator& emu, emulator_allocator& allocator,
|
||||
emulator_object<API_SET_NAMESPACE> clone(x86_64_emulator& emu, emulator_allocator& allocator,
|
||||
const container& container)
|
||||
{
|
||||
return clone(emu, allocator, container.get());
|
||||
}
|
||||
|
||||
emulator_object<API_SET_NAMESPACE> clone(x64_emulator& emu, emulator_allocator& allocator,
|
||||
emulator_object<API_SET_NAMESPACE> clone(x86_64_emulator& emu, emulator_allocator& allocator,
|
||||
const API_SET_NAMESPACE& orig_api_set_map)
|
||||
{
|
||||
const auto api_set_map_obj = allocator.reserve<API_SET_NAMESPACE>();
|
||||
|
||||
@@ -29,9 +29,9 @@ namespace apiset
|
||||
container obtain(location location, const std::filesystem::path& root);
|
||||
container obtain(const std::filesystem::path& root);
|
||||
|
||||
emulator_object<API_SET_NAMESPACE> clone(x64_emulator& emu, emulator_allocator& allocator,
|
||||
emulator_object<API_SET_NAMESPACE> clone(x86_64_emulator& emu, emulator_allocator& allocator,
|
||||
const API_SET_NAMESPACE& orig_api_set_map);
|
||||
|
||||
emulator_object<API_SET_NAMESPACE> clone(x64_emulator& emu, emulator_allocator& allocator,
|
||||
emulator_object<API_SET_NAMESPACE> clone(x86_64_emulator& emu, emulator_allocator& allocator,
|
||||
const container& container);
|
||||
}
|
||||
|
||||
@@ -3,147 +3,147 @@
|
||||
|
||||
namespace cpu_context
|
||||
{
|
||||
void restore(x64_emulator& emu, const CONTEXT64& context)
|
||||
void restore(x86_64_emulator& emu, const CONTEXT64& context)
|
||||
{
|
||||
if ((context.ContextFlags & CONTEXT_DEBUG_REGISTERS_64) == CONTEXT_DEBUG_REGISTERS_64)
|
||||
{
|
||||
emu.reg(x64_register::dr0, context.Dr0);
|
||||
emu.reg(x64_register::dr1, context.Dr1);
|
||||
emu.reg(x64_register::dr2, context.Dr2);
|
||||
emu.reg(x64_register::dr3, context.Dr3);
|
||||
emu.reg(x64_register::dr6, context.Dr6);
|
||||
emu.reg(x64_register::dr7, context.Dr7);
|
||||
emu.reg(x86_register::dr0, context.Dr0);
|
||||
emu.reg(x86_register::dr1, context.Dr1);
|
||||
emu.reg(x86_register::dr2, context.Dr2);
|
||||
emu.reg(x86_register::dr3, context.Dr3);
|
||||
emu.reg(x86_register::dr6, context.Dr6);
|
||||
emu.reg(x86_register::dr7, context.Dr7);
|
||||
}
|
||||
|
||||
if ((context.ContextFlags & CONTEXT_CONTROL_64) == CONTEXT_CONTROL_64)
|
||||
{
|
||||
emu.reg<uint16_t>(x64_register::ss, context.SegSs);
|
||||
emu.reg<uint16_t>(x64_register::cs, context.SegCs);
|
||||
emu.reg<uint16_t>(x86_register::ss, context.SegSs);
|
||||
emu.reg<uint16_t>(x86_register::cs, context.SegCs);
|
||||
|
||||
emu.reg(x64_register::rip, context.Rip);
|
||||
emu.reg(x64_register::rsp, context.Rsp);
|
||||
emu.reg(x86_register::rip, context.Rip);
|
||||
emu.reg(x86_register::rsp, context.Rsp);
|
||||
|
||||
emu.reg<uint32_t>(x64_register::eflags, context.EFlags);
|
||||
emu.reg<uint32_t>(x86_register::eflags, context.EFlags);
|
||||
}
|
||||
|
||||
if ((context.ContextFlags & CONTEXT_INTEGER_64) == CONTEXT_INTEGER_64)
|
||||
{
|
||||
emu.reg(x64_register::rax, context.Rax);
|
||||
emu.reg(x64_register::rbx, context.Rbx);
|
||||
emu.reg(x64_register::rcx, context.Rcx);
|
||||
emu.reg(x64_register::rdx, context.Rdx);
|
||||
emu.reg(x64_register::rbp, context.Rbp);
|
||||
emu.reg(x64_register::rsi, context.Rsi);
|
||||
emu.reg(x64_register::rdi, context.Rdi);
|
||||
emu.reg(x64_register::r8, context.R8);
|
||||
emu.reg(x64_register::r9, context.R9);
|
||||
emu.reg(x64_register::r10, context.R10);
|
||||
emu.reg(x64_register::r11, context.R11);
|
||||
emu.reg(x64_register::r12, context.R12);
|
||||
emu.reg(x64_register::r13, context.R13);
|
||||
emu.reg(x64_register::r14, context.R14);
|
||||
emu.reg(x64_register::r15, context.R15);
|
||||
emu.reg(x86_register::rax, context.Rax);
|
||||
emu.reg(x86_register::rbx, context.Rbx);
|
||||
emu.reg(x86_register::rcx, context.Rcx);
|
||||
emu.reg(x86_register::rdx, context.Rdx);
|
||||
emu.reg(x86_register::rbp, context.Rbp);
|
||||
emu.reg(x86_register::rsi, context.Rsi);
|
||||
emu.reg(x86_register::rdi, context.Rdi);
|
||||
emu.reg(x86_register::r8, context.R8);
|
||||
emu.reg(x86_register::r9, context.R9);
|
||||
emu.reg(x86_register::r10, context.R10);
|
||||
emu.reg(x86_register::r11, context.R11);
|
||||
emu.reg(x86_register::r12, context.R12);
|
||||
emu.reg(x86_register::r13, context.R13);
|
||||
emu.reg(x86_register::r14, context.R14);
|
||||
emu.reg(x86_register::r15, context.R15);
|
||||
}
|
||||
|
||||
/*if ((context.ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS)
|
||||
{
|
||||
emu.reg<uint16_t>(x64_register::ds, context.SegDs);
|
||||
emu.reg<uint16_t>(x64_register::es, context.SegEs);
|
||||
emu.reg<uint16_t>(x64_register::fs, context.SegFs);
|
||||
emu.reg<uint16_t>(x64_register::gs, context.SegGs);
|
||||
emu.reg<uint16_t>(x86_register::ds, context.SegDs);
|
||||
emu.reg<uint16_t>(x86_register::es, context.SegEs);
|
||||
emu.reg<uint16_t>(x86_register::fs, context.SegFs);
|
||||
emu.reg<uint16_t>(x86_register::gs, context.SegGs);
|
||||
}*/
|
||||
|
||||
if ((context.ContextFlags & CONTEXT_FLOATING_POINT_64) == CONTEXT_FLOATING_POINT_64)
|
||||
{
|
||||
emu.reg<uint16_t>(x64_register::fpcw, context.FltSave.ControlWord);
|
||||
emu.reg<uint16_t>(x64_register::fpsw, context.FltSave.StatusWord);
|
||||
emu.reg<uint16_t>(x64_register::fptag, context.FltSave.TagWord);
|
||||
emu.reg<uint16_t>(x86_register::fpcw, context.FltSave.ControlWord);
|
||||
emu.reg<uint16_t>(x86_register::fpsw, context.FltSave.StatusWord);
|
||||
emu.reg<uint16_t>(x86_register::fptag, context.FltSave.TagWord);
|
||||
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
const auto reg = static_cast<x64_register>(static_cast<int>(x64_register::st0) + i);
|
||||
const auto reg = static_cast<x86_register>(static_cast<int>(x86_register::st0) + i);
|
||||
emu.reg<M128A>(reg, context.FltSave.FloatRegisters[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if ((context.ContextFlags & CONTEXT_XSTATE_64) == CONTEXT_XSTATE_64)
|
||||
{
|
||||
emu.reg<uint32_t>(x64_register::mxcsr, context.MxCsr);
|
||||
emu.reg<uint32_t>(x86_register::mxcsr, context.MxCsr);
|
||||
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
const auto reg = static_cast<x64_register>(static_cast<int>(x64_register::xmm0) + i);
|
||||
const auto reg = static_cast<x86_register>(static_cast<int>(x86_register::xmm0) + i);
|
||||
emu.reg<M128A>(reg, (&context.Xmm0)[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void save(x64_emulator& emu, CONTEXT64& context)
|
||||
void save(x86_64_emulator& emu, CONTEXT64& context)
|
||||
{
|
||||
if ((context.ContextFlags & CONTEXT_DEBUG_REGISTERS_64) == CONTEXT_DEBUG_REGISTERS_64)
|
||||
{
|
||||
context.Dr0 = emu.reg(x64_register::dr0);
|
||||
context.Dr1 = emu.reg(x64_register::dr1);
|
||||
context.Dr2 = emu.reg(x64_register::dr2);
|
||||
context.Dr3 = emu.reg(x64_register::dr3);
|
||||
context.Dr6 = emu.reg(x64_register::dr6);
|
||||
context.Dr7 = emu.reg(x64_register::dr7);
|
||||
context.Dr0 = emu.reg(x86_register::dr0);
|
||||
context.Dr1 = emu.reg(x86_register::dr1);
|
||||
context.Dr2 = emu.reg(x86_register::dr2);
|
||||
context.Dr3 = emu.reg(x86_register::dr3);
|
||||
context.Dr6 = emu.reg(x86_register::dr6);
|
||||
context.Dr7 = emu.reg(x86_register::dr7);
|
||||
}
|
||||
|
||||
if ((context.ContextFlags & CONTEXT_CONTROL_64) == CONTEXT_CONTROL_64)
|
||||
{
|
||||
context.SegSs = emu.reg<uint16_t>(x64_register::ss);
|
||||
context.SegCs = emu.reg<uint16_t>(x64_register::cs);
|
||||
context.Rip = emu.reg(x64_register::rip);
|
||||
context.Rsp = emu.reg(x64_register::rsp);
|
||||
context.EFlags = emu.reg<uint32_t>(x64_register::eflags);
|
||||
context.SegSs = emu.reg<uint16_t>(x86_register::ss);
|
||||
context.SegCs = emu.reg<uint16_t>(x86_register::cs);
|
||||
context.Rip = emu.reg(x86_register::rip);
|
||||
context.Rsp = emu.reg(x86_register::rsp);
|
||||
context.EFlags = emu.reg<uint32_t>(x86_register::eflags);
|
||||
}
|
||||
|
||||
if ((context.ContextFlags & CONTEXT_INTEGER_64) == CONTEXT_INTEGER_64)
|
||||
{
|
||||
context.Rax = emu.reg(x64_register::rax);
|
||||
context.Rbx = emu.reg(x64_register::rbx);
|
||||
context.Rcx = emu.reg(x64_register::rcx);
|
||||
context.Rdx = emu.reg(x64_register::rdx);
|
||||
context.Rbp = emu.reg(x64_register::rbp);
|
||||
context.Rsi = emu.reg(x64_register::rsi);
|
||||
context.Rdi = emu.reg(x64_register::rdi);
|
||||
context.R8 = emu.reg(x64_register::r8);
|
||||
context.R9 = emu.reg(x64_register::r9);
|
||||
context.R10 = emu.reg(x64_register::r10);
|
||||
context.R11 = emu.reg(x64_register::r11);
|
||||
context.R12 = emu.reg(x64_register::r12);
|
||||
context.R13 = emu.reg(x64_register::r13);
|
||||
context.R14 = emu.reg(x64_register::r14);
|
||||
context.R15 = emu.reg(x64_register::r15);
|
||||
context.Rax = emu.reg(x86_register::rax);
|
||||
context.Rbx = emu.reg(x86_register::rbx);
|
||||
context.Rcx = emu.reg(x86_register::rcx);
|
||||
context.Rdx = emu.reg(x86_register::rdx);
|
||||
context.Rbp = emu.reg(x86_register::rbp);
|
||||
context.Rsi = emu.reg(x86_register::rsi);
|
||||
context.Rdi = emu.reg(x86_register::rdi);
|
||||
context.R8 = emu.reg(x86_register::r8);
|
||||
context.R9 = emu.reg(x86_register::r9);
|
||||
context.R10 = emu.reg(x86_register::r10);
|
||||
context.R11 = emu.reg(x86_register::r11);
|
||||
context.R12 = emu.reg(x86_register::r12);
|
||||
context.R13 = emu.reg(x86_register::r13);
|
||||
context.R14 = emu.reg(x86_register::r14);
|
||||
context.R15 = emu.reg(x86_register::r15);
|
||||
}
|
||||
|
||||
if ((context.ContextFlags & CONTEXT_SEGMENTS_64) == CONTEXT_SEGMENTS_64)
|
||||
{
|
||||
context.SegDs = emu.reg<uint16_t>(x64_register::ds);
|
||||
context.SegEs = emu.reg<uint16_t>(x64_register::es);
|
||||
context.SegFs = emu.reg<uint16_t>(x64_register::fs);
|
||||
context.SegGs = emu.reg<uint16_t>(x64_register::gs);
|
||||
context.SegDs = emu.reg<uint16_t>(x86_register::ds);
|
||||
context.SegEs = emu.reg<uint16_t>(x86_register::es);
|
||||
context.SegFs = emu.reg<uint16_t>(x86_register::fs);
|
||||
context.SegGs = emu.reg<uint16_t>(x86_register::gs);
|
||||
}
|
||||
|
||||
if ((context.ContextFlags & CONTEXT_FLOATING_POINT_64) == CONTEXT_FLOATING_POINT_64)
|
||||
{
|
||||
context.FltSave.ControlWord = emu.reg<uint16_t>(x64_register::fpcw);
|
||||
context.FltSave.StatusWord = emu.reg<uint16_t>(x64_register::fpsw);
|
||||
context.FltSave.TagWord = static_cast<BYTE>(emu.reg<uint16_t>(x64_register::fptag));
|
||||
context.FltSave.ControlWord = emu.reg<uint16_t>(x86_register::fpcw);
|
||||
context.FltSave.StatusWord = emu.reg<uint16_t>(x86_register::fpsw);
|
||||
context.FltSave.TagWord = static_cast<BYTE>(emu.reg<uint16_t>(x86_register::fptag));
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
const auto reg = static_cast<x64_register>(static_cast<int>(x64_register::st0) + i);
|
||||
const auto reg = static_cast<x86_register>(static_cast<int>(x86_register::st0) + i);
|
||||
context.FltSave.FloatRegisters[i] = emu.reg<M128A>(reg);
|
||||
}
|
||||
}
|
||||
|
||||
if ((context.ContextFlags & CONTEXT_INTEGER_64) == CONTEXT_INTEGER_64)
|
||||
{
|
||||
context.MxCsr = emu.reg<uint32_t>(x64_register::mxcsr);
|
||||
context.MxCsr = emu.reg<uint32_t>(x86_register::mxcsr);
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
const auto reg = static_cast<x64_register>(static_cast<int>(x64_register::xmm0) + i);
|
||||
const auto reg = static_cast<x86_register>(static_cast<int>(x86_register::xmm0) + i);
|
||||
(&context.Xmm0)[i] = emu.reg<M128A>(reg);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#pragma once
|
||||
#include "x64_emulator.hpp"
|
||||
#include "arch_emulator.hpp"
|
||||
|
||||
namespace cpu_context
|
||||
{
|
||||
void save(x64_emulator& emu, CONTEXT64& context);
|
||||
void restore(x64_emulator& emu, const CONTEXT64& context);
|
||||
void save(x86_64_emulator& emu, CONTEXT64& context);
|
||||
void restore(x86_64_emulator& emu, const CONTEXT64& context);
|
||||
}
|
||||
|
||||
@@ -7,25 +7,26 @@
|
||||
namespace
|
||||
{
|
||||
template <typename T>
|
||||
emulator_object<T> allocate_object_on_stack(x64_emulator& emu)
|
||||
emulator_object<T> allocate_object_on_stack(x86_64_emulator& emu)
|
||||
{
|
||||
const auto old_sp = emu.reg(x64_register::rsp);
|
||||
const auto new_sp = align_down(old_sp - sizeof(T), std::max(alignof(T), alignof(x64_emulator::pointer_type)));
|
||||
emu.reg(x64_register::rsp, new_sp);
|
||||
const auto old_sp = emu.reg(x86_register::rsp);
|
||||
const auto new_sp =
|
||||
align_down(old_sp - sizeof(T), std::max(alignof(T), alignof(x86_64_emulator::pointer_type)));
|
||||
emu.reg(x86_register::rsp, new_sp);
|
||||
return {emu, new_sp};
|
||||
}
|
||||
|
||||
void unalign_stack(x64_emulator& emu)
|
||||
void unalign_stack(x86_64_emulator& emu)
|
||||
{
|
||||
auto sp = emu.reg(x64_register::rsp);
|
||||
auto sp = emu.reg(x86_register::rsp);
|
||||
sp = align_down(sp - 0x10, 0x10) + 8;
|
||||
emu.reg(x64_register::rsp, sp);
|
||||
emu.reg(x86_register::rsp, sp);
|
||||
}
|
||||
|
||||
void setup_stack(x64_emulator& emu, const uint64_t stack_base, const size_t stack_size)
|
||||
void setup_stack(x86_64_emulator& emu, const uint64_t stack_base, const size_t stack_size)
|
||||
{
|
||||
const uint64_t stack_end = stack_base + stack_size;
|
||||
emu.reg(x64_register::rsp, stack_end);
|
||||
emu.reg(x86_register::rsp, stack_end);
|
||||
}
|
||||
|
||||
bool is_object_signaled(process_context& c, const handle h, const uint32_t current_thread_id)
|
||||
@@ -207,7 +208,7 @@ bool emulator_thread::is_thread_ready(process_context& process, utils::clock& cl
|
||||
return true;
|
||||
}
|
||||
|
||||
void emulator_thread::setup_registers(x64_emulator& emu, const process_context& context) const
|
||||
void emulator_thread::setup_registers(x86_64_emulator& emu, const process_context& context) const
|
||||
{
|
||||
if (!this->gs_segment)
|
||||
{
|
||||
@@ -215,7 +216,7 @@ void emulator_thread::setup_registers(x64_emulator& emu, const process_context&
|
||||
}
|
||||
|
||||
setup_stack(emu, this->stack_base, static_cast<size_t>(this->stack_size));
|
||||
emu.set_segment_base(x64_register::gs, this->gs_segment->get_base());
|
||||
emu.set_segment_base(x86_register::gs, this->gs_segment->get_base());
|
||||
|
||||
CONTEXT64 ctx{};
|
||||
ctx.ContextFlags = CONTEXT64_ALL;
|
||||
@@ -232,7 +233,7 @@ void emulator_thread::setup_registers(x64_emulator& emu, const process_context&
|
||||
|
||||
unalign_stack(emu);
|
||||
|
||||
emu.reg(x64_register::rcx, ctx_obj.value());
|
||||
emu.reg(x64_register::rdx, context.ntdll_image_base);
|
||||
emu.reg(x64_register::rip, context.ldr_initialize_thunk);
|
||||
emu.reg(x86_register::rcx, ctx_obj.value());
|
||||
emu.reg(x86_register::rdx, context.ntdll_image_base);
|
||||
emu.reg(x86_register::rip, context.ldr_initialize_thunk);
|
||||
}
|
||||
|
||||
@@ -105,17 +105,17 @@ class emulator_thread : public ref_counted_object
|
||||
|
||||
bool is_thread_ready(process_context& process, utils::clock& clock);
|
||||
|
||||
void save(x64_emulator& emu)
|
||||
void save(x86_64_emulator& emu)
|
||||
{
|
||||
this->last_registers = emu.save_registers();
|
||||
}
|
||||
|
||||
void restore(x64_emulator& emu) const
|
||||
void restore(x86_64_emulator& emu) const
|
||||
{
|
||||
emu.restore_registers(this->last_registers);
|
||||
}
|
||||
|
||||
void setup_if_necessary(x64_emulator& emu, const process_context& context)
|
||||
void setup_if_necessary(x86_64_emulator& emu, const process_context& context)
|
||||
{
|
||||
if (!this->executed_instructions)
|
||||
{
|
||||
@@ -127,7 +127,7 @@ class emulator_thread : public ref_counted_object
|
||||
const auto status = *this->pending_status;
|
||||
this->pending_status = {};
|
||||
|
||||
emu.reg<uint64_t>(x64_register::rax, static_cast<uint64_t>(status));
|
||||
emu.reg<uint64_t>(x86_register::rax, static_cast<uint64_t>(status));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -211,7 +211,7 @@ class emulator_thread : public ref_counted_object
|
||||
}
|
||||
|
||||
private:
|
||||
void setup_registers(x64_emulator& emu, const process_context& context) const;
|
||||
void setup_registers(x86_64_emulator& emu, const process_context& context) const;
|
||||
|
||||
void release()
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <x64_emulator.hpp>
|
||||
#include <arch_emulator.hpp>
|
||||
|
||||
#include "memory_manager.hpp"
|
||||
#include "memory_utils.hpp"
|
||||
@@ -51,7 +51,7 @@ class module_manager;
|
||||
struct process_context;
|
||||
|
||||
using clock_wrapper = object_wrapper<utils::clock>;
|
||||
using x64_emulator_wrapper = object_wrapper<x64_emulator>;
|
||||
using x64_emulator_wrapper = object_wrapper<x86_64_emulator>;
|
||||
using memory_manager_wrapper = object_wrapper<memory_manager>;
|
||||
using module_manager_wrapper = object_wrapper<module_manager>;
|
||||
using process_context_wrapper = object_wrapper<process_context>;
|
||||
|
||||
@@ -89,7 +89,7 @@ namespace
|
||||
uint64_t ss;
|
||||
};
|
||||
|
||||
void dispatch_exception_pointers(x64_emulator& emu, const uint64_t dispatcher,
|
||||
void dispatch_exception_pointers(x86_64_emulator& emu, const uint64_t dispatcher,
|
||||
const EMU_EXCEPTION_POINTERS<EmulatorTraits<Emu64>> pointers)
|
||||
{
|
||||
constexpr auto mach_frame_size = 0x40;
|
||||
@@ -102,7 +102,7 @@ namespace
|
||||
|
||||
const auto allocation_size = combined_size + mach_frame_size;
|
||||
|
||||
const auto initial_sp = emu.reg(x64_register::rsp);
|
||||
const auto initial_sp = emu.reg(x86_register::rsp);
|
||||
const auto new_sp = align_down(initial_sp - allocation_size, 0x100);
|
||||
|
||||
const auto total_size = initial_sp - new_sp;
|
||||
@@ -113,8 +113,8 @@ namespace
|
||||
|
||||
emu.write_memory(new_sp, zero_memory.data(), zero_memory.size());
|
||||
|
||||
emu.reg(x64_register::rsp, new_sp);
|
||||
emu.reg(x64_register::rip, dispatcher);
|
||||
emu.reg(x86_register::rsp, new_sp);
|
||||
emu.reg(x86_register::rip, dispatcher);
|
||||
|
||||
const emulator_object<CONTEXT64> context_record_obj{emu, new_sp};
|
||||
context_record_obj.write(*reinterpret_cast<CONTEXT64*>(pointers.ContextRecord));
|
||||
@@ -140,7 +140,7 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
void dispatch_exception(x64_emulator& emu, const process_context& proc, const DWORD status,
|
||||
void dispatch_exception(x86_64_emulator& emu, const process_context& proc, const DWORD status,
|
||||
const std::vector<EmulatorTraits<Emu64>::ULONG_PTR>& parameters)
|
||||
{
|
||||
CONTEXT64 ctx{};
|
||||
@@ -172,7 +172,7 @@ void dispatch_exception(x64_emulator& emu, const process_context& proc, const DW
|
||||
dispatch_exception_pointers(emu, proc.ki_user_exception_dispatcher, pointers);
|
||||
}
|
||||
|
||||
void dispatch_access_violation(x64_emulator& emu, const process_context& proc, const uint64_t address,
|
||||
void dispatch_access_violation(x86_64_emulator& emu, const process_context& proc, const uint64_t address,
|
||||
const memory_operation operation)
|
||||
{
|
||||
dispatch_exception(emu, proc, STATUS_ACCESS_VIOLATION,
|
||||
@@ -182,22 +182,22 @@ void dispatch_access_violation(x64_emulator& emu, const process_context& proc, c
|
||||
});
|
||||
}
|
||||
|
||||
void dispatch_illegal_instruction_violation(x64_emulator& emu, const process_context& proc)
|
||||
void dispatch_illegal_instruction_violation(x86_64_emulator& emu, const process_context& proc)
|
||||
{
|
||||
dispatch_exception(emu, proc, STATUS_ILLEGAL_INSTRUCTION, {});
|
||||
}
|
||||
|
||||
void dispatch_integer_division_by_zero(x64_emulator& emu, const process_context& proc)
|
||||
void dispatch_integer_division_by_zero(x86_64_emulator& emu, const process_context& proc)
|
||||
{
|
||||
dispatch_exception(emu, proc, STATUS_INTEGER_DIVIDE_BY_ZERO, {});
|
||||
}
|
||||
|
||||
void dispatch_single_step(x64_emulator& emu, const process_context& proc)
|
||||
void dispatch_single_step(x86_64_emulator& emu, const process_context& proc)
|
||||
{
|
||||
dispatch_exception(emu, proc, STATUS_SINGLE_STEP, {});
|
||||
}
|
||||
|
||||
void dispatch_breakpoint(x64_emulator& emu, const process_context& proc)
|
||||
void dispatch_breakpoint(x86_64_emulator& emu, const process_context& proc)
|
||||
{
|
||||
dispatch_exception(emu, proc, STATUS_BREAKPOINT, {});
|
||||
}
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include <x64_emulator.hpp>
|
||||
#include <arch_emulator.hpp>
|
||||
|
||||
#include <platform/traits.hpp>
|
||||
#include <platform/primitives.hpp>
|
||||
|
||||
struct process_context;
|
||||
|
||||
void dispatch_exception(x64_emulator& emu, const process_context& proc, DWORD status,
|
||||
void dispatch_exception(x86_64_emulator& emu, const process_context& proc, DWORD status,
|
||||
const std::vector<EmulatorTraits<Emu64>::ULONG_PTR>& parameters);
|
||||
template <typename T>
|
||||
requires(std::is_integral_v<T> && !std::is_same_v<T, DWORD>)
|
||||
void dispatch_exception(x64_emulator& emu, const process_context& proc, const T status,
|
||||
void dispatch_exception(x86_64_emulator& emu, const process_context& proc, const T status,
|
||||
const std::vector<EmulatorTraits<Emu64>::ULONG_PTR>& parameters)
|
||||
{
|
||||
dispatch_exception(emu, proc, static_cast<DWORD>(status), parameters);
|
||||
}
|
||||
|
||||
void dispatch_access_violation(x64_emulator& emu, const process_context& proc, uint64_t address,
|
||||
void dispatch_access_violation(x86_64_emulator& emu, const process_context& proc, uint64_t address,
|
||||
memory_operation operation);
|
||||
void dispatch_illegal_instruction_violation(x64_emulator& emu, const process_context& proc);
|
||||
void dispatch_integer_division_by_zero(x64_emulator& emu, const process_context& proc);
|
||||
void dispatch_single_step(x64_emulator& emu, const process_context& proc);
|
||||
void dispatch_breakpoint(x64_emulator& emu, const process_context& proc);
|
||||
void dispatch_illegal_instruction_violation(x86_64_emulator& emu, const process_context& proc);
|
||||
void dispatch_integer_division_by_zero(x86_64_emulator& emu, const process_context& proc);
|
||||
void dispatch_single_step(x86_64_emulator& emu, const process_context& proc);
|
||||
void dispatch_breakpoint(x86_64_emulator& emu, const process_context& proc);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <x64_emulator.hpp>
|
||||
#include <arch_emulator.hpp>
|
||||
#include <serialization.hpp>
|
||||
|
||||
#include "emulator_utils.hpp"
|
||||
@@ -22,7 +22,7 @@ struct io_device_context
|
||||
emulator_pointer output_buffer{};
|
||||
ULONG output_buffer_length{};
|
||||
|
||||
io_device_context(x64_emulator& emu)
|
||||
io_device_context(x86_64_emulator& emu)
|
||||
: io_status_block(emu)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include "std_include.hpp"
|
||||
#include <serialization.hpp>
|
||||
|
||||
#include "x64_emulator.hpp"
|
||||
#include "arch_emulator.hpp"
|
||||
|
||||
#include <utils/time.hpp>
|
||||
|
||||
|
||||
@@ -14,20 +14,20 @@ namespace
|
||||
return emulator_allocator{memory, base, size};
|
||||
}
|
||||
|
||||
void setup_gdt(x64_emulator& emu, memory_manager& memory)
|
||||
void setup_gdt(x86_64_emulator& emu, memory_manager& memory)
|
||||
{
|
||||
memory.allocate_memory(GDT_ADDR, GDT_LIMIT, memory_permission::read);
|
||||
emu.load_gdt(GDT_ADDR, GDT_LIMIT);
|
||||
|
||||
emu.write_memory<uint64_t>(GDT_ADDR + 6 * (sizeof(uint64_t)), 0xEFFE000000FFFF);
|
||||
emu.reg<uint16_t>(x64_register::cs, 0x33);
|
||||
emu.reg<uint16_t>(x86_register::cs, 0x33);
|
||||
|
||||
emu.write_memory<uint64_t>(GDT_ADDR + 5 * (sizeof(uint64_t)), 0xEFF6000000FFFF);
|
||||
emu.reg<uint16_t>(x64_register::ss, 0x2B);
|
||||
emu.reg<uint16_t>(x86_register::ss, 0x2B);
|
||||
}
|
||||
}
|
||||
|
||||
void process_context::setup(x64_emulator& emu, memory_manager& memory, const application_settings& app_settings,
|
||||
void process_context::setup(x86_64_emulator& emu, memory_manager& memory, const application_settings& app_settings,
|
||||
const mapped_module& executable, const mapped_module& ntdll,
|
||||
const apiset::container& apiset_container)
|
||||
{
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include "module/module_manager.hpp"
|
||||
#include <utils/nt_handle.hpp>
|
||||
|
||||
#include <x64_emulator.hpp>
|
||||
#include <arch_emulator.hpp>
|
||||
|
||||
#include "io_device.hpp"
|
||||
#include "kusd_mmio.hpp"
|
||||
@@ -50,7 +50,7 @@ struct process_context
|
||||
atom_entry() = default;
|
||||
};
|
||||
|
||||
process_context(x64_emulator& emu, memory_manager& memory, utils::clock& clock, callbacks& cb)
|
||||
process_context(x86_64_emulator& emu, memory_manager& memory, utils::clock& clock, callbacks& cb)
|
||||
: callbacks_(&cb),
|
||||
base_allocator(emu),
|
||||
peb(emu),
|
||||
@@ -59,7 +59,7 @@ struct process_context
|
||||
{
|
||||
}
|
||||
|
||||
void setup(x64_emulator& emu, memory_manager& memory, const application_settings& app_settings,
|
||||
void setup(x86_64_emulator& emu, memory_manager& memory, const application_settings& app_settings,
|
||||
const mapped_module& executable, const mapped_module& ntdll, const apiset::container& apiset_container);
|
||||
|
||||
handle create_thread(memory_manager& memory, uint64_t start_address, uint64_t argument, uint64_t stack_size,
|
||||
|
||||
@@ -65,7 +65,7 @@ void syscall_dispatcher::dispatch(windows_emulator& win_emu)
|
||||
auto& context = win_emu.process;
|
||||
|
||||
const auto address = emu.read_instruction_pointer();
|
||||
const auto syscall_id = emu.reg<uint32_t>(x64_register::eax);
|
||||
const auto syscall_id = emu.reg<uint32_t>(x86_register::eax);
|
||||
|
||||
const syscall_context c{
|
||||
.win_emu = win_emu,
|
||||
@@ -82,7 +82,7 @@ void syscall_dispatcher::dispatch(windows_emulator& win_emu)
|
||||
if (entry == this->handlers_.end())
|
||||
{
|
||||
win_emu.log.error("Unknown syscall: 0x%X\n", syscall_id);
|
||||
c.emu.reg<uint64_t>(x64_register::rax, STATUS_NOT_SUPPORTED);
|
||||
c.emu.reg<uint64_t>(x86_register::rax, STATUS_NOT_SUPPORTED);
|
||||
c.emu.stop();
|
||||
return;
|
||||
}
|
||||
@@ -97,7 +97,7 @@ void syscall_dispatcher::dispatch(windows_emulator& win_emu)
|
||||
if (!entry->second.handler)
|
||||
{
|
||||
win_emu.log.error("Unimplemented syscall: %s - 0x%X\n", entry->second.name.c_str(), syscall_id);
|
||||
c.emu.reg<uint64_t>(x64_register::rax, STATUS_NOT_SUPPORTED);
|
||||
c.emu.reg<uint64_t>(x86_register::rax, STATUS_NOT_SUPPORTED);
|
||||
c.emu.stop();
|
||||
return;
|
||||
}
|
||||
@@ -139,13 +139,13 @@ void syscall_dispatcher::dispatch(windows_emulator& win_emu)
|
||||
catch (std::exception& e)
|
||||
{
|
||||
win_emu.log.error("Syscall threw an exception: %X (0x%" PRIx64 ") - %s\n", syscall_id, address, e.what());
|
||||
emu.reg<uint64_t>(x64_register::rax, STATUS_UNSUCCESSFUL);
|
||||
emu.reg<uint64_t>(x86_register::rax, STATUS_UNSUCCESSFUL);
|
||||
emu.stop();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
win_emu.log.error("Syscall threw an unknown exception: %X (0x%" PRIx64 ")\n", syscall_id, address);
|
||||
emu.reg<uint64_t>(x64_register::rax, STATUS_UNSUCCESSFUL);
|
||||
emu.reg<uint64_t>(x86_register::rax, STATUS_UNSUCCESSFUL);
|
||||
emu.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,24 +7,24 @@
|
||||
struct syscall_context
|
||||
{
|
||||
windows_emulator& win_emu;
|
||||
x64_emulator& emu;
|
||||
x86_64_emulator& emu;
|
||||
process_context& proc;
|
||||
mutable bool write_status{true};
|
||||
mutable bool retrigger_syscall{false};
|
||||
};
|
||||
|
||||
inline uint64_t get_syscall_argument(x64_emulator& emu, const size_t index)
|
||||
inline uint64_t get_syscall_argument(x86_64_emulator& emu, const size_t index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
return emu.reg(x64_register::r10);
|
||||
return emu.reg(x86_register::r10);
|
||||
case 1:
|
||||
return emu.reg(x64_register::rdx);
|
||||
return emu.reg(x86_register::rdx);
|
||||
case 2:
|
||||
return emu.reg(x64_register::r8);
|
||||
return emu.reg(x86_register::r8);
|
||||
case 3:
|
||||
return emu.reg(x64_register::r9);
|
||||
return emu.reg(x86_register::r9);
|
||||
default:
|
||||
return emu.read_stack(index + 1);
|
||||
}
|
||||
@@ -110,7 +110,7 @@ inline void map_syscalls(std::map<uint64_t, syscall_handler_entry>& handlers, st
|
||||
|
||||
template <typename T>
|
||||
requires(std::is_integral_v<T> || std::is_enum_v<T>)
|
||||
T resolve_argument(x64_emulator& emu, const size_t index)
|
||||
T resolve_argument(x86_64_emulator& emu, const size_t index)
|
||||
{
|
||||
const auto arg = get_syscall_argument(emu, index);
|
||||
return static_cast<T>(arg);
|
||||
@@ -118,7 +118,7 @@ T resolve_argument(x64_emulator& emu, const size_t index)
|
||||
|
||||
template <typename T>
|
||||
requires(std::is_same_v<std::remove_cvref_t<T>, handle>)
|
||||
handle resolve_argument(x64_emulator& emu, const size_t index)
|
||||
handle resolve_argument(x86_64_emulator& emu, const size_t index)
|
||||
{
|
||||
handle h{};
|
||||
h.bits = resolve_argument<uint64_t>(emu, index);
|
||||
@@ -127,14 +127,14 @@ handle resolve_argument(x64_emulator& emu, const size_t index)
|
||||
|
||||
template <typename T>
|
||||
requires(std::is_same_v<T, emulator_object<typename T::value_type>>)
|
||||
T resolve_argument(x64_emulator& emu, const size_t index)
|
||||
T resolve_argument(x86_64_emulator& emu, const size_t index)
|
||||
{
|
||||
const auto arg = get_syscall_argument(emu, index);
|
||||
return T(emu, arg);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T resolve_indexed_argument(x64_emulator& emu, size_t& index)
|
||||
T resolve_indexed_argument(x86_64_emulator& emu, size_t& index)
|
||||
{
|
||||
return resolve_argument<T>(emu, index++);
|
||||
}
|
||||
@@ -143,13 +143,13 @@ inline void write_syscall_status(const syscall_context& c, const NTSTATUS status
|
||||
{
|
||||
if (c.write_status && !c.retrigger_syscall)
|
||||
{
|
||||
c.emu.reg<uint64_t>(x64_register::rax, static_cast<uint64_t>(status));
|
||||
c.emu.reg<uint64_t>(x86_register::rax, static_cast<uint64_t>(status));
|
||||
}
|
||||
|
||||
const auto new_ip = c.emu.read_instruction_pointer();
|
||||
if (initial_ip != new_ip || c.retrigger_syscall)
|
||||
{
|
||||
c.emu.reg(x64_register::rip, new_ip - 2);
|
||||
c.emu.reg(x86_register::rip, new_ip - 2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -197,7 +197,7 @@ void write_attribute(emulator& emu, const PS_ATTRIBUTE<Traits>& attribute, const
|
||||
}
|
||||
|
||||
template <typename ResponseType, typename Action, typename ReturnLengthSetter>
|
||||
NTSTATUS handle_query_internal(x64_emulator& emu, const uint64_t buffer, const uint32_t length,
|
||||
NTSTATUS handle_query_internal(x86_64_emulator& emu, const uint64_t buffer, const uint32_t length,
|
||||
const ReturnLengthSetter& return_length_setter, const Action& action)
|
||||
{
|
||||
constexpr auto required_size = sizeof(ResponseType);
|
||||
@@ -217,7 +217,7 @@ NTSTATUS handle_query_internal(x64_emulator& emu, const uint64_t buffer, const u
|
||||
}
|
||||
|
||||
template <typename ResponseType, typename Action>
|
||||
NTSTATUS handle_query(x64_emulator& emu, const uint64_t buffer, const uint32_t length,
|
||||
NTSTATUS handle_query(x86_64_emulator& emu, const uint64_t buffer, const uint32_t length,
|
||||
const emulator_object<uint32_t> return_length, const Action& action)
|
||||
{
|
||||
const auto length_setter = [&](const uint32_t required_size) {
|
||||
@@ -231,7 +231,7 @@ NTSTATUS handle_query(x64_emulator& emu, const uint64_t buffer, const uint32_t l
|
||||
}
|
||||
|
||||
template <typename ResponseType, typename Action>
|
||||
NTSTATUS handle_query(x64_emulator& emu, const uint64_t buffer, const uint32_t length,
|
||||
NTSTATUS handle_query(x86_64_emulator& emu, const uint64_t buffer, const uint32_t length,
|
||||
const emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block,
|
||||
const Action& action)
|
||||
{
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
|
||||
#include "cpu_context.hpp"
|
||||
|
||||
#include <unicorn_x64_emulator.hpp>
|
||||
#include <unicorn_x86_64_emulator.hpp>
|
||||
|
||||
#if MOMO_ENABLE_RUST_CODE
|
||||
#include <icicle_x64_emulator.hpp>
|
||||
#include <icicle_x86_64_emulator.hpp>
|
||||
#endif
|
||||
|
||||
#include <utils/io.hpp>
|
||||
@@ -117,13 +117,13 @@ namespace
|
||||
ctx.ContextFlags = CONTEXT64_ALL;
|
||||
cpu_context::save(emu, ctx);
|
||||
|
||||
const auto initial_sp = emu.reg(x64_register::rsp);
|
||||
const auto initial_sp = emu.reg(x86_register::rsp);
|
||||
const auto new_sp = align_down(initial_sp - sizeof(stack_layout), 0x100);
|
||||
|
||||
emu.write_memory(new_sp, stack_layout);
|
||||
|
||||
emu.reg(x64_register::rsp, new_sp);
|
||||
emu.reg(x64_register::rip, win_emu.process.ki_user_apc_dispatcher);
|
||||
emu.reg(x86_register::rsp, new_sp);
|
||||
emu.reg(x86_register::rip, win_emu.process.ki_user_apc_dispatcher);
|
||||
}
|
||||
|
||||
bool switch_to_thread(windows_emulator& win_emu, emulator_thread& thread, const bool force = false)
|
||||
@@ -267,22 +267,22 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<x64_emulator> create_default_x64_emulator()
|
||||
std::unique_ptr<x86_64_emulator> create_default_x86_64_emulator()
|
||||
{
|
||||
#if MOMO_ENABLE_RUST_CODE
|
||||
const auto* env = getenv("EMULATOR_ICICLE");
|
||||
if (env && (env == "1"sv || env == "true"sv))
|
||||
{
|
||||
return icicle::create_x64_emulator();
|
||||
return icicle::create_x86_64_emulator();
|
||||
}
|
||||
#endif
|
||||
|
||||
return unicorn::create_x64_emulator();
|
||||
return unicorn::create_x86_64_emulator();
|
||||
}
|
||||
|
||||
windows_emulator::windows_emulator(application_settings app_settings, const emulator_settings& settings,
|
||||
emulator_callbacks callbacks, emulator_interfaces interfaces,
|
||||
std::unique_ptr<x64_emulator> emu)
|
||||
std::unique_ptr<x86_64_emulator> emu)
|
||||
: windows_emulator(settings, std::move(callbacks), std::move(interfaces), std::move(emu))
|
||||
{
|
||||
fixup_application_settings(app_settings);
|
||||
@@ -290,7 +290,7 @@ windows_emulator::windows_emulator(application_settings app_settings, const emul
|
||||
}
|
||||
|
||||
windows_emulator::windows_emulator(const emulator_settings& settings, emulator_callbacks callbacks,
|
||||
emulator_interfaces interfaces, std::unique_ptr<x64_emulator> emu)
|
||||
emulator_interfaces interfaces, std::unique_ptr<x86_64_emulator> emu)
|
||||
: emu_(std::move(emu)),
|
||||
clock_(get_clock(interfaces, this->executed_instructions_, settings.use_relative_time)),
|
||||
socket_factory_(get_socket_factory(interfaces)),
|
||||
@@ -485,26 +485,26 @@ void windows_emulator::on_instruction_execution(const uint64_t address)
|
||||
log.print(color::gray,
|
||||
"Inst: %16" PRIx64 " - RAX: %16" PRIx64 " - RBX: %16" PRIx64 " - RCX: %16" PRIx64 " - RDX: %16" PRIx64
|
||||
" - R8: %16" PRIx64 " - R9: %16" PRIx64 " - RDI: %16" PRIx64 " - RSI: %16" PRIx64 " - %s\n",
|
||||
address, emu.reg(x64_register::rax), emu.reg(x64_register::rbx), emu.reg(x64_register::rcx),
|
||||
emu.reg(x64_register::rdx), emu.reg(x64_register::r8), emu.reg(x64_register::r9),
|
||||
emu.reg(x64_register::rdi), emu.reg(x64_register::rsi), binary ? binary->name.c_str() : "<N/A>");
|
||||
address, emu.reg(x86_register::rax), emu.reg(x86_register::rbx), emu.reg(x86_register::rcx),
|
||||
emu.reg(x86_register::rdx), emu.reg(x86_register::r8), emu.reg(x86_register::r9),
|
||||
emu.reg(x86_register::rdi), emu.reg(x86_register::rsi), binary ? binary->name.c_str() : "<N/A>");
|
||||
}
|
||||
|
||||
void windows_emulator::setup_hooks()
|
||||
{
|
||||
this->emu().hook_instruction(x64_hookable_instructions::syscall, [&] {
|
||||
this->emu().hook_instruction(x86_hookable_instructions::syscall, [&] {
|
||||
this->dispatcher.dispatch(*this);
|
||||
return instruction_hook_continuation::skip_instruction;
|
||||
});
|
||||
|
||||
this->emu().hook_instruction(x64_hookable_instructions::rdtsc, [&] {
|
||||
this->emu().hook_instruction(x86_hookable_instructions::rdtsc, [&] {
|
||||
const auto ticks = this->clock_->timestamp_counter();
|
||||
this->emu().reg(x64_register::rax, ticks & 0xFFFFFFFF);
|
||||
this->emu().reg(x64_register::rdx, (ticks >> 32) & 0xFFFFFFFF);
|
||||
this->emu().reg(x86_register::rax, ticks & 0xFFFFFFFF);
|
||||
this->emu().reg(x86_register::rdx, (ticks >> 32) & 0xFFFFFFFF);
|
||||
return instruction_hook_continuation::skip_instruction;
|
||||
});
|
||||
|
||||
this->emu().hook_instruction(x64_hookable_instructions::invalid, [&] {
|
||||
this->emu().hook_instruction(x86_hookable_instructions::invalid, [&] {
|
||||
const auto ip = this->emu().read_instruction_pointer();
|
||||
|
||||
this->log.print(color::gray, "Invalid instruction at: 0x%" PRIx64 " (via 0x%" PRIx64 ")\n", ip,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
#include "std_include.hpp"
|
||||
|
||||
#include <x64_emulator.hpp>
|
||||
#include <arch_emulator.hpp>
|
||||
|
||||
#include <utils/function.hpp>
|
||||
|
||||
@@ -13,11 +13,11 @@
|
||||
#include "module/module_manager.hpp"
|
||||
#include "network/socket_factory.hpp"
|
||||
|
||||
std::unique_ptr<x64_emulator> create_default_x64_emulator();
|
||||
std::unique_ptr<x86_64_emulator> create_default_x86_64_emulator();
|
||||
|
||||
struct emulator_callbacks : module_manager::callbacks, process_context::callbacks
|
||||
{
|
||||
utils::optional_function<instruction_hook_continuation(uint32_t syscall_id, x64_emulator::pointer_type address,
|
||||
utils::optional_function<instruction_hook_continuation(uint32_t syscall_id, x86_64_emulator::pointer_type address,
|
||||
std::string_view mod_name, std::string_view syscall_name)>
|
||||
on_syscall{};
|
||||
|
||||
@@ -57,7 +57,7 @@ class windows_emulator
|
||||
{
|
||||
uint64_t executed_instructions_{0};
|
||||
|
||||
std::unique_ptr<x64_emulator> emu_{};
|
||||
std::unique_ptr<x86_64_emulator> emu_{};
|
||||
std::unique_ptr<utils::clock> clock_{};
|
||||
std::unique_ptr<network::socket_factory> socket_factory_{};
|
||||
|
||||
@@ -74,10 +74,10 @@ class windows_emulator
|
||||
|
||||
windows_emulator(const emulator_settings& settings = {}, emulator_callbacks callbacks = {},
|
||||
emulator_interfaces interfaces = {},
|
||||
std::unique_ptr<x64_emulator> emu = create_default_x64_emulator());
|
||||
std::unique_ptr<x86_64_emulator> emu = create_default_x86_64_emulator());
|
||||
windows_emulator(application_settings app_settings, const emulator_settings& settings = {},
|
||||
emulator_callbacks callbacks = {}, emulator_interfaces interfaces = {},
|
||||
std::unique_ptr<x64_emulator> emu = create_default_x64_emulator());
|
||||
std::unique_ptr<x86_64_emulator> emu = create_default_x86_64_emulator());
|
||||
|
||||
windows_emulator(windows_emulator&&) = delete;
|
||||
windows_emulator(const windows_emulator&) = delete;
|
||||
@@ -86,12 +86,12 @@ class windows_emulator
|
||||
|
||||
~windows_emulator();
|
||||
|
||||
x64_emulator& emu()
|
||||
x86_64_emulator& emu()
|
||||
{
|
||||
return *this->emu_;
|
||||
}
|
||||
|
||||
const x64_emulator& emu() const
|
||||
const x86_64_emulator& emu() const
|
||||
{
|
||||
return *this->emu_;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user