mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-29 15:51:02 +00:00
migrate to platform structures
This commit is contained in:
@@ -14,8 +14,8 @@ namespace
|
||||
emulator_object<T> allocate_object_on_stack(x64_emulator& emu)
|
||||
{
|
||||
const auto old_sp = emu.reg(x64_register::rsp);
|
||||
const auto new_sp = align_down(old_sp - sizeof(CONTEXT),
|
||||
std::max(alignof(CONTEXT), alignof(x64_emulator::pointer_type)));
|
||||
const auto new_sp = align_down(old_sp - sizeof(CONTEXT64),
|
||||
std::max(alignof(CONTEXT64), alignof(x64_emulator::pointer_type)));
|
||||
emu.reg(x64_register::rsp, new_sp);
|
||||
|
||||
return {emu, new_sp};
|
||||
@@ -143,8 +143,11 @@ namespace
|
||||
|
||||
emulator_object<API_SET_NAMESPACE> build_api_set_map(x64_emulator& emu, emulator_allocator& allocator)
|
||||
{
|
||||
const auto& orig_api_set_map = *NtCurrentTeb()->ProcessEnvironmentBlock->ApiSetMap;
|
||||
return clone_api_set_map(emu, allocator, orig_api_set_map);
|
||||
// TODO: fix
|
||||
// const auto& orig_api_set_map = *NtCurrentTeb()->ProcessEnvironmentBlock->ApiSetMap;
|
||||
// return clone_api_set_map(emu, allocator, orig_api_set_map);
|
||||
|
||||
return clone_api_set_map(emu, allocator, {});
|
||||
}
|
||||
|
||||
emulator_allocator create_allocator(emulator& emu, const size_t size)
|
||||
@@ -187,7 +190,7 @@ namespace
|
||||
context.base_allocator = create_allocator(emu, PEB_SEGMENT_SIZE);
|
||||
auto& allocator = context.base_allocator;
|
||||
|
||||
context.peb = allocator.reserve<PEB>();
|
||||
context.peb = allocator.reserve<PEB64>();
|
||||
|
||||
/* Values of the following fields must be
|
||||
* allocated relative to the process_params themselves
|
||||
@@ -204,9 +207,9 @@ namespace
|
||||
* RedirectionDllName
|
||||
*/
|
||||
|
||||
context.process_params = allocator.reserve<RTL_USER_PROCESS_PARAMETERS>();
|
||||
context.process_params = allocator.reserve<RTL_USER_PROCESS_PARAMETERS64>();
|
||||
|
||||
context.process_params.access([&](RTL_USER_PROCESS_PARAMETERS& proc_params)
|
||||
context.process_params.access([&](RTL_USER_PROCESS_PARAMETERS64& proc_params)
|
||||
{
|
||||
proc_params.Flags = 0x6001; //| 0x80000000; // Prevent CsrClientConnectToServer
|
||||
|
||||
@@ -249,7 +252,7 @@ namespace
|
||||
proc_params.MaximumLength = proc_params.Length;
|
||||
});
|
||||
|
||||
context.peb.access([&](PEB& peb)
|
||||
context.peb.access([&](PEB64& peb)
|
||||
{
|
||||
peb.ImageBaseAddress = nullptr;
|
||||
peb.ProcessParameters = context.process_params.ptr();
|
||||
@@ -266,21 +269,21 @@ namespace
|
||||
});
|
||||
}
|
||||
|
||||
using exception_record_map = std::unordered_map<const EXCEPTION_RECORD*, emulator_object<EXCEPTION_RECORD>>;
|
||||
using exception_record_map = std::unordered_map<const EMU_EXCEPTION_RECORD<EmulatorTraits<Emu64>>*, emulator_object<EMU_EXCEPTION_RECORD<EmulatorTraits<Emu64>>>>;
|
||||
|
||||
emulator_object<EXCEPTION_RECORD> save_exception_record(emulator_allocator& allocator,
|
||||
const EXCEPTION_RECORD& record,
|
||||
emulator_object<EMU_EXCEPTION_RECORD<EmulatorTraits<Emu64>>> save_exception_record(emulator_allocator& allocator,
|
||||
const EMU_EXCEPTION_RECORD<EmulatorTraits<Emu64>>& record,
|
||||
exception_record_map& record_mapping)
|
||||
{
|
||||
const auto record_obj = allocator.reserve<EXCEPTION_RECORD>();
|
||||
const auto record_obj = allocator.reserve<EMU_EXCEPTION_RECORD<EmulatorTraits<Emu64>>>();
|
||||
record_obj.write(record);
|
||||
|
||||
if (record.ExceptionRecord)
|
||||
{
|
||||
record_mapping.emplace(&record, record_obj);
|
||||
|
||||
emulator_object<EXCEPTION_RECORD> nested_record_obj{allocator.get_emulator()};
|
||||
const auto nested_record = record_mapping.find(record.ExceptionRecord);
|
||||
emulator_object<EMU_EXCEPTION_RECORD<EmulatorTraits<Emu64>>> nested_record_obj{allocator.get_emulator()};
|
||||
const auto nested_record = record_mapping.find(reinterpret_cast<EMU_EXCEPTION_RECORD<EmulatorTraits<Emu64>>*>(record.ExceptionRecord));
|
||||
|
||||
if (nested_record != record_mapping.end())
|
||||
{
|
||||
@@ -288,21 +291,21 @@ namespace
|
||||
}
|
||||
else
|
||||
{
|
||||
nested_record_obj = save_exception_record(allocator, *record.ExceptionRecord,
|
||||
nested_record_obj = save_exception_record(allocator, *reinterpret_cast<EMU_EXCEPTION_RECORD<EmulatorTraits<Emu64>>*>(record.ExceptionRecord),
|
||||
record_mapping);
|
||||
}
|
||||
|
||||
record_obj.access([&](EXCEPTION_RECORD& r)
|
||||
record_obj.access([&](EMU_EXCEPTION_RECORD<EmulatorTraits<Emu64>>& r)
|
||||
{
|
||||
r.ExceptionRecord = nested_record_obj.ptr();
|
||||
r.ExceptionRecord = reinterpret_cast<EmulatorTraits<Emu64>::PVOID>(nested_record_obj.ptr());
|
||||
});
|
||||
}
|
||||
|
||||
return record_obj;
|
||||
}
|
||||
|
||||
emulator_object<EXCEPTION_RECORD> save_exception_record(emulator_allocator& allocator,
|
||||
const EXCEPTION_RECORD& record)
|
||||
emulator_object<EMU_EXCEPTION_RECORD<EmulatorTraits<Emu64>>> save_exception_record(emulator_allocator& allocator,
|
||||
const EMU_EXCEPTION_RECORD<EmulatorTraits<Emu64>>& record)
|
||||
{
|
||||
exception_record_map record_mapping{};
|
||||
return save_exception_record(allocator, record, record_mapping);
|
||||
@@ -321,12 +324,12 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
size_t calculate_exception_record_size(const EXCEPTION_RECORD& record)
|
||||
size_t calculate_exception_record_size(const EMU_EXCEPTION_RECORD<EmulatorTraits<Emu64>>& record)
|
||||
{
|
||||
std::unordered_set<const EXCEPTION_RECORD*> records{};
|
||||
std::unordered_set<const EMU_EXCEPTION_RECORD<EmulatorTraits<Emu64>>*> records{};
|
||||
size_t total_size = 0;
|
||||
|
||||
const EXCEPTION_RECORD* current_record = &record;
|
||||
const EMU_EXCEPTION_RECORD<EmulatorTraits<Emu64>>* current_record = &record;
|
||||
while (current_record)
|
||||
{
|
||||
if (!records.insert(current_record).second)
|
||||
@@ -335,7 +338,7 @@ namespace
|
||||
}
|
||||
|
||||
total_size += sizeof(*current_record);
|
||||
current_record = record.ExceptionRecord;
|
||||
current_record = reinterpret_cast<EMU_EXCEPTION_RECORD<EmulatorTraits<Emu64>>*>(record.ExceptionRecord);
|
||||
}
|
||||
|
||||
return total_size;
|
||||
@@ -350,11 +353,11 @@ namespace
|
||||
uint64_t ss;
|
||||
};
|
||||
|
||||
void dispatch_exception_pointers(x64_emulator& emu, const uint64_t dispatcher, const EXCEPTION_POINTERS pointers)
|
||||
void dispatch_exception_pointers(x64_emulator& emu, const uint64_t dispatcher, const EMU_EXCEPTION_POINTERS<EmulatorTraits<Emu64>> pointers)
|
||||
{
|
||||
constexpr auto mach_frame_size = 0x40;
|
||||
constexpr auto context_record_size = 0x4F0;
|
||||
const auto exception_record_size = calculate_exception_record_size(*pointers.ExceptionRecord);
|
||||
const auto exception_record_size = calculate_exception_record_size(*reinterpret_cast<EMU_EXCEPTION_RECORD<EmulatorTraits<Emu64>>*>(pointers.ExceptionRecord));
|
||||
const auto combined_size = align_up(exception_record_size + context_record_size, 0x10);
|
||||
|
||||
assert(combined_size == 0x590);
|
||||
@@ -375,11 +378,11 @@ namespace
|
||||
emu.reg(x64_register::rsp, new_sp);
|
||||
emu.reg(x64_register::rip, dispatcher);
|
||||
|
||||
const emulator_object<CONTEXT> context_record_obj{emu, new_sp};
|
||||
context_record_obj.write(*pointers.ContextRecord);
|
||||
const emulator_object<CONTEXT64> context_record_obj{emu, new_sp};
|
||||
context_record_obj.write(*reinterpret_cast<CONTEXT64*>(pointers.ContextRecord));
|
||||
|
||||
emulator_allocator allocator{emu, new_sp + context_record_size, exception_record_size};
|
||||
const auto exception_record_obj = save_exception_record(allocator, *pointers.ExceptionRecord);
|
||||
const auto exception_record_obj = save_exception_record(allocator, *reinterpret_cast<EMU_EXCEPTION_RECORD<EmulatorTraits<Emu64>>*>(pointers.ExceptionRecord));
|
||||
|
||||
if (exception_record_obj.value() != allocator.get_base())
|
||||
{
|
||||
@@ -389,34 +392,34 @@ namespace
|
||||
const emulator_object<machine_frame> machine_frame_obj{emu, new_sp + combined_size};
|
||||
machine_frame_obj.access([&](machine_frame& frame)
|
||||
{
|
||||
frame.rip = pointers.ContextRecord->Rip;
|
||||
frame.rsp = pointers.ContextRecord->Rsp;
|
||||
frame.ss = pointers.ContextRecord->SegSs;
|
||||
frame.cs = pointers.ContextRecord->SegCs;
|
||||
frame.eflags = pointers.ContextRecord->EFlags;
|
||||
frame.rip = reinterpret_cast<CONTEXT64*>(pointers.ContextRecord)->Rip;
|
||||
frame.rsp = reinterpret_cast<CONTEXT64*>(pointers.ContextRecord)->Rsp;
|
||||
frame.ss = reinterpret_cast<CONTEXT64*>(pointers.ContextRecord)->SegSs;
|
||||
frame.cs = reinterpret_cast<CONTEXT64*>(pointers.ContextRecord)->SegCs;
|
||||
frame.eflags = reinterpret_cast<CONTEXT64*>(pointers.ContextRecord)->EFlags;
|
||||
});
|
||||
}
|
||||
|
||||
void dispatch_access_violation(x64_emulator& emu, const uint64_t dispatcher, const uint64_t address,
|
||||
const memory_operation operation)
|
||||
{
|
||||
CONTEXT ctx{};
|
||||
ctx.ContextFlags = CONTEXT_ALL;
|
||||
CONTEXT64 ctx{};
|
||||
ctx.ContextFlags = CONTEXT64_ALL;
|
||||
context_frame::save(emu, ctx);
|
||||
|
||||
EXCEPTION_RECORD record{};
|
||||
EMU_EXCEPTION_RECORD<EmulatorTraits<Emu64>> record{};
|
||||
memset(&record, 0, sizeof(record));
|
||||
record.ExceptionCode = static_cast<DWORD>(STATUS_ACCESS_VIOLATION);
|
||||
record.ExceptionFlags = 0;
|
||||
record.ExceptionRecord = nullptr;
|
||||
record.ExceptionAddress = reinterpret_cast<void*>(emu.read_instruction_pointer());
|
||||
record.ExceptionRecord = 0;
|
||||
record.ExceptionAddress = static_cast<EmulatorTraits<Emu64>::PVOID>(emu.read_instruction_pointer());
|
||||
record.NumberParameters = 2;
|
||||
record.ExceptionInformation[0] = map_violation_operation_to_parameter(operation);
|
||||
record.ExceptionInformation[1] = address;
|
||||
|
||||
EXCEPTION_POINTERS pointers{};
|
||||
pointers.ContextRecord = &ctx;
|
||||
pointers.ExceptionRecord = &record;
|
||||
EMU_EXCEPTION_POINTERS<EmulatorTraits<Emu64>> pointers{};
|
||||
pointers.ContextRecord = reinterpret_cast<EmulatorTraits<Emu64>::PVOID>(&ctx);
|
||||
pointers.ExceptionRecord = reinterpret_cast<EmulatorTraits<Emu64>::PVOID>(&record);
|
||||
|
||||
dispatch_exception_pointers(emu, dispatcher, pointers);
|
||||
}
|
||||
@@ -560,7 +563,7 @@ emulator_thread::emulator_thread(x64_emulator& emu, const process_context& conte
|
||||
const uint64_t argument,
|
||||
const uint64_t stack_size, const uint32_t id)
|
||||
: emu_ptr(&emu)
|
||||
, stack_size(page_align_up(std::max(stack_size, STACK_SIZE)))
|
||||
, stack_size(page_align_up(std::max(stack_size, static_cast<uint64_t>(STACK_SIZE))))
|
||||
, start_address(start_address)
|
||||
, argument(argument)
|
||||
, id(id)
|
||||
@@ -574,14 +577,14 @@ emulator_thread::emulator_thread(x64_emulator& emu, const process_context& conte
|
||||
GS_SEGMENT_SIZE,
|
||||
};
|
||||
|
||||
this->teb = this->gs_segment->reserve<TEB>();
|
||||
this->teb = this->gs_segment->reserve<TEB64>();
|
||||
|
||||
this->teb->access([&](TEB& teb_obj)
|
||||
this->teb->access([&](TEB64& teb_obj)
|
||||
{
|
||||
teb_obj.ClientId.UniqueProcess = reinterpret_cast<HANDLE>(1);
|
||||
teb_obj.ClientId.UniqueThread = reinterpret_cast<HANDLE>(static_cast<uint64_t>(this->id));
|
||||
teb_obj.NtTib.StackLimit = reinterpret_cast<void*>(this->stack_base);
|
||||
teb_obj.NtTib.StackBase = reinterpret_cast<void*>(this->stack_base + this->stack_size);
|
||||
teb_obj.ClientId.UniqueProcess = 1ul;
|
||||
teb_obj.ClientId.UniqueThread = static_cast<uint64_t>(this->id);
|
||||
teb_obj.NtTib.StackLimit = reinterpret_cast<std::uint64_t*>(this->stack_base);
|
||||
teb_obj.NtTib.StackBase = reinterpret_cast<std::uint64_t*>(this->stack_base + this->stack_size);
|
||||
teb_obj.NtTib.Self = &this->teb->ptr()->NtTib;
|
||||
teb_obj.ProcessEnvironmentBlock = context.peb.ptr();
|
||||
});
|
||||
@@ -661,8 +664,8 @@ void emulator_thread::setup_registers(x64_emulator& emu, const process_context&
|
||||
setup_stack(emu, this->stack_base, this->stack_size);
|
||||
setup_gs_segment(emu, *this->gs_segment);
|
||||
|
||||
CONTEXT ctx{};
|
||||
ctx.ContextFlags = CONTEXT_ALL;
|
||||
CONTEXT64 ctx{};
|
||||
ctx.ContextFlags = CONTEXT64_ALL;
|
||||
|
||||
unalign_stack(emu);
|
||||
context_frame::save(emu, ctx);
|
||||
@@ -671,7 +674,7 @@ void emulator_thread::setup_registers(x64_emulator& emu, const process_context&
|
||||
ctx.Rcx = this->start_address;
|
||||
ctx.Rdx = this->argument;
|
||||
|
||||
const auto ctx_obj = allocate_object_on_stack<CONTEXT>(emu);
|
||||
const auto ctx_obj = allocate_object_on_stack<CONTEXT64>(emu);
|
||||
ctx_obj.write(ctx);
|
||||
|
||||
unalign_stack(emu);
|
||||
@@ -714,9 +717,9 @@ void windows_emulator::setup_process(const emulator_settings& settings)
|
||||
|
||||
context.executable = context.module_manager.map_module(settings.application, this->logger);
|
||||
|
||||
context.peb.access([&](PEB& peb)
|
||||
context.peb.access([&](PEB64& peb)
|
||||
{
|
||||
peb.ImageBaseAddress = reinterpret_cast<void*>(context.executable->image_base);
|
||||
peb.ImageBaseAddress = reinterpret_cast<std::uint64_t*>(context.executable->image_base);
|
||||
});
|
||||
|
||||
context.ntdll = context.module_manager.map_module(R"(C:\Windows\System32\ntdll.dll)", this->logger);
|
||||
@@ -777,14 +780,14 @@ void windows_emulator::setup_hooks()
|
||||
this->emu().hook_instruction(x64_hookable_instructions::invalid, [&]
|
||||
{
|
||||
const auto ip = this->emu().read_instruction_pointer();
|
||||
printf("Invalid instruction at: 0x%llX\n", ip);
|
||||
printf("Invalid instruction at: 0x%zX\n", ip);
|
||||
return instruction_hook_continuation::skip_instruction;
|
||||
});
|
||||
|
||||
this->emu().hook_interrupt([&](const int interrupt)
|
||||
{
|
||||
const auto rip = this->emu().read_instruction_pointer();
|
||||
printf("Interrupt: %i 0x%llX\n", interrupt, rip);
|
||||
printf("Interrupt: %i 0x%zX\n", interrupt, rip);
|
||||
|
||||
if (this->fuzzing)
|
||||
{
|
||||
@@ -889,7 +892,7 @@ void windows_emulator::setup_hooks()
|
||||
auto& emu = this->emu();
|
||||
|
||||
printf(
|
||||
"Inst: %16llX - RAX: %16llX - RBX: %16llX - RCX: %16llX - RDX: %16llX - R8: %16llX - R9: %16llX - RDI: %16llX - RSI: %16llX - %s\n",
|
||||
"Inst: %16zX - RAX: %16zX - RBX: %16zX - RCX: %16zX - RDX: %16zX - R8: %16zX - R9: %16zX - RDI: %16zX - RSI: %16zX - %s\n",
|
||||
address,
|
||||
emu.reg(x64_register::rax), emu.reg(x64_register::rbx),
|
||||
emu.reg(x64_register::rcx),
|
||||
|
||||
Reference in New Issue
Block a user