diff --git a/src/common/platform/file_management.hpp b/src/common/platform/file_management.hpp index 59780332..a324a744 100644 --- a/src/common/platform/file_management.hpp +++ b/src/common/platform/file_management.hpp @@ -319,6 +319,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; @@ -330,6 +338,24 @@ 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; + +#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; @@ -423,11 +449,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/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/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/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); + } } } diff --git a/src/windows-emulator/emulator_thread.cpp b/src/windows-emulator/emulator_thread.cpp index 4c7b541d..7e578c05 100644 --- a/src/windows-emulator/emulator_thread.cpp +++ b/src/windows-emulator/emulator_thread.cpp @@ -207,7 +207,10 @@ emulator_thread::emulator_thread(memory_manager& memory, const process_context& teb_obj.NtTib.StackBase = wow64_cpureserved_base; teb_obj.NtTib.Self = this->teb64->value(); teb_obj.CurrentLocale = 0x409; + teb_obj.ProcessEnvironmentBlock = context.peb64.value(); + teb_obj.StaticUnicodeString.MaximumLength = sizeof(teb_obj.StaticUnicodeBuffer); + teb_obj.StaticUnicodeString.Buffer = this->teb64->value() + offsetof(TEB64, StaticUnicodeBuffer); // Set WowTebOffset to point to 32-bit TEB offset teb_obj.WowTebOffset = static_cast(wow_teb_offset); // 0x2000 diff --git a/src/windows-emulator/memory_manager.cpp b/src/windows-emulator/memory_manager.cpp index 47a15357..2b91105f 100644 --- a/src/windows-emulator/memory_manager.cpp +++ b/src/windows-emulator/memory_manager.cpp @@ -490,7 +490,7 @@ uint64_t memory_manager::find_free_allocation_base(const size_t size, const uint // Since reserved_regions_ is a sorted map, we can iterate through it // and find gaps between regions - while (start_address + size <= MAX_ALLOCATION_ADDRESS) + while (start_address + size <= MAX_ALLOCATION_END_EXCL) { bool conflict = false; @@ -530,7 +530,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 = {}; @@ -555,7 +555,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 fd30198a..44900aba 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; constexpr auto DEFAULT_ALLOCATION_ADDRESS_64BIT = 0x100000000ULL; constexpr auto DEFAULT_ALLOCATION_ADDRESS_32BIT = 0x10000ULL; 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/module/mapped_module.hpp b/src/windows-emulator/module/mapped_module.hpp index e2fae9ce..3eac1ded 100644 --- a/src/windows-emulator/module/mapped_module.hpp +++ b/src/windows-emulator/module/mapped_module.hpp @@ -54,7 +54,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 89b4f2b2..cd92f66f 100644 --- a/src/windows-emulator/module/module_manager.cpp +++ b/src/windows-emulator/module/module_manager.cpp @@ -211,6 +211,7 @@ mapped_module* module_manager::map_module_core(const pe_detection_result& detect 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(); // TODO: Patch shell32.dll entry point to prevent TLS storage issues // The shell32.dll module in SysWOW64 has TLS storage that fails, causing crashes @@ -409,6 +410,7 @@ void module_manager::install_wow64_heaven_gate(const logger& logger) module.sections.emplace_back(std::move(section)); this->modules_.emplace(module.image_base, std::move(module)); + this->last_module_cache_ = this->modules_.end(); } } @@ -521,6 +523,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(); @@ -559,6 +562,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 045563a0..5490e14d 100644 --- a/src/windows-emulator/module/module_manager.hpp +++ b/src/windows-emulator/module/module_manager.hpp @@ -173,6 +173,7 @@ class module_manager callbacks* callbacks_{}; module_map modules_{}; + mutable module_map::iterator last_module_cache_{modules_.end()}; // Strategy pattern components mapping_strategy_factory strategy_factory_; @@ -198,6 +199,11 @@ class module_manager 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(); @@ -213,6 +219,7 @@ class module_manager if (upper_bound->second.contains(address)) { + last_module_cache_ = upper_bound; return upper_bound; } 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) diff --git a/src/windows-emulator/syscalls.cpp b/src/windows-emulator/syscalls.cpp index a1895dc7..8e7e1e10 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, @@ -920,32 +921,78 @@ 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 = 0; - 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; } + 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 || mode_num == 0)) + { + 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 STATUS_SUCCESS; + } + } + + return STATUS_UNSUCCESSFUL; + } + NTSTATUS handle_NtAssociateWaitCompletionPacket() { return STATUS_SUCCESS; @@ -1142,6 +1189,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); @@ -1165,6 +1213,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/file.cpp b/src/windows-emulator/syscalls/file.cpp index aa21a590..79b88a60 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; + constexpr auto name = u"NTFS"sv; + 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); } @@ -211,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(), }); } @@ -232,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(), }); }); @@ -537,12 +547,68 @@ 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 == 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); } - 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); diff --git a/src/windows-emulator/syscalls/memory.cpp b/src/windows-emulator/syscalls/memory.cpp index a727101c..0b8e45c3 100644 --- a/src/windows-emulator/syscalls/memory.cpp +++ b/src/windows-emulator/syscalls/memory.cpp @@ -20,6 +20,15 @@ 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/syscalls/object.cpp b/src/windows-emulator/syscalls/object.cpp index 4c0e6d5e..99b77746 100644 --- a/src/windows-emulator/syscalls/object.cpp +++ b/src/windows-emulator/syscalls/object.cpp @@ -434,4 +434,9 @@ namespace syscalls return STATUS_SUCCESS; } + + NTSTATUS handle_NtSetSecurityObject() + { + return STATUS_SUCCESS; + } } diff --git a/src/windows-emulator/windows_emulator.cpp b/src/windows-emulator/windows_emulator.cpp index 7d6c7a04..2598b5ed 100644 --- a/src/windows-emulator/windows_emulator.cpp +++ b/src/windows-emulator/windows_emulator.cpp @@ -448,8 +448,8 @@ void windows_emulator::setup_hooks() 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); + 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 @@ -462,8 +462,8 @@ void windows_emulator::setup_hooks() 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); + 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; });