mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-11 08:36:16 +00:00
migrate to platform structures
This commit is contained in:
@@ -16,15 +16,15 @@ namespace
|
||||
//watch_object(win_emu, win_emu.process().kusd);
|
||||
auto* params_hook = watch_object(win_emu, win_emu.process().process_params);
|
||||
|
||||
win_emu.emu().hook_memory_write(win_emu.process().peb.value() + offsetof(PEB, ProcessParameters), 0x8,
|
||||
win_emu.emu().hook_memory_write(win_emu.process().peb.value() + offsetof(PEB64, ProcessParameters), 0x8,
|
||||
[&](const uint64_t address, size_t, const uint64_t value)
|
||||
{
|
||||
const auto target_address = win_emu.process().peb.value() + offsetof(
|
||||
PEB, ProcessParameters);
|
||||
PEB64, ProcessParameters);
|
||||
|
||||
if (address == target_address)
|
||||
{
|
||||
const emulator_object<RTL_USER_PROCESS_PARAMETERS> obj{
|
||||
const emulator_object<RTL_USER_PROCESS_PARAMETERS64> obj{
|
||||
win_emu.emu(), value
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef OS_WINDOWS
|
||||
|
||||
#define NOMINMAX
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
@@ -83,3 +85,5 @@ namespace utils::nt
|
||||
HANDLE handle_{InvalidHandleFunction()};
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -3,9 +3,9 @@
|
||||
|
||||
namespace context_frame
|
||||
{
|
||||
void restore(x64_emulator& emu, const CONTEXT& context)
|
||||
void restore(x64_emulator& emu, const CONTEXT64& context)
|
||||
{
|
||||
if (context.ContextFlags & CONTEXT_DEBUG_REGISTERS)
|
||||
if (context.ContextFlags & CONTEXT_DEBUG_REGISTERS_64)
|
||||
{
|
||||
emu.reg(x64_register::dr0, context.Dr0);
|
||||
emu.reg(x64_register::dr1, context.Dr1);
|
||||
@@ -15,7 +15,7 @@ namespace context_frame
|
||||
emu.reg(x64_register::dr7, context.Dr7);
|
||||
}
|
||||
|
||||
if (context.ContextFlags & CONTEXT_CONTROL)
|
||||
if (context.ContextFlags & CONTEXT_CONTROL_64)
|
||||
{
|
||||
emu.reg<uint16_t>(x64_register::ss, context.SegSs);
|
||||
emu.reg<uint16_t>(x64_register::cs, context.SegCs);
|
||||
@@ -26,7 +26,7 @@ namespace context_frame
|
||||
emu.reg<uint32_t>(x64_register::eflags, context.EFlags);
|
||||
}
|
||||
|
||||
if (context.ContextFlags & CONTEXT_INTEGER)
|
||||
if (context.ContextFlags & CONTEXT_INTEGER_64)
|
||||
{
|
||||
emu.reg(x64_register::rax, context.Rax);
|
||||
emu.reg(x64_register::rbx, context.Rbx);
|
||||
@@ -53,7 +53,7 @@ namespace context_frame
|
||||
emu.reg<uint16_t>(x64_register::gs, context.SegGs);
|
||||
}*/
|
||||
|
||||
if (context.ContextFlags & CONTEXT_FLOATING_POINT)
|
||||
if (context.ContextFlags & CONTEXT_FLOATING_POINT_64)
|
||||
{
|
||||
emu.reg<uint16_t>(x64_register::fpcw, context.FltSave.ControlWord);
|
||||
emu.reg<uint16_t>(x64_register::fpsw, context.FltSave.StatusWord);
|
||||
@@ -66,7 +66,7 @@ namespace context_frame
|
||||
}
|
||||
}
|
||||
|
||||
if (context.ContextFlags & CONTEXT_XSTATE)
|
||||
if (context.ContextFlags & CONTEXT_XSTATE_64)
|
||||
{
|
||||
emu.reg<uint32_t>(x64_register::mxcsr, context.MxCsr);
|
||||
|
||||
@@ -78,9 +78,9 @@ namespace context_frame
|
||||
}
|
||||
}
|
||||
|
||||
void save(x64_emulator& emu, CONTEXT& context)
|
||||
void save(x64_emulator& emu, CONTEXT64& context)
|
||||
{
|
||||
if (context.ContextFlags & CONTEXT_DEBUG_REGISTERS)
|
||||
if (context.ContextFlags & CONTEXT_DEBUG_REGISTERS_64)
|
||||
{
|
||||
context.Dr0 = emu.reg(x64_register::dr0);
|
||||
context.Dr1 = emu.reg(x64_register::dr1);
|
||||
@@ -90,7 +90,7 @@ namespace context_frame
|
||||
context.Dr7 = emu.reg(x64_register::dr7);
|
||||
}
|
||||
|
||||
if (context.ContextFlags & CONTEXT_CONTROL)
|
||||
if (context.ContextFlags & CONTEXT_CONTROL_64)
|
||||
{
|
||||
context.SegSs = emu.reg<uint16_t>(x64_register::ss);
|
||||
context.SegCs = emu.reg<uint16_t>(x64_register::cs);
|
||||
@@ -99,7 +99,7 @@ namespace context_frame
|
||||
context.EFlags = emu.reg<uint32_t>(x64_register::eflags);
|
||||
}
|
||||
|
||||
if (context.ContextFlags & CONTEXT_INTEGER)
|
||||
if (context.ContextFlags & CONTEXT_INTEGER_64)
|
||||
{
|
||||
context.Rax = emu.reg(x64_register::rax);
|
||||
context.Rbx = emu.reg(x64_register::rbx);
|
||||
@@ -118,7 +118,7 @@ namespace context_frame
|
||||
context.R15 = emu.reg(x64_register::r15);
|
||||
}
|
||||
|
||||
if (context.ContextFlags & CONTEXT_SEGMENTS)
|
||||
if (context.ContextFlags & CONTEXT_SEGMENTS_64)
|
||||
{
|
||||
context.SegDs = emu.reg<uint16_t>(x64_register::ds);
|
||||
context.SegEs = emu.reg<uint16_t>(x64_register::es);
|
||||
@@ -126,7 +126,7 @@ namespace context_frame
|
||||
context.SegGs = emu.reg<uint16_t>(x64_register::gs);
|
||||
}
|
||||
|
||||
if (context.ContextFlags & CONTEXT_FLOATING_POINT)
|
||||
if (context.ContextFlags & CONTEXT_FLOATING_POINT_64)
|
||||
{
|
||||
context.FltSave.ControlWord = emu.reg<uint16_t>(x64_register::fpcw);
|
||||
context.FltSave.StatusWord = emu.reg<uint16_t>(x64_register::fpsw);
|
||||
@@ -138,7 +138,7 @@ namespace context_frame
|
||||
}
|
||||
}
|
||||
|
||||
if (context.ContextFlags & CONTEXT_XSTATE)
|
||||
if (context.ContextFlags & CONTEXT_XSTATE_64)
|
||||
{
|
||||
context.MxCsr = emu.reg<uint32_t>(x64_register::mxcsr);
|
||||
for (int i = 0; i < 16; i++)
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
|
||||
namespace context_frame
|
||||
{
|
||||
void save(x64_emulator& emu, CONTEXT& context);
|
||||
void restore(x64_emulator& emu, const CONTEXT& context);
|
||||
void save(x64_emulator& emu, CONTEXT64& context);
|
||||
void restore(x64_emulator& emu, const CONTEXT64& context);
|
||||
}
|
||||
|
||||
@@ -32,23 +32,23 @@ namespace
|
||||
return win_emu.emu().read_memory<afd_creation_data>(data.buffer);
|
||||
}
|
||||
|
||||
std::pair<AFD_POLL_INFO, std::vector<AFD_POLL_HANDLE_INFO>> get_poll_info(
|
||||
std::pair<AFD_POLL_INFO64, std::vector<AFD_POLL_HANDLE_INFO64>> get_poll_info(
|
||||
windows_emulator& win_emu, const io_device_context& c)
|
||||
{
|
||||
constexpr auto info_size = offsetof(AFD_POLL_INFO, Handles);
|
||||
constexpr auto info_size = offsetof(AFD_POLL_INFO64, Handles);
|
||||
if (!c.input_buffer || c.input_buffer_length < info_size)
|
||||
{
|
||||
throw std::runtime_error("Bad AFD poll data");
|
||||
}
|
||||
|
||||
AFD_POLL_INFO poll_info{};
|
||||
AFD_POLL_INFO64 poll_info{};
|
||||
win_emu.emu().read_memory(c.input_buffer, &poll_info, info_size);
|
||||
|
||||
std::vector<AFD_POLL_HANDLE_INFO> handle_info{};
|
||||
std::vector<AFD_POLL_HANDLE_INFO64> handle_info{};
|
||||
|
||||
const emulator_object<AFD_POLL_HANDLE_INFO> handle_info_obj{win_emu.emu(), c.input_buffer + info_size};
|
||||
const emulator_object<AFD_POLL_HANDLE_INFO64> handle_info_obj{win_emu.emu(), c.input_buffer + info_size};
|
||||
|
||||
if (c.input_buffer_length < (info_size + sizeof(AFD_POLL_HANDLE_INFO) * poll_info.NumberOfHandles))
|
||||
if (c.input_buffer_length < (info_size + sizeof(AFD_POLL_HANDLE_INFO64) * poll_info.NumberOfHandles))
|
||||
{
|
||||
throw std::runtime_error("Bad AFD poll handle data");
|
||||
}
|
||||
@@ -126,7 +126,7 @@ namespace
|
||||
|
||||
NTSTATUS perform_poll(windows_emulator& win_emu, const io_device_context& c,
|
||||
const std::span<const SOCKET> endpoints,
|
||||
const std::span<const AFD_POLL_HANDLE_INFO> handles)
|
||||
const std::span<const AFD_POLL_HANDLE_INFO64> handles)
|
||||
{
|
||||
std::vector<pollfd> poll_data{};
|
||||
poll_data.resize(endpoints.size());
|
||||
@@ -147,8 +147,8 @@ namespace
|
||||
return STATUS_PENDING;
|
||||
}
|
||||
|
||||
constexpr auto info_size = offsetof(AFD_POLL_INFO, Handles);
|
||||
const emulator_object<AFD_POLL_HANDLE_INFO> handle_info_obj{win_emu.emu(), c.input_buffer + info_size};
|
||||
constexpr auto info_size = offsetof(AFD_POLL_INFO64, Handles);
|
||||
const emulator_object<AFD_POLL_HANDLE_INFO64> handle_info_obj{win_emu.emu(), c.input_buffer + info_size};
|
||||
|
||||
size_t current_index = 0;
|
||||
|
||||
@@ -170,7 +170,7 @@ namespace
|
||||
|
||||
assert(current_index == static_cast<size_t>(count));
|
||||
|
||||
emulator_object<AFD_POLL_INFO>{win_emu.emu(), c.input_buffer}.access([&](AFD_POLL_INFO& info)
|
||||
emulator_object<AFD_POLL_INFO64>{win_emu.emu(), c.input_buffer}.access([&](AFD_POLL_INFO64& info)
|
||||
{
|
||||
info.NumberOfHandles = static_cast<ULONG>(current_index);
|
||||
});
|
||||
@@ -367,7 +367,7 @@ namespace
|
||||
}
|
||||
|
||||
static std::vector<SOCKET> resolve_endpoints(windows_emulator& win_emu,
|
||||
const std::span<const AFD_POLL_HANDLE_INFO> handles)
|
||||
const std::span<const AFD_POLL_HANDLE_INFO64> handles)
|
||||
{
|
||||
auto& proc = win_emu.process();
|
||||
|
||||
@@ -376,7 +376,7 @@ namespace
|
||||
|
||||
for (const auto& handle : handles)
|
||||
{
|
||||
auto* device = proc.devices.get(reinterpret_cast<uint64_t>(handle.Handle));
|
||||
auto* device = proc.devices.get(handle.Handle);
|
||||
if (!device)
|
||||
{
|
||||
throw std::runtime_error("Bad device!");
|
||||
@@ -428,17 +428,17 @@ namespace
|
||||
{
|
||||
auto& emu = win_emu.emu();
|
||||
|
||||
if (c.input_buffer_length < sizeof(AFD_RECV_DATAGRAM_INFO))
|
||||
if (c.input_buffer_length < sizeof(AFD_RECV_DATAGRAM_INFO<EmulatorTraits<Emu64>>))
|
||||
{
|
||||
return STATUS_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
const auto receive_info = emu.read_memory<AFD_RECV_DATAGRAM_INFO>(c.input_buffer);
|
||||
const auto buffer = emu.read_memory<WSABUF>(receive_info.BufferArray);
|
||||
const auto receive_info = emu.read_memory<AFD_RECV_DATAGRAM_INFO<EmulatorTraits<Emu64>>>(c.input_buffer);
|
||||
const auto buffer = emu.read_memory<EMU_WSABUF<EmulatorTraits<Emu64>>>(receive_info.BufferArray);
|
||||
|
||||
std::vector<std::byte> address{};
|
||||
|
||||
ULONG address_length = 0x1000;
|
||||
unsigned long address_length = 0x1000;
|
||||
if (receive_info.AddressLength)
|
||||
{
|
||||
address_length = emu.read_memory<ULONG>(receive_info.AddressLength);
|
||||
@@ -456,8 +456,13 @@ namespace
|
||||
std::vector<char> data{};
|
||||
data.resize(buffer.len);
|
||||
|
||||
#ifdef OS_WINDOWS
|
||||
const auto recevied_data = recvfrom(*this->s_, data.data(), static_cast<int>(data.size()), 0,
|
||||
reinterpret_cast<sockaddr*>(address.data()), &fromlength);
|
||||
#else
|
||||
const auto recevied_data = recvfrom(*this->s_, data.data(), static_cast<int>(data.size()), 0,
|
||||
reinterpret_cast<sockaddr*>(address.data()), (socklen_t*)&fromlength);
|
||||
#endif
|
||||
|
||||
if (recevied_data < 0)
|
||||
{
|
||||
@@ -482,7 +487,7 @@ namespace
|
||||
|
||||
if (c.io_status_block)
|
||||
{
|
||||
IO_STATUS_BLOCK block{};
|
||||
IO_STATUS_BLOCK<EmulatorTraits<Emu64>> block{};
|
||||
block.Information = static_cast<uint32_t>(recevied_data);
|
||||
c.io_status_block.write(block);
|
||||
}
|
||||
@@ -494,13 +499,13 @@ namespace
|
||||
{
|
||||
const auto& emu = win_emu.emu();
|
||||
|
||||
if (c.input_buffer_length < sizeof(AFD_SEND_DATAGRAM_INFO))
|
||||
if (c.input_buffer_length < sizeof(AFD_SEND_DATAGRAM_INFO<EmulatorTraits<Emu64>>))
|
||||
{
|
||||
return STATUS_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
const auto send_info = emu.read_memory<AFD_SEND_DATAGRAM_INFO>(c.input_buffer);
|
||||
const auto buffer = emu.read_memory<WSABUF>(send_info.BufferArray);
|
||||
const auto send_info = emu.read_memory<AFD_SEND_DATAGRAM_INFO<EmulatorTraits<Emu64>>>(c.input_buffer);
|
||||
const auto buffer = emu.read_memory<EMU_WSABUF<EmulatorTraits<Emu64>>>(send_info.BufferArray);
|
||||
|
||||
const auto address = emu.read_memory(send_info.TdiConnInfo.RemoteAddress,
|
||||
send_info.TdiConnInfo.RemoteAddressLength);
|
||||
@@ -528,7 +533,7 @@ namespace
|
||||
|
||||
if (c.io_status_block)
|
||||
{
|
||||
IO_STATUS_BLOCK block{};
|
||||
IO_STATUS_BLOCK<EmulatorTraits<Emu64>> block{};
|
||||
block.Information = static_cast<uint32_t>(sent_data);
|
||||
c.io_status_block.write(block);
|
||||
}
|
||||
|
||||
@@ -3,87 +3,93 @@
|
||||
#include "../std_include.hpp"
|
||||
|
||||
typedef LONG TDI_STATUS;
|
||||
typedef PVOID CONNECTION_CONTEXT;
|
||||
|
||||
typedef struct _TDI_CONNECTION_INFORMATION
|
||||
template <typename Traits>
|
||||
struct TDI_CONNECTION_INFORMATION
|
||||
{
|
||||
LONG UserDataLength;
|
||||
PVOID UserData;
|
||||
typename Traits::PVOID UserData;
|
||||
LONG OptionsLength;
|
||||
PVOID Options;
|
||||
typename Traits::PVOID Options;
|
||||
LONG RemoteAddressLength;
|
||||
PVOID RemoteAddress;
|
||||
} TDI_CONNECTION_INFORMATION, *PTDI_CONNECTION_INFORMATION;
|
||||
typename Traits::PVOID RemoteAddress;
|
||||
};
|
||||
|
||||
typedef struct _TDI_REQUEST
|
||||
template <typename Traits>
|
||||
struct TDI_REQUEST
|
||||
{
|
||||
union
|
||||
{
|
||||
HANDLE AddressHandle;
|
||||
CONNECTION_CONTEXT ConnectionContext;
|
||||
HANDLE ControlChannel;
|
||||
typename Traits::HANDLE AddressHandle;
|
||||
EMULATOR_CAST(typename Traits::PVOID, CONNECTION_CONTEXT) ConnectionContext;
|
||||
typename Traits::HANDLE ControlChannel;
|
||||
} Handle;
|
||||
|
||||
PVOID RequestNotifyObject;
|
||||
PVOID RequestContext;
|
||||
typename Traits::PVOID RequestNotifyObject;
|
||||
typename Traits::PVOID RequestContext;
|
||||
TDI_STATUS TdiStatus;
|
||||
} TDI_REQUEST, *PTDI_REQUEST;
|
||||
};
|
||||
|
||||
typedef struct _TDI_REQUEST_SEND_DATAGRAM
|
||||
template <typename Traits>
|
||||
struct TDI_REQUEST_SEND_DATAGRAM
|
||||
{
|
||||
TDI_REQUEST Request;
|
||||
PTDI_CONNECTION_INFORMATION SendDatagramInformation;
|
||||
} TDI_REQUEST_SEND_DATAGRAM, *PTDI_REQUEST_SEND_DATAGRAM;
|
||||
TDI_REQUEST<Traits> Request;
|
||||
EMULATOR_CAST(typename Traits::PVOID, PTDI_CONNECTION_INFORMATION) SendDatagramInformation;
|
||||
};
|
||||
|
||||
typedef struct _AFD_SEND_INFO
|
||||
template <typename Traits>
|
||||
struct AFD_SEND_INFO
|
||||
{
|
||||
LPWSABUF BufferArray;
|
||||
EMULATOR_CAST(typename Traits::PVOID, LPWSABUF) BufferArray;
|
||||
ULONG BufferCount;
|
||||
ULONG AfdFlags;
|
||||
ULONG TdiFlags;
|
||||
} AFD_SEND_INFO, *PAFD_SEND_INFO;
|
||||
};
|
||||
|
||||
typedef struct _AFD_SEND_DATAGRAM_INFO
|
||||
template <typename Traits>
|
||||
struct AFD_SEND_DATAGRAM_INFO
|
||||
{
|
||||
LPWSABUF BufferArray;
|
||||
EMULATOR_CAST(typename Traits::PVOID, LPWSABUF) BufferArray;
|
||||
ULONG BufferCount;
|
||||
ULONG AfdFlags;
|
||||
TDI_REQUEST_SEND_DATAGRAM TdiRequest;
|
||||
TDI_CONNECTION_INFORMATION TdiConnInfo;
|
||||
} AFD_SEND_DATAGRAM_INFO, *PAFD_SEND_DATAGRAM_INFO;
|
||||
TDI_REQUEST_SEND_DATAGRAM<Traits> TdiRequest;
|
||||
TDI_CONNECTION_INFORMATION<Traits> TdiConnInfo;
|
||||
};
|
||||
|
||||
typedef struct _AFD_RECV_INFO
|
||||
template <typename Traits>
|
||||
struct AFD_RECV_INFO
|
||||
{
|
||||
LPWSABUF BufferArray;
|
||||
EMULATOR_CAST(typename Traits::PVOID, LPWSABUF) BufferArray;
|
||||
ULONG BufferCount;
|
||||
ULONG AfdFlags;
|
||||
ULONG TdiFlags;
|
||||
} AFD_RECV_INFO, *PAFD_RECV_INFO;
|
||||
};
|
||||
|
||||
typedef struct _AFD_RECV_DATAGRAM_INFO
|
||||
template <typename Traits>
|
||||
struct AFD_RECV_DATAGRAM_INFO
|
||||
{
|
||||
LPWSABUF BufferArray;
|
||||
EMULATOR_CAST(typename Traits::PVOID, LPWSABUF) BufferArray;
|
||||
ULONG BufferCount;
|
||||
ULONG AfdFlags;
|
||||
ULONG TdiFlags;
|
||||
PVOID Address;
|
||||
PULONG AddressLength;
|
||||
} AFD_RECV_DATAGRAM_INFO, *PAFD_RECV_DATAGRAM_INFO;
|
||||
typename Traits::PVOID Address;
|
||||
EMULATOR_CAST(typename Traits::PVOID, PULONG) AddressLength;
|
||||
};
|
||||
|
||||
typedef struct _AFD_POLL_HANDLE_INFO
|
||||
struct AFD_POLL_HANDLE_INFO64
|
||||
{
|
||||
HANDLE Handle;
|
||||
EmulatorTraits<Emu64>::HANDLE Handle;
|
||||
ULONG PollEvents;
|
||||
NTSTATUS Status;
|
||||
} AFD_POLL_HANDLE_INFO, *PAFD_POLL_HANDLE_INFO;
|
||||
};
|
||||
|
||||
typedef struct _AFD_POLL_INFO
|
||||
struct AFD_POLL_INFO64
|
||||
{
|
||||
LARGE_INTEGER Timeout;
|
||||
ULONG NumberOfHandles;
|
||||
BOOLEAN Unique;
|
||||
AFD_POLL_HANDLE_INFO Handles[1];
|
||||
} AFD_POLL_INFO, *PAFD_POLL_INFO;
|
||||
AFD_POLL_HANDLE_INFO64 Handles[1];
|
||||
};
|
||||
|
||||
#define AFD_POLL_RECEIVE_BIT 0
|
||||
#define AFD_POLL_RECEIVE (1 << AFD_POLL_RECEIVE_BIT)
|
||||
|
||||
@@ -31,11 +31,12 @@ struct handle_value
|
||||
|
||||
static_assert(sizeof(handle_value) == 8);
|
||||
|
||||
// TODO: this is a concrete 64bit handle
|
||||
union handle
|
||||
{
|
||||
handle_value value;
|
||||
uint64_t bits;
|
||||
HANDLE h;
|
||||
std::uint64_t h;
|
||||
};
|
||||
|
||||
inline void serialize(utils::buffer_serializer& buffer, const handle& h)
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace
|
||||
};
|
||||
}
|
||||
|
||||
std::unique_ptr<io_device<EmulatorTraits<Emu64>>> create_device64(const std::u16string_view device)
|
||||
std::unique_ptr<io_device> create_device(const std::u16string_view device)
|
||||
{
|
||||
if (device == u"CNG"
|
||||
|| device == u"KsecDD"
|
||||
@@ -27,5 +27,5 @@ std::unique_ptr<io_device<EmulatorTraits<Emu64>>> create_device64(const std::u16
|
||||
return create_afd_endpoint();
|
||||
}
|
||||
|
||||
throw std::runtime_error("Unsupported device: " + std::string(device.begin(), device.end()));
|
||||
throw std::runtime_error("Unsupported device: " + u16_to_u8(device));
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ struct io_device_context
|
||||
handle event{};
|
||||
emulator_pointer /*PIO_APC_ROUTINE*/ apc_routine{};
|
||||
emulator_pointer apc_context{};
|
||||
emulator_object<IO_STATUS_BLOCK> io_status_block;
|
||||
emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block;
|
||||
ULONG io_control_code{};
|
||||
emulator_pointer input_buffer{};
|
||||
ULONG input_buffer_length{};
|
||||
@@ -65,11 +65,11 @@ struct io_device_creation_data
|
||||
uint32_t length;
|
||||
};
|
||||
|
||||
inline void write_io_status(const emulator_object<IO_STATUS_BLOCK> io_status_block, const NTSTATUS status)
|
||||
inline void write_io_status(const emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block, const NTSTATUS status)
|
||||
{
|
||||
if (io_status_block)
|
||||
{
|
||||
io_status_block.access([&](IO_STATUS_BLOCK& status_block)
|
||||
io_status_block.access([&](IO_STATUS_BLOCK<EmulatorTraits<Emu64>>& status_block)
|
||||
{
|
||||
status_block.Status = status;
|
||||
});
|
||||
@@ -131,14 +131,14 @@ struct stateless_device : io_device
|
||||
}
|
||||
};
|
||||
|
||||
std::unique_ptr<io_device> create_device(std::wstring_view device);
|
||||
std::unique_ptr<io_device> create_device(std::u16string_view device);
|
||||
|
||||
class io_device_container : public io_device
|
||||
{
|
||||
public:
|
||||
io_device_container() = default;
|
||||
|
||||
io_device_container(std::wstring device, windows_emulator& win_emu, const io_device_creation_data& data)
|
||||
io_device_container(std::u16string device, windows_emulator& win_emu, const io_device_creation_data& data)
|
||||
: device_name_(std::move(device))
|
||||
{
|
||||
this->setup();
|
||||
@@ -182,7 +182,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
std::wstring device_name_{};
|
||||
std::u16string device_name_{};
|
||||
std::unique_ptr<io_device> device_{};
|
||||
|
||||
void setup()
|
||||
|
||||
@@ -5,12 +5,12 @@
|
||||
#include <address_utils.hpp>
|
||||
|
||||
constexpr auto KUSD_ADDRESS = 0x7ffe0000ULL;
|
||||
constexpr auto KUSD_SIZE = sizeof(KUSER_SHARED_DATA);
|
||||
constexpr auto KUSD_SIZE = sizeof(KUSER_SHARED_DATA64);
|
||||
constexpr auto KUSD_BUFFER_SIZE = page_align_up(KUSD_SIZE);
|
||||
|
||||
namespace
|
||||
{
|
||||
void setup_kusd(KUSER_SHARED_DATA& kusd, const bool use_relative_time)
|
||||
void setup_kusd(KUSER_SHARED_DATA64& kusd, const bool use_relative_time)
|
||||
{
|
||||
memset(&kusd, 0, sizeof(kusd));
|
||||
|
||||
@@ -88,13 +88,13 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
inline void serialize(utils::buffer_serializer& buffer, const KUSER_SHARED_DATA& kusd)
|
||||
inline void serialize(utils::buffer_serializer& buffer, const KUSER_SHARED_DATA64& kusd)
|
||||
{
|
||||
static_assert(KUSD_SIZE == sizeof(kusd));
|
||||
buffer.write(&kusd, KUSD_SIZE);
|
||||
}
|
||||
|
||||
inline void deserialize(utils::buffer_deserializer& buffer, KUSER_SHARED_DATA& kusd)
|
||||
inline void deserialize(utils::buffer_deserializer& buffer, KUSER_SHARED_DATA64& kusd)
|
||||
{
|
||||
buffer.read(&kusd, KUSD_SIZE);
|
||||
}
|
||||
|
||||
@@ -24,12 +24,12 @@ public:
|
||||
void serialize(utils::buffer_serializer& buffer) const;
|
||||
void deserialize(utils::buffer_deserializer& buffer);
|
||||
|
||||
KUSER_SHARED_DATA& get()
|
||||
KUSER_SHARED_DATA64& get()
|
||||
{
|
||||
return this->kusd_;
|
||||
}
|
||||
|
||||
const KUSER_SHARED_DATA& get() const
|
||||
const KUSER_SHARED_DATA64& get() const
|
||||
{
|
||||
return this->kusd_;
|
||||
}
|
||||
@@ -45,7 +45,7 @@ private:
|
||||
bool registered_{};
|
||||
bool use_relative_time_{};
|
||||
|
||||
KUSER_SHARED_DATA kusd_{};
|
||||
KUSER_SHARED_DATA64 kusd_{};
|
||||
std::chrono::system_clock::time_point start_time_{};
|
||||
|
||||
uint64_t read(uint64_t addr, size_t size);
|
||||
|
||||
@@ -7,9 +7,14 @@
|
||||
|
||||
namespace
|
||||
{
|
||||
uint64_t get_first_section_offset(const IMAGE_NT_HEADERS& nt_headers, const uint64_t nt_headers_offset)
|
||||
uint64_t get_first_section_offset(const PENTHeaders_t<std::uint64_t>& nt_headers, const uint64_t nt_headers_offset)
|
||||
{
|
||||
const auto first_section_absolute = reinterpret_cast<uint64_t>(IMAGE_FIRST_SECTION(&nt_headers));
|
||||
const uint8_t* nt_headers_addr = reinterpret_cast<const uint8_t*>(&nt_headers);
|
||||
size_t optional_header_offset = reinterpret_cast<uintptr_t>(&(nt_headers.OptionalHeader)) - reinterpret_cast<uintptr_t>(&nt_headers);
|
||||
size_t optional_header_size = nt_headers.FileHeader.SizeOfOptionalHeader;
|
||||
const uint8_t* first_section_addr = nt_headers_addr + optional_header_offset + optional_header_size;
|
||||
|
||||
const auto first_section_absolute = reinterpret_cast<uint64_t>(first_section_addr);
|
||||
const auto absolute_base = reinterpret_cast<uint64_t>(&nt_headers);
|
||||
return nt_headers_offset + (first_section_absolute - absolute_base);
|
||||
}
|
||||
@@ -24,7 +29,7 @@ namespace
|
||||
}
|
||||
|
||||
void collect_exports(mapped_module& binary, const utils::safe_buffer_accessor<const uint8_t> buffer,
|
||||
const IMAGE_OPTIONAL_HEADER& optional_header)
|
||||
const PEOptionalHeader_t<std::uint64_t>& optional_header)
|
||||
{
|
||||
auto& export_directory_entry = optional_header.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
|
||||
if (export_directory_entry.VirtualAddress == 0 || export_directory_entry.Size == 0)
|
||||
@@ -71,7 +76,7 @@ namespace
|
||||
}
|
||||
|
||||
void apply_relocations(const mapped_module& binary, const utils::safe_buffer_accessor<uint8_t> buffer,
|
||||
const IMAGE_OPTIONAL_HEADER& optional_header)
|
||||
const PEOptionalHeader_t<std::uint64_t>& optional_header)
|
||||
{
|
||||
const auto delta = binary.image_base - optional_header.ImageBase;
|
||||
if (delta == 0)
|
||||
@@ -134,7 +139,7 @@ namespace
|
||||
|
||||
void map_sections(emulator& emu, const mapped_module& binary,
|
||||
const utils::safe_buffer_accessor<const uint8_t> buffer,
|
||||
const IMAGE_NT_HEADERS& nt_headers, const uint64_t nt_headers_offset)
|
||||
const PENTHeaders_t<std::uint64_t>& nt_headers, const uint64_t nt_headers_offset)
|
||||
{
|
||||
const auto first_section_offset = get_first_section_offset(nt_headers, nt_headers_offset);
|
||||
const auto sections = buffer.as<IMAGE_SECTION_HEADER>(first_section_offset);
|
||||
@@ -183,10 +188,10 @@ namespace
|
||||
|
||||
utils::safe_buffer_accessor buffer{data};
|
||||
|
||||
const auto dos_header = buffer.as<IMAGE_DOS_HEADER>(0).get();
|
||||
const auto dos_header = buffer.as<PEDosHeader_t>(0).get();
|
||||
const auto nt_headers_offset = dos_header.e_lfanew;
|
||||
|
||||
const auto nt_headers = buffer.as<IMAGE_NT_HEADERS>(nt_headers_offset).get();
|
||||
const auto nt_headers = buffer.as<PENTHeaders_t<std::uint64_t>>(nt_headers_offset).get();
|
||||
auto& optional_header = nt_headers.OptionalHeader;
|
||||
|
||||
binary.image_base = optional_header.ImageBase;
|
||||
|
||||
@@ -229,7 +229,7 @@ public:
|
||||
std::optional<NTSTATUS> pending_status{};
|
||||
|
||||
std::optional<emulator_allocator> gs_segment;
|
||||
std::optional<emulator_object<TEB>> teb;
|
||||
std::optional<emulator_object<TEB64>> teb;
|
||||
|
||||
std::vector<std::byte> last_registers{};
|
||||
|
||||
@@ -325,7 +325,7 @@ public:
|
||||
buffer.read_optional(this->await_time);
|
||||
buffer.read_optional(this->pending_status);
|
||||
buffer.read_optional(this->gs_segment, [this] { return emulator_allocator(*this->emu_ptr); });
|
||||
buffer.read_optional(this->teb, [this] { return emulator_object<TEB>(*this->emu_ptr); });
|
||||
buffer.read_optional(this->teb, [this] { return emulator_object<TEB64>(*this->emu_ptr); });
|
||||
|
||||
buffer.read_vector(this->last_registers);
|
||||
}
|
||||
@@ -381,8 +381,8 @@ struct process_context
|
||||
|
||||
emulator_allocator base_allocator;
|
||||
|
||||
emulator_object<PEB> peb;
|
||||
emulator_object<RTL_USER_PROCESS_PARAMETERS> process_params;
|
||||
emulator_object<PEB64> peb;
|
||||
emulator_object<RTL_USER_PROCESS_PARAMETERS64> process_params;
|
||||
kusd_mmio kusd;
|
||||
|
||||
module_manager module_manager;
|
||||
|
||||
@@ -161,12 +161,12 @@ syscall_handler make_syscall_handler()
|
||||
};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void write_attribute(emulator& emu, const PS_ATTRIBUTE& attribute, const T& value)
|
||||
template <typename T, typename Traits>
|
||||
void write_attribute(emulator& emu, const PS_ATTRIBUTE<Traits>& attribute, const T& value)
|
||||
{
|
||||
if (attribute.ReturnLength)
|
||||
{
|
||||
emulator_object<SIZE_T>{emu, attribute.ReturnLength}.write(sizeof(T));
|
||||
emulator_object<typename Traits::SIZE_T>{emu, attribute.ReturnLength}.write(sizeof(T));
|
||||
}
|
||||
|
||||
if (attribute.Size >= sizeof(T))
|
||||
|
||||
@@ -5,7 +5,9 @@
|
||||
#include "syscall_utils.hpp"
|
||||
|
||||
#include <numeric>
|
||||
#include <ranges>
|
||||
#include <cwctype>
|
||||
#include <algorithm>
|
||||
#include <utils/io.hpp>
|
||||
|
||||
#include "utils/finally.hpp"
|
||||
@@ -61,14 +63,14 @@ namespace
|
||||
|
||||
NTSTATUS handle_NtOpenKey(const syscall_context& c, const emulator_object<handle> key_handle,
|
||||
const ACCESS_MASK /*desired_access*/,
|
||||
const emulator_object<OBJECT_ATTRIBUTES> object_attributes)
|
||||
const emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes)
|
||||
{
|
||||
const auto attributes = object_attributes.read();
|
||||
auto key = read_unicode_string(c.emu, reinterpret_cast<UNICODE_STRING<EmulatorTraits<Emu64>>*>(attributes.ObjectName));
|
||||
|
||||
if (attributes.RootDirectory)
|
||||
{
|
||||
const auto* parent_handle = c.proc.registry_keys.get(reinterpret_cast<uint64_t>(attributes.RootDirectory));
|
||||
const auto* parent_handle = c.proc.registry_keys.get(attributes.RootDirectory);
|
||||
if (!parent_handle)
|
||||
{
|
||||
return STATUS_INVALID_HANDLE;
|
||||
@@ -95,7 +97,7 @@ namespace
|
||||
|
||||
NTSTATUS handle_NtOpenKeyEx(const syscall_context& c, const emulator_object<handle> key_handle,
|
||||
const ACCESS_MASK desired_access,
|
||||
const emulator_object<OBJECT_ATTRIBUTES> object_attributes,
|
||||
const emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes,
|
||||
ULONG /*open_options*/)
|
||||
{
|
||||
return handle_NtOpenKey(c, key_handle, desired_access, object_attributes);
|
||||
@@ -180,9 +182,8 @@ namespace
|
||||
}
|
||||
|
||||
const auto query_name = read_unicode_string(c.emu, value_name);
|
||||
const std::string name(query_name.begin(), query_name.end());
|
||||
|
||||
const auto value = c.proc.registry.get_value(*key, name);
|
||||
const auto value = c.proc.registry.get_value(*key, u16_to_u8(query_name));
|
||||
if (!value)
|
||||
{
|
||||
return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
@@ -313,12 +314,12 @@ namespace
|
||||
|
||||
if (info_class == ThreadNameInformation)
|
||||
{
|
||||
if (thread_information_length != sizeof(THREAD_NAME_INFORMATION))
|
||||
if (thread_information_length != sizeof(THREAD_NAME_INFORMATION<EmulatorTraits<Emu64>>))
|
||||
{
|
||||
return STATUS_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
const emulator_object<THREAD_NAME_INFORMATION> info{c.emu, thread_information};
|
||||
const emulator_object<THREAD_NAME_INFORMATION<EmulatorTraits<Emu64>>> info{c.emu, thread_information};
|
||||
const auto i = info.read();
|
||||
thread->name = read_unicode_string(c.emu, i.ThreadName);
|
||||
|
||||
@@ -403,7 +404,7 @@ namespace
|
||||
|
||||
NTSTATUS handle_NtCreateEvent(const syscall_context& c, const emulator_object<handle> event_handle,
|
||||
const ACCESS_MASK /*desired_access*/,
|
||||
const emulator_object<OBJECT_ATTRIBUTES> object_attributes,
|
||||
const emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes,
|
||||
const EVENT_TYPE event_type, const BOOLEAN initial_state)
|
||||
{
|
||||
std::u16string name{};
|
||||
@@ -432,7 +433,7 @@ namespace
|
||||
|
||||
NTSTATUS handle_NtOpenEvent(const syscall_context& c, const emulator_object<uint64_t> event_handle,
|
||||
const ACCESS_MASK /*desired_access*/,
|
||||
const emulator_object<OBJECT_ATTRIBUTES> object_attributes)
|
||||
const emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes)
|
||||
{
|
||||
const auto attributes = object_attributes.read();
|
||||
const auto name = read_unicode_string(c.emu, reinterpret_cast<UNICODE_STRING<EmulatorTraits<Emu64>>*>(attributes.ObjectName));
|
||||
@@ -482,20 +483,20 @@ namespace
|
||||
|
||||
NTSTATUS handle_NtOpenSection(const syscall_context& c, const emulator_object<handle> section_handle,
|
||||
const ACCESS_MASK /*desired_access*/,
|
||||
const emulator_object<OBJECT_ATTRIBUTES> object_attributes)
|
||||
const emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes)
|
||||
{
|
||||
const auto attributes = object_attributes.read();
|
||||
|
||||
auto filename = read_unicode_string(c.emu, reinterpret_cast<UNICODE_STRING<EmulatorTraits<Emu64>>*>(attributes.ObjectName));
|
||||
c.win_emu.logger.print(color::gray, "Opening section: %S\n", filename.c_str());
|
||||
|
||||
if (filename == L"\\Windows\\SharedSection")
|
||||
if (filename == u"\\Windows\\SharedSection")
|
||||
{
|
||||
section_handle.write(SHARED_SECTION);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (reinterpret_cast<uint64_t>(attributes.RootDirectory) != KNOWN_DLLS_DIRECTORY)
|
||||
if (attributes.RootDirectory != KNOWN_DLLS_DIRECTORY)
|
||||
{
|
||||
puts("Unsupported section");
|
||||
c.emu.stop();
|
||||
@@ -519,9 +520,9 @@ namespace
|
||||
|
||||
NTSTATUS handle_NtMapViewOfSection(const syscall_context& c, const handle section_handle,
|
||||
const handle process_handle, const emulator_object<uint64_t> base_address,
|
||||
const ULONG_PTR /*zero_bits*/, const SIZE_T /*commit_size*/,
|
||||
const EMULATOR_CAST(EmulatorTraits<Emu64>::ULONG_PTR, ULONG_PTR) /*zero_bits*/, const EMULATOR_CAST(EmulatorTraits<Emu64>::SIZE_T, SIZE_T) /*commit_size*/,
|
||||
const emulator_object<LARGE_INTEGER> /*section_offset*/,
|
||||
const emulator_object<SIZE_T> view_size,
|
||||
const emulator_object<EMULATOR_CAST(EmulatorTraits<Emu64>::SIZE_T, SIZE_T)> view_size,
|
||||
const SECTION_INHERIT /*inherit_disposition*/, const ULONG /*allocation_type*/,
|
||||
const ULONG /*win32_protect*/)
|
||||
{
|
||||
@@ -547,7 +548,7 @@ namespace
|
||||
const emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> windir_obj{c.emu, obj_address};
|
||||
windir_obj.access([&](UNICODE_STRING<EmulatorTraits<Emu64>>& ucs)
|
||||
{
|
||||
const auto dir_address = kusd_mmio::address() + offsetof(KUSER_SHARED_DATA, NtSystemRoot);
|
||||
const auto dir_address = kusd_mmio::address() + offsetof(KUSER_SHARED_DATA64, NtSystemRoot);
|
||||
|
||||
ucs.Buffer = dir_address - obj_address;
|
||||
ucs.Length = static_cast<uint16_t>(windows_dir_size);
|
||||
@@ -597,7 +598,7 @@ namespace
|
||||
|
||||
NTSTATUS handle_NtCreateIoCompletion(const syscall_context& c, const emulator_object<handle> event_handle,
|
||||
const ACCESS_MASK desired_access,
|
||||
const emulator_object<OBJECT_ATTRIBUTES> object_attributes,
|
||||
const emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes,
|
||||
const uint32_t /*number_of_concurrent_threads*/)
|
||||
{
|
||||
return handle_NtCreateEvent(c, event_handle, desired_access, object_attributes, NotificationEvent, FALSE);
|
||||
@@ -605,7 +606,7 @@ namespace
|
||||
|
||||
NTSTATUS handle_NtCreateWaitCompletionPacket(const syscall_context& c, const emulator_object<handle> event_handle,
|
||||
const ACCESS_MASK desired_access,
|
||||
const emulator_object<OBJECT_ATTRIBUTES> object_attributes)
|
||||
const emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes)
|
||||
{
|
||||
return handle_NtCreateEvent(c, event_handle, desired_access, object_attributes, NotificationEvent, FALSE);
|
||||
}
|
||||
@@ -630,17 +631,17 @@ namespace
|
||||
{
|
||||
if (return_length)
|
||||
{
|
||||
return_length.write(sizeof(MEMORY_BASIC_INFORMATION));
|
||||
return_length.write(sizeof(EMU_MEMORY_BASIC_INFORMATION64));
|
||||
}
|
||||
|
||||
if (memory_information_length != sizeof(MEMORY_BASIC_INFORMATION))
|
||||
if (memory_information_length != sizeof(EMU_MEMORY_BASIC_INFORMATION64))
|
||||
{
|
||||
return STATUS_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
const emulator_object<MEMORY_BASIC_INFORMATION> info{c.emu, memory_information};
|
||||
const emulator_object<EMU_MEMORY_BASIC_INFORMATION64> info{c.emu, memory_information};
|
||||
|
||||
info.access([&](MEMORY_BASIC_INFORMATION& image_info)
|
||||
info.access([&](EMU_MEMORY_BASIC_INFORMATION64& image_info)
|
||||
{
|
||||
const auto region_info = c.emu.get_region_info(base_address);
|
||||
|
||||
@@ -667,10 +668,10 @@ namespace
|
||||
{
|
||||
if (return_length)
|
||||
{
|
||||
return_length.write(sizeof(MEMORY_IMAGE_INFORMATION));
|
||||
return_length.write(sizeof(MEMORY_IMAGE_INFORMATION64));
|
||||
}
|
||||
|
||||
if (memory_information_length != sizeof(MEMORY_IMAGE_INFORMATION))
|
||||
if (memory_information_length != sizeof(MEMORY_IMAGE_INFORMATION64))
|
||||
{
|
||||
return STATUS_BUFFER_OVERFLOW;
|
||||
}
|
||||
@@ -678,13 +679,13 @@ namespace
|
||||
const auto mod = c.proc.module_manager.find_by_address(base_address);
|
||||
if (!mod)
|
||||
{
|
||||
printf("Bad address for memory image request: 0x%llX\n", base_address);
|
||||
printf("Bad address for memory image request: 0x%zX\n", base_address);
|
||||
return STATUS_INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
const emulator_object<MEMORY_IMAGE_INFORMATION> info{c.emu, memory_information};
|
||||
const emulator_object<MEMORY_IMAGE_INFORMATION64> info{c.emu, memory_information};
|
||||
|
||||
info.access([&](MEMORY_IMAGE_INFORMATION& image_info)
|
||||
info.access([&](MEMORY_IMAGE_INFORMATION64& image_info)
|
||||
{
|
||||
image_info.ImageBase = reinterpret_cast<void*>(mod->image_base);
|
||||
image_info.SizeOfImage = mod->size_of_image;
|
||||
@@ -697,10 +698,10 @@ namespace
|
||||
{
|
||||
if (return_length)
|
||||
{
|
||||
return_length.write(sizeof(MEMORY_REGION_INFORMATION));
|
||||
return_length.write(sizeof(MEMORY_REGION_INFORMATION64));
|
||||
}
|
||||
|
||||
if (memory_information_length != sizeof(MEMORY_REGION_INFORMATION))
|
||||
if (memory_information_length != sizeof(MEMORY_REGION_INFORMATION64))
|
||||
{
|
||||
return STATUS_BUFFER_OVERFLOW;
|
||||
}
|
||||
@@ -711,9 +712,9 @@ namespace
|
||||
return STATUS_INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
const emulator_object<MEMORY_REGION_INFORMATION> info{c.emu, memory_information};
|
||||
const emulator_object<MEMORY_REGION_INFORMATION64> info{c.emu, memory_information};
|
||||
|
||||
info.access([&](MEMORY_REGION_INFORMATION& image_info)
|
||||
info.access([&](MEMORY_REGION_INFORMATION64& image_info)
|
||||
{
|
||||
memset(&image_info, 0, sizeof(image_info));
|
||||
|
||||
@@ -749,17 +750,17 @@ namespace
|
||||
{
|
||||
if (return_length)
|
||||
{
|
||||
return_length.write(sizeof(SYSTEM_TIMEOFDAY_INFORMATION));
|
||||
return_length.write(sizeof(SYSTEM_TIMEOFDAY_INFORMATION64));
|
||||
}
|
||||
|
||||
if (system_information_length != sizeof(SYSTEM_TIMEOFDAY_INFORMATION))
|
||||
if (system_information_length != sizeof(SYSTEM_TIMEOFDAY_INFORMATION64))
|
||||
{
|
||||
return STATUS_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
const emulator_object<SYSTEM_TIMEOFDAY_INFORMATION> info_obj{c.emu, system_information};
|
||||
const emulator_object<SYSTEM_TIMEOFDAY_INFORMATION64> info_obj{c.emu, system_information};
|
||||
|
||||
info_obj.access([&](SYSTEM_TIMEOFDAY_INFORMATION& info)
|
||||
info_obj.access([&](SYSTEM_TIMEOFDAY_INFORMATION64& info)
|
||||
{
|
||||
info.BootTime.QuadPart = 0;
|
||||
// TODO: Fill
|
||||
@@ -772,17 +773,17 @@ namespace
|
||||
{
|
||||
if (return_length)
|
||||
{
|
||||
return_length.write(sizeof(SYSTEM_RANGE_START_INFORMATION));
|
||||
return_length.write(sizeof(SYSTEM_RANGE_START_INFORMATION64));
|
||||
}
|
||||
|
||||
if (system_information_length != sizeof(SYSTEM_RANGE_START_INFORMATION))
|
||||
if (system_information_length != sizeof(SYSTEM_RANGE_START_INFORMATION64))
|
||||
{
|
||||
return STATUS_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
const emulator_object<SYSTEM_RANGE_START_INFORMATION> info_obj{c.emu, system_information};
|
||||
const emulator_object<SYSTEM_RANGE_START_INFORMATION64> info_obj{c.emu, system_information};
|
||||
|
||||
info_obj.access([&](SYSTEM_RANGE_START_INFORMATION& info)
|
||||
info_obj.access([&](SYSTEM_RANGE_START_INFORMATION64& info)
|
||||
{
|
||||
info.SystemRangeStart = 0xFFFF800000000000;
|
||||
});
|
||||
@@ -794,17 +795,17 @@ namespace
|
||||
{
|
||||
if (return_length)
|
||||
{
|
||||
return_length.write(sizeof(SYSTEM_PROCESSOR_INFORMATION));
|
||||
return_length.write(sizeof(SYSTEM_PROCESSOR_INFORMATION64));
|
||||
}
|
||||
|
||||
if (system_information_length != sizeof(SYSTEM_PROCESSOR_INFORMATION))
|
||||
if (system_information_length != sizeof(SYSTEM_PROCESSOR_INFORMATION64))
|
||||
{
|
||||
return STATUS_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
const emulator_object<SYSTEM_PROCESSOR_INFORMATION> info_obj{c.emu, system_information};
|
||||
const emulator_object<SYSTEM_PROCESSOR_INFORMATION64> info_obj{c.emu, system_information};
|
||||
|
||||
info_obj.access([&](SYSTEM_PROCESSOR_INFORMATION& info)
|
||||
info_obj.access([&](SYSTEM_PROCESSOR_INFORMATION64& info)
|
||||
{
|
||||
memset(&info, 0, sizeof(info));
|
||||
info.MaximumProcessors = 2;
|
||||
@@ -818,17 +819,17 @@ namespace
|
||||
{
|
||||
if (return_length)
|
||||
{
|
||||
return_length.write(sizeof(SYSTEM_NUMA_INFORMATION));
|
||||
return_length.write(sizeof(SYSTEM_NUMA_INFORMATION64));
|
||||
}
|
||||
|
||||
if (system_information_length != sizeof(SYSTEM_NUMA_INFORMATION))
|
||||
if (system_information_length != sizeof(SYSTEM_NUMA_INFORMATION64))
|
||||
{
|
||||
return STATUS_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
const emulator_object<SYSTEM_NUMA_INFORMATION> info_obj{c.emu, system_information};
|
||||
const emulator_object<SYSTEM_NUMA_INFORMATION64> info_obj{c.emu, system_information};
|
||||
|
||||
info_obj.access([&](SYSTEM_NUMA_INFORMATION& info)
|
||||
info_obj.access([&](SYSTEM_NUMA_INFORMATION64& info)
|
||||
{
|
||||
memset(&info, 0, sizeof(info));
|
||||
info.ActiveProcessorsGroupAffinity->Mask = 0xFFF;
|
||||
@@ -871,17 +872,17 @@ namespace
|
||||
|
||||
if (return_length)
|
||||
{
|
||||
return_length.write(sizeof(SYSTEM_BASIC_INFORMATION));
|
||||
return_length.write(sizeof(SYSTEM_BASIC_INFORMATION64));
|
||||
}
|
||||
|
||||
if (system_information_length != sizeof(SYSTEM_BASIC_INFORMATION))
|
||||
if (system_information_length != sizeof(SYSTEM_BASIC_INFORMATION64))
|
||||
{
|
||||
return STATUS_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
const emulator_object<SYSTEM_BASIC_INFORMATION> info{c.emu, system_information};
|
||||
const emulator_object<SYSTEM_BASIC_INFORMATION64> info{c.emu, system_information};
|
||||
|
||||
info.access([&](SYSTEM_BASIC_INFORMATION& basic_info)
|
||||
info.access([&](SYSTEM_BASIC_INFORMATION64& basic_info)
|
||||
{
|
||||
basic_info.Reserved = 0;
|
||||
basic_info.TimerResolution = 0x0002625a;
|
||||
@@ -944,10 +945,15 @@ namespace
|
||||
|
||||
return_length.access([&](uint32_t& len)
|
||||
{
|
||||
#ifdef OS_WINDOWS
|
||||
code = NtQuerySystemInformationEx(static_cast<SYSTEM_INFORMATION_CLASS>(info_class), buffer,
|
||||
input_buffer_length,
|
||||
res_buff,
|
||||
system_information_length, reinterpret_cast<ULONG*>(&len));
|
||||
#else
|
||||
// TODO: unsupported
|
||||
code = STATUS_SUCCESS;
|
||||
#endif
|
||||
});
|
||||
|
||||
if (code == 0)
|
||||
@@ -970,17 +976,17 @@ namespace
|
||||
|
||||
if (return_length)
|
||||
{
|
||||
return_length.write(sizeof(SYSTEM_BASIC_INFORMATION));
|
||||
return_length.write(sizeof(SYSTEM_BASIC_INFORMATION64));
|
||||
}
|
||||
|
||||
if (system_information_length != sizeof(SYSTEM_BASIC_INFORMATION))
|
||||
if (system_information_length != sizeof(SYSTEM_BASIC_INFORMATION64))
|
||||
{
|
||||
return STATUS_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
const emulator_object<SYSTEM_BASIC_INFORMATION> info{c.emu, system_information};
|
||||
const emulator_object<SYSTEM_BASIC_INFORMATION64> info{c.emu, system_information};
|
||||
|
||||
info.access([&](SYSTEM_BASIC_INFORMATION& basic_info)
|
||||
info.access([&](SYSTEM_BASIC_INFORMATION64& basic_info)
|
||||
{
|
||||
basic_info.Reserved = 0;
|
||||
basic_info.TimerResolution = 0x0002625a;
|
||||
@@ -1011,29 +1017,29 @@ namespace
|
||||
{
|
||||
if (return_length)
|
||||
{
|
||||
return_length.write(sizeof(SECTION_IMAGE_INFORMATION));
|
||||
return_length.write(sizeof(SECTION_IMAGE_INFORMATION<EmulatorTraits<Emu64>>));
|
||||
}
|
||||
|
||||
if (process_information_length != sizeof(SECTION_IMAGE_INFORMATION))
|
||||
if (process_information_length != sizeof(SECTION_IMAGE_INFORMATION<EmulatorTraits<Emu64>>))
|
||||
{
|
||||
return STATUS_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
const emulator_object<SECTION_IMAGE_INFORMATION> info{c.emu, process_information};
|
||||
info.access([&](SECTION_IMAGE_INFORMATION& i)
|
||||
const emulator_object<SECTION_IMAGE_INFORMATION<EmulatorTraits<Emu64>>> info{c.emu, process_information};
|
||||
info.access([&](SECTION_IMAGE_INFORMATION<EmulatorTraits<Emu64>>& i)
|
||||
{
|
||||
const auto& mod = *c.proc.executable;
|
||||
|
||||
const emulator_object<IMAGE_DOS_HEADER> dos_header_obj{c.emu, mod.image_base};
|
||||
const emulator_object<PEDosHeader_t> dos_header_obj{c.emu, mod.image_base};
|
||||
const auto dos_header = dos_header_obj.read();
|
||||
|
||||
const emulator_object<IMAGE_NT_HEADERS> nt_headers_obj{c.emu, mod.image_base + dos_header.e_lfanew};
|
||||
const emulator_object<PENTHeaders_t<uint64_t>> nt_headers_obj{c.emu, mod.image_base + dos_header.e_lfanew};
|
||||
const auto nt_headers = nt_headers_obj.read();
|
||||
|
||||
const auto& file_header = nt_headers.FileHeader;
|
||||
const auto& optional_header = nt_headers.OptionalHeader;
|
||||
|
||||
i.TransferAddress = nullptr;
|
||||
i.TransferAddress = 0;
|
||||
i.MaximumStackSize = optional_header.SizeOfStackReserve;
|
||||
i.CommittedStackSize = optional_header.SizeOfStackCommit;
|
||||
i.SubSystemType = optional_header.Subsystem;
|
||||
@@ -1076,15 +1082,15 @@ namespace
|
||||
{
|
||||
if (return_length)
|
||||
{
|
||||
return_length.write(sizeof(DWORD_PTR));
|
||||
return_length.write(sizeof(EmulatorTraits<Emu64>::PVOID));
|
||||
}
|
||||
|
||||
if (process_information_length != sizeof(DWORD_PTR))
|
||||
if (process_information_length != sizeof(EmulatorTraits<Emu64>::PVOID))
|
||||
{
|
||||
return STATUS_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
const emulator_object<DWORD_PTR> info{c.emu, process_information};
|
||||
const emulator_object<EmulatorTraits<Emu64>::PVOID> info{c.emu, process_information};
|
||||
info.write(0);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
@@ -1118,19 +1124,19 @@ namespace
|
||||
{
|
||||
if (return_length)
|
||||
{
|
||||
return_length.write(sizeof(PROCESS_BASIC_INFORMATION));
|
||||
return_length.write(sizeof(PROCESS_BASIC_INFORMATION64));
|
||||
}
|
||||
|
||||
if (process_information_length != sizeof(PROCESS_BASIC_INFORMATION))
|
||||
if (process_information_length != sizeof(PROCESS_BASIC_INFORMATION64))
|
||||
{
|
||||
return STATUS_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
const emulator_object<PROCESS_BASIC_INFORMATION> info{c.emu, process_information};
|
||||
info.access([&](PROCESS_BASIC_INFORMATION& basic_info)
|
||||
const emulator_object<PROCESS_BASIC_INFORMATION64> info{c.emu, process_information};
|
||||
info.access([&](PROCESS_BASIC_INFORMATION64& basic_info)
|
||||
{
|
||||
basic_info.PebBaseAddress = c.proc.peb.ptr();
|
||||
basic_info.UniqueProcessId = reinterpret_cast<HANDLE>(1);
|
||||
basic_info.UniqueProcessId = 1;
|
||||
});
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
@@ -1139,7 +1145,7 @@ namespace
|
||||
if (info_class == ProcessImageFileNameWin32)
|
||||
{
|
||||
const auto peb = c.proc.peb.read();
|
||||
emulator_object<RTL_USER_PROCESS_PARAMETERS> proc_params{c.emu, peb.ProcessParameters};
|
||||
emulator_object<RTL_USER_PROCESS_PARAMETERS64> proc_params{c.emu, peb.ProcessParameters};
|
||||
const auto params = proc_params.read();
|
||||
const auto length = params.ImagePathName.Length + sizeof(UNICODE_STRING<EmulatorTraits<Emu64>>) + 2;
|
||||
|
||||
@@ -1153,10 +1159,10 @@ namespace
|
||||
return STATUS_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
const emulator_object<UNICODE_STRING> info{c.emu, process_information};
|
||||
info.access([&](UNICODE_STRING& str)
|
||||
const emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> info{c.emu, process_information};
|
||||
info.access([&](UNICODE_STRING<EmulatorTraits<Emu64>>& str)
|
||||
{
|
||||
const auto buffer_start = static_cast<uint64_t>(process_information) + sizeof(UNICODE_STRING);
|
||||
const auto buffer_start = static_cast<uint64_t>(process_information) + sizeof(UNICODE_STRING<EmulatorTraits<Emu64>>);
|
||||
const auto string = read_unicode_string(c.emu, params.ImagePathName);
|
||||
c.emu.write_memory(buffer_start, string.c_str(), (string.size() + 1) * 2);
|
||||
str.Length = params.ImagePathName.Length;
|
||||
@@ -1187,16 +1193,16 @@ namespace
|
||||
{
|
||||
if (return_length)
|
||||
{
|
||||
return_length.write(sizeof(THREAD_BASIC_INFORMATION));
|
||||
return_length.write(sizeof(THREAD_BASIC_INFORMATION64));
|
||||
}
|
||||
|
||||
if (thread_information_length != sizeof(THREAD_BASIC_INFORMATION))
|
||||
if (thread_information_length != sizeof(THREAD_BASIC_INFORMATION64))
|
||||
{
|
||||
return STATUS_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
const emulator_object<THREAD_BASIC_INFORMATION> info{c.emu, thread_information};
|
||||
info.access([&](THREAD_BASIC_INFORMATION& i)
|
||||
const emulator_object<THREAD_BASIC_INFORMATION64> info{c.emu, thread_information};
|
||||
info.access([&](THREAD_BASIC_INFORMATION64& i)
|
||||
{
|
||||
i.TebBaseAddress = c.win_emu.current_thread().teb->ptr();
|
||||
i.ClientId = c.win_emu.current_thread().teb->read().ClientId;
|
||||
@@ -1230,7 +1236,7 @@ namespace
|
||||
}
|
||||
|
||||
NTSTATUS handle_NtSetInformationFile(const syscall_context& c, const handle file_handle,
|
||||
const emulator_object<IO_STATUS_BLOCK> io_status_block,
|
||||
const emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block,
|
||||
const uint64_t file_information,
|
||||
const ULONG length, const FILE_INFORMATION_CLASS info_class)
|
||||
{
|
||||
@@ -1249,7 +1255,7 @@ namespace
|
||||
|
||||
if (io_status_block)
|
||||
{
|
||||
IO_STATUS_BLOCK block{};
|
||||
IO_STATUS_BLOCK<EmulatorTraits<Emu64>> block{};
|
||||
block.Information = sizeof(FILE_POSITION_INFORMATION);
|
||||
io_status_block.write(block);
|
||||
}
|
||||
@@ -1277,7 +1283,7 @@ namespace
|
||||
}
|
||||
|
||||
NTSTATUS handle_NtQueryInformationFile(const syscall_context& c, const handle file_handle,
|
||||
const emulator_object<IO_STATUS_BLOCK> io_status_block,
|
||||
const emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block,
|
||||
const uint64_t file_information, const uint32_t length,
|
||||
const uint32_t info_class)
|
||||
{
|
||||
@@ -1291,7 +1297,7 @@ namespace
|
||||
{
|
||||
if (io_status_block)
|
||||
{
|
||||
IO_STATUS_BLOCK block{};
|
||||
IO_STATUS_BLOCK<EmulatorTraits<Emu64>> block{};
|
||||
block.Information = sizeof(FILE_STANDARD_INFORMATION);
|
||||
io_status_block.write(block);
|
||||
}
|
||||
@@ -1324,7 +1330,7 @@ namespace
|
||||
|
||||
if (io_status_block)
|
||||
{
|
||||
IO_STATUS_BLOCK block{};
|
||||
IO_STATUS_BLOCK<EmulatorTraits<Emu64>> block{};
|
||||
block.Information = sizeof(FILE_POSITION_INFORMATION);
|
||||
io_status_block.write(block);
|
||||
}
|
||||
@@ -1425,12 +1431,12 @@ namespace
|
||||
NTSTATUS handle_NtOpenDirectoryObject(const syscall_context& c,
|
||||
const emulator_object<handle> directory_handle,
|
||||
const ACCESS_MASK /*desired_access*/,
|
||||
const emulator_object<OBJECT_ATTRIBUTES> object_attributes)
|
||||
const emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes)
|
||||
{
|
||||
const auto attributes = object_attributes.read();
|
||||
const auto object_name = read_unicode_string(c.emu, reinterpret_cast<UNICODE_STRING<EmulatorTraits<Emu64>>*>(attributes.ObjectName));
|
||||
|
||||
if (object_name == L"\\KnownDlls")
|
||||
if (object_name == u"\\KnownDlls")
|
||||
{
|
||||
directory_handle.write(KNOWN_DLLS_DIRECTORY);
|
||||
return STATUS_SUCCESS;
|
||||
@@ -1441,12 +1447,12 @@ namespace
|
||||
|
||||
NTSTATUS handle_NtOpenSymbolicLinkObject(const syscall_context& c, const emulator_object<handle> link_handle,
|
||||
ACCESS_MASK /*desired_access*/,
|
||||
const emulator_object<OBJECT_ATTRIBUTES> object_attributes)
|
||||
const emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes)
|
||||
{
|
||||
const auto attributes = object_attributes.read();
|
||||
const auto object_name = read_unicode_string(c.emu, reinterpret_cast<UNICODE_STRING<EmulatorTraits<Emu64>>*>(attributes.ObjectName));
|
||||
|
||||
if (object_name == L"KnownDllPath")
|
||||
if (object_name == u"KnownDllPath")
|
||||
{
|
||||
link_handle.write(KNOWN_DLLS_SYMLINK);
|
||||
return STATUS_SUCCESS;
|
||||
@@ -1455,8 +1461,9 @@ namespace
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
// TODO: warning stdcall problem
|
||||
NTSTATUS WINAPI handle_NtQuerySymbolicLinkObject(const syscall_context& c, const handle link_handle,
|
||||
const emulator_object<UNICODE_STRING> link_target,
|
||||
const emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> link_target,
|
||||
const emulator_object<ULONG> returned_length)
|
||||
{
|
||||
if (link_handle == KNOWN_DLLS_SYMLINK)
|
||||
@@ -1477,7 +1484,7 @@ namespace
|
||||
}
|
||||
|
||||
str.Length = str_length;
|
||||
c.emu.write_memory(reinterpret_cast<uint64_t>(str.Buffer), system32.data(), max_length);
|
||||
c.emu.write_memory(str.Buffer, system32.data(), max_length);
|
||||
});
|
||||
|
||||
return too_small
|
||||
@@ -1576,7 +1583,7 @@ namespace
|
||||
|
||||
NTSTATUS handle_NtCreateSection(const syscall_context& c, const emulator_object<handle> section_handle,
|
||||
const ACCESS_MASK /*desired_access*/,
|
||||
const emulator_object<OBJECT_ATTRIBUTES> /*object_attributes*/,
|
||||
const emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> /*object_attributes*/,
|
||||
const emulator_object<ULARGE_INTEGER> maximum_size,
|
||||
const ULONG /*section_page_protection*/, const ULONG /*allocation_attributes*/,
|
||||
const handle /*file_handle*/)
|
||||
@@ -1596,8 +1603,8 @@ namespace
|
||||
NTSTATUS handle_NtConnectPort(const syscall_context& c, const emulator_object<handle> client_port_handle,
|
||||
const emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> server_port_name,
|
||||
const emulator_object<SECURITY_QUALITY_OF_SERVICE> /*security_qos*/,
|
||||
const emulator_object<PORT_VIEW> client_shared_memory,
|
||||
const emulator_object<REMOTE_PORT_VIEW> /*server_shared_memory*/,
|
||||
const emulator_object<PORT_VIEW64> client_shared_memory,
|
||||
const emulator_object<REMOTE_PORT_VIEW64> /*server_shared_memory*/,
|
||||
const emulator_object<ULONG> /*maximum_message_length*/,
|
||||
const emulator_pointer connection_info,
|
||||
const emulator_object<ULONG> connection_info_length)
|
||||
@@ -1615,10 +1622,10 @@ namespace
|
||||
c.emu.write_memory(connection_info, zero_mem.data(), zero_mem.size());
|
||||
}
|
||||
|
||||
client_shared_memory.access([&](PORT_VIEW& view)
|
||||
client_shared_memory.access([&](PORT_VIEW64& view)
|
||||
{
|
||||
p.view_base = c.emu.allocate_memory(view.ViewSize, memory_permission::read_write);
|
||||
view.ViewBase = reinterpret_cast<void*>(p.view_base);
|
||||
view.ViewBase = p.view_base;
|
||||
view.ViewRemoteBase = view.ViewBase;
|
||||
});
|
||||
|
||||
@@ -1657,7 +1664,7 @@ namespace
|
||||
const handle event,
|
||||
const emulator_pointer /*PIO_APC_ROUTINE*/ apc_routine,
|
||||
const emulator_pointer apc_context,
|
||||
const emulator_object<IO_STATUS_BLOCK> io_status_block,
|
||||
const emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block,
|
||||
const ULONG io_control_code,
|
||||
const emulator_pointer input_buffer,
|
||||
const ULONG input_buffer_length, const emulator_pointer output_buffer,
|
||||
@@ -1751,11 +1758,11 @@ namespace
|
||||
return STATUS_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
TOKEN_USER user{};
|
||||
TOKEN_USER64 user{};
|
||||
user.User.Attributes = 0;
|
||||
user.User.Sid = reinterpret_cast<void*>(token_information + 0x10);
|
||||
user.User.Sid = token_information + 0x10;
|
||||
|
||||
emulator_object<TOKEN_USER>{c.emu, token_information}.write(user);
|
||||
emulator_object<TOKEN_USER64>{c.emu, token_information}.write(user);
|
||||
c.emu.write_memory(token_information + 0x10, sid, sizeof(sid));
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
@@ -1774,7 +1781,7 @@ namespace
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
printf("Unsupported token info class: %lX\n", token_information_class);
|
||||
printf("Unsupported token info class: %X\n", token_information_class);
|
||||
c.emu.stop();
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
@@ -1798,11 +1805,11 @@ namespace
|
||||
|
||||
NTSTATUS handle_NtGdiInit2(const syscall_context& c)
|
||||
{
|
||||
c.proc.peb.access([&](PEB& peb)
|
||||
c.proc.peb.access([&](PEB64& peb)
|
||||
{
|
||||
if (!peb.GdiSharedHandleTable)
|
||||
{
|
||||
peb.GdiSharedHandleTable = c.proc.base_allocator.reserve<GDI_SHARED_MEMORY>().ptr();
|
||||
peb.GdiSharedHandleTable = reinterpret_cast<EmulatorTraits<Emu64>::PVOID*>(c.proc.base_allocator.reserve<GDI_SHARED_MEMORY64>().ptr());
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1841,12 +1848,12 @@ namespace
|
||||
|
||||
NTSTATUS handle_NtAlpcSendWaitReceivePort(const syscall_context& c, const handle port_handle,
|
||||
const ULONG /*flags*/,
|
||||
const emulator_object<PORT_MESSAGE> /*send_message*/,
|
||||
const emulator_object<PORT_MESSAGE64> /*send_message*/,
|
||||
const emulator_object<ALPC_MESSAGE_ATTRIBUTES>
|
||||
/*send_message_attributes*/
|
||||
,
|
||||
const emulator_object<PORT_MESSAGE> receive_message,
|
||||
const emulator_object<SIZE_T> /*buffer_length*/,
|
||||
const emulator_object<PORT_MESSAGE64> receive_message,
|
||||
const emulator_object<EmulatorTraits<Emu64>::SIZE_T> /*buffer_length*/,
|
||||
const emulator_object<ALPC_MESSAGE_ATTRIBUTES>
|
||||
/*receive_message_attributes*/,
|
||||
const emulator_object<LARGE_INTEGER> /*timeout*/)
|
||||
@@ -1863,9 +1870,9 @@ namespace
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
const emulator_object<PORT_DATA_ENTRY> data{c.emu, receive_message.value() + 0x48};
|
||||
const emulator_object<PORT_DATA_ENTRY<EmulatorTraits<Emu64>>> data{c.emu, receive_message.value() + 0x48};
|
||||
const auto dest = data.read();
|
||||
const auto base = reinterpret_cast<uint64_t>(dest.Base);
|
||||
const auto base = dest.Base;
|
||||
|
||||
const auto value = base + 0x10;
|
||||
c.emu.write_memory(base + 8, &value, sizeof(value));
|
||||
@@ -1893,7 +1900,7 @@ namespace
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS handle_NtContinue(const syscall_context& c, const emulator_object<CONTEXT> thread_context,
|
||||
NTSTATUS handle_NtContinue(const syscall_context& c, const emulator_object<CONTEXT64> thread_context,
|
||||
const BOOLEAN /*raise_alert*/)
|
||||
{
|
||||
c.write_status = false;
|
||||
@@ -1933,7 +1940,7 @@ namespace
|
||||
NTSTATUS handle_NtReadFile(const syscall_context& c, const handle file_handle, const uint64_t /*event*/,
|
||||
const uint64_t /*apc_routine*/,
|
||||
const uint64_t /*apc_context*/,
|
||||
const emulator_object<IO_STATUS_BLOCK> io_status_block,
|
||||
const emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block,
|
||||
uint64_t buffer, const ULONG length,
|
||||
const emulator_object<LARGE_INTEGER> /*byte_offset*/,
|
||||
const emulator_object<ULONG> /*key*/)
|
||||
@@ -1951,7 +1958,7 @@ namespace
|
||||
|
||||
if (io_status_block)
|
||||
{
|
||||
IO_STATUS_BLOCK block{};
|
||||
IO_STATUS_BLOCK<EmulatorTraits<Emu64>> block{};
|
||||
block.Information = bytes_read;
|
||||
io_status_block.write(block);
|
||||
}
|
||||
@@ -1963,7 +1970,7 @@ namespace
|
||||
NTSTATUS handle_NtWriteFile(const syscall_context& c, const handle file_handle, const uint64_t /*event*/,
|
||||
const uint64_t /*apc_routine*/,
|
||||
const uint64_t /*apc_context*/,
|
||||
const emulator_object<IO_STATUS_BLOCK> io_status_block,
|
||||
const emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block,
|
||||
uint64_t buffer, const ULONG length,
|
||||
const emulator_object<LARGE_INTEGER> /*byte_offset*/,
|
||||
const emulator_object<ULONG> /*key*/)
|
||||
@@ -1977,7 +1984,7 @@ namespace
|
||||
{
|
||||
if (io_status_block)
|
||||
{
|
||||
IO_STATUS_BLOCK block{};
|
||||
IO_STATUS_BLOCK<EmulatorTraits<Emu64>> block{};
|
||||
block.Information = length;
|
||||
io_status_block.write(block);
|
||||
}
|
||||
@@ -2003,7 +2010,7 @@ namespace
|
||||
|
||||
if (io_status_block)
|
||||
{
|
||||
IO_STATUS_BLOCK block{};
|
||||
IO_STATUS_BLOCK<EmulatorTraits<Emu64>> block{};
|
||||
block.Information = bytes_written;
|
||||
io_status_block.write(block);
|
||||
}
|
||||
@@ -2060,8 +2067,8 @@ namespace
|
||||
|
||||
NTSTATUS handle_NtCreateFile(const syscall_context& c, const emulator_object<handle> file_handle,
|
||||
ACCESS_MASK desired_access,
|
||||
const emulator_object<OBJECT_ATTRIBUTES> object_attributes,
|
||||
const emulator_object<IO_STATUS_BLOCK> /*io_status_block*/,
|
||||
const emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes,
|
||||
const emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> /*io_status_block*/,
|
||||
const emulator_object<LARGE_INTEGER> /*allocation_size*/, ULONG /*file_attributes*/,
|
||||
ULONG /*share_access*/, ULONG create_disposition, ULONG create_options,
|
||||
uint64_t ea_buffer,
|
||||
@@ -2093,7 +2100,7 @@ namespace
|
||||
}
|
||||
|
||||
handle root_handle{};
|
||||
root_handle.bits = reinterpret_cast<uint64_t>(attributes.RootDirectory);
|
||||
root_handle.bits = attributes.RootDirectory;
|
||||
if (root_handle.value.is_pseudo && (filename == u"\\Reference" || filename == u"\\Connect"))
|
||||
{
|
||||
file_handle.write(root_handle);
|
||||
@@ -2105,7 +2112,7 @@ namespace
|
||||
|
||||
if (attributes.RootDirectory)
|
||||
{
|
||||
const auto* root = c.proc.files.get(reinterpret_cast<uint64_t>(attributes.RootDirectory));
|
||||
const auto* root = c.proc.files.get(attributes.RootDirectory);
|
||||
if (!root)
|
||||
{
|
||||
return STATUS_INVALID_HANDLE;
|
||||
@@ -2181,8 +2188,8 @@ namespace
|
||||
NTSTATUS handle_NtOpenFile(const syscall_context& c,
|
||||
const emulator_object<handle> file_handle,
|
||||
const ACCESS_MASK desired_access,
|
||||
const emulator_object<OBJECT_ATTRIBUTES> object_attributes,
|
||||
const emulator_object<IO_STATUS_BLOCK> io_status_block,
|
||||
const emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes,
|
||||
const emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block,
|
||||
const ULONG share_access,
|
||||
const ULONG open_options)
|
||||
{
|
||||
@@ -2234,8 +2241,8 @@ namespace
|
||||
}
|
||||
|
||||
NTSTATUS handle_NtRaiseException(const syscall_context& c,
|
||||
const emulator_object<EXCEPTION_RECORD> /*exception_record*/,
|
||||
const emulator_object<CONTEXT> thread_context, BOOLEAN handle_exception)
|
||||
const emulator_object<EMU_EXCEPTION_RECORD<EmulatorTraits<Emu64>>> /*exception_record*/,
|
||||
const emulator_object<CONTEXT64> thread_context, BOOLEAN handle_exception)
|
||||
{
|
||||
if (handle_exception)
|
||||
{
|
||||
@@ -2252,7 +2259,7 @@ namespace
|
||||
|
||||
NTSTATUS handle_NtCreateSemaphore(const syscall_context& c, const emulator_object<handle> semaphore_handle,
|
||||
const ACCESS_MASK /*desired_access*/,
|
||||
const emulator_object<OBJECT_ATTRIBUTES> object_attributes,
|
||||
const emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes,
|
||||
const ULONG initial_count, const ULONG maximum_count)
|
||||
{
|
||||
semaphore s{};
|
||||
@@ -2350,11 +2357,11 @@ namespace
|
||||
|
||||
NTSTATUS handle_NtCreateThreadEx(const syscall_context& c, const emulator_object<handle> thread_handle,
|
||||
const ACCESS_MASK /*desired_access*/,
|
||||
const emulator_object<OBJECT_ATTRIBUTES> /*object_attributes*/,
|
||||
const emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> /*object_attributes*/,
|
||||
const handle process_handle, const uint64_t start_routine,
|
||||
const uint64_t argument, const ULONG /*create_flags*/, const SIZE_T /*zero_bits*/,
|
||||
const SIZE_T stack_size, const SIZE_T /*maximum_stack_size*/,
|
||||
const emulator_object<PS_ATTRIBUTE_LIST> attribute_list)
|
||||
const uint64_t argument, const ULONG /*create_flags*/, const EmulatorTraits<Emu64>::SIZE_T /*zero_bits*/,
|
||||
const EmulatorTraits<Emu64>::SIZE_T stack_size, const EmulatorTraits<Emu64>::SIZE_T /*maximum_stack_size*/,
|
||||
const emulator_object<PS_ATTRIBUTE_LIST<EmulatorTraits<Emu64>>> attribute_list)
|
||||
{
|
||||
if (process_handle != ~0ULL)
|
||||
{
|
||||
@@ -2371,19 +2378,19 @@ namespace
|
||||
|
||||
const auto* thread = c.proc.threads.get(h);
|
||||
|
||||
const emulator_object<PS_ATTRIBUTE> attributes{
|
||||
c.emu, attribute_list.value() + offsetof(PS_ATTRIBUTE_LIST, Attributes)
|
||||
const emulator_object<PS_ATTRIBUTE<EmulatorTraits<Emu64>>> attributes{
|
||||
c.emu, attribute_list.value() + offsetof(PS_ATTRIBUTE_LIST<EmulatorTraits<Emu64>>, Attributes)
|
||||
};
|
||||
|
||||
const auto total_length = attribute_list.read().TotalLength;
|
||||
|
||||
constexpr auto entry_size = sizeof(PS_ATTRIBUTE);
|
||||
constexpr auto header_size = sizeof(PS_ATTRIBUTE_LIST) - entry_size;
|
||||
constexpr auto entry_size = sizeof(PS_ATTRIBUTE<EmulatorTraits<Emu64>>);
|
||||
constexpr auto header_size = sizeof(PS_ATTRIBUTE_LIST<EmulatorTraits<Emu64>>) - entry_size;
|
||||
const auto attribute_count = (total_length - header_size) / entry_size;
|
||||
|
||||
for (size_t i = 0; i < attribute_count; ++i)
|
||||
{
|
||||
attributes.access([&](const PS_ATTRIBUTE& attribute)
|
||||
attributes.access([&](const PS_ATTRIBUTE<EmulatorTraits<Emu64>>& attribute)
|
||||
{
|
||||
const auto type = attribute.Attribute & ~PS_ATTRIBUTE_THREAD;
|
||||
|
||||
@@ -2398,7 +2405,7 @@ namespace
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Unsupported thread attribute type: %llX\n", type);
|
||||
printf("Unsupported thread attribute type: %zX\n", type);
|
||||
}
|
||||
}, i);
|
||||
}
|
||||
@@ -2492,7 +2499,7 @@ namespace
|
||||
}
|
||||
|
||||
NTSTATUS handle_NtAlertThreadByThreadIdEx(const syscall_context& c, const uint64_t thread_id,
|
||||
const emulator_object<RTL_SRWLOCK> lock)
|
||||
const emulator_object<EMU_RTL_SRWLOCK<EmulatorTraits<Emu64>>> lock)
|
||||
{
|
||||
if (lock.value())
|
||||
{
|
||||
|
||||
@@ -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