From 1f5afe4c741fd369f92f3004bdd9ecf75f079a4b Mon Sep 17 00:00:00 2001 From: CarlTSpeak Date: Sat, 18 Oct 2025 14:19:53 +0100 Subject: [PATCH 01/16] Minidump can load pages with C permission set. Minor instrumentation. --- src/analyzer/analysis.cpp | 11 +++++++++++ src/windows-emulator/memory_utils.hpp | 4 +++- src/windows-emulator/windows_emulator.cpp | 19 ++++++++++++------- src/windows-emulator/windows_emulator.hpp | 8 ++++++++ 4 files changed, 34 insertions(+), 8 deletions(-) diff --git a/src/analyzer/analysis.cpp b/src/analyzer/analysis.cpp index d4df4e5a..1667a421 100644 --- a/src/analyzer/analysis.cpp +++ b/src/analyzer/analysis.cpp @@ -204,6 +204,17 @@ namespace emu.reg(x86_register::rsp, emu.reg(x86_register::rsp) + 8); emu.reg(x86_register::rax, 1); } + else if (function == "VirtualQuery") + { + auto& emu = c.win_emu->emu(); + const auto lpAddress = emu.reg(x86_register::rcx); + const auto lpBuffer = emu.reg(x86_register::rdx); + const auto dwLength = emu.reg(x86_register::r8); + + c.win_emu->log.print(color::yellow, + "VirtualQuery called: lpAddress=0x%" PRIx64 ", lpBuffer=0x%" PRIx64 ", dwLength=%" PRIu64 "\n", lpAddress, + lpBuffer, dwLength); + } else if (function == "lstrcmp" || function == "lstrcmpi") { print_arg_as_string(*c.win_emu, 0); diff --git a/src/windows-emulator/memory_utils.hpp b/src/windows-emulator/memory_utils.hpp index 5c490223..632979c6 100644 --- a/src/windows-emulator/memory_utils.hpp +++ b/src/windows-emulator/memory_utils.hpp @@ -51,8 +51,10 @@ inline std::optional try_map_nt_to_emulator_protection(uin case PAGE_EXECUTE_READWRITE: common = memory_permission::all; break; - case 0: case PAGE_EXECUTE_WRITECOPY: + common = memory_permission::all; + break; + case 0: default: return std::nullopt; } diff --git a/src/windows-emulator/windows_emulator.cpp b/src/windows-emulator/windows_emulator.cpp index ab9ecbd8..988f396a 100644 --- a/src/windows-emulator/windows_emulator.cpp +++ b/src/windows-emulator/windows_emulator.cpp @@ -328,7 +328,7 @@ windows_emulator::windows_emulator(std::unique_ptr emu, const e this->map_port(mapping.first, mapping.second); } - this->setup_hooks(); + this->setup_hooks(); } windows_emulator::~windows_emulator() = default; @@ -434,6 +434,9 @@ void windows_emulator::on_instruction_execution(const uint64_t address) void windows_emulator::setup_hooks() { + uint64_t tsc_base = splitmix64(0xCAFEBABEDEADBEEFull); + constexpr uint64_t tick_scale = 50; + this->emu().hook_instruction(x86_hookable_instructions::syscall, [&] { this->dispatcher.dispatch(*this); return instruction_hook_continuation::skip_instruction; @@ -442,9 +445,10 @@ void windows_emulator::setup_hooks() this->emu().hook_instruction(x86_hookable_instructions::rdtscp, [&] { this->callbacks.on_rdtscp(); - const auto ticks = this->clock_->timestamp_counter(); - this->emu().reg(x86_register::rax, ticks & 0xFFFFFFFF); - this->emu().reg(x86_register::rdx, (ticks >> 32) & 0xFFFFFFFF); + const uint64_t retired = this->executed_instructions_; + const uint64_t ticks = tsc_base + (retired * tick_scale); + this->emu().reg(x86_register::rax, static_cast(ticks)); + this->emu().reg(x86_register::rdx, static_cast(ticks >> 32)); // Return the IA32_TSC_AUX value in RCX (low 32 bits) auto tsc_aux = 0; // Need to replace this with proper CPUID later @@ -456,9 +460,10 @@ void windows_emulator::setup_hooks() this->emu().hook_instruction(x86_hookable_instructions::rdtsc, [&] { this->callbacks.on_rdtsc(); - const auto ticks = this->clock_->timestamp_counter(); - this->emu().reg(x86_register::rax, ticks & 0xFFFFFFFF); - this->emu().reg(x86_register::rdx, (ticks >> 32) & 0xFFFFFFFF); + const uint64_t retired = this->executed_instructions_; + const uint64_t ticks = tsc_base + (retired * tick_scale); + this->emu().reg(x86_register::rax, static_cast(ticks)); + this->emu().reg(x86_register::rdx, static_cast(ticks >> 32)); return instruction_hook_continuation::skip_instruction; }); diff --git a/src/windows-emulator/windows_emulator.hpp b/src/windows-emulator/windows_emulator.hpp index 86e2a0e2..720bec3b 100644 --- a/src/windows-emulator/windows_emulator.hpp +++ b/src/windows-emulator/windows_emulator.hpp @@ -225,3 +225,11 @@ class windows_emulator void register_factories(utils::buffer_deserializer& buffer); }; + +static inline uint64_t splitmix64(uint64_t x) noexcept +{ + x += 0x9E3779B97F4A7C15ull; + x = (x ^ (x >> 30)) * 0xBF58476D1CE4E5B9ull; + x = (x ^ (x >> 27)) * 0x94D049BB133111EBull; + return x ^ (x >> 31); +} \ No newline at end of file From c0fd8ebf51c158477a9dd97aaaa6dd7a4358548c Mon Sep 17 00:00:00 2001 From: Igor Pissolati Date: Wed, 22 Oct 2025 17:14:19 -0300 Subject: [PATCH 02/16] Add FileFsAttributeInformation fs info class --- src/common/platform/file_management.hpp | 8 ++++++++ src/windows-emulator/syscalls/file.cpp | 12 +++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/common/platform/file_management.hpp b/src/common/platform/file_management.hpp index e0243003..34dbdd05 100644 --- a/src/common/platform/file_management.hpp +++ b/src/common/platform/file_management.hpp @@ -309,6 +309,14 @@ typedef struct _FILE_FS_DEVICE_INFORMATION ULONG Characteristics; } FILE_FS_DEVICE_INFORMATION, *PFILE_FS_DEVICE_INFORMATION; +typedef struct _FILE_FS_ATTRIBUTE_INFORMATION +{ + ULONG FileSystemAttributes; + LONG MaximumComponentNameLength; + ULONG FileSystemNameLength; + char16_t FileSystemName[10]; +} FILE_FS_ATTRIBUTE_INFORMATION, *PFILE_FS_ATTRIBUTE_INFORMATION; + typedef struct _FILE_POSITION_INFORMATION { LARGE_INTEGER CurrentByteOffset; diff --git a/src/windows-emulator/syscalls/file.cpp b/src/windows-emulator/syscalls/file.cpp index 4bf4b3fb..a9b75937 100644 --- a/src/windows-emulator/syscalls/file.cpp +++ b/src/windows-emulator/syscalls/file.cpp @@ -182,8 +182,18 @@ namespace syscalls return handle_query(c.emu, fs_information, length, io_status_block, [&](FILE_FS_VOLUME_INFORMATION&) {}); + case FileFsAttributeInformation: + return handle_query<_FILE_FS_ATTRIBUTE_INFORMATION>( + c.emu, fs_information, length, io_status_block, [&](_FILE_FS_ATTRIBUTE_INFORMATION& info) { + info.FileSystemAttributes = 0x40006; // FILE_CASE_PRESERVED_NAMES | FILE_UNICODE_ON_DISK | FILE_NAMED_STREAMS + info.MaximumComponentNameLength = 255; + const auto name = u"NTFS"s; + info.FileSystemNameLength = static_cast(name.size() * sizeof(char16_t)); + memcpy(info.FileSystemName, name.data(), info.FileSystemNameLength); + }); + default: - c.win_emu.log.error("Unsupported fs info class: %X\n", fs_information_class); + c.win_emu.log.error("Unsupported fs info class: 0x%X\n", fs_information_class); c.emu.stop(); return write_io_status(io_status_block, STATUS_NOT_SUPPORTED, true); } From c8a18cf61c885911417c998d21d16ae5a55dd075 Mon Sep 17 00:00:00 2001 From: Igor Pissolati Date: Wed, 22 Oct 2025 17:14:51 -0300 Subject: [PATCH 03/16] Add FileIsRemoteDeviceInformation file info class --- src/common/platform/file_management.hpp | 5 +++++ src/windows-emulator/syscalls/file.cpp | 26 ++++++++++++++++++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/common/platform/file_management.hpp b/src/common/platform/file_management.hpp index 34dbdd05..5c6d091e 100644 --- a/src/common/platform/file_management.hpp +++ b/src/common/platform/file_management.hpp @@ -328,6 +328,11 @@ typedef struct _FILE_ATTRIBUTE_TAG_INFORMATION ULONG ReparseTag; } FILE_ATTRIBUTE_TAG_INFORMATION, *PFILE_ATTRIBUTE_TAG_INFORMATION; +typedef struct _FILE_IS_REMOTE_DEVICE_INFORMATION +{ + BOOLEAN IsRemote; +} FILE_IS_REMOTE_DEVICE_INFORMATION, *PFILE_IS_REMOTE_DEVICE_INFORMATION; + typedef struct _FILE_STANDARD_INFORMATION { LARGE_INTEGER AllocationSize; diff --git a/src/windows-emulator/syscalls/file.cpp b/src/windows-emulator/syscalls/file.cpp index a9b75937..49fece70 100644 --- a/src/windows-emulator/syscalls/file.cpp +++ b/src/windows-emulator/syscalls/file.cpp @@ -547,12 +547,36 @@ namespace syscalls return ret(STATUS_SUCCESS); } + if (info_class == FileIsRemoteDeviceInformation) + { + if (!f->handle) + { + return ret(STATUS_NOT_SUPPORTED); + } + + block.Information = sizeof(FILE_IS_REMOTE_DEVICE_INFORMATION); + + if (length < block.Information) + { + return ret(STATUS_BUFFER_OVERFLOW); + } + + const emulator_object info{c.emu, file_information}; + FILE_IS_REMOTE_DEVICE_INFORMATION i{}; + + i.IsRemote = FALSE; + + info.write(i); + + return ret(STATUS_SUCCESS); + } + if (info_class == FileAllInformation) { return ret(STATUS_NOT_SUPPORTED); } - c.win_emu.log.error("Unsupported query file info class: %X\n", info_class); + c.win_emu.log.error("Unsupported query file info class: 0x%X\n", info_class); c.emu.stop(); return ret(STATUS_NOT_SUPPORTED); From 54ebbe27c2171dee66d601647f2755b4a65f1350 Mon Sep 17 00:00:00 2001 From: Igor Pissolati Date: Wed, 22 Oct 2025 17:16:10 -0300 Subject: [PATCH 04/16] Implement NtUserEnumDisplaySettings syscall --- src/common/platform/window.hpp | 59 +++++++++++++++++++++++++++++++ src/windows-emulator/syscalls.cpp | 26 ++++++++++++++ 2 files changed, 85 insertions(+) diff --git a/src/common/platform/window.hpp b/src/common/platform/window.hpp index b5bbee90..31607d2a 100644 --- a/src/common/platform/window.hpp +++ b/src/common/platform/window.hpp @@ -52,4 +52,63 @@ struct EMU_DISPLAY_DEVICEW char16_t DeviceKey[128]; }; +#ifndef ENUM_CURRENT_SETTINGS +#define ENUM_CURRENT_SETTINGS ((DWORD) - 1) +#endif + +struct EMU_DEVMODEW +{ + char16_t dmDeviceName[32]; + WORD dmSpecVersion; + WORD dmDriverVersion; + WORD dmSize; + WORD dmDriverExtra; + DWORD dmFields; + union + { + struct + { + int16_t dmOrientation; + int16_t dmPaperSize; + int16_t dmPaperLength; + int16_t dmPaperWidth; + int16_t dmScale; + int16_t dmCopies; + int16_t dmDefaultSource; + int16_t dmPrintQuality; + } s; + POINT dmPosition; + struct + { + POINT dmPosition; + DWORD dmDisplayOrientation; + DWORD dmDisplayFixedOutput; + } s2; + } u; + int16_t dmColor; + int16_t dmDuplex; + int16_t dmYResolution; + int16_t dmTTOption; + int16_t dmCollate; + char16_t dmFormName[32]; + WORD dmLogPixels; + DWORD dmBitsPerPel; + DWORD dmPelsWidth; + DWORD dmPelsHeight; + union + { + DWORD dmDisplayFlags; + DWORD dmNup; + } u2; + DWORD dmDisplayFrequency; + DWORD dmICMMethod; + DWORD dmICMIntent; + DWORD dmMediaType; + DWORD dmDitherType; + DWORD dmReserved1; + DWORD dmReserved2; + DWORD dmPanningWidth; + DWORD dmPanningHeight; +}; + // NOLINTEND(modernize-use-using,cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) diff --git a/src/windows-emulator/syscalls.cpp b/src/windows-emulator/syscalls.cpp index 778e8b90..0cb3813f 100644 --- a/src/windows-emulator/syscalls.cpp +++ b/src/windows-emulator/syscalls.cpp @@ -937,6 +937,31 @@ namespace syscalls return STATUS_SUCCESS; } + BOOL handle_NtUserEnumDisplaySettings(const syscall_context& c, + const emulator_object>> device_name, const DWORD mode_num, + const emulator_object dev_mode, const DWORD /*flags*/) + { + if (dev_mode && mode_num == ENUM_CURRENT_SETTINGS) + { + const auto dev_name = read_unicode_string(c.emu, device_name); + + if (dev_name == u"\\\\.\\DISPLAY1") + { + dev_mode.access([](EMU_DEVMODEW& dm) { + dm.dmFields = 0x5C0000; // DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY + dm.dmPelsWidth = 1920; + dm.dmPelsHeight = 1080; + dm.dmBitsPerPel = 32; + dm.dmDisplayFrequency = 60; + }); + + return TRUE; + } + } + + return FALSE; + } + NTSTATUS handle_NtAssociateWaitCompletionPacket() { return STATUS_SUCCESS; @@ -1131,6 +1156,7 @@ void syscall_dispatcher::add_handlers(std::map& ha add_handler(NtUserGetRawInputDeviceList); add_handler(NtUserGetKeyboardType); add_handler(NtUserEnumDisplayDevices); + add_handler(NtUserEnumDisplaySettings); add_handler(NtUserSetProp); add_handler(NtUserSetProp2); add_handler(NtUserChangeWindowMessageFilterEx); From 4fbd65a3020d3ba2c6577e16a2f607d80e0ec945 Mon Sep 17 00:00:00 2001 From: Igor Pissolati Date: Wed, 22 Oct 2025 17:17:02 -0300 Subject: [PATCH 05/16] Fix DISPLAY_DEVICEW value --- src/common/utils/string.hpp | 14 +++----------- src/windows-emulator/syscalls.cpp | 2 +- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/src/common/utils/string.hpp b/src/common/utils/string.hpp index c2ea97ea..2ab1a772 100644 --- a/src/common/utils/string.hpp +++ b/src/common/utils/string.hpp @@ -19,26 +19,18 @@ namespace utils::string template requires(std::is_trivially_copyable_v) // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) - void copy(T (&array)[Size], const std::basic_string_view str) + void copy(T (&array)[Size], const T* str) { if constexpr (Size == 0) { return; } - const auto size = std::min(Size, str.size()); - memcpy(array, str.data(), size * sizeof(T)); + const auto size = std::min(Size, std::char_traits::length(str)); + memcpy(array, str, size * sizeof(T)); array[std::min(Size - 1, size)] = {}; } - template - requires(std::is_trivially_copyable_v) - // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) - void copy(T (&array)[Size], const T* str) - { - copy(array, std::basic_string_view(str)); - } - inline char char_to_lower(const char val) { return static_cast(std::tolower(static_cast(val))); diff --git a/src/windows-emulator/syscalls.cpp b/src/windows-emulator/syscalls.cpp index 0cb3813f..683ae614 100644 --- a/src/windows-emulator/syscalls.cpp +++ b/src/windows-emulator/syscalls.cpp @@ -926,7 +926,7 @@ namespace syscalls } display_device.access([&](EMU_DISPLAY_DEVICEW& dev) { - dev.StateFlags = 0; + dev.StateFlags = 0x80005; // DISPLAY_DEVICE_UNSAFE_MODES_ON | DISPLAY_DEVICE_PRIMARY_DEVICE | DISPLAY_DEVICE_ATTACHED_TO_DESKTOP utils::string::copy(dev.DeviceName, u"\\\\.\\DISPLAY1"); utils::string::copy(dev.DeviceID, u"PCI\\VEN_10DE&DEV_0000&SUBSYS_00000000&REV_A1"); utils::string::copy(dev.DeviceString, u"Emulator Display"); From 0d06e6822af69083d20d6cc73570eba33a2f4092 Mon Sep 17 00:00:00 2001 From: Igor Pissolati Date: Wed, 22 Oct 2025 17:17:57 -0300 Subject: [PATCH 06/16] Add support for SHA256 in KSecDD --- .../devices/security_support_provider.cpp | 46 ++++++++++++++++--- 1 file changed, 40 insertions(+), 6 deletions(-) diff --git a/src/windows-emulator/devices/security_support_provider.cpp b/src/windows-emulator/devices/security_support_provider.cpp index 214d363c..06f3d670 100644 --- a/src/windows-emulator/devices/security_support_provider.cpp +++ b/src/windows-emulator/devices/security_support_provider.cpp @@ -9,7 +9,7 @@ namespace { // RNG Microsoft Primitive Provider // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) - std::uint8_t output_data[216] = // + std::uint8_t rng_output_data[216] = // {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, @@ -22,6 +22,21 @@ namespace 0x70, 0x00, 0x72, 0x00, 0x69, 0x00, 0x6D, 0x00, 0x69, 0x00, 0x74, 0x00, 0x69, 0x00, 0x76, 0x00, 0x65, 0x00, 0x73, 0x00, 0x2E, 0x00, 0x64, 0x00, 0x6C, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + // SHA256 Microsoft Primitive Provider + // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) + std::uint8_t sha256_output_data[224] = // + {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x32, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x53, 0x00, 0x48, 0x00, + 0x41, 0x00, 0x32, 0x00, 0x35, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4D, 0x00, 0x69, 0x00, 0x63, 0x00, 0x72, 0x00, 0x6F, + 0x00, 0x73, 0x00, 0x6F, 0x00, 0x66, 0x00, 0x74, 0x00, 0x20, 0x00, 0x50, 0x00, 0x72, 0x00, 0x69, 0x00, 0x6D, 0x00, 0x69, 0x00, + 0x74, 0x00, 0x69, 0x00, 0x76, 0x00, 0x65, 0x00, 0x20, 0x00, 0x50, 0x00, 0x72, 0x00, 0x6F, 0x00, 0x76, 0x00, 0x69, 0x00, 0x64, + 0x00, 0x65, 0x00, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x00, 0x63, 0x00, 0x72, 0x00, 0x79, 0x00, 0x70, 0x00, 0x74, 0x00, 0x70, + 0x00, 0x72, 0x00, 0x69, 0x00, 0x6D, 0x00, 0x69, 0x00, 0x74, 0x00, 0x69, 0x00, 0x76, 0x00, 0x65, 0x00, 0x73, 0x00, 0x2E, 0x00, + 0x64, 0x00, 0x6C, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + NTSTATUS io_control(windows_emulator& win_emu, const io_device_context& c) override { if (c.io_control_code != 0x390400) @@ -33,13 +48,32 @@ namespace if (operation == 2) { - win_emu.emu().write_memory(c.output_buffer, output_data); + std::array alg_name_buffer{}; + win_emu.emu().read_memory(c.input_buffer + 0x30, alg_name_buffer.data(), sizeof(alg_name_buffer)); - if (c.io_status_block) + const std::u16string algorithm_name(alg_name_buffer.data()); + + if (algorithm_name == u"SHA256") { - IO_STATUS_BLOCK> block{}; - block.Information = sizeof(output_data); - c.io_status_block.write(block); + win_emu.emu().write_memory(c.output_buffer, sha256_output_data); + + if (c.io_status_block) + { + IO_STATUS_BLOCK> block{}; + block.Information = sizeof(sha256_output_data); + c.io_status_block.write(block); + } + } + else + { + win_emu.emu().write_memory(c.output_buffer, rng_output_data); + + if (c.io_status_block) + { + IO_STATUS_BLOCK> block{}; + block.Information = sizeof(rng_output_data); + c.io_status_block.write(block); + } } } From 1c89c4e3b38ae610d225754a7d07e21577693b87 Mon Sep 17 00:00:00 2001 From: Igor Pissolati Date: Wed, 22 Oct 2025 17:18:41 -0300 Subject: [PATCH 07/16] Initialize StaticUnicodeString in TEB --- src/windows-emulator/emulator_thread.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/windows-emulator/emulator_thread.cpp b/src/windows-emulator/emulator_thread.cpp index 19af1b48..a56e5686 100644 --- a/src/windows-emulator/emulator_thread.cpp +++ b/src/windows-emulator/emulator_thread.cpp @@ -119,6 +119,8 @@ emulator_thread::emulator_thread(memory_manager& memory, const process_context& teb_obj.NtTib.Self = this->teb->value(); teb_obj.CurrentLocale = 0x409; teb_obj.ProcessEnvironmentBlock = context.peb.value(); + teb_obj.StaticUnicodeString.MaximumLength = sizeof(teb_obj.StaticUnicodeBuffer); + teb_obj.StaticUnicodeString.Buffer = this->teb->value() + offsetof(TEB64, StaticUnicodeBuffer); }); } From d20da120525ac9454bc5a61c6a594e34c55ac84d Mon Sep 17 00:00:00 2001 From: Igor Pissolati Date: Wed, 22 Oct 2025 17:19:51 -0300 Subject: [PATCH 08/16] Add '\??\pipe\' prefix to is_named_pipe_path --- src/windows-emulator/syscall_utils.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/windows-emulator/syscall_utils.hpp b/src/windows-emulator/syscall_utils.hpp index 0fe55849..ad7ce564 100644 --- a/src/windows-emulator/syscall_utils.hpp +++ b/src/windows-emulator/syscall_utils.hpp @@ -31,7 +31,7 @@ inline bool is_syscall(const std::string_view name) inline bool is_named_pipe_path(const std::u16string_view& filename) { - return filename == u"\\Device\\NamedPipe\\" || filename.starts_with(u"\\Device\\NamedPipe\\"); + return filename == u"\\Device\\NamedPipe\\" || filename.starts_with(u"\\Device\\NamedPipe\\") || filename.starts_with(u"\\??\\pipe\\"); } inline std::optional extract_syscall_id(const exported_symbol& symbol, std::span data) From c07f5415284af9d1d273eb216158988e1f81d11f Mon Sep 17 00:00:00 2001 From: Igor Pissolati Date: Wed, 22 Oct 2025 17:20:14 -0300 Subject: [PATCH 09/16] Stub NtSetSecurityObject --- src/windows-emulator/syscalls.cpp | 2 ++ src/windows-emulator/syscalls/object.cpp | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/src/windows-emulator/syscalls.cpp b/src/windows-emulator/syscalls.cpp index 683ae614..35fbec27 100644 --- a/src/windows-emulator/syscalls.cpp +++ b/src/windows-emulator/syscalls.cpp @@ -155,6 +155,7 @@ namespace syscalls NTSTATUS handle_NtSetInformationObject(); NTSTATUS handle_NtQuerySecurityObject(const syscall_context& c, handle /*h*/, SECURITY_INFORMATION /*security_information*/, emulator_pointer security_descriptor, ULONG length, emulator_object length_needed); + NTSTATUS handle_NtSetSecurityObject(); // syscalls/port.cpp: NTSTATUS handle_NtConnectPort(const syscall_context& c, emulator_object client_port_handle, @@ -1180,6 +1181,7 @@ void syscall_dispatcher::add_handlers(std::map& ha add_handler(NtReleaseWorkerFactoryWorker); add_handler(NtAlpcCreateSecurityContext); add_handler(NtAlpcDeleteSecurityContext); + add_handler(NtSetSecurityObject); #undef add_handler } diff --git a/src/windows-emulator/syscalls/object.cpp b/src/windows-emulator/syscalls/object.cpp index c1b9e5d4..5399e578 100644 --- a/src/windows-emulator/syscalls/object.cpp +++ b/src/windows-emulator/syscalls/object.cpp @@ -386,4 +386,9 @@ namespace syscalls return STATUS_SUCCESS; } + + NTSTATUS handle_NtSetSecurityObject() + { + return STATUS_SUCCESS; + } } From 46b97fd91c9f64fd9faa92f25e2492ae4200521b Mon Sep 17 00:00:00 2001 From: Igor Pissolati Date: Wed, 22 Oct 2025 17:21:04 -0300 Subject: [PATCH 10/16] Don't request 'file_size' for directories --- src/windows-emulator/syscalls/file.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/windows-emulator/syscalls/file.cpp b/src/windows-emulator/syscalls/file.cpp index 49fece70..62fd7ff7 100644 --- a/src/windows-emulator/syscalls/file.cpp +++ b/src/windows-emulator/syscalls/file.cpp @@ -221,7 +221,7 @@ namespace syscalls files.emplace_back(file_entry{ .file_path = file.path().filename(), - .file_size = file.file_size(), + .file_size = file.is_directory() ? 0 : file.file_size(), .is_directory = file.is_directory(), }); } @@ -242,7 +242,7 @@ namespace syscalls files.emplace_back(file_entry{ .file_path = filename, - .file_size = dir_entry.file_size(), + .file_size = dir_entry.is_directory() ? 0 : dir_entry.file_size(), .is_directory = dir_entry.is_directory(), }); }); From 83aa3b663a867ce97fcc87480086a045d3766ac7 Mon Sep 17 00:00:00 2001 From: Igor Pissolati Date: Wed, 22 Oct 2025 17:21:34 -0300 Subject: [PATCH 11/16] Optimize module_manager::get_module --- src/windows-emulator/module/mapped_module.hpp | 2 +- src/windows-emulator/module/module_manager.cpp | 3 +++ src/windows-emulator/module/module_manager.hpp | 7 +++++++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/windows-emulator/module/mapped_module.hpp b/src/windows-emulator/module/mapped_module.hpp index aaabaee8..6e7ced61 100644 --- a/src/windows-emulator/module/mapped_module.hpp +++ b/src/windows-emulator/module/mapped_module.hpp @@ -46,7 +46,7 @@ struct mapped_module bool contains(const uint64_t address) const { - return address >= this->image_base && address < (this->image_base + this->size_of_image); + return (address - this->image_base) < this->size_of_image; } uint64_t find_export(const std::string_view export_name) const diff --git a/src/windows-emulator/module/module_manager.cpp b/src/windows-emulator/module/module_manager.cpp index 448103a7..9294e066 100644 --- a/src/windows-emulator/module/module_manager.cpp +++ b/src/windows-emulator/module/module_manager.cpp @@ -156,6 +156,7 @@ mapped_module* module_manager::map_memory_module(uint64_t base_address, uint64_t const auto image_base = mod.image_base; const auto entry = this->modules_.try_emplace(image_base, std::move(mod)); + this->last_module_cache_ = this->modules_.end(); this->callbacks_->on_module_load(entry.first->second); return &entry.first->second; } @@ -183,6 +184,7 @@ void module_manager::serialize(utils::buffer_serializer& buffer) const void module_manager::deserialize(utils::buffer_deserializer& buffer) { buffer.read_map(this->modules_); + this->last_module_cache_ = this->modules_.end(); const auto executable_base = buffer.read(); const auto ntdll_base = buffer.read(); @@ -209,6 +211,7 @@ bool module_manager::unmap(const uint64_t address) this->callbacks_->on_module_unload(mod->second); unmap_module(*this->memory_, mod->second); this->modules_.erase(mod); + this->last_module_cache_ = this->modules_.end(); return true; } diff --git a/src/windows-emulator/module/module_manager.hpp b/src/windows-emulator/module/module_manager.hpp index eec4b04a..06afef9c 100644 --- a/src/windows-emulator/module/module_manager.hpp +++ b/src/windows-emulator/module/module_manager.hpp @@ -83,9 +83,15 @@ class module_manager callbacks* callbacks_{}; module_map modules_{}; + mutable module_map::iterator last_module_cache_{modules_.end()}; module_map::iterator get_module(const uint64_t address) { + if (last_module_cache_ != this->modules_.end() && last_module_cache_->second.contains(address)) + { + return last_module_cache_; + } + if (this->modules_.empty()) { return this->modules_.end(); @@ -101,6 +107,7 @@ class module_manager if (upper_bound->second.contains(address)) { + last_module_cache_ = upper_bound; return upper_bound; } From 2c82277b5e7ac7e43edefe60aaf6dfeaa36d620b Mon Sep 17 00:00:00 2001 From: Igor Pissolati Date: Thu, 23 Oct 2025 11:19:17 -0300 Subject: [PATCH 12/16] Add FileIdInformation file info class --- src/common/platform/file_management.hpp | 18 ++++++++++---- src/windows-emulator/syscalls/file.cpp | 32 +++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/src/common/platform/file_management.hpp b/src/common/platform/file_management.hpp index 5c6d091e..0d8745e1 100644 --- a/src/common/platform/file_management.hpp +++ b/src/common/platform/file_management.hpp @@ -333,6 +333,19 @@ typedef struct _FILE_IS_REMOTE_DEVICE_INFORMATION BOOLEAN IsRemote; } FILE_IS_REMOTE_DEVICE_INFORMATION, *PFILE_IS_REMOTE_DEVICE_INFORMATION; +#ifndef OS_WINDOWS +typedef struct _FILE_ID_128 +{ + BYTE Identifier[16]; +} FILE_ID_128, *PFILE_ID_128; +#endif + +typedef struct _FILE_ID_INFORMATION +{ + ULONGLONG VolumeSerialNumber; + FILE_ID_128 FileId; +} FILE_ID_INFORMATION, *PFILE_ID_INFORMATION; + typedef struct _FILE_STANDARD_INFORMATION { LARGE_INTEGER AllocationSize; @@ -426,11 +439,6 @@ typedef struct _FILE_RENAME_INFORMATION } FILE_RENAME_INFORMATION, *PFILE_RENAME_INFORMATION; #ifndef OS_WINDOWS -typedef struct _FILE_ID_128 -{ - BYTE Identifier[16]; -} FILE_ID_128, *PFILE_ID_128; - typedef BOOLEAN SECURITY_CONTEXT_TRACKING_MODE, *PSECURITY_CONTEXT_TRACKING_MODE; typedef struct _SECURITY_QUALITY_OF_SERVICE { diff --git a/src/windows-emulator/syscalls/file.cpp b/src/windows-emulator/syscalls/file.cpp index 62fd7ff7..7c9a0199 100644 --- a/src/windows-emulator/syscalls/file.cpp +++ b/src/windows-emulator/syscalls/file.cpp @@ -571,6 +571,38 @@ namespace syscalls return ret(STATUS_SUCCESS); } + if (info_class == FileIdInformation) + { + if (!f->handle) + { + return ret(STATUS_NOT_SUPPORTED); + } + + block.Information = sizeof(FILE_ID_INFORMATION); + + if (length < block.Information) + { + return ret(STATUS_BUFFER_OVERFLOW); + } + + struct _stat64 file_stat{}; + if (fstat64(f->handle, &file_stat) != 0) + { + return ret(STATUS_INVALID_HANDLE); + } + + const emulator_object info{c.emu, file_information}; + FILE_ID_INFORMATION i{}; + + i.VolumeSerialNumber = file_stat.st_dev; + memset(&i.FileId, 0, sizeof(i.FileId)); + memcpy(&i.FileId.Identifier[0], &file_stat.st_ino, sizeof(file_stat.st_ino)); + + info.write(i); + + return ret(STATUS_SUCCESS); + } + if (info_class == FileAllInformation) { return ret(STATUS_NOT_SUPPORTED); From 3c6c2e2dde3d980d340794efb4c86772eb4814e4 Mon Sep 17 00:00:00 2001 From: Igor Pissolati Date: Thu, 23 Oct 2025 11:19:35 -0300 Subject: [PATCH 13/16] Apply review suggestion --- src/windows-emulator/syscalls/file.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/windows-emulator/syscalls/file.cpp b/src/windows-emulator/syscalls/file.cpp index 7c9a0199..1829d3fa 100644 --- a/src/windows-emulator/syscalls/file.cpp +++ b/src/windows-emulator/syscalls/file.cpp @@ -187,7 +187,7 @@ namespace syscalls c.emu, fs_information, length, io_status_block, [&](_FILE_FS_ATTRIBUTE_INFORMATION& info) { info.FileSystemAttributes = 0x40006; // FILE_CASE_PRESERVED_NAMES | FILE_UNICODE_ON_DISK | FILE_NAMED_STREAMS info.MaximumComponentNameLength = 255; - const auto name = u"NTFS"s; + constexpr auto name = u"NTFS"sv; info.FileSystemNameLength = static_cast(name.size() * sizeof(char16_t)); memcpy(info.FileSystemName, name.data(), info.FileSystemNameLength); }); From b6d7a012d727ab82b374afae8db8178a5c4575a2 Mon Sep 17 00:00:00 2001 From: Igor Pissolati Date: Thu, 23 Oct 2025 16:02:53 -0300 Subject: [PATCH 14/16] Fix issue in NtUserEnumDisplayDevices and NtUserEnumDisplaySettings --- src/windows-emulator/syscalls.cpp | 63 ++++++++++++++++++++----------- 1 file changed, 42 insertions(+), 21 deletions(-) diff --git a/src/windows-emulator/syscalls.cpp b/src/windows-emulator/syscalls.cpp index 35fbec27..4d0d6276 100644 --- a/src/windows-emulator/syscalls.cpp +++ b/src/windows-emulator/syscalls.cpp @@ -912,37 +912,58 @@ namespace syscalls return FALSE; } - NTSTATUS handle_NtUserEnumDisplayDevices(const syscall_context& /*c*/, + NTSTATUS handle_NtUserEnumDisplayDevices(const syscall_context& c, const emulator_object>> str_device, const DWORD dev_num, const emulator_object display_device, const DWORD /*flags*/) { - if (str_device && dev_num != 0) + if (!str_device) { - return STATUS_UNSUCCESSFUL; - } + if (dev_num > 0) + { + return STATUS_UNSUCCESSFUL; + } - if (dev_num > 0) + display_device.access([&](EMU_DISPLAY_DEVICEW& dev) { + dev.StateFlags = 0x5; // DISPLAY_DEVICE_PRIMARY_DEVICE | DISPLAY_DEVICE_ATTACHED_TO_DESKTOP + utils::string::copy(dev.DeviceName, u"\\\\.\\DISPLAY1"); + utils::string::copy(dev.DeviceString, u"Emulated Virtual Adapter"); + utils::string::copy(dev.DeviceID, u"PCI\\VEN_10DE&DEV_0000&SUBSYS_00000000&REV_A1"); + utils::string::copy(dev.DeviceKey, u"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Video\\{00000001-" + u"0002-0003-0004-000000000005}\\0000"); + }); + } + else { - return STATUS_UNSUCCESSFUL; - } + const auto dev_name = read_unicode_string(c.emu, str_device); - display_device.access([&](EMU_DISPLAY_DEVICEW& dev) { - dev.StateFlags = 0x80005; // DISPLAY_DEVICE_UNSAFE_MODES_ON | DISPLAY_DEVICE_PRIMARY_DEVICE | DISPLAY_DEVICE_ATTACHED_TO_DESKTOP - utils::string::copy(dev.DeviceName, u"\\\\.\\DISPLAY1"); - utils::string::copy(dev.DeviceID, u"PCI\\VEN_10DE&DEV_0000&SUBSYS_00000000&REV_A1"); - utils::string::copy(dev.DeviceString, u"Emulator Display"); - utils::string::copy(dev.DeviceKey, u"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Video\\{00000001-" - u"0002-0003-0004-000000000005}\\0001"); - }); + if (dev_name != u"\\\\.\\DISPLAY1") + { + return STATUS_UNSUCCESSFUL; + } + + if (dev_num > 0) + { + return STATUS_UNSUCCESSFUL; + } + + display_device.access([&](EMU_DISPLAY_DEVICEW& dev) { + dev.StateFlags = 0x1; // DISPLAY_DEVICE_ACTIVE + utils::string::copy(dev.DeviceName, u"\\\\.\\DISPLAY1\\Monitor0"); + utils::string::copy(dev.DeviceString, u"Generic PnP Monitor"); + utils::string::copy(dev.DeviceID, u"MONITOR\\EMU1234\\{4d36e96e-e325-11ce-bfc1-08002be10318}\\0000"); + utils::string::copy(dev.DeviceKey, u"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\DISPLAY\\EMU1234\\" + u"1&23a45b&0&UID67568640"); + }); + } return STATUS_SUCCESS; } - BOOL handle_NtUserEnumDisplaySettings(const syscall_context& c, - const emulator_object>> device_name, const DWORD mode_num, - const emulator_object dev_mode, const DWORD /*flags*/) + NTSTATUS handle_NtUserEnumDisplaySettings(const syscall_context& c, + const emulator_object>> device_name, + const DWORD mode_num, const emulator_object dev_mode, const DWORD /*flags*/) { - if (dev_mode && mode_num == ENUM_CURRENT_SETTINGS) + if (dev_mode && (mode_num == ENUM_CURRENT_SETTINGS || mode_num == 0)) { const auto dev_name = read_unicode_string(c.emu, device_name); @@ -956,11 +977,11 @@ namespace syscalls dm.dmDisplayFrequency = 60; }); - return TRUE; + return STATUS_SUCCESS; } } - return FALSE; + return STATUS_UNSUCCESSFUL; } NTSTATUS handle_NtAssociateWaitCompletionPacket() From 064df5b6efe2f032481c5e5f0524565037041f9e Mon Sep 17 00:00:00 2001 From: CarlTSpeak Date: Fri, 24 Oct 2025 10:59:28 +0100 Subject: [PATCH 15/16] Revert earlier rdtsc changes, implement fixes --- src/analyzer/analysis.cpp | 11 ----------- src/windows-emulator/memory_manager.cpp | 6 +++--- src/windows-emulator/memory_manager.hpp | 1 + src/windows-emulator/syscalls/memory.cpp | 7 +++++++ src/windows-emulator/windows_emulator.cpp | 11 +++-------- src/windows-emulator/windows_emulator.hpp | 8 -------- 6 files changed, 14 insertions(+), 30 deletions(-) diff --git a/src/analyzer/analysis.cpp b/src/analyzer/analysis.cpp index 1667a421..d4df4e5a 100644 --- a/src/analyzer/analysis.cpp +++ b/src/analyzer/analysis.cpp @@ -204,17 +204,6 @@ namespace emu.reg(x86_register::rsp, emu.reg(x86_register::rsp) + 8); emu.reg(x86_register::rax, 1); } - else if (function == "VirtualQuery") - { - auto& emu = c.win_emu->emu(); - const auto lpAddress = emu.reg(x86_register::rcx); - const auto lpBuffer = emu.reg(x86_register::rdx); - const auto dwLength = emu.reg(x86_register::r8); - - c.win_emu->log.print(color::yellow, - "VirtualQuery called: lpAddress=0x%" PRIx64 ", lpBuffer=0x%" PRIx64 ", dwLength=%" PRIu64 "\n", lpAddress, - lpBuffer, dwLength); - } else if (function == "lstrcmp" || function == "lstrcmpi") { print_arg_as_string(*c.win_emu, 0); diff --git a/src/windows-emulator/memory_manager.cpp b/src/windows-emulator/memory_manager.cpp index cabcd9f2..b5f6e574 100644 --- a/src/windows-emulator/memory_manager.cpp +++ b/src/windows-emulator/memory_manager.cpp @@ -504,7 +504,7 @@ uint64_t memory_manager::find_free_allocation_base(const size_t size, const uint start_address = align_up(region_end, ALLOCATION_GRANULARITY); } - if (start_address + size <= MAX_ALLOCATION_ADDRESS) + if (start_address + size <= MAX_ALLOCATION_END_EXCL) { return start_address; } @@ -516,7 +516,7 @@ region_info memory_manager::get_region_info(const uint64_t address) { region_info result{}; result.start = MIN_ALLOCATION_ADDRESS; - result.length = static_cast(MAX_ALLOCATION_ADDRESS - result.start); + result.length = static_cast(MAX_ALLOCATION_END_EXCL - result.start); result.permissions = nt_memory_permission(); result.initial_permissions = nt_memory_permission(); result.allocation_base = {}; @@ -541,7 +541,7 @@ region_info memory_manager::get_region_info(const uint64_t address) if (lower_end <= address) { result.start = lower_end; - result.length = static_cast(MAX_ALLOCATION_ADDRESS - result.start); + result.length = static_cast(MAX_ALLOCATION_END_EXCL - result.start); return result; } diff --git a/src/windows-emulator/memory_manager.hpp b/src/windows-emulator/memory_manager.hpp index 669d9ecc..a6467fee 100644 --- a/src/windows-emulator/memory_manager.hpp +++ b/src/windows-emulator/memory_manager.hpp @@ -12,6 +12,7 @@ constexpr auto ALLOCATION_GRANULARITY = 0x0000000000010000ULL; constexpr auto MIN_ALLOCATION_ADDRESS = 0x0000000000010000ULL; constexpr auto MAX_ALLOCATION_ADDRESS = 0x00007ffffffeffffULL; +constexpr auto MAX_ALLOCATION_END_EXCL = MAX_ALLOCATION_ADDRESS + 1ULL; // This maps to the `basic_memory_region` struct defined in // emulator\memory_region.hpp diff --git a/src/windows-emulator/syscalls/memory.cpp b/src/windows-emulator/syscalls/memory.cpp index a727101c..403ba2a7 100644 --- a/src/windows-emulator/syscalls/memory.cpp +++ b/src/windows-emulator/syscalls/memory.cpp @@ -20,6 +20,13 @@ namespace syscalls return STATUS_NOT_SUPPORTED; } + if (base_address < MIN_ALLOCATION_ADDRESS || base_address >= MAX_ALLOCATION_END_EXCL) + { + if (return_length) + return_length.write(0); + return STATUS_INVALID_PARAMETER; + } + if (info_class == MemoryBasicInformation) { if (return_length) diff --git a/src/windows-emulator/windows_emulator.cpp b/src/windows-emulator/windows_emulator.cpp index 988f396a..8cd1c0a8 100644 --- a/src/windows-emulator/windows_emulator.cpp +++ b/src/windows-emulator/windows_emulator.cpp @@ -328,7 +328,7 @@ windows_emulator::windows_emulator(std::unique_ptr emu, const e this->map_port(mapping.first, mapping.second); } - this->setup_hooks(); + this->setup_hooks(); } windows_emulator::~windows_emulator() = default; @@ -434,9 +434,6 @@ void windows_emulator::on_instruction_execution(const uint64_t address) void windows_emulator::setup_hooks() { - uint64_t tsc_base = splitmix64(0xCAFEBABEDEADBEEFull); - constexpr uint64_t tick_scale = 50; - this->emu().hook_instruction(x86_hookable_instructions::syscall, [&] { this->dispatcher.dispatch(*this); return instruction_hook_continuation::skip_instruction; @@ -445,8 +442,7 @@ void windows_emulator::setup_hooks() this->emu().hook_instruction(x86_hookable_instructions::rdtscp, [&] { this->callbacks.on_rdtscp(); - const uint64_t retired = this->executed_instructions_; - const uint64_t ticks = tsc_base + (retired * tick_scale); + const auto ticks = this->clock_->timestamp_counter(); this->emu().reg(x86_register::rax, static_cast(ticks)); this->emu().reg(x86_register::rdx, static_cast(ticks >> 32)); @@ -460,8 +456,7 @@ void windows_emulator::setup_hooks() this->emu().hook_instruction(x86_hookable_instructions::rdtsc, [&] { this->callbacks.on_rdtsc(); - const uint64_t retired = this->executed_instructions_; - const uint64_t ticks = tsc_base + (retired * tick_scale); + const auto ticks = this->clock_->timestamp_counter(); this->emu().reg(x86_register::rax, static_cast(ticks)); this->emu().reg(x86_register::rdx, static_cast(ticks >> 32)); diff --git a/src/windows-emulator/windows_emulator.hpp b/src/windows-emulator/windows_emulator.hpp index 720bec3b..86e2a0e2 100644 --- a/src/windows-emulator/windows_emulator.hpp +++ b/src/windows-emulator/windows_emulator.hpp @@ -225,11 +225,3 @@ class windows_emulator void register_factories(utils::buffer_deserializer& buffer); }; - -static inline uint64_t splitmix64(uint64_t x) noexcept -{ - x += 0x9E3779B97F4A7C15ull; - x = (x ^ (x >> 30)) * 0xBF58476D1CE4E5B9ull; - x = (x ^ (x >> 27)) * 0x94D049BB133111EBull; - return x ^ (x >> 31); -} \ No newline at end of file From 22df3e7889b41603fbc4c108e6d167d81e006558 Mon Sep 17 00:00:00 2001 From: CarlTSpeak Date: Fri, 24 Oct 2025 11:13:55 +0100 Subject: [PATCH 16/16] Fix format issue --- src/windows-emulator/syscalls/memory.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/windows-emulator/syscalls/memory.cpp b/src/windows-emulator/syscalls/memory.cpp index 403ba2a7..0b8e45c3 100644 --- a/src/windows-emulator/syscalls/memory.cpp +++ b/src/windows-emulator/syscalls/memory.cpp @@ -23,7 +23,9 @@ namespace syscalls if (base_address < MIN_ALLOCATION_ADDRESS || base_address >= MAX_ALLOCATION_END_EXCL) { if (return_length) + { return_length.write(0); + } return STATUS_INVALID_PARAMETER; }