InitSystem (Windows): adds support

Note: Windows doesn't have a unix-like init system process, but it does have the first userland process, which is `smss.exe`
This commit is contained in:
李通洲
2026-07-14 14:36:20 +08:00
parent a0fd59d869
commit 7dcc7d40d5
2 changed files with 39 additions and 1 deletions
+1 -1
View File
@@ -1123,7 +1123,7 @@ elseif(WIN32)
src/detection/gpu/gpu_windows.cpp
src/detection/host/host_windows.c
src/detection/icons/icons_windows.c
src/detection/initsystem/initsystem_nosupport.c
src/detection/initsystem/initsystem_windows.c
src/detection/keyboard/keyboard_windows.c
src/detection/libc/libc_windows.cpp
src/detection/lm/lm_nosupport.c
@@ -0,0 +1,38 @@
#include "initsystem.h"
#include "common/windows/unicode.h"
#include "common/windows/nt.h"
#include "common/windows/version.h"
#include <ntstatus.h>
#include <winternl.h>
#include <wchar.h>
const char* ffDetectInitSystem(FFInitSystemResult* result) {
// We only need to find the first user process, so 1024 entries should be enough
SYSTEM_PROCESS_INFORMATION buffer[1024] = {};
ULONG size = sizeof(buffer);
NTSTATUS status = NtQuerySystemInformation(SystemProcessInformation, buffer, size, &size);
if (status != STATUS_INFO_LENGTH_MISMATCH && !NT_SUCCESS(status)) {
return "NtQuerySystemInformation(SystemProcessInformation) failed";
}
for (SYSTEM_PROCESS_INFORMATION* ptr = buffer; ; ptr = (SYSTEM_PROCESS_INFORMATION*) ((uint8_t*) ptr + ptr->NextEntryOffset)) {
assert(ptr >= buffer && (uint8_t*) ptr < (uint8_t*) buffer + size);
uint16_t len = ptr->ImageName.Length / sizeof(*ptr->ImageName.Buffer);
if (ptr->InheritedFromUniqueProcessId == (HANDLE)(uintptr_t) 4 /* System */ &&
len > 4 && _wcsnicmp(ptr->ImageName.Buffer + len - 4, L".exe", 4) == 0) { // smss.exe
result->pid = (uint32_t)(uintptr_t) ptr->UniqueProcessId;
// We have no permission to open the process for querying the full information
wchar_t exePath[MAX_PATH];
_snwprintf(exePath, ARRAY_SIZE(exePath), L"%ls\\system32\\%.*ls", (const wchar_t*) SharedUserData->NtSystemRoot, len, ptr->ImageName.Buffer);
ffGetFileVersion(exePath, NULL, &result->version);
ffStrbufSetWS(&result->exe, exePath);
ffStrbufSetNWS(&result->name, len - 4, ptr->ImageName.Buffer);
return nullptr;
}
// The last process in the list always has a NextEntryOffset of 0, even if the buffer was truncated.
if (!ptr->NextEntryOffset) {
return "Could not find init system process";
}
}
}