Windows程序提升为最高System权限(XP-Win10)

xingyun86 2021-5-3 908

Windows程序提升为最高System权限(XP-Win10)

#pragma once

#include <winsvc.h>
#include <wtsapi32.h>
#pragma comment(lib, "wtsapi32.lib")
#include <userenv.h>
#pragma comment(lib,"userenv")
#include <tlhelp32.h>

#include <string>

class SvcMgr {
public:
    SvcMgr() {
        m_strProgramName.resize(MAX_PATH, '\0');
        GetModuleFileNameA(NULL, (LPSTR)m_strProgramName.data(), m_strProgramName.size());
        m_strProgramName = m_strProgramName.c_str();
        m_strRootPath = m_strProgramName.substr(0, m_strProgramName.rfind('\\'));
        m_strServiceName = m_strProgramName.substr(m_strProgramName.rfind('\\') + 1);
        m_strSingleInstanceMutexName = ("__" + m_strServiceName + "__SINGLE_INSTANCE_MUTEX__");
    }
    virtual ~SvcMgr(){}
public:
    std::string m_strRootPath = ("");
    std::string m_strProgramName = ("");
    std::string m_strServiceName = ("");
    std::string m_strSingleInstanceMutexName = ("");
public:
    SERVICE_STATUS m_ServiceStatus = { 0 };
    SERVICE_STATUS_HANDLE m_hServiceStatusHandle = NULL;
public:
    //通用版将wstring转化为string
    std::string W_To_A(const std::wstring& ws, unsigned int cp = CP_ACP)
    {
        if (!ws.empty())
        {
            std::string s(WideCharToMultiByte(cp, 0, ws.data(), -1, NULL, 0, NULL, NULL), ('\0'));
            return s.substr(0, WideCharToMultiByte(cp, 0, ws.c_str(), -1, (LPSTR)s.data(), (int)s.size(), NULL, NULL) - 1);
        }
        return ("");
    }
    //通用版将string转化为wstring
    std::wstring A_To_W(const std::string& s, unsigned int cp = CP_ACP)
    {
        if (!s.empty())
        {
            std::wstring ws(MultiByteToWideChar(cp, 0, s.data(), -1, NULL, 0), (L'\0'));
            return ws.substr(0, MultiByteToWideChar(cp, 0, s.data(), -1, (LPWSTR)ws.data(), (int)ws.size()) - 1);
        }
        return (L"");
    }
    //  ANSI to Unicode
    std::wstring AToW(const std::string& s)
    {
        return A_To_W(s);
    }
    //Unicode to ANSI
    std::string WToA(const std::wstring& ws)
    {
        return W_To_A(ws);
    }
#if !defined(UNICODE) && !defined(_UNICODE)
#define AToT(X) X
#define WToT(X) WToA(X)
#define TToA(X) X
#define TToW(X) AToW(X)
#else
#define AToT(X) AToW(X)
#define WToT(X) X
#define TToA(X) WToA(X)
#define TToW(X) X
#endif
public:
    BOOL CreateProcessWithUI(LPCTSTR lpProcessName, LPCTSTR lpCommandLine, LPPROCESS_INFORMATION process)
    {
        BOOL bResult = FALSE;
        HANDLE hToken = NULL;
        STARTUPINFO si = { 0 };
        DWORD dwSessionId = 0L;
        HANDLE hTokenDuplicate = NULL;

        if (!lpProcessName || !(*lpProcessName))
        {
            goto __LEAVE_CLEAN__;
        }

        if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken))
        {
            goto __LEAVE_CLEAN__;
        }

        if (!DuplicateTokenEx(hToken, TOKEN_ALL_ACCESS, NULL, SecurityAnonymous, TokenPrimary, &hTokenDuplicate))
        {
            goto __LEAVE_CLEAN__;
        }

        dwSessionId = WTSGetActiveConsoleSessionId();
        if (!SetTokenInformation(hTokenDuplicate, TokenSessionId, &dwSessionId, sizeof(dwSessionId)))
        {
            CloseHandle(hToken);
            CloseHandle(hTokenDuplicate);
            return FALSE;
        }

        ZeroMemory(&si, sizeof(STARTUPINFO));
        si.cb = sizeof(STARTUPINFO);
        si.wShowWindow = SW_SHOW;
        si.dwFlags = STARTF_USESHOWWINDOW;
        if (!CreateProcessAsUser(hTokenDuplicate, lpProcessName, (LPTSTR)lpCommandLine, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT,    NULL, NULL, &si, process))
        {
            goto __LEAVE_CLEAN__;
        }

        bResult = TRUE;

    __LEAVE_CLEAN__:

        if (hToken != NULL)
        {
            CloseHandle(hToken);
            hToken = NULL;
        }
        if (hTokenDuplicate != NULL)
        {
            CloseHandle(hTokenDuplicate);
            hTokenDuplicate = NULL;
        }

        return bResult;
    }
    void ExecuteProgram()
    {
        PROCESS_INFORMATION pi = { 0 };
        if (CreateProcessWithUI(AToT(m_strProgramName).c_str(), TEXT(" --program --execute"), &pi) && (pi.hProcess != NULL))
        {
            CloseHandle(pi.hProcess);
        }
    }

    static void WINAPI ServiceHandler(DWORD fdwControl)
    {
        switch (fdwControl)
        {
        case SERVICE_CONTROL_STOP:
        case SERVICE_CONTROL_SHUTDOWN:
        {
            SvcMgr::Inst()->m_ServiceStatus.dwWin32ExitCode = 0;
            SvcMgr::Inst()->m_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
            SvcMgr::Inst()->m_ServiceStatus.dwCheckPoint = 0;
            SvcMgr::Inst()->m_ServiceStatus.dwWaitHint = 0;
            //add you quit code here
        }
        break;
        default:
        {
            return;
        }
        break;
        };
        if (!SetServiceStatus(SvcMgr::Inst()->m_hServiceStatusHandle, &SvcMgr::Inst()->m_ServiceStatus))
        {
            return;
        }
    }

    static void WINAPI ServiceMain(int argc, char** argv)
    {
        SvcMgr::Inst()->m_ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS;// SERVICE_WIN32;
        SvcMgr::Inst()->m_ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
        SvcMgr::Inst()->m_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_PAUSE_CONTINUE;
        SvcMgr::Inst()->m_ServiceStatus.dwWin32ExitCode = 0;
        SvcMgr::Inst()->m_ServiceStatus.dwServiceSpecificExitCode = 0;
        SvcMgr::Inst()->m_ServiceStatus.dwCheckPoint = 0;
        SvcMgr::Inst()->m_ServiceStatus.dwWaitHint = 0;
        SvcMgr::Inst()->m_hServiceStatusHandle = RegisterServiceCtrlHandler(SvcMgr::Inst()->AToT(SvcMgr::Inst()->m_strServiceName).c_str(), ServiceHandler);
        if (SvcMgr::Inst()->m_hServiceStatusHandle == NULL)
        {
            return;
        }

        //add your service thread here
        SvcMgr::Inst()->ExecuteProgram();

        // Initialization complete - report running status 
        SvcMgr::Inst()->m_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
        SvcMgr::Inst()->m_ServiceStatus.dwCheckPoint = 0;
        SvcMgr::Inst()->m_ServiceStatus.dwWaitHint = 9000;
        if (!SetServiceStatus(SvcMgr::Inst()->m_hServiceStatusHandle, &SvcMgr::Inst()->m_ServiceStatus))
        {
            return;
        }
    }
    /////////////////////////////////////////////////////////////////////////////////////
    VOID MySvcInstall()
    {
        SC_HANDLE schSCManager;
        SC_HANDLE schService;
        std::string m_strBinPath = m_strProgramName + " --service";
        
        // Get a handle to the SCM database. 
        schSCManager = OpenSCManager(
            NULL,                    // local computer
            NULL,                    // ServicesActive database 
            SC_MANAGER_ALL_ACCESS);  // full access rights 
        if (NULL == schSCManager)
        {
            printf("OpenSCManager failed (%d)\n", GetLastError());
            return;
        }
        // Create the service
        schService = CreateService(
            schSCManager,              // SCM database 
            AToT(m_strServiceName).c_str(),                   // name of service 
            AToT(m_strServiceName).c_str(),                   // service name to display 
            SERVICE_ALL_ACCESS,        // desired access 
            SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, // service type 
            SERVICE_DEMAND_START,      // start type 
            SERVICE_ERROR_NORMAL,      // error control type 
            AToT(m_strBinPath).c_str(),                    // path to service's binary 
            NULL,                      // no load ordering group 
            NULL,                      // no tag identifier 
            NULL,                      // no dependencies 
            NULL,                      // LocalSystem account 
            NULL);                     // no password 
        if (schService == NULL)
        {
            printf("CreateService failed (%d)\n", GetLastError());
            CloseServiceHandle(schSCManager);
            return;
        }
        StartService(schService, 0, NULL);
        CloseServiceHandle(schService);
        CloseServiceHandle(schSCManager);
    }
    void MySvcRemove()
    {
        SC_HANDLE schSCManager;
        SC_HANDLE schService;
        // Get a handle to the SCM database. 
        schSCManager = OpenSCManager(
            NULL,                    // local computer
            NULL,                    // ServicesActive database 
            SC_MANAGER_ALL_ACCESS);  // full access rights 
        if (NULL == schSCManager)
        {
            printf("OpenSCManager failed (%d)\n", GetLastError());
            return;
        }
        // Create the service
        schService = OpenService(
            schSCManager,              // SCM database 
            AToT(m_strServiceName).c_str(),                   // name of service
            SERVICE_ALL_ACCESS        // desired access
        );
        if (schService == NULL)
        {
            printf("CreateService failed (%d)\n", GetLastError());
            CloseServiceHandle(schSCManager);
            return;
        }
        SERVICE_STATUS ss = { 0 };
        ControlService(schService, SERVICE_CONTROL_STOP, &ss);
        if (DeleteService(schService) == FALSE)
        {
            printf("Service remove failed (%d)\n", GetLastError());
            CloseServiceHandle(schService);
            CloseServiceHandle(schSCManager);
            return;
        }
        CloseServiceHandle(schService);
        CloseServiceHandle(schSCManager);
    }
public:
    bool Run()
    {
        // TODO: Place code here.
        INT nArgvNum = 0;
        LPWSTR lpwCmdLine = GetCommandLineW();
        CommandLineToArgvW(lpwCmdLine, &nArgvNum);
        if (nArgvNum == 1)
        {
            HANDLE hMutex = CreateMutex(NULL, FALSE, AToT(m_strSingleInstanceMutexName).c_str());
            if (hMutex == NULL)
            {
                return false;
            }

            //如果程序已经存在并且正在运行
            if (GetLastError() != ERROR_ALREADY_EXISTS)
            {
                SetCurrentDirectory(AToT(m_strRootPath).c_str());
                //卸载服务
                MySvcRemove();
                //安装服务并启动服务
                MySvcInstall();
            }
            CloseHandle(hMutex);
        }
        else if (nArgvNum == 2)
        {
            SERVICE_TABLE_ENTRY ServiceTable[2] = { 0 };

            ServiceTable[0].lpServiceName = (LPTSTR)(AToT(m_strServiceName).c_str());
            ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;

            ServiceTable[1].lpServiceName = NULL;
            ServiceTable[1].lpServiceProc = NULL;
            // 启动服务的控制分派机线程
            StartServiceCtrlDispatcher(ServiceTable);
        }
        else if (nArgvNum == 3)
        {
            SvcMgr::Inst()->MySvcRemove();
            return true;
        }
        else
        {
            SetCurrentDirectory(AToT(m_strRootPath).c_str());
            //卸载服务
            MySvcRemove();
        }
        return false;
    }
public:
    static SvcMgr* Inst()
    {
        static SvcMgr SvcMrgInstance;
        return &SvcMrgInstance;
    }
};

使用方法:

int main(int argc, char** argv)
{
    if (SvcMgr::Inst()->Run() == false)
    {
        return (-1);
    }
    //添加应用的功能逻辑代码

    return 0;
}


×
打赏作者
最新回复 (0)
只看楼主
全部楼主
返回