From 1421550764970269d9313b2c810caaa2b8ae0841 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Sun, 15 Jun 2025 09:21:39 +0200 Subject: [PATCH] Cleanup and fix NtQueryInformationProcess --- src/common/platform/primitives.hpp | 1 + src/windows-emulator/syscall_utils.hpp | 15 +- src/windows-emulator/syscalls/process.cpp | 281 +++++++--------------- 3 files changed, 98 insertions(+), 199 deletions(-) diff --git a/src/common/platform/primitives.hpp b/src/common/platform/primitives.hpp index 419e61d9..9fcfa316 100644 --- a/src/common/platform/primitives.hpp +++ b/src/common/platform/primitives.hpp @@ -69,5 +69,6 @@ using USHORT = WORD; static_assert(sizeof(DWORD) == 4); static_assert(sizeof(ULONG) == 4); static_assert(sizeof(int) == 4); +static_assert(sizeof(BOOLEAN) == 1); // NOLINTEND(modernize-use-using) diff --git a/src/windows-emulator/syscall_utils.hpp b/src/windows-emulator/syscall_utils.hpp index 086a4741..347d8269 100644 --- a/src/windows-emulator/syscall_utils.hpp +++ b/src/windows-emulator/syscall_utils.hpp @@ -210,11 +210,22 @@ NTSTATUS handle_query_internal(x86_64_emulator& emu, const uint64_t buffer, cons } ResponseType obj{}; - action(obj); + NTSTATUS result = STATUS_SUCCESS; + + using action_result = std::invoke_result_t; + + if constexpr (std::is_same_v) + { + result = action(obj); + } + else + { + action(obj); + } emu.write_memory(buffer, obj); - return STATUS_SUCCESS; + return result; } template diff --git a/src/windows-emulator/syscalls/process.cpp b/src/windows-emulator/syscalls/process.cpp index 3c830b3b..4ccc227c 100644 --- a/src/windows-emulator/syscalls/process.cpp +++ b/src/windows-emulator/syscalls/process.cpp @@ -16,211 +16,96 @@ namespace syscalls return STATUS_NOT_SUPPORTED; } - if (info_class == ProcessImageInformation) - { - if (return_length) - { - return_length.write(sizeof(SECTION_IMAGE_INFORMATION>)); - } - - if (process_information_length != sizeof(SECTION_IMAGE_INFORMATION>)) - { - return STATUS_BUFFER_OVERFLOW; - } - - const emulator_object>> info{c.emu, process_information}; - info.access([&](SECTION_IMAGE_INFORMATION>& i) { - const auto& mod = *c.win_emu.mod_manager.executable; - - const emulator_object dos_header_obj{c.emu, mod.image_base}; - const auto dos_header = dos_header_obj.read(); - - const emulator_object> nt_headers_obj{c.emu, - mod.image_base + dos_header.e_lfanew}; - const auto nt_headers = nt_headers_obj.read(); - - const auto& file_header = nt_headers.FileHeader; - const auto& optional_header = nt_headers.OptionalHeader; - - i.TransferAddress = 0; - i.MaximumStackSize = optional_header.SizeOfStackReserve; - i.CommittedStackSize = optional_header.SizeOfStackCommit; - i.SubSystemType = optional_header.Subsystem; - i.SubSystemMajorVersion = optional_header.MajorSubsystemVersion; - i.SubSystemMinorVersion = optional_header.MinorSubsystemVersion; - i.MajorOperatingSystemVersion = optional_header.MajorOperatingSystemVersion; - i.MinorOperatingSystemVersion = optional_header.MinorOperatingSystemVersion; - i.ImageCharacteristics = file_header.Characteristics; - i.DllCharacteristics = optional_header.DllCharacteristics; - i.Machine = file_header.Machine; - i.ImageContainsCode = TRUE; - i.ImageFlags = 0; // TODO - i.ImageFileSize = optional_header.SizeOfImage; - i.LoaderFlags = optional_header.LoaderFlags; - i.CheckSum = optional_header.CheckSum; - }); - - return STATUS_SUCCESS; - } - - if (info_class == ProcessCookie) - { - if (return_length) - { - return_length.write(sizeof(uint32_t)); - } - - if (process_information_length != sizeof(uint32_t)) - { - return STATUS_BUFFER_OVERFLOW; - } - - const emulator_object info{c.emu, process_information}; - info.write(0x01234567); - - return STATUS_SUCCESS; - } - - if (info_class == ProcessDebugPort) - { - if (return_length) - { - return_length.write(sizeof(EmulatorTraits::PVOID)); - } - - if (process_information_length != sizeof(EmulatorTraits::PVOID)) - { - return STATUS_BUFFER_OVERFLOW; - } - - const emulator_object::PVOID> info{c.emu, process_information}; - info.write(0); - - return STATUS_SUCCESS; - } - - if (info_class == ProcessDefaultHardErrorMode || info_class == ProcessWx86Information || - info_class == ProcessDebugFlags) - { - if (return_length) - { - return_length.write(sizeof(ULONG)); - } - - if (process_information_length != sizeof(ULONG)) - { - return STATUS_BUFFER_OVERFLOW; - } - - const emulator_object info{c.emu, process_information}; - info.write(info_class == ProcessDebugFlags ? 1 : 0); - - return STATUS_SUCCESS; - } - - if (info_class == ProcessDeviceMap) - { - c.win_emu.log.info("Handling ProcessDeviceMap request.\n"); - - if (return_length) - { - return_length.write(sizeof(EmulatorTraits::PVOID)); - } - - if (process_information_length != sizeof(EmulatorTraits::PVOID)) - { - return STATUS_BUFFER_OVERFLOW; - } - - const emulator_object::PVOID> info{c.emu, process_information}; - info.write(0); // NULL pointer - - return STATUS_SUCCESS; - } - - if (info_class == ProcessEnableAlignmentFaultFixup) - { - if (return_length) - { - return_length.write(sizeof(BOOLEAN)); - } - - if (process_information_length != sizeof(BOOLEAN)) - { - return STATUS_BUFFER_OVERFLOW; - } - - const emulator_object info{c.emu, process_information}; - info.write(FALSE); // Alignment fault fixup is disabled - - return STATUS_SUCCESS; - } - - if (info_class == ProcessDebugObjectHandle) - { - if (process_information_length != sizeof(handle)) - { - return STATUS_BUFFER_OVERFLOW; - } - - const emulator_object info{c.emu, process_information}; - info.write(NULL_HANDLE); - - if (return_length) - { - return_length.write(sizeof(handle)); - } - - return STATUS_PORT_NOT_SET; - } - - if (info_class == ProcessEnclaveInformation || info_class == ProcessMitigationPolicy || - info_class == ProcessGroupInformation) + switch (info_class) { + case ProcessGroupInformation: + case ProcessMitigationPolicy: + case ProcessEnclaveInformation: return STATUS_NOT_SUPPORTED; - } - if (info_class == ProcessTimes) - { - if (return_length) - { - return_length.write(sizeof(KERNEL_USER_TIMES)); - } + case ProcessTimes: + return handle_query(c.emu, process_information, process_information_length, + return_length, [](KERNEL_USER_TIMES& t) { + t = {}; // + }); - if (process_information_length != sizeof(KERNEL_USER_TIMES)) - { - return STATUS_BUFFER_OVERFLOW; - } + case ProcessCookie: + return handle_query(c.emu, process_information, process_information_length, return_length, + [](uint32_t& cookie) { + cookie = 0x01234567; // + }); - const emulator_object info{c.emu, process_information}; - info.write(KERNEL_USER_TIMES{}); + case ProcessDebugObjectHandle: + return handle_query(c.emu, process_information, process_information_length, return_length, + [](handle& h) { + h = NULL_HANDLE; + return STATUS_PORT_NOT_SET; + }); - return STATUS_SUCCESS; - } + case ProcessDebugFlags: + case ProcessWx86Information: + case ProcessDefaultHardErrorMode: + return handle_query(c.emu, process_information, process_information_length, return_length, + [&](ULONG& res) { + res = (info_class == ProcessDebugFlags ? 1 : 0); // + }); - if (info_class == ProcessBasicInformation) - { - if (return_length) - { - return_length.write(sizeof(PROCESS_BASIC_INFORMATION64)); - } + case ProcessDebugPort: + case ProcessDeviceMap: + return handle_query::PVOID>(c.emu, process_information, process_information_length, + return_length, [](EmulatorTraits::PVOID& ptr) { + ptr = 0; // + }); - if (process_information_length != sizeof(PROCESS_BASIC_INFORMATION64)) - { - return STATUS_BUFFER_OVERFLOW; - } + case ProcessEnableAlignmentFaultFixup: + return handle_query(c.emu, process_information, process_information_length, return_length, + [](BOOLEAN& b) { + b = FALSE; // + }); - const emulator_object info{c.emu, process_information}; - info.access([&](PROCESS_BASIC_INFORMATION64& basic_info) { - basic_info.PebBaseAddress = c.proc.peb.value(); - basic_info.UniqueProcessId = 1; - }); + case ProcessBasicInformation: + return handle_query(c.emu, process_information, process_information_length, + return_length, + [&](PROCESS_BASIC_INFORMATION64& basic_info) { + basic_info.PebBaseAddress = c.proc.peb.value(); + basic_info.UniqueProcessId = 1; + }); - return STATUS_SUCCESS; - } + case ProcessImageInformation: + return handle_query>>( + c.emu, process_information, process_information_length, return_length, + [&](SECTION_IMAGE_INFORMATION>& i) { + const auto& mod = *c.win_emu.mod_manager.executable; - if (info_class == ProcessImageFileNameWin32) - { + const emulator_object dos_header_obj{c.emu, mod.image_base}; + const auto dos_header = dos_header_obj.read(); + + const emulator_object> nt_headers_obj{c.emu, + mod.image_base + dos_header.e_lfanew}; + const auto nt_headers = nt_headers_obj.read(); + + const auto& file_header = nt_headers.FileHeader; + const auto& optional_header = nt_headers.OptionalHeader; + + i.TransferAddress = 0; + i.MaximumStackSize = optional_header.SizeOfStackReserve; + i.CommittedStackSize = optional_header.SizeOfStackCommit; + i.SubSystemType = optional_header.Subsystem; + i.SubSystemMajorVersion = optional_header.MajorSubsystemVersion; + i.SubSystemMinorVersion = optional_header.MinorSubsystemVersion; + i.MajorOperatingSystemVersion = optional_header.MajorOperatingSystemVersion; + i.MinorOperatingSystemVersion = optional_header.MinorOperatingSystemVersion; + i.ImageCharacteristics = file_header.Characteristics; + i.DllCharacteristics = optional_header.DllCharacteristics; + i.Machine = file_header.Machine; + i.ImageContainsCode = TRUE; + i.ImageFlags = 0; // TODO + i.ImageFileSize = optional_header.SizeOfImage; + i.LoaderFlags = optional_header.LoaderFlags; + i.CheckSum = optional_header.CheckSum; + }); + + case ProcessImageFileNameWin32: { const auto peb = c.proc.peb.read(); emulator_object proc_params{c.emu, peb.ProcessParameters}; const auto params = proc_params.read(); @@ -250,10 +135,12 @@ namespace syscalls return STATUS_SUCCESS; } - c.win_emu.log.error("Unsupported process info class: %X\n", info_class); - c.emu.stop(); + default: + c.win_emu.log.error("Unsupported process info class: %X\n", info_class); + c.emu.stop(); - return STATUS_NOT_SUPPORTED; + return STATUS_NOT_SUPPORTED; + } } NTSTATUS handle_NtSetInformationProcess(const syscall_context& c, const handle process_handle,