mirror of
https://github.com/BeneficialCode/WinArk.git
synced 2026-10-17 04:40:35 +08:00
Run the WInArk under System account.
This commit is contained in:
+23
-3
@@ -239,7 +239,11 @@ void CMainFrame::InitDriverInterface() {
|
||||
if (!DriverHelper::IsDriverLoaded()) {
|
||||
if (!SecurityHelper::IsRunningElevated()) {
|
||||
if (AtlMessageBox(nullptr, L"Kernel Driver not loaded. Some functionality will not be available. Install?", IDS_TITLE, MB_YESNO | MB_ICONQUESTION) == IDYES) {
|
||||
if (!SecurityHelper::RunElevated(L"install", false)) {
|
||||
if (SecurityHelper::IsSysRun()) {
|
||||
if(!SecurityHelper::SysRun(L"install"))
|
||||
AtlMessageBox(*this, L"Error running driver installer", IDS_TITLE, MB_ICONERROR);
|
||||
}
|
||||
else if (!SecurityHelper::RunElevated(L"install", false)) {
|
||||
AtlMessageBox(*this, L"Error running driver installer", IDS_TITLE, MB_ICONERROR);
|
||||
}
|
||||
}
|
||||
@@ -261,7 +265,12 @@ void CMainFrame::InitDriverInterface() {
|
||||
}
|
||||
else {
|
||||
DriverHelper::CloseDevice();
|
||||
SecurityHelper::RunElevated(L"update", false);
|
||||
if (SecurityHelper::IsSysRun()) {
|
||||
if (!SecurityHelper::SysRun(L"update"))
|
||||
AtlMessageBox(*this, L"Error update driver service", IDS_TITLE, MB_ICONERROR);
|
||||
}
|
||||
else
|
||||
SecurityHelper::RunElevated(L"update", false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -310,6 +319,12 @@ void CMainFrame::InitConfigView() {
|
||||
}
|
||||
|
||||
LRESULT CMainFrame::OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) {
|
||||
if (SecurityHelper::EnablePrivilege(SE_DEBUG_NAME, true)) {
|
||||
if (!SecurityHelper::IsSysRun()) {
|
||||
if (SecurityHelper::SysRun(L"runas"))
|
||||
SendMessage(WM_CLOSE);
|
||||
}
|
||||
}
|
||||
LoadSettings();
|
||||
CreateSimpleReBar(ATL_SIMPLE_REBAR_NOBORDER_STYLE);
|
||||
|
||||
@@ -319,7 +334,11 @@ LRESULT CMainFrame::OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/
|
||||
hMenu.GetSubMenu(0).DeleteMenu(ID_FILE_RUNASADMIN, MF_BYCOMMAND);
|
||||
CString text;
|
||||
GetWindowText(text);
|
||||
SetWindowText(text + L" (Administrator)");
|
||||
CString append = L" (Administrator)";
|
||||
if (SecurityHelper::IsSysRun()) {
|
||||
append = L" (System)";
|
||||
}
|
||||
SetWindowText(text + append);
|
||||
}
|
||||
|
||||
UIAddMenu(hMenu);
|
||||
@@ -410,6 +429,7 @@ LRESULT CMainFrame::OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/
|
||||
pLoop->AddIdleHandler(this);
|
||||
|
||||
InitDriverInterface();
|
||||
|
||||
InitProcessTable();
|
||||
InitNetworkTable();
|
||||
InitKernelModuleTable();
|
||||
|
||||
+7
-4
@@ -15,6 +15,7 @@
|
||||
#include <Helpers.h>
|
||||
#include "SymbolHelper.h"
|
||||
|
||||
|
||||
CAppModule _Module;
|
||||
HWND _hMainWnd;
|
||||
AppSettings _Settings;
|
||||
@@ -215,10 +216,12 @@ LONG WINAPI SelfUnhandledExceptionFilter(EXCEPTION_POINTERS* ExceptionInfo)
|
||||
|
||||
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR lpstrCmdLine, int nCmdShow) {
|
||||
g_hSingleInstMutex = ::CreateMutex(nullptr, FALSE, L"WinArkSingleInstanceMutex");
|
||||
if (g_hSingleInstMutex) {
|
||||
if (::GetLastError() == ERROR_ALREADY_EXISTS) {
|
||||
MessageBox(nullptr, L"请勿重复启动!!!", L"Error", MB_ICONERROR);
|
||||
return -1;
|
||||
if (!::wcsstr(lpstrCmdLine, L"runas")) {
|
||||
if (g_hSingleInstMutex) {
|
||||
if (::GetLastError() == ERROR_ALREADY_EXISTS) {
|
||||
MessageBox(nullptr, L"请勿重复启动!!!", L"Error", MB_ICONERROR);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
HRESULT hRes = ::CoInitializeEx(nullptr,COINIT_APARTMENTTHREADED|COINIT_DISABLE_OLE1DDE);
|
||||
|
||||
@@ -3,6 +3,34 @@
|
||||
#include <sddl.h>
|
||||
#include <shellapi.h>
|
||||
#include "DriverHelper.h"
|
||||
#include <WtsApi32.h>
|
||||
#include <WinBase.h>
|
||||
|
||||
#pragma comment(lib,"wtsapi32")
|
||||
|
||||
bool SecurityHelper::IsSysRun() {
|
||||
static bool runningSystem = false;
|
||||
static bool runningSystemCheck = false;
|
||||
if (runningSystemCheck)
|
||||
return runningSystem;
|
||||
|
||||
runningSystemCheck = true;
|
||||
wil::unique_handle hToken;
|
||||
if (!::OpenProcessToken(::GetCurrentProcess(), TOKEN_QUERY, hToken.addressof()))
|
||||
return false;
|
||||
|
||||
BYTE buffer[128];
|
||||
DWORD len;
|
||||
if (::GetTokenInformation(hToken.get(), TokenUser, &buffer, sizeof(buffer), &len)) {
|
||||
auto user = reinterpret_cast<TOKEN_USER*>(buffer);
|
||||
runningSystem = IsSystemSid(user->User.Sid);
|
||||
}
|
||||
return runningSystem;
|
||||
}
|
||||
|
||||
bool SecurityHelper::IsSystemSid(PSID sid) {
|
||||
return ::IsWellKnownSid(sid, WinLocalSystemSid);
|
||||
}
|
||||
|
||||
bool SecurityHelper::IsRunningElevated() {
|
||||
static bool runningElevated = false;
|
||||
@@ -34,6 +62,7 @@ HICON SecurityHelper::GetShieldIcon() {
|
||||
bool SecurityHelper::RunElevated(PCWSTR param, bool ui) {
|
||||
WCHAR path[MAX_PATH];
|
||||
::GetModuleFileName(nullptr, path, _countof(path));
|
||||
|
||||
SHELLEXECUTEINFO shi = { sizeof(shi) };
|
||||
shi.lpFile = path;
|
||||
shi.nShow = SW_SHOWDEFAULT;
|
||||
@@ -52,6 +81,97 @@ bool SecurityHelper::RunElevated(PCWSTR param, bool ui) {
|
||||
return rc == WAIT_OBJECT_0;
|
||||
}
|
||||
|
||||
// find first SYSTEM process with a good token to use
|
||||
HANDLE SecurityHelper::OpenSystemProcessToken() {
|
||||
PWTS_PROCESS_INFO pInfo;
|
||||
DWORD count;
|
||||
if (!::WTSEnumerateProcesses(WTS_CURRENT_SERVER_HANDLE, 0, 1, &pInfo, &count)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
HANDLE hToken{};
|
||||
for (DWORD i = 0; i < count && !hToken; i++) {
|
||||
if (pInfo[i].SessionId == 0 && IsSystemSid(pInfo[i].pUserSid)
|
||||
&& !_wcsicmp(pInfo[i].pProcessName,L"services.exe")) {
|
||||
auto hProcess = DriverHelper::OpenProcess(pInfo[i].ProcessId, PROCESS_QUERY_INFORMATION);
|
||||
if (hProcess) {
|
||||
::OpenProcessToken(hProcess, TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY | TOKEN_QUERY | TOKEN_IMPERSONATE, &hToken);
|
||||
::CloseHandle(hProcess);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
::WTSFreeMemory(pInfo);
|
||||
return hToken;
|
||||
}
|
||||
|
||||
bool SecurityHelper::SysRun(PCWSTR param) {
|
||||
auto hToken = OpenSystemProcessToken();
|
||||
if (!hToken)
|
||||
return false;
|
||||
|
||||
HANDLE hDupToken, hPrimary;
|
||||
::DuplicateTokenEx(hToken, TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_ASSIGN_PRIMARY | TOKEN_ADJUST_PRIVILEGES,
|
||||
nullptr, SecurityImpersonation, TokenImpersonation, &hDupToken);
|
||||
::DuplicateTokenEx(hToken, TOKEN_ALL_ACCESS, nullptr, SecurityImpersonation, TokenPrimary, &hPrimary);
|
||||
::CloseHandle(hToken);
|
||||
|
||||
if (hDupToken == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
WCHAR path[MAX_PATH];
|
||||
::GetModuleFileName(nullptr, path, _countof(path));
|
||||
|
||||
STARTUPINFO si = { sizeof(si) };
|
||||
si.lpDesktop = const_cast<wchar_t*>(L"Winsta0\\default");
|
||||
|
||||
PROCESS_INFORMATION pi;
|
||||
BOOL impersonated = ::SetThreadToken(nullptr, hDupToken);
|
||||
if (!impersonated)
|
||||
return false;
|
||||
|
||||
HANDLE hCurrentToken = INVALID_HANDLE_VALUE;
|
||||
DWORD session = 0, len = sizeof(session);
|
||||
bool ok = ::OpenProcessToken(::GetCurrentProcess(), TOKEN_ALL_ACCESS, &hCurrentToken);
|
||||
if (!ok)
|
||||
return false;
|
||||
::GetTokenInformation(hCurrentToken, TokenSessionId, &session, len, &len);
|
||||
::CloseHandle(hCurrentToken);
|
||||
|
||||
if (!SetPrivilege(hDupToken, SE_ASSIGNPRIMARYTOKEN_NAME, true) ||
|
||||
!SetPrivilege(hDupToken, SE_INCREASE_QUOTA_NAME, true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::wstring commandLine = path;
|
||||
commandLine += L" ";
|
||||
commandLine += param;
|
||||
|
||||
ok = ::SetTokenInformation(hPrimary, TokenSessionId, &session, sizeof(session));
|
||||
if (!::CreateProcessAsUser(hPrimary, nullptr,
|
||||
const_cast<wchar_t*>(commandLine.c_str()), nullptr, nullptr,
|
||||
FALSE, 0, nullptr, nullptr,
|
||||
&si, &pi)) {
|
||||
DWORD error = ::GetLastError();
|
||||
if (error == ERROR_PRIVILEGE_NOT_HELD) {
|
||||
if (!SetPrivilege(hDupToken, SE_IMPERSONATE_NAME, true))
|
||||
return false;
|
||||
if (!::CreateProcessWithTokenW(hPrimary, 0, nullptr,
|
||||
const_cast<wchar_t*>(commandLine.c_str()), 0, nullptr, nullptr,
|
||||
&si, &pi)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
::CloseHandle(hPrimary);
|
||||
::CloseHandle(hDupToken);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SecurityHelper::EnablePrivilege(PCWSTR privName, bool enable) {
|
||||
HANDLE hToken;
|
||||
if (!::OpenProcessToken(::GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
|
||||
@@ -69,6 +189,31 @@ bool SecurityHelper::EnablePrivilege(PCWSTR privName, bool enable) {
|
||||
return result;
|
||||
}
|
||||
|
||||
bool SecurityHelper::SetPrivilege(HANDLE hToken, PCWSTR privName, bool enable) {
|
||||
TOKEN_PRIVILEGES tp;
|
||||
LUID luid;
|
||||
|
||||
if (!::LookupPrivilegeValue(nullptr, privName, &luid))
|
||||
return false;
|
||||
|
||||
tp.PrivilegeCount = 1;
|
||||
tp.Privileges[0].Luid = luid;
|
||||
if (enable)
|
||||
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
||||
else
|
||||
tp.Privileges[0].Attributes = 0;
|
||||
|
||||
// Enable the privilege or disable all privileges.
|
||||
if (!::AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), nullptr, nullptr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (::GetLastError() == ERROR_NOT_ALL_ASSIGNED)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::wstring SecurityHelper::GetSidFromUser(PCWSTR name) {
|
||||
BYTE sid[SECURITY_MAX_SID_SIZE];
|
||||
DWORD size = sizeof(sid);
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
struct SecurityHelper final {
|
||||
static bool IsSysRun();
|
||||
static bool IsRunningElevated();
|
||||
static HICON GetShieldIcon();
|
||||
static bool RunElevated(PCWSTR privName, bool enable);
|
||||
static bool IsSystemSid(PSID sid);
|
||||
static bool RunElevated(PCWSTR param, bool ui);
|
||||
static bool SysRun(PCWSTR param);
|
||||
static HANDLE OpenSystemProcessToken();
|
||||
static bool EnablePrivilege(PCWSTR privName, bool enable);
|
||||
static std::wstring GetSidFromUser(PCWSTR name);
|
||||
static HANDLE DupHandle(HANDLE hSoruce, DWORD sourcePid, DWORD access = 0);
|
||||
static bool SetPrivilege(HANDLE hToken, PCWSTR privName, bool enable);
|
||||
};
|
||||
Reference in New Issue
Block a user