From 7bf0b671670bc7519d0806934ab6ef1f11099853 Mon Sep 17 00:00:00 2001 From: RektInator <7003455+RektInator@users.noreply.github.com> Date: Mon, 14 Apr 2025 12:23:08 +0200 Subject: [PATCH] wip --- src/common/platform/file_management.hpp | 27 +++++++++---- src/common/platform/process.hpp | 21 +++++++---- src/windows-emulator/syscalls.cpp | 31 ++++++++++++++- src/windows-emulator/syscalls/exception.cpp | 14 +++++-- src/windows-emulator/syscalls/file.cpp | 42 +++++++++++++++++++++ src/windows-emulator/syscalls/memory.cpp | 6 +-- src/windows-emulator/syscalls/section.cpp | 24 +++++++----- src/windows-emulator/syscalls/thread.cpp | 6 +-- src/windows-emulator/syscalls/token.cpp | 18 +++++++++ 9 files changed, 153 insertions(+), 36 deletions(-) diff --git a/src/common/platform/file_management.hpp b/src/common/platform/file_management.hpp index bbef40df..13e53053 100644 --- a/src/common/platform/file_management.hpp +++ b/src/common/platform/file_management.hpp @@ -97,7 +97,7 @@ typedef enum _FSINFOCLASS FileFsMaximumInformation } FSINFOCLASS, *PFSINFOCLASS; -typedef enum _FSINFOCLASS FS_INFORMATION_CLASS; +using FS_INFORMATION_CLASS = enum _FSINFOCLASS; typedef enum _FILE_INFORMATION_CLASS { @@ -210,7 +210,7 @@ typedef enum _FILE_INFORMATION_CLASS FileMaximumInformation } FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS; -typedef enum _OBJECT_INFORMATION_CLASS +using OBJECT_INFORMATION_CLASS = enum _OBJECT_INFORMATION_CLASS { ObjectBasicInformation, // q: OBJECT_BASIC_INFORMATION ObjectNameInformation, // q: OBJECT_NAME_INFORMATION @@ -220,9 +220,9 @@ typedef enum _OBJECT_INFORMATION_CLASS ObjectSessionInformation, // s: void // change object session // (requires SeTcbPrivilege) ObjectSessionObjectInformation, // s: void // change object session // (requires SeTcbPrivilege) MaxObjectInfoClass -} OBJECT_INFORMATION_CLASS; +}; -typedef enum _HARDERROR_RESPONSE_OPTION +using HARDERROR_RESPONSE_OPTION = enum _HARDERROR_RESPONSE_OPTION { OptionAbortRetryIgnore, OptionOk, @@ -233,9 +233,9 @@ typedef enum _HARDERROR_RESPONSE_OPTION OptionShutdownSystem, OptionOkNoWait, OptionCancelTryContinue -} HARDERROR_RESPONSE_OPTION; +}; -typedef enum _HARDERROR_RESPONSE +using HARDERROR_RESPONSE = enum _HARDERROR_RESPONSE { ResponseReturnToCaller, ResponseNotHandled, @@ -248,9 +248,9 @@ typedef enum _HARDERROR_RESPONSE ResponseYes, ResponseTryAgain, ResponseContinue -} HARDERROR_RESPONSE; +}; -typedef USHORT RTL_ATOM; +using RTL_ATOM = USHORT; template struct IO_STATUS_BLOCK @@ -333,6 +333,17 @@ typedef struct _FILE_BASIC_INFORMATION ULONG FileAttributes; // Specifies one or more FILE_ATTRIBUTE_XXX flags. } FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION; +typedef struct _FILE_NETWORK_OPEN_INFORMATION +{ + LARGE_INTEGER CreationTime; + LARGE_INTEGER LastAccessTime; + LARGE_INTEGER LastWriteTime; + LARGE_INTEGER ChangeTime; + LARGE_INTEGER AllocationSize; + LARGE_INTEGER EndOfFile; + ULONG FileAttributes; +} FILE_NETWORK_OPEN_INFORMATION, *PFILE_NETWORK_OPEN_INFORMATION; + typedef struct _FILE_DIRECTORY_INFORMATION { ULONG NextEntryOffset; diff --git a/src/common/platform/process.hpp b/src/common/platform/process.hpp index cd512b9d..85b1a1a0 100644 --- a/src/common/platform/process.hpp +++ b/src/common/platform/process.hpp @@ -25,7 +25,7 @@ (CONTEXT_CONTROL_64 | CONTEXT_INTEGER_64 | CONTEXT_SEGMENTS_64 | CONTEXT_FLOATING_POINT_64 | \ CONTEXT_DEBUG_REGISTERS_64) -typedef enum _SYSTEM_INFORMATION_CLASS +using SYSTEM_INFORMATION_CLASS = enum _SYSTEM_INFORMATION_CLASS { SystemBasicInformation, // q: SYSTEM_BASIC_INFORMATION SystemProcessorInformation, // q: SYSTEM_PROCESSOR_INFORMATION @@ -323,7 +323,7 @@ typedef enum _SYSTEM_INFORMATION_CLASS SystemBreakOnContextUnwindFailureInformation, // ULONG (requires SeDebugPrivilege) SystemOslRamdiskInformation, // SYSTEM_OSL_RAMDISK_INFORMATION MaxSystemInfoClass -} SYSTEM_INFORMATION_CLASS; +}; #ifndef OS_WINDOWS typedef enum _TOKEN_INFORMATION_CLASS @@ -383,7 +383,7 @@ typedef enum _TOKEN_INFORMATION_CLASS #endif -typedef enum _PROCESSINFOCLASS +using PROCESSINFOCLASS = enum _PROCESSINFOCLASS { ProcessBasicInformation, // q: PROCESS_BASIC_INFORMATION, PROCESS_EXTENDED_BASIC_INFORMATION ProcessQuotaLimits, // qs: QUOTA_LIMITS, QUOTA_LIMITS_EX @@ -502,9 +502,9 @@ typedef enum _PROCESSINFOCLASS ProcessNetworkIoCounters, // q: PROCESS_NETWORK_COUNTERS ProcessFindFirstThreadByTebValue, // PROCESS_TEB_VALUE_INFORMATION MaxProcessInfoClass -} PROCESSINFOCLASS; +}; -typedef enum _PS_ATTRIBUTE_NUM +using PS_ATTRIBUTE_NUM = enum _PS_ATTRIBUTE_NUM { PsAttributeParentProcess, // in HANDLE PsAttributeDebugObject, // in HANDLE @@ -542,7 +542,7 @@ typedef enum _PS_ATTRIBUTE_NUM PsAttributeSupportedMachines, // since 24H2 PsAttributeSveVectorLength, // PPS_PROCESS_CREATION_SVE_VECTOR_LENGTH PsAttributeMax -} PS_ATTRIBUTE_NUM; +}; struct SYSTEM_PROCESSOR_INFORMATION64 { @@ -583,11 +583,11 @@ typedef struct _XMM_SAVE_AREA32 #endif -typedef struct _NEON128 +using NEON128 = struct _NEON128 { ULONGLONG Low; LONGLONG High; -} NEON128; +}; typedef struct DECLSPEC_ALIGN(16) _CONTEXT64 { @@ -768,6 +768,11 @@ struct TOKEN_USER64 SID_AND_ATTRIBUTES64 User; }; +struct TOKEN_OWNER64 +{ + EMULATOR_CAST(EmulatorTraits::PVOID, PSID) Owner; +}; + struct TOKEN_BNO_ISOLATION_INFORMATION64 { EmulatorTraits::PVOID IsolationPrefix; diff --git a/src/windows-emulator/syscalls.cpp b/src/windows-emulator/syscalls.cpp index 5ebaa267..7d65af2b 100644 --- a/src/windows-emulator/syscalls.cpp +++ b/src/windows-emulator/syscalls.cpp @@ -79,6 +79,9 @@ namespace syscalls NTSTATUS handle_NtQueryAttributesFile(const syscall_context& c, emulator_object>> object_attributes, emulator_object file_information); + NTSTATUS handle_NtQueryFullAttributesFile( + const syscall_context& c, emulator_object>> object_attributes, + emulator_object file_information); NTSTATUS handle_NtOpenFile(const syscall_context& c, emulator_object file_handle, ACCESS_MASK desired_access, emulator_object>> object_attributes, @@ -627,6 +630,29 @@ namespace syscalls { return 0; } + + NTSTATUS handle_NtCreateNamedPipeFile( + const syscall_context& c, const emulator_object file_handle, const ULONG desired_access, + const emulator_object>> object_attributes, + const emulator_object>> io_status_block, const ULONG share_access, + const ULONG create_disposition, const ULONG create_options, const ULONG named_pipe_type, const ULONG read_mode, + const ULONG completion_mode, const ULONG maximum_instances, const ULONG inbound_quota, + const ULONG outbound_quota, const emulator_object default_timeout) + { + file_handle.write(handle{.value = {.id = 1337, .type = handle_types::file, .is_pseudo = 1}}); + + return STATUS_SUCCESS; + } + + NTSTATUS handle_NtFsControlFile(const syscall_context& c, const handle event_handle, const uint64_t apc_routine, + const uint64_t app_context, + const emulator_object>> io_status_block, + const ULONG fs_control_code, const uint64_t input_buffer, + const ULONG input_buffer_length, const uint64_t output_buffer, + const ULONG output_buffer_length) + { + return STATUS_SUCCESS; + } } void syscall_dispatcher::add_handlers(std::map& handler_mapping) @@ -769,6 +795,9 @@ void syscall_dispatcher::add_handlers(std::map& ha add_handler(NtQueueApcThreadEx); add_handler(NtQueueApcThread); add_handler(NtCreateUserProcess); + add_handler(NtCreateNamedPipeFile); + add_handler(NtFsControlFile); + add_handler(NtQueryFullAttributesFile); #undef add_handler -} \ No newline at end of file +} diff --git a/src/windows-emulator/syscalls/exception.cpp b/src/windows-emulator/syscalls/exception.cpp index dcaebb91..34f8cf5c 100644 --- a/src/windows-emulator/syscalls/exception.cpp +++ b/src/windows-emulator/syscalls/exception.cpp @@ -24,10 +24,9 @@ namespace syscalls return STATUS_SUCCESS; } - NTSTATUS handle_NtRaiseException(const syscall_context& c, - const emulator_object>> - /*exception_record*/, - const emulator_object thread_context, const BOOLEAN handle_exception) + NTSTATUS handle_NtRaiseException( + const syscall_context& c, const emulator_object>> exception_record, + const emulator_object thread_context, const BOOLEAN handle_exception) { if (handle_exception) { @@ -36,6 +35,13 @@ namespace syscalls return STATUS_NOT_SUPPORTED; } + const auto& exception_data = exception_record.read(); + if (exception_data.ExceptionCode == 0xC0000602) // STATUS_FAIL_FAST_EXCEPTION + { + c.emu.stop(); + return STATUS_SUCCESS; + } + c.proc.exception_rip = thread_context.read().Rip; c.emu.stop(); diff --git a/src/windows-emulator/syscalls/file.cpp b/src/windows-emulator/syscalls/file.cpp index c2c675ef..0c4ad0d9 100644 --- a/src/windows-emulator/syscalls/file.cpp +++ b/src/windows-emulator/syscalls/file.cpp @@ -1,6 +1,7 @@ #include "../std_include.hpp" #include "../emulator_utils.hpp" #include "../syscall_utils.hpp" +#include "utils/io.hpp" #include #include @@ -660,6 +661,47 @@ namespace syscalls return STATUS_SUCCESS; } + NTSTATUS handle_NtQueryFullAttributesFile( + const syscall_context& c, const emulator_object>> object_attributes, + const emulator_object file_information) + { + if (!object_attributes) + { + return STATUS_INVALID_PARAMETER; + } + + const auto attributes = object_attributes.read(); + if (!attributes.ObjectName) + { + return STATUS_INVALID_PARAMETER; + } + + const auto filename = read_unicode_string( + c.emu, emulator_object>>{c.emu, attributes.ObjectName}); + + c.win_emu.log.print(color::dark_gray, "--> Querying file attributes: %s\n", u16_to_u8(filename).c_str()); + + const auto local_filename = c.win_emu.file_sys.translate(filename).string(); + + struct _stat64 file_stat{}; + if (_stat64(local_filename.c_str(), &file_stat) != 0) + { + return STATUS_OBJECT_NAME_NOT_FOUND; + } + + file_information.access([&](FILE_NETWORK_OPEN_INFORMATION& info) { + info.CreationTime = utils::convert_unix_to_windows_time(file_stat.st_atime); + info.LastAccessTime = utils::convert_unix_to_windows_time(file_stat.st_atime); + info.LastWriteTime = utils::convert_unix_to_windows_time(file_stat.st_mtime); + info.AllocationSize.QuadPart = file_stat.st_size; + info.EndOfFile.QuadPart = file_stat.st_size; + info.ChangeTime = info.LastWriteTime; + info.FileAttributes = FILE_ATTRIBUTE_NORMAL; + }); + + return STATUS_SUCCESS; + } + NTSTATUS handle_NtQueryAttributesFile( const syscall_context& c, const emulator_object>> object_attributes, const emulator_object file_information) diff --git a/src/windows-emulator/syscalls/memory.cpp b/src/windows-emulator/syscalls/memory.cpp index 0fa59202..ef714196 100644 --- a/src/windows-emulator/syscalls/memory.cpp +++ b/src/windows-emulator/syscalls/memory.cpp @@ -28,9 +28,9 @@ namespace syscalls return_length.write(sizeof(EMU_MEMORY_BASIC_INFORMATION64)); } - if (memory_information_length != sizeof(EMU_MEMORY_BASIC_INFORMATION64)) + if (memory_information_length < sizeof(EMU_MEMORY_BASIC_INFORMATION64)) { - return STATUS_BUFFER_OVERFLOW; + return STATUS_BUFFER_TOO_SMALL; } const emulator_object info{c.emu, memory_information}; @@ -198,7 +198,7 @@ namespace syscalls const bool reserve = allocation_type & MEM_RESERVE; const bool commit = allocation_type & MEM_COMMIT; - if ((allocation_type & ~(MEM_RESERVE | MEM_COMMIT | MEM_TOP_DOWN)) || (!commit && !reserve)) + if ((allocation_type & ~(MEM_RESERVE | MEM_COMMIT | MEM_TOP_DOWN | MEM_WRITE_WATCH)) || (!commit && !reserve)) { throw std::runtime_error("Unsupported allocation type!"); } diff --git a/src/windows-emulator/syscalls/section.cpp b/src/windows-emulator/syscalls/section.cpp index 5cf2cc3b..119874f2 100644 --- a/src/windows-emulator/syscalls/section.cpp +++ b/src/windows-emulator/syscalls/section.cpp @@ -109,7 +109,7 @@ namespace syscalls const syscall_context& c, const handle section_handle, const handle process_handle, const emulator_object base_address, const EMULATOR_CAST(EmulatorTraits::ULONG_PTR, ULONG_PTR) /*zero_bits*/, - const EMULATOR_CAST(EmulatorTraits::SIZE_T, SIZE_T) /*commit_size*/, + const EMULATOR_CAST(EmulatorTraits::SIZE_T, SIZE_T) commit_size, const emulator_object /*section_offset*/, const emulator_object::SIZE_T, SIZE_T)> view_size, const SECTION_INHERIT /*inherit_disposition*/, const ULONG /*allocation_type*/, const ULONG /*win32_protect*/) @@ -225,10 +225,11 @@ namespace syscalls size = page_align_up(file_data.size()); } + const auto reserve_only = section_entry->allocation_attributes == SEC_RESERVE; const auto protection = map_nt_to_emulator_protection(section_entry->section_page_protection); - const auto address = c.win_emu.memory.allocate_memory(size, protection); + const auto address = c.win_emu.memory.allocate_memory(size, protection, reserve_only); - if (!file_data.empty()) + if (!reserve_only && !file_data.empty()) { c.emu.write_memory(address, file_data.data(), file_data.size()); } @@ -263,19 +264,24 @@ namespace syscalls } const auto* mod = c.win_emu.mod_manager.find_by_address(base_address); - if (!mod) + if (mod != nullptr) { - c.win_emu.log.error("Unmapping non-module section not supported!\n"); - c.emu.stop(); - return STATUS_NOT_SUPPORTED; + if (c.win_emu.mod_manager.unmap(base_address, c.win_emu.log)) + { + return STATUS_SUCCESS; + } + + return STATUS_INVALID_PARAMETER; } - if (c.win_emu.mod_manager.unmap(base_address, c.win_emu.log)) + if (c.win_emu.memory.release_memory(base_address, 0)) { return STATUS_SUCCESS; } - return STATUS_INVALID_PARAMETER; + c.win_emu.log.error("Unmapping non-module/non-memory section not supported!\n"); + c.emu.stop(); + return STATUS_NOT_SUPPORTED; } NTSTATUS handle_NtUnmapViewOfSectionEx(const syscall_context& c, const handle process_handle, diff --git a/src/windows-emulator/syscalls/thread.cpp b/src/windows-emulator/syscalls/thread.cpp index 5a6b1f4c..70e442c5 100644 --- a/src/windows-emulator/syscalls/thread.cpp +++ b/src/windows-emulator/syscalls/thread.cpp @@ -578,8 +578,8 @@ namespace syscalls if (apc_flags) { c.win_emu.log.error("Unsupported APC flags: %X\n", apc_flags); - c.emu.stop(); - return STATUS_NOT_SUPPORTED; + // c.emu.stop(); + // return STATUS_NOT_SUPPORTED; } thread->pending_apcs.push_back({ @@ -590,7 +590,7 @@ namespace syscalls .apc_argument3 = apc_argument3, }); - return STATUS_NOT_SUPPORTED; + return STATUS_SUCCESS; } NTSTATUS handle_NtQueueApcThreadEx(const syscall_context& c, const handle thread_handle, diff --git a/src/windows-emulator/syscalls/token.cpp b/src/windows-emulator/syscalls/token.cpp index 70dbe135..52857c72 100644 --- a/src/windows-emulator/syscalls/token.cpp +++ b/src/windows-emulator/syscalls/token.cpp @@ -75,6 +75,24 @@ namespace syscalls return STATUS_SUCCESS; } + if (token_information_class == TokenOwner) + { + constexpr auto required_size = sizeof(sid) + sizeof(TOKEN_OWNER64); + return_length.write(required_size); + + if (required_size > token_information_length) + { + return STATUS_BUFFER_TOO_SMALL; + } + + TOKEN_OWNER64 owner{}; + owner.Owner = token_information + sizeof(TOKEN_OWNER64); + + emulator_object{c.emu, token_information}.write(owner); + c.emu.write_memory(token_information + sizeof(TOKEN_OWNER64), sid, sizeof(sid)); + return STATUS_SUCCESS; + } + if (token_information_class == TokenType) { constexpr auto required_size = sizeof(TOKEN_TYPE);