cgbsmy 发表于 2020-4-22 10:28

单EXE以SYSTEM权限运行,并可以创建交互窗口或对话框

声明代码大部分都是在网上收集,如有侵权请联系我删除
在XP/WIN7/WIN10测试通过,理论上XP以上系统都可以使用

BOOL LaunchAppIntoDifferentSession(WCHAR *szExe,WCHAR *szDir)//以SYSTEM运行程序
{
        PROCESS_INFORMATION pi;
        STARTUPINFO si;
        BOOL bResult = FALSE;
        DWORD dwSessionId, winlogonPid;
        HANDLE hUserToken, hUserTokenDup, hPToken, hProcess;
        DWORD dwCreationFlags;
        dwSessionId = WTSGetActiveConsoleSessionId();
        //////////////////////////////////////////
           // Find the winlogon process
        ////////////////////////////////////////
        PROCESSENTRY32 procEntry;
        HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
        if (hSnap == INVALID_HANDLE_VALUE)
        {
                return 1;
        }

        procEntry.dwSize = sizeof(PROCESSENTRY32);

        if (!Process32First(hSnap, &procEntry))
        {
                return 1;
        }

        do
        {
                if (_wcsicmp(procEntry.szExeFile, L"winlogon.exe") == 0)
                {
                        // We found a winlogon process...
                // make sure it's running in the console session
                        DWORD winlogonSessId = 0;
                        if (ProcessIdToSessionId(procEntry.th32ProcessID, &winlogonSessId)
                                && winlogonSessId == dwSessionId)
                        {
                                winlogonPid = procEntry.th32ProcessID;
                                break;
                        }
                }

        } while (Process32Next(hSnap, &procEntry));

        ////////////////////////////////////////////////////////////////////////

        WTSQueryUserToken(dwSessionId, &hUserToken);
        dwCreationFlags = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE;
        ZeroMemory(&si, sizeof(STARTUPINFO));
        si.cb = sizeof(STARTUPINFO);
        si.lpDesktop = (LPWSTR)L"winsta0\\default";
        ZeroMemory(&pi, sizeof(pi));
        TOKEN_PRIVILEGES tp;
        LUID luid;
        hProcess = OpenProcess(MAXIMUM_ALLOWED, FALSE, winlogonPid);

        if (!::OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY
                | TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY | TOKEN_ADJUST_SESSIONID
                | TOKEN_READ | TOKEN_WRITE, &hPToken))
        {
                int abcd = GetLastError();
//                printf("Process token open Error: %u\n", GetLastError());
        }

        if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid))
        {
//                printf("Lookup Privilege value Error: %u\n", GetLastError());
        }
        tp.PrivilegeCount = 1;
        tp.Privileges.Luid = luid;
        tp.Privileges.Attributes = SE_PRIVILEGE_ENABLED;

        DuplicateTokenEx(hPToken, MAXIMUM_ALLOWED, NULL,
                SecurityIdentification, TokenPrimary, &hUserTokenDup);
        int dup = GetLastError();

        //Adjust Token privilege
        SetTokenInformation(hUserTokenDup,
                TokenSessionId, (void*)dwSessionId, sizeof(DWORD));

        if (!AdjustTokenPrivileges(hUserTokenDup, FALSE, &tp, sizeof(TOKEN_PRIVILEGES),
                (PTOKEN_PRIVILEGES)NULL, NULL))
        {
                int abc = GetLastError();
//                printf("Adjust Privilege value Error: %u\n", GetLastError());
        }

        if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
        {
//                printf("Token does not have the provilege\n");
        }

        LPVOID pEnv = NULL;

        if (CreateEnvironmentBlock(&pEnv, hUserTokenDup, TRUE))
        {
                dwCreationFlags |= CREATE_UNICODE_ENVIRONMENT;
        }
        else
                pEnv = NULL;

        // Launch the process in the client's logon session.

        bResult = CreateProcessAsUser(
                hUserTokenDup,                     // client's access token
                szExe,    // file to execute
                NULL,               // command line
                NULL,            // pointer to process SECURITY_ATTRIBUTES
                NULL,               // pointer to thread SECURITY_ATTRIBUTES
                FALSE,            // handles are not inheritable
                dwCreationFlags,   // creation flags
                pEnv,               // pointer to new environment block
                szDir,               // name of current directory
                &si,               // pointer to STARTUPINFO structure
                &pi                // receives information about new process
        );

        CloseHandle(hProcess);
        CloseHandle(hUserToken);
        CloseHandle(hUserTokenDup);
        CloseHandle(hPToken);
        return bResult;
}


BOOL bInstallService;
WHCAR szAppName[]=L"TopC";
SERVICE_STATUS_HANDLE hServiceStatus;
SERVICE_STATUS status;
void WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv);

HANDLE hEvent = INVALID_HANDLE_VALUE;

//服务控制函数
void WINAPI ServiceStrl(DWORD dwOpcode)
{       
        switch (dwOpcode)
        {
        case SERVICE_CONTROL_STOP:
                status.dwCurrentState = SERVICE_STOP_PENDING;
                SetServiceStatus(hServiceStatus, &status);
                //告诉服务线程停止工作
                ::SetEvent(hEvent);
                break;
        case SERVICE_CONTROL_PAUSE:
                break;
        case SERVICE_CONTROL_CONTINUE:
                break;
        case SERVICE_CONTROL_INTERROGATE:
                break;
        case SERVICE_CONTROL_SHUTDOWN:
                break;
        default:
                break;
        }
}
void WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv)
{
       

        // Register the control request handler
        status.dwCurrentState = SERVICE_START_PENDING;
        status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
        //注册服务控制
        hServiceStatus = RegisterServiceCtrlHandler(szServiceName, ServiceStrl);
        if (hServiceStatus == NULL)
        {
                return;
        }
        SetServiceStatus(hServiceStatus, &status);
        //如下代码可以为启动服务前的准备工作
        hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
        if (hEvent == NULL)
        {
                status.dwCurrentState = SERVICE_STOPPED;
                SetServiceStatus(hServiceStatus, &status);
                return;
        }
        //更改服务状态为启动
        status.dwWin32ExitCode = S_OK;
        status.dwCheckPoint = 0;
        status.dwWaitHint = 0;
        status.dwCurrentState = SERVICE_RUNNING;
        SetServiceStatus(hServiceStatus, &status);
        //等待用户选择停止服务,
        //当然你也可以把你的服务代码用线程来执行,
        //此时这里只需等待线程结束既可。
///////////////////////////////////////////////////////////////////////以SYSTEM启动自己或别的程序
        WCHAR szExe;
        HINSTANCE hInst = GetModuleHandle(NULL);
        GetModuleFileName(hInst, szExe, MAX_PATH);
        int iLen = wcslen(szExe);
        szExe = L'\0';
        LaunchAppIntoDifferentSession(szExe,NULL);
///////////////////////////////////////////////////////////////////////
        while (WaitForSingleObject(hEvent, 1000) != WAIT_OBJECT_0)
        {
                //服务程序代码放这里
        }
        //停止服务
        status.dwCurrentState = SERVICE_STOPPED;
        SetServiceStatus(hServiceStatus, &status);
}
DWORD ServiceRunState()//查询当前服务状态
{
        BOOL bResult = FALSE;
        //打开服务控制管理器
        SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
        if (hSCM != NULL)
        {
                //打开服务
                SC_HANDLE hService = ::OpenService(hSCM, szServiceName, SERVICE_QUERY_STATUS);
                if (hService != NULL)
                {
                        SERVICE_STATUS ss;
                        QueryServiceStatus(hService, &ss);
                        bResult = ss.dwCurrentState;
                        ::CloseServiceHandle(hService);
                }
                ::CloseServiceHandle(hSCM);
        }
        return bResult;       
}
BOOL IsServiceInstalled()//查询服务是否安装
{
        BOOL bResult = FALSE;
        //打开服务控制管理器
        SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
        if (hSCM != NULL)
        {
                //打开服务
                SC_HANDLE hService = ::OpenService(hSCM, szServiceName, SERVICE_QUERY_CONFIG);
                if (hService != NULL)
                {
                        bResult = TRUE;
                        ::CloseServiceHandle(hService);
                }
                ::CloseServiceHandle(hSCM);
        }
        return bResult;
}


BOOL InstallService()//安装服务
{
        if (IsServiceInstalled())
                return TRUE;
        //打开服务控制管理器
        SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
        if (hSCM == NULL)
        {
                return FALSE;
        }
        // Get the executable file path
        TCHAR szFilePath;
        ::GetModuleFileName(NULL, szFilePath, MAX_PATH);
        //创建服务
        SC_HANDLE hService = ::CreateService(
                hSCM,
                szServiceName,
                szServiceName,
                SERVICE_ALL_ACCESS,
                SERVICE_WIN32_OWN_PROCESS,
                SERVICE_AUTO_START, //如果为SERVICE_DEMAND_START则表示此服务需手工启动
                SERVICE_ERROR_NORMAL,
                szFilePath,
                NULL,
                NULL,
                _T(""),
                NULL,
                NULL);
        if (hService == NULL)
        {
                ::CloseServiceHandle(hSCM);
                return FALSE;
        }
        ::CloseServiceHandle(hService);
        ::CloseServiceHandle(hSCM);
        return TRUE;
}
BOOL UninstallService()//卸载服务
{
        if (!IsServiceInstalled())
                return TRUE;
        SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
        if (hSCM == NULL)
        {
                return FALSE;
        }
        SC_HANDLE hService = ::OpenService(hSCM, szServiceName, SERVICE_STOP | DELETE);
        if (hService == NULL)
        {
                ::CloseServiceHandle(hSCM);
                return FALSE;
        }
        SERVICE_STATUS status;
        ::ControlService(hService, SERVICE_CONTROL_STOP, &status);
        //删除服务
        BOOL bDelete = ::DeleteService(hService);
        ::CloseServiceHandle(hService);
        ::CloseServiceHandle(hSCM);
        if (bDelete)
                return TRUE;
        return FALSE;
}
void Init()//初始化参数
{
        hServiceStatus = NULL;
        status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
        status.dwCurrentState = SERVICE_STOPPED;
        status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
        status.dwWin32ExitCode = 0;
        status.dwServiceSpecificExitCode = 0;
        status.dwCheckPoint = 0;
        status.dwWaitHint = 0;
}

//开启服务
BOOL ServiceCtrlStart()
{
        BOOL bRet;
        SC_HANDLE hSCM;
        SC_HANDLE hService;
        hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
        if (hSCM != NULL)
        {
//                hService = OpenService(hSCM, szServiceName, SERVICE_START);
                hService = OpenService(hSCM, szServiceName, SERVICE_ALL_ACCESS);
                if (hService != NULL)
                {
                        ChangeServiceConfig(hService, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_NO_CHANGE, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
                        //开始Service
                        bRet = StartService(hService, 0, NULL);
                        CloseServiceHandle(hService);
                }
                else
                {
                        bRet = FALSE;
                }
                CloseServiceHandle(hSCM);
        }
        else
        {
                bRet = FALSE;
        }
        return bRet;
}

//停止服务
BOOL ServiceCtrlStop()
{
        BOOL bRet;
        SC_HANDLE hSCM;
        SC_HANDLE hService;
        SERVICE_STATUS ServiceStatus;
        hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
        if (hSCM != NULL)
        {
                hService = OpenService(hSCM, szServiceName, SERVICE_STOP | SERVICE_QUERY_STATUS);
                if (hService != NULL)
                {
                        QueryServiceStatus(hService, &ServiceStatus);
                        if (ServiceStatus.dwCurrentState == SERVICE_RUNNING)
                        {
                                bRet = ControlService(hService, SERVICE_CONTROL_STOP, &ServiceStatus);
                        }
                        else
                        {
                                bRet = FALSE;
                        }
                        CloseServiceHandle(hService);
                }
                else
                {
                        bRet = FALSE;
                }
                CloseServiceHandle(hSCM);
        }
        else
        {
                bRet = FALSE;
        }
        return bRet;
}
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
        _In_opt_ HINSTANCE hPrevInstance,
        _In_ LPWSTR    lpCmdLine,
        _In_ int       nCmdShow)
{
        UNREFERENCED_PARAMETER(hPrevInstance);
        UNREFERENCED_PARAMETER(lpCmdLine);
        hInst = hInstance;
        Init();
        SERVICE_TABLE_ENTRY st[] =
        {
                { szServiceName, (LPSERVICE_MAIN_FUNCTION)ServiceMain},
                { NULL, NULL }
        };
        if (_wcsicmp(lpCmdLine, L"/install") == 0)//安装服务
        {
                InstallService();
                return 0;
        }
        else if (_wcsicmp(lpCmdLine, L"/uninstall") == 0)//卸载服务
        {
                UninstallService();
                return 0;
        }
        else if (_wcsicmp(lpCmdLine, L"/start") == 0)//开始启动服务
        {
                ServiceCtrlStart();
                return 0;
        }
        else if (_wcsicmp(lpCmdLine, L"/stop") == 0)//停止服务
        {
                ServiceCtrlStop();
                return 0;
        }
        if (ServiceRunState() != SERVICE_RUNNING)
        {
                if (IsServiceInstalled())
                {
                        if (ServiceRunState() == SERVICE_STOPPED)
                                ServiceCtrlStart();
                        StartServiceCtrlDispatcher(st);
                        return 0;
                }
        }
        ServiceCtrlStop();//程序已经以SYSTEM运行,退出服务
//下面是程序运行代码
}

crowhack 发表于 2020-10-16 22:16

没看懂,这是搞什么的
页: [1]
查看完整版本: 单EXE以SYSTEM权限运行,并可以创建交互窗口或对话框