diff --git a/src/common/platform/file_management.hpp b/src/common/platform/file_management.hpp index bbef40df..60097940 100644 --- a/src/common/platform/file_management.hpp +++ b/src/common/platform/file_management.hpp @@ -73,6 +73,7 @@ #define SL_NO_CURSOR_UPDATE 0x10 #define SEC_IMAGE 0x01000000 +#define SEC_RESERVE 0x04000000 typedef enum _FSINFOCLASS { @@ -97,7 +98,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 +211,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 +221,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 +234,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 +249,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 +334,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..bf18f69c 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, @@ -93,6 +96,19 @@ namespace syscalls NTSTATUS handle_NtQuerySymbolicLinkObject(const syscall_context& c, handle link_handle, emulator_object>> link_target, emulator_object returned_length); + NTSTATUS handle_NtCreateNamedPipeFile(const syscall_context& c, emulator_object file_handle, + ULONG desired_access, + emulator_object>> object_attributes, + emulator_object>> io_status_block, + ULONG share_access, ULONG create_disposition, ULONG create_options, + ULONG named_pipe_type, ULONG read_mode, ULONG completion_mode, + ULONG maximum_instances, ULONG inbound_quota, ULONG outbound_quota, + emulator_object default_timeout); + NTSTATUS handle_NtFsControlFile(const syscall_context& c, handle event_handle, uint64_t apc_routine, + uint64_t app_context, + emulator_object>> io_status_block, + ULONG fs_control_code, uint64_t input_buffer, ULONG input_buffer_length, + uint64_t output_buffer, ULONG output_buffer_length); // syscalls/locale.cpp: NTSTATUS handle_NtInitializeNlsFiles(const syscall_context& c, emulator_object base_address, @@ -109,7 +125,7 @@ namespace syscalls // syscalls/memory.cpp: NTSTATUS handle_NtQueryVirtualMemory(const syscall_context& c, handle process_handle, uint64_t base_address, uint32_t info_class, uint64_t memory_information, - uint32_t memory_information_length, emulator_object return_length); + uint64_t memory_information_length, emulator_object return_length); NTSTATUS handle_NtProtectVirtualMemory(const syscall_context& c, handle process_handle, emulator_object base_address, emulator_object bytes_to_protect, uint32_t protection, @@ -769,6 +785,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..42362bc3 100644 --- a/src/windows-emulator/syscalls/exception.cpp +++ b/src/windows-emulator/syscalls/exception.cpp @@ -24,10 +24,10 @@ 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) { diff --git a/src/windows-emulator/syscalls/file.cpp b/src/windows-emulator/syscalls/file.cpp index c2c675ef..0cad972c 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) @@ -778,4 +820,32 @@ namespace syscalls return STATUS_NOT_SUPPORTED; } + + 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*/) + { + c.win_emu.log.error("Unimplemented syscall NtCreateNamedPipeFile!"); + c.emu.stop(); + + return STATUS_NOT_SUPPORTED; + } + + 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*/) + { + c.win_emu.log.error("Unimplemented syscall NtFsControlFile!"); + c.emu.stop(); + + return STATUS_NOT_SUPPORTED; + } } \ No newline at end of file diff --git a/src/windows-emulator/syscalls/memory.cpp b/src/windows-emulator/syscalls/memory.cpp index 0fa59202..7e12521d 100644 --- a/src/windows-emulator/syscalls/memory.cpp +++ b/src/windows-emulator/syscalls/memory.cpp @@ -8,8 +8,8 @@ namespace syscalls { NTSTATUS handle_NtQueryVirtualMemory(const syscall_context& c, const handle process_handle, const uint64_t base_address, const uint32_t info_class, - const uint64_t memory_information, const uint32_t memory_information_length, - const emulator_object return_length) + const uint64_t memory_information, const uint64_t memory_information_length, + const emulator_object return_length) { if (process_handle != CURRENT_PROCESS) { @@ -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..415206dd 100644 --- a/src/windows-emulator/syscalls/section.cpp +++ b/src/windows-emulator/syscalls/section.cpp @@ -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..3cc470a7 100644 --- a/src/windows-emulator/syscalls/thread.cpp +++ b/src/windows-emulator/syscalls/thread.cpp @@ -577,9 +577,9 @@ 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.win_emu.log.warn("Unsupported APC flags: %X\n", apc_flags); + // 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);