// SPDX-License-Identifier: GPL-2.0 OR GPL-3.0
/*
* Copyright (C) 2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
*/
#include <windows.h>
#include <tlhelp32.h>
HANDLE CreateFileAsSystemW(
LPCWSTR lpFileName,
DWORD dwDesiredAccess,
DWORD dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreationDisposition,
DWORD dwFlagsAndAttributes,
HANDLE hTemplateFile
) {
HANDLE thread_token, process_snapshot, winlogon_process, winlogon_token, duplicated_token, file_handle;
PROCESSENTRY32 entry = { .dwSize = sizeof(PROCESSENTRY32) };
BOOL ret;
DWORD pid = 0;
TOKEN_PRIVILEGES privileges = {
.PrivilegeCount = 1,
.Privileges = {{ .Attributes = SE_PRIVILEGE_ENABLED }}
};
if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &privileges.Privileges[0].Luid))
return INVALID_HANDLE_VALUE;
if (!ImpersonateSelf(SecurityImpersonation))
return INVALID_HANDLE_VALUE;
if (!OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES, FALSE, &thread_token)) {
RevertToSelf();
return INVALID_HANDLE_VALUE;
}
if (!AdjustTokenPrivileges(thread_token, FALSE, &privileges, sizeof(privileges), NULL, NULL)) {
CloseHandle(thread_token);
RevertToSelf();
return INVALID_HANDLE_VALUE;
}
CloseHandle(thread_token);
process_snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (process_snapshot == INVALID_HANDLE_VALUE) {
RevertToSelf();
return INVALID_HANDLE_VALUE;
}
for (ret = Process32First(process_snapshot, &entry); ret; ret = Process32Next(process_snapshot, &entry)) {
if (!_stricmp(entry.szExeFile, "winlogon.exe")) {
pid = entry.th32ProcessID;
break;
}
}
CloseHandle(process_snapshot);
if (!pid) {
RevertToSelf();
return INVALID_HANDLE_VALUE;
}
winlogon_process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
if (!winlogon_process) {
RevertToSelf();
return INVALID_HANDLE_VALUE;
}
if (!OpenProcessToken(winlogon_process, TOKEN_IMPERSONATE | TOKEN_DUPLICATE, &winlogon_token)) {
CloseHandle(winlogon_process);
RevertToSelf();
return INVALID_HANDLE_VALUE;
}
CloseHandle(winlogon_process);
if (!DuplicateToken(winlogon_token, SecurityImpersonation, &duplicated_token)) {
CloseHandle(winlogon_token);
RevertToSelf();
return INVALID_HANDLE_VALUE;
}
CloseHandle(winlogon_token);
if (!SetThreadToken(NULL, duplicated_token)) {
CloseHandle(duplicated_token);
RevertToSelf();
return INVALID_HANDLE_VALUE;
}
CloseHandle(duplicated_token);
file_handle = CreateFileW(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
RevertToSelf();
return file_handle;
}