diff --git a/src/analyzer/main.cpp b/src/analyzer/main.cpp index 8ba74aad..5c2b53c1 100644 --- a/src/analyzer/main.cpp +++ b/src/analyzer/main.cpp @@ -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 obj{ + const emulator_object obj{ win_emu.emu(), value }; diff --git a/src/common/utils/nt_handle.hpp b/src/common/utils/nt_handle.hpp index 0545027e..b90cba1c 100644 --- a/src/common/utils/nt_handle.hpp +++ b/src/common/utils/nt_handle.hpp @@ -1,5 +1,7 @@ #pragma once +#ifdef OS_WINDOWS + #define NOMINMAX #define WIN32_LEAN_AND_MEAN #include @@ -83,3 +85,5 @@ namespace utils::nt HANDLE handle_{InvalidHandleFunction()}; }; } + +#endif \ No newline at end of file diff --git a/src/windows-emulator/context_frame.cpp b/src/windows-emulator/context_frame.cpp index 3f9d7a02..3ca0c9d4 100644 --- a/src/windows-emulator/context_frame.cpp +++ b/src/windows-emulator/context_frame.cpp @@ -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(x64_register::ss, context.SegSs); emu.reg(x64_register::cs, context.SegCs); @@ -26,7 +26,7 @@ namespace context_frame emu.reg(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(x64_register::gs, context.SegGs); }*/ - if (context.ContextFlags & CONTEXT_FLOATING_POINT) + if (context.ContextFlags & CONTEXT_FLOATING_POINT_64) { emu.reg(x64_register::fpcw, context.FltSave.ControlWord); emu.reg(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(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(x64_register::ss); context.SegCs = emu.reg(x64_register::cs); @@ -99,7 +99,7 @@ namespace context_frame context.EFlags = emu.reg(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(x64_register::ds); context.SegEs = emu.reg(x64_register::es); @@ -126,7 +126,7 @@ namespace context_frame context.SegGs = emu.reg(x64_register::gs); } - if (context.ContextFlags & CONTEXT_FLOATING_POINT) + if (context.ContextFlags & CONTEXT_FLOATING_POINT_64) { context.FltSave.ControlWord = emu.reg(x64_register::fpcw); context.FltSave.StatusWord = emu.reg(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(x64_register::mxcsr); for (int i = 0; i < 16; i++) diff --git a/src/windows-emulator/context_frame.hpp b/src/windows-emulator/context_frame.hpp index 63f3e36b..9f922446 100644 --- a/src/windows-emulator/context_frame.hpp +++ b/src/windows-emulator/context_frame.hpp @@ -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); } diff --git a/src/windows-emulator/devices/afd_endpoint.cpp b/src/windows-emulator/devices/afd_endpoint.cpp index 4a38a7b0..1723dfb7 100644 --- a/src/windows-emulator/devices/afd_endpoint.cpp +++ b/src/windows-emulator/devices/afd_endpoint.cpp @@ -32,23 +32,23 @@ namespace return win_emu.emu().read_memory(data.buffer); } - std::pair> get_poll_info( + std::pair> 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 handle_info{}; + std::vector handle_info{}; - const emulator_object handle_info_obj{win_emu.emu(), c.input_buffer + info_size}; + const emulator_object 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 endpoints, - const std::span handles) + const std::span handles) { std::vector 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 handle_info_obj{win_emu.emu(), c.input_buffer + info_size}; + constexpr auto info_size = offsetof(AFD_POLL_INFO64, Handles); + const emulator_object 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(count)); - emulator_object{win_emu.emu(), c.input_buffer}.access([&](AFD_POLL_INFO& info) + emulator_object{win_emu.emu(), c.input_buffer}.access([&](AFD_POLL_INFO64& info) { info.NumberOfHandles = static_cast(current_index); }); @@ -367,7 +367,7 @@ namespace } static std::vector resolve_endpoints(windows_emulator& win_emu, - const std::span handles) + const std::span handles) { auto& proc = win_emu.process(); @@ -376,7 +376,7 @@ namespace for (const auto& handle : handles) { - auto* device = proc.devices.get(reinterpret_cast(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>)) { return STATUS_BUFFER_TOO_SMALL; } - const auto receive_info = emu.read_memory(c.input_buffer); - const auto buffer = emu.read_memory(receive_info.BufferArray); + const auto receive_info = emu.read_memory>>(c.input_buffer); + const auto buffer = emu.read_memory>>(receive_info.BufferArray); std::vector address{}; - ULONG address_length = 0x1000; + unsigned long address_length = 0x1000; if (receive_info.AddressLength) { address_length = emu.read_memory(receive_info.AddressLength); @@ -456,8 +456,13 @@ namespace std::vector data{}; data.resize(buffer.len); +#ifdef OS_WINDOWS const auto recevied_data = recvfrom(*this->s_, data.data(), static_cast(data.size()), 0, reinterpret_cast(address.data()), &fromlength); +#else + const auto recevied_data = recvfrom(*this->s_, data.data(), static_cast(data.size()), 0, + reinterpret_cast(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> block{}; block.Information = static_cast(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>)) { return STATUS_BUFFER_TOO_SMALL; } - const auto send_info = emu.read_memory(c.input_buffer); - const auto buffer = emu.read_memory(send_info.BufferArray); + const auto send_info = emu.read_memory>>(c.input_buffer); + const auto buffer = emu.read_memory>>(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> block{}; block.Information = static_cast(sent_data); c.io_status_block.write(block); } diff --git a/src/windows-emulator/devices/afd_types.hpp b/src/windows-emulator/devices/afd_types.hpp index 944ae5e4..55310bce 100644 --- a/src/windows-emulator/devices/afd_types.hpp +++ b/src/windows-emulator/devices/afd_types.hpp @@ -3,87 +3,93 @@ #include "../std_include.hpp" typedef LONG TDI_STATUS; -typedef PVOID CONNECTION_CONTEXT; -typedef struct _TDI_CONNECTION_INFORMATION +template +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 +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 +struct TDI_REQUEST_SEND_DATAGRAM { - TDI_REQUEST Request; - PTDI_CONNECTION_INFORMATION SendDatagramInformation; -} TDI_REQUEST_SEND_DATAGRAM, *PTDI_REQUEST_SEND_DATAGRAM; + TDI_REQUEST Request; + EMULATOR_CAST(typename Traits::PVOID, PTDI_CONNECTION_INFORMATION) SendDatagramInformation; +}; -typedef struct _AFD_SEND_INFO +template +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 +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 TdiRequest; + TDI_CONNECTION_INFORMATION TdiConnInfo; +}; -typedef struct _AFD_RECV_INFO +template +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 +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::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) diff --git a/src/windows-emulator/handles.hpp b/src/windows-emulator/handles.hpp index 31cd553c..c47b0621 100644 --- a/src/windows-emulator/handles.hpp +++ b/src/windows-emulator/handles.hpp @@ -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) diff --git a/src/windows-emulator/io_device.cpp b/src/windows-emulator/io_device.cpp index d249989f..c619db60 100644 --- a/src/windows-emulator/io_device.cpp +++ b/src/windows-emulator/io_device.cpp @@ -12,7 +12,7 @@ namespace }; } -std::unique_ptr>> create_device64(const std::u16string_view device) +std::unique_ptr create_device(const std::u16string_view device) { if (device == u"CNG" || device == u"KsecDD" @@ -27,5 +27,5 @@ std::unique_ptr>> 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)); } diff --git a/src/windows-emulator/io_device.hpp b/src/windows-emulator/io_device.hpp index 5b1ab9a1..0175f3ab 100644 --- a/src/windows-emulator/io_device.hpp +++ b/src/windows-emulator/io_device.hpp @@ -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; + emulator_object>> 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, const NTSTATUS status) +inline void write_io_status(const emulator_object>> 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>& status_block) { status_block.Status = status; }); @@ -131,14 +131,14 @@ struct stateless_device : io_device } }; -std::unique_ptr create_device(std::wstring_view device); +std::unique_ptr 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 device_{}; void setup() diff --git a/src/windows-emulator/kusd_mmio.cpp b/src/windows-emulator/kusd_mmio.cpp index 83fdb0e4..fce57201 100644 --- a/src/windows-emulator/kusd_mmio.cpp +++ b/src/windows-emulator/kusd_mmio.cpp @@ -5,12 +5,12 @@ #include 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); } diff --git a/src/windows-emulator/kusd_mmio.hpp b/src/windows-emulator/kusd_mmio.hpp index 97548ceb..fc7c2adc 100644 --- a/src/windows-emulator/kusd_mmio.hpp +++ b/src/windows-emulator/kusd_mmio.hpp @@ -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); diff --git a/src/windows-emulator/module/module_mapping.cpp b/src/windows-emulator/module/module_mapping.cpp index 5f7b3ba1..b68658b3 100644 --- a/src/windows-emulator/module/module_mapping.cpp +++ b/src/windows-emulator/module/module_mapping.cpp @@ -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& nt_headers, const uint64_t nt_headers_offset) { - const auto first_section_absolute = reinterpret_cast(IMAGE_FIRST_SECTION(&nt_headers)); + const uint8_t* nt_headers_addr = reinterpret_cast(&nt_headers); + size_t optional_header_offset = reinterpret_cast(&(nt_headers.OptionalHeader)) - reinterpret_cast(&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(first_section_addr); const auto absolute_base = reinterpret_cast(&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 buffer, - const IMAGE_OPTIONAL_HEADER& optional_header) + const PEOptionalHeader_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 buffer, - const IMAGE_OPTIONAL_HEADER& optional_header) + const PEOptionalHeader_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 buffer, - const IMAGE_NT_HEADERS& nt_headers, const uint64_t nt_headers_offset) + const PENTHeaders_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(first_section_offset); @@ -183,10 +188,10 @@ namespace utils::safe_buffer_accessor buffer{data}; - const auto dos_header = buffer.as(0).get(); + const auto dos_header = buffer.as(0).get(); const auto nt_headers_offset = dos_header.e_lfanew; - const auto nt_headers = buffer.as(nt_headers_offset).get(); + const auto nt_headers = buffer.as>(nt_headers_offset).get(); auto& optional_header = nt_headers.OptionalHeader; binary.image_base = optional_header.ImageBase; diff --git a/src/windows-emulator/process_context.hpp b/src/windows-emulator/process_context.hpp index 67c19661..23795743 100644 --- a/src/windows-emulator/process_context.hpp +++ b/src/windows-emulator/process_context.hpp @@ -229,7 +229,7 @@ public: std::optional pending_status{}; std::optional gs_segment; - std::optional> teb; + std::optional> teb; std::vector 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(*this->emu_ptr); }); + buffer.read_optional(this->teb, [this] { return emulator_object(*this->emu_ptr); }); buffer.read_vector(this->last_registers); } @@ -381,8 +381,8 @@ struct process_context emulator_allocator base_allocator; - emulator_object peb; - emulator_object process_params; + emulator_object peb; + emulator_object process_params; kusd_mmio kusd; module_manager module_manager; diff --git a/src/windows-emulator/syscall_utils.hpp b/src/windows-emulator/syscall_utils.hpp index cb053c0a..5f5d5b8e 100644 --- a/src/windows-emulator/syscall_utils.hpp +++ b/src/windows-emulator/syscall_utils.hpp @@ -161,12 +161,12 @@ syscall_handler make_syscall_handler() }; } -template -void write_attribute(emulator& emu, const PS_ATTRIBUTE& attribute, const T& value) +template +void write_attribute(emulator& emu, const PS_ATTRIBUTE& attribute, const T& value) { if (attribute.ReturnLength) { - emulator_object{emu, attribute.ReturnLength}.write(sizeof(T)); + emulator_object{emu, attribute.ReturnLength}.write(sizeof(T)); } if (attribute.Size >= sizeof(T)) diff --git a/src/windows-emulator/syscalls.cpp b/src/windows-emulator/syscalls.cpp index 555a7425..59d5dcaa 100644 --- a/src/windows-emulator/syscalls.cpp +++ b/src/windows-emulator/syscalls.cpp @@ -5,7 +5,9 @@ #include "syscall_utils.hpp" #include +#include #include +#include #include #include "utils/finally.hpp" @@ -61,14 +63,14 @@ namespace NTSTATUS handle_NtOpenKey(const syscall_context& c, const emulator_object key_handle, const ACCESS_MASK /*desired_access*/, - const emulator_object object_attributes) + const emulator_object>> object_attributes) { const auto attributes = object_attributes.read(); auto key = read_unicode_string(c.emu, reinterpret_cast>*>(attributes.ObjectName)); if (attributes.RootDirectory) { - const auto* parent_handle = c.proc.registry_keys.get(reinterpret_cast(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 key_handle, const ACCESS_MASK desired_access, - const emulator_object object_attributes, + const emulator_object>> 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>)) { return STATUS_BUFFER_OVERFLOW; } - const emulator_object info{c.emu, thread_information}; + const emulator_object>> 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 event_handle, const ACCESS_MASK /*desired_access*/, - const emulator_object object_attributes, + const emulator_object>> 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 event_handle, const ACCESS_MASK /*desired_access*/, - const emulator_object object_attributes) + const emulator_object>> object_attributes) { const auto attributes = object_attributes.read(); const auto name = read_unicode_string(c.emu, reinterpret_cast>*>(attributes.ObjectName)); @@ -482,20 +483,20 @@ namespace NTSTATUS handle_NtOpenSection(const syscall_context& c, const emulator_object section_handle, const ACCESS_MASK /*desired_access*/, - const emulator_object object_attributes) + const emulator_object>> object_attributes) { const auto attributes = object_attributes.read(); auto filename = read_unicode_string(c.emu, reinterpret_cast>*>(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(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 base_address, - const ULONG_PTR /*zero_bits*/, const SIZE_T /*commit_size*/, + const EMULATOR_CAST(EmulatorTraits::ULONG_PTR, ULONG_PTR) /*zero_bits*/, const EMULATOR_CAST(EmulatorTraits::SIZE_T, SIZE_T) /*commit_size*/, const emulator_object /*section_offset*/, - const emulator_object view_size, + const emulator_object::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>> windir_obj{c.emu, obj_address}; windir_obj.access([&](UNICODE_STRING>& 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(windows_dir_size); @@ -597,7 +598,7 @@ namespace NTSTATUS handle_NtCreateIoCompletion(const syscall_context& c, const emulator_object event_handle, const ACCESS_MASK desired_access, - const emulator_object object_attributes, + const emulator_object>> 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 event_handle, const ACCESS_MASK desired_access, - const emulator_object object_attributes) + const emulator_object>> 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 info{c.emu, memory_information}; + const emulator_object 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 info{c.emu, memory_information}; + const emulator_object info{c.emu, memory_information}; - info.access([&](MEMORY_IMAGE_INFORMATION& image_info) + info.access([&](MEMORY_IMAGE_INFORMATION64& image_info) { image_info.ImageBase = reinterpret_cast(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 info{c.emu, memory_information}; + const emulator_object 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 info_obj{c.emu, system_information}; + const emulator_object 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 info_obj{c.emu, system_information}; + const emulator_object 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 info_obj{c.emu, system_information}; + const emulator_object 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 info_obj{c.emu, system_information}; + const emulator_object 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 info{c.emu, system_information}; + const emulator_object 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(info_class), buffer, input_buffer_length, res_buff, system_information_length, reinterpret_cast(&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 info{c.emu, system_information}; + const emulator_object 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>)); } - if (process_information_length != sizeof(SECTION_IMAGE_INFORMATION)) + if (process_information_length != sizeof(SECTION_IMAGE_INFORMATION>)) { return STATUS_BUFFER_OVERFLOW; } - const emulator_object info{c.emu, process_information}; - info.access([&](SECTION_IMAGE_INFORMATION& i) + const emulator_object>> info{c.emu, process_information}; + info.access([&](SECTION_IMAGE_INFORMATION>& i) { const auto& mod = *c.proc.executable; - const emulator_object dos_header_obj{c.emu, mod.image_base}; + const emulator_object dos_header_obj{c.emu, mod.image_base}; const auto dos_header = dos_header_obj.read(); - const emulator_object nt_headers_obj{c.emu, mod.image_base + dos_header.e_lfanew}; + const emulator_object> 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::PVOID)); } - if (process_information_length != sizeof(DWORD_PTR)) + if (process_information_length != sizeof(EmulatorTraits::PVOID)) { return STATUS_BUFFER_OVERFLOW; } - const emulator_object info{c.emu, process_information}; + const emulator_object::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 info{c.emu, process_information}; - info.access([&](PROCESS_BASIC_INFORMATION& basic_info) + const emulator_object info{c.emu, process_information}; + info.access([&](PROCESS_BASIC_INFORMATION64& basic_info) { basic_info.PebBaseAddress = c.proc.peb.ptr(); - basic_info.UniqueProcessId = reinterpret_cast(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 proc_params{c.emu, peb.ProcessParameters}; + emulator_object proc_params{c.emu, peb.ProcessParameters}; const auto params = proc_params.read(); const auto length = params.ImagePathName.Length + sizeof(UNICODE_STRING>) + 2; @@ -1153,10 +1159,10 @@ namespace return STATUS_BUFFER_OVERFLOW; } - const emulator_object info{c.emu, process_information}; - info.access([&](UNICODE_STRING& str) + const emulator_object>> info{c.emu, process_information}; + info.access([&](UNICODE_STRING>& str) { - const auto buffer_start = static_cast(process_information) + sizeof(UNICODE_STRING); + const auto buffer_start = static_cast(process_information) + sizeof(UNICODE_STRING>); 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 info{c.emu, thread_information}; - info.access([&](THREAD_BASIC_INFORMATION& i) + const emulator_object 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, + const emulator_object>> 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> 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, + const emulator_object>> 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> 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> 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 directory_handle, const ACCESS_MASK /*desired_access*/, - const emulator_object object_attributes) + const emulator_object>> object_attributes) { const auto attributes = object_attributes.read(); const auto object_name = read_unicode_string(c.emu, reinterpret_cast>*>(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 link_handle, ACCESS_MASK /*desired_access*/, - const emulator_object object_attributes) + const emulator_object>> object_attributes) { const auto attributes = object_attributes.read(); const auto object_name = read_unicode_string(c.emu, reinterpret_cast>*>(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 link_target, + const emulator_object>> link_target, const emulator_object returned_length) { if (link_handle == KNOWN_DLLS_SYMLINK) @@ -1477,7 +1484,7 @@ namespace } str.Length = str_length; - c.emu.write_memory(reinterpret_cast(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 section_handle, const ACCESS_MASK /*desired_access*/, - const emulator_object /*object_attributes*/, + const emulator_object>> /*object_attributes*/, const emulator_object 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 client_port_handle, const emulator_object>> server_port_name, const emulator_object /*security_qos*/, - const emulator_object client_shared_memory, - const emulator_object /*server_shared_memory*/, + const emulator_object client_shared_memory, + const emulator_object /*server_shared_memory*/, const emulator_object /*maximum_message_length*/, const emulator_pointer connection_info, const emulator_object 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(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, + const emulator_object>> 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(token_information + 0x10); + user.User.Sid = token_information + 0x10; - emulator_object{c.emu, token_information}.write(user); + emulator_object{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().ptr(); + peb.GdiSharedHandleTable = reinterpret_cast::PVOID*>(c.proc.base_allocator.reserve().ptr()); } }); @@ -1841,12 +1848,12 @@ namespace NTSTATUS handle_NtAlpcSendWaitReceivePort(const syscall_context& c, const handle port_handle, const ULONG /*flags*/, - const emulator_object /*send_message*/, + const emulator_object /*send_message*/, const emulator_object /*send_message_attributes*/ , - const emulator_object receive_message, - const emulator_object /*buffer_length*/, + const emulator_object receive_message, + const emulator_object::SIZE_T> /*buffer_length*/, const emulator_object /*receive_message_attributes*/, const emulator_object /*timeout*/) @@ -1863,9 +1870,9 @@ namespace return STATUS_NOT_SUPPORTED; } - const emulator_object data{c.emu, receive_message.value() + 0x48}; + const emulator_object>> data{c.emu, receive_message.value() + 0x48}; const auto dest = data.read(); - const auto base = reinterpret_cast(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 thread_context, + NTSTATUS handle_NtContinue(const syscall_context& c, const emulator_object 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, + const emulator_object>> io_status_block, uint64_t buffer, const ULONG length, const emulator_object /*byte_offset*/, const emulator_object /*key*/) @@ -1951,7 +1958,7 @@ namespace if (io_status_block) { - IO_STATUS_BLOCK block{}; + IO_STATUS_BLOCK> 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, + const emulator_object>> io_status_block, uint64_t buffer, const ULONG length, const emulator_object /*byte_offset*/, const emulator_object /*key*/) @@ -1977,7 +1984,7 @@ namespace { if (io_status_block) { - IO_STATUS_BLOCK block{}; + IO_STATUS_BLOCK> 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> 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 file_handle, ACCESS_MASK desired_access, - const emulator_object object_attributes, - const emulator_object /*io_status_block*/, + const emulator_object>> object_attributes, + const emulator_object>> /*io_status_block*/, const emulator_object /*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(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(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 file_handle, const ACCESS_MASK desired_access, - const emulator_object object_attributes, - const emulator_object io_status_block, + const emulator_object>> object_attributes, + const emulator_object>> 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*/, - const emulator_object thread_context, BOOLEAN handle_exception) + const emulator_object>> /*exception_record*/, + const emulator_object thread_context, BOOLEAN handle_exception) { if (handle_exception) { @@ -2252,7 +2259,7 @@ namespace NTSTATUS handle_NtCreateSemaphore(const syscall_context& c, const emulator_object semaphore_handle, const ACCESS_MASK /*desired_access*/, - const emulator_object object_attributes, + const emulator_object>> 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 thread_handle, const ACCESS_MASK /*desired_access*/, - const emulator_object /*object_attributes*/, + const emulator_object>> /*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 attribute_list) + const uint64_t argument, const ULONG /*create_flags*/, const EmulatorTraits::SIZE_T /*zero_bits*/, + const EmulatorTraits::SIZE_T stack_size, const EmulatorTraits::SIZE_T /*maximum_stack_size*/, + const emulator_object>> attribute_list) { if (process_handle != ~0ULL) { @@ -2371,19 +2378,19 @@ namespace const auto* thread = c.proc.threads.get(h); - const emulator_object attributes{ - c.emu, attribute_list.value() + offsetof(PS_ATTRIBUTE_LIST, Attributes) + const emulator_object>> attributes{ + c.emu, attribute_list.value() + offsetof(PS_ATTRIBUTE_LIST>, 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>); + constexpr auto header_size = sizeof(PS_ATTRIBUTE_LIST>) - 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>& 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 lock) + const emulator_object>> lock) { if (lock.value()) { diff --git a/src/windows-emulator/windows_emulator.cpp b/src/windows-emulator/windows_emulator.cpp index c04e5b9f..a366cbe0 100644 --- a/src/windows-emulator/windows_emulator.cpp +++ b/src/windows-emulator/windows_emulator.cpp @@ -14,8 +14,8 @@ namespace emulator_object 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 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(); + context.peb = allocator.reserve(); /* 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(); + context.process_params = allocator.reserve(); - 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>; + using exception_record_map = std::unordered_map>*, emulator_object>>>; - emulator_object save_exception_record(emulator_allocator& allocator, - const EXCEPTION_RECORD& record, + emulator_object>> save_exception_record(emulator_allocator& allocator, + const EMU_EXCEPTION_RECORD>& record, exception_record_map& record_mapping) { - const auto record_obj = allocator.reserve(); + const auto record_obj = allocator.reserve>>(); record_obj.write(record); if (record.ExceptionRecord) { record_mapping.emplace(&record, record_obj); - emulator_object nested_record_obj{allocator.get_emulator()}; - const auto nested_record = record_mapping.find(record.ExceptionRecord); + emulator_object>> nested_record_obj{allocator.get_emulator()}; + const auto nested_record = record_mapping.find(reinterpret_cast>*>(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>*>(record.ExceptionRecord), record_mapping); } - record_obj.access([&](EXCEPTION_RECORD& r) + record_obj.access([&](EMU_EXCEPTION_RECORD>& r) { - r.ExceptionRecord = nested_record_obj.ptr(); + r.ExceptionRecord = reinterpret_cast::PVOID>(nested_record_obj.ptr()); }); } return record_obj; } - emulator_object save_exception_record(emulator_allocator& allocator, - const EXCEPTION_RECORD& record) + emulator_object>> save_exception_record(emulator_allocator& allocator, + const EMU_EXCEPTION_RECORD>& 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>& record) { - std::unordered_set records{}; + std::unordered_set>*> records{}; size_t total_size = 0; - const EXCEPTION_RECORD* current_record = &record; + const EMU_EXCEPTION_RECORD>* 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>*>(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> 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>*>(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_record_obj{emu, new_sp}; - context_record_obj.write(*pointers.ContextRecord); + const emulator_object context_record_obj{emu, new_sp}; + context_record_obj.write(*reinterpret_cast(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>*>(pointers.ExceptionRecord)); if (exception_record_obj.value() != allocator.get_base()) { @@ -389,34 +392,34 @@ namespace const emulator_object 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(pointers.ContextRecord)->Rip; + frame.rsp = reinterpret_cast(pointers.ContextRecord)->Rsp; + frame.ss = reinterpret_cast(pointers.ContextRecord)->SegSs; + frame.cs = reinterpret_cast(pointers.ContextRecord)->SegCs; + frame.eflags = reinterpret_cast(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> record{}; memset(&record, 0, sizeof(record)); record.ExceptionCode = static_cast(STATUS_ACCESS_VIOLATION); record.ExceptionFlags = 0; - record.ExceptionRecord = nullptr; - record.ExceptionAddress = reinterpret_cast(emu.read_instruction_pointer()); + record.ExceptionRecord = 0; + record.ExceptionAddress = static_cast::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> pointers{}; + pointers.ContextRecord = reinterpret_cast::PVOID>(&ctx); + pointers.ExceptionRecord = reinterpret_cast::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(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(); + this->teb = this->gs_segment->reserve(); - this->teb->access([&](TEB& teb_obj) + this->teb->access([&](TEB64& teb_obj) { - teb_obj.ClientId.UniqueProcess = reinterpret_cast(1); - teb_obj.ClientId.UniqueThread = reinterpret_cast(static_cast(this->id)); - teb_obj.NtTib.StackLimit = reinterpret_cast(this->stack_base); - teb_obj.NtTib.StackBase = reinterpret_cast(this->stack_base + this->stack_size); + teb_obj.ClientId.UniqueProcess = 1ul; + teb_obj.ClientId.UniqueThread = static_cast(this->id); + teb_obj.NtTib.StackLimit = reinterpret_cast(this->stack_base); + teb_obj.NtTib.StackBase = reinterpret_cast(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(emu); + const auto ctx_obj = allocate_object_on_stack(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(context.executable->image_base); + peb.ImageBaseAddress = reinterpret_cast(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),