系统权限服务创建桌面进程(进程也是系统权限)

系统权限服务,创建进程.

一丶简介

为什么要创建系统权限服务.首先.强调权限一说. 我们创建的系统服务默认是系统权限的.然后系统权限(System)创建我们的进程.那么也是系统权限.我们的进程如果要注入到Explorer.exe中就很简单了.

二丶创建服务的几个步骤

1.编写服务步骤

1.main函数中注册服务的入口函数(servicemain)并开始派发
2.服务入口函数注册服务控制函数.并且设置自己的服务状态
3.服务控制函数回调的处理

1.1 main函数注册服务入口函数

int main()
{
    /*

    定义服务列表结构体
    参数1.指定的服务名字.
    参数2.服务的入口Main函数地址.
    */
    ////安装服务.

        SERVICE_TABLE_ENTRY ServiceTable[2] = { NULL };
        ServiceTable[0].lpServiceName = (LPWSTR)TEXT(SERVICE_NAME); //指定我们的服务名字
        ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)SerMain;//指向服务的函数地址
        //LPSERVICE_MAIN_FUNCTIONW

        ServiceTable[1].lpServiceName = NULL;
        ServiceTable[1].lpServiceProc = NULL;
        StartServiceCtrlDispatcher(ServiceTable); //开始派发.

    return 0;
}

2.服务入口函数注册服务控制函数.

服务入口服务控制回调函数,注册到SCM(服务控制管理器)当中.
当我们服务控制管理器中点击 启动服务.关闭服务.暂停服务的时候.则会调用我们的回调函数.
代码如下

VOID WINAPI SerMain(DWORD   dwNumServicesArgs,LPWSTR* lpServiceArgVectors)
{
    //在服务Main里面.我们需要注册服务.
    /*
    RegisterServiceCtrlHandler
    注册一个函数来处理服务的请求控制.
    */

    g_ServiceStatus.dwServiceType = SERVICE_WIN32;    //服务的类型是Win32服务
    g_ServiceStatus.dwCurrentState = SERVICE_START_PENDING; ; //服务的状态是正在巡行
    g_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP ;// 服务接手的控制代码喊处理函数中的处理. (Reg注册的函数地址); 当前的意思就是这个服务可以停止.并且会传入Reg注册的ServiceHandle处理.
    g_ServiceStatus.dwWin32ExitCode = 0;  //服务用语报告启动或停止时候发生的错误代码.返回特定的错误代码就设置.
    g_ServiceStatus.dwServiceSpecificExitCode = 0;//服务特定的错误代码
    g_ServiceStatus.dwCheckPoint = 0;             //跟进度条一样,服务在启动的时候会递增这个值
    g_ServiceStatus.dwWaitHint = 0;               //挂起启动,停止,暂停.或继续操作所需要的估计时间. 

    BOOL bRet = FALSE;
    g_RegRetServiceStatusHandle = RegisterServiceCtrlHandlerEx(TEXT(SERVICE_NAME), ServiceHandle,NULL);//返回服务状态. 注册服务控制函数
    if (g_RegRetServiceStatusHandle == (SERVICE_STATUS_HANDLE)0)
    {
        return;
    }
    //否则,调用SetServiceStatus进行更新服务的状态信息 结构体是最新服务状态结构信息.

    g_ServiceStatus.dwCurrentState = SERVICE_RUNNING; //Service Status Setting Start.
     bRet = SetServiceStatus(g_RegRetServiceStatusHandle,&g_ServiceStatus);//设置服务的状态.

    if (!bRet)
    {
        return ;
    }
    //编写自己的代码.
    g_ContrlCodeExcue = TRUE;

    RunRemoteControl();

    while (g_ContrlCodeExcue)
    {
        Sleep(2000);
    }
    return;
}

3.服务控制函数回调的处理


DWORD WINAPI ServiceHandle(DWORD    dwControl, DWORD    dwEventType, LPVOID   lpEventData, LPVOID   lpContext)
{
    //服务的控制状态.管理
    switch (dwControl)
    {
        //回调函数会传入dwControl让我们控制服务.我们只需要控制即可.更改状态并且设置即可.
    case SERVICE_CONTROL_PAUSE:
        //暂停
        g_ServiceStatus.dwCurrentState = SERVICE_PAUSED;
        break;
    case SERVICE_CONTROL_CONTINUE:
        g_ServiceStatus.dwCurrentState = SERVICE_RUNNING;

        break;
    case SERVICE_CONTROL_STOP:
        g_ServiceStatus.dwWin32ExitCode = 0;
        g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
        g_ServiceStatus.dwCheckPoint = 0;
        g_ServiceStatus.dwWaitHint = 0;
        //SetServiceStatus(g_RegRetServiceStatusHandle, &g_ServiceStatus);
        g_ContrlCodeExcue = FALSE;
        break;
    case SERVICE_CONTROL_INTERROGATE:
        break;
    default:
        break;
    }
    SetServiceStatus(g_RegRetServiceStatusHandle, &g_ServiceStatus);
    return 0;
}

编写完上面的几步,我们的一个系统服务就能创建出来了.

4.服务控制的完整代码


#pragma warning (disable:4996)
#include <userenv.h>
#include <Windows.h>
#include <stdio.h>
#include <tlhelp32.h>
#include <string>
#include <vector>
using namespace std;

#pragma comment(lib,"Userenv.lib")
SERVICE_STATUS_HANDLE g_RegRetServiceStatusHandle;
SERVICE_STATUS        g_ServiceStatus; //服务的状态
BOOL g_ContrlCodeExcue;   //控制我们的代码是否执行

DWORD WINAPI ServiceHandle(DWORD    dwControl, DWORD    dwEventType, LPVOID   lpEventData, LPVOID   lpContext)
{
    //服务的控制状态.管理
    switch (dwControl)
    {
        //回调函数会传入dwControl让我们控制服务.我们只需要控制即可.更改状态并且设置即可.
    case SERVICE_CONTROL_PAUSE:
        //暂停
        g_ServiceStatus.dwCurrentState = SERVICE_PAUSED;
        break;
    case SERVICE_CONTROL_CONTINUE:
        g_ServiceStatus.dwCurrentState = SERVICE_RUNNING;

        break;
    case SERVICE_CONTROL_STOP:
        g_ServiceStatus.dwWin32ExitCode = 0;
        g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
        g_ServiceStatus.dwCheckPoint = 0;
        g_ServiceStatus.dwWaitHint = 0;
        //SetServiceStatus(g_RegRetServiceStatusHandle, &g_ServiceStatus);
        g_ContrlCodeExcue = FALSE;
        break;
    case SERVICE_CONTROL_INTERROGATE:
        break;
    default:
        break;
    }
    SetServiceStatus(g_RegRetServiceStatusHandle, &g_ServiceStatus);
    return 0;
}

VOID WINAPI SerMain(DWORD   dwNumServicesArgs,LPWSTR* lpServiceArgVectors)
{
    //在服务Main里面.我们需要注册服务.
    /*
    RegisterServiceCtrlHandler
    注册一个函数来处理服务的请求控制.
    */

    g_ServiceStatus.dwServiceType = SERVICE_WIN32;    //服务的类型是Win32服务
    g_ServiceStatus.dwCurrentState = SERVICE_START_PENDING; ; //服务的状态是正在巡行
    g_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP ;// 服务接手的控制代码喊处理函数中的处理. (Reg注册的函数地址); 当前的意思就是这个服务可以停止.并且会传入Reg注册的ServiceHandle处理.
    g_ServiceStatus.dwWin32ExitCode = 0;  //服务用语报告启动或停止时候发生的错误代码.返回特定的错误代码就设置.
    g_ServiceStatus.dwServiceSpecificExitCode = 0;//服务特定的错误代码
    g_ServiceStatus.dwCheckPoint = 0;             //跟进度条一样,服务在启动的时候会递增这个值
    g_ServiceStatus.dwWaitHint = 0;               //挂起启动,停止,暂停.或继续操作所需要的估计时间. 

    BOOL bRet = FALSE;
    g_RegRetServiceStatusHandle = RegisterServiceCtrlHandlerEx(TEXT(SERVICE_NAME), ServiceHandle,NULL);//返回服务状态.
    if (g_RegRetServiceStatusHandle == (SERVICE_STATUS_HANDLE)0)
    {
        return;
    }
    //否则,调用SetServiceStatus进行更新服务的状态信息 结构体是最新服务状态结构信息.

    g_ServiceStatus.dwCurrentState = SERVICE_RUNNING; //Service Status Setting Start.
     bRet = SetServiceStatus(g_RegRetServiceStatusHandle,&g_ServiceStatus);

    if (!bRet)
    {
        return ;
    }
    //编写自己的代码.
    g_ContrlCodeExcue = TRUE;

    while (g_ContrlCodeExcue)
    {
        Sleep(2000); //写你自己的代码
    }
    return;
}

int main()
{
    /*

    定义服务列表结构体
    参数1.指定的服务名字.
    参数2.服务的入后Main函数地址.
    */
    ////安装服务.

    //SERVICE_TABLE_ENTRY ServiceTable[2] = { NULL };
    //ServiceTable[0].lpServiceName = (LPWSTR)TEXT(SERVICE_NAME); //指定我们的服务名字
    //ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)SerMain;//指向服务的函数地址
    ////LPSERVICE_MAIN_FUNCTIONW

    //ServiceTable[1].lpServiceName = NULL;
    //ServiceTable[1].lpServiceProc = NULL;
    //StartServiceCtrlDispatcher(ServiceTable); //开始派发.

         SERVICE_TABLE_ENTRY ServiceTable[2] = { NULL };
        ServiceTable[0].lpServiceName = (LPWSTR)TEXT(SERVICE_NAME); //指定我们的服务名字
        ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)SerMain;//指向服务的函数地址
        //LPSERVICE_MAIN_FUNCTIONW

        ServiceTable[1].lpServiceName = NULL;
        ServiceTable[1].lpServiceProc = NULL;
        StartServiceCtrlDispatcher(ServiceTable); //开始派发.

    return 0;
}

三丶服务中创建桌面进程

3.1服务中创建桌面进程原理

在服务中虽然说创建的进程是System权限.但是在win7系统以上,我们创建的进程都会是隐藏的.也就是说你的进程虽然创建出来了.
也是Sysem权限.但是并不能操作.仅仅就只能在管理器看到这个进程而已.
ps:(winxp下没有尝试是否能创建进程)
所以我们有了新的方法.不调用CreateProcess函数.而调用 CreateProcessAsUser函数.
并且进行一定的设置才可以.

核心代码如下:

void RunRemoteControl() //在服务中创建桌面进程.
{
    HANDLE ProcessHandle = NULL;
    HANDLE CurrentToken = NULL;
    HANDLE TokenDup = NULL;
    wstring wOpenProcessName;
    if (!GetAppendNmae(wOpenProcessName, PROCESS_NAME))
    {
        int d = GetLastError();
        WriteLogString(L"RunRemoteControl OpenProcessToken failed.Last Error is:%d", d);
        return ;
    }
    ProcessHandle = GetCurrentProcess();
    if (!OpenProcessToken(ProcessHandle, TOKEN_ALL_ACCESS, &CurrentToken))
    {
        int d = GetLastError();
        WriteLogString(L"RunRemoteControl OpenProcessToken failed.Last Error is:%d", d);
        return;
    }
    if (!DuplicateTokenEx(CurrentToken, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary, &TokenDup))
    {
        int dd = GetLastError();
        WriteLogString(L"RunRemoteControl DuplicateTokenEx failed.Last error is:%d", dd);
        return;
    }
    DWORD dwSessionID = WTSGetActiveConsoleSessionId();
    WriteLogString(L" WTSGetActiveConsoleSessionId:%d", dwSessionID);
    if (!SetTokenInformation(TokenDup, TokenSessionId, &dwSessionID, sizeof(DWORD)))
    {
        int ddd = GetLastError();
        WriteLogString(L"RunRemoteControl SetTokenInformation failed.Last error is:%d", ddd);
        return;
    }
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    ZeroMemory(&si, sizeof(STARTUPINFO));
    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
    si.cb = sizeof(STARTUPINFO);
    si.lpDesktop = L"WinSta0\\Default";

    LPVOID pEnv = NULL;
    DWORD dwCreationFlags = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT;
    if (!CreateEnvironmentBlock(&pEnv, TokenDup, FALSE))
    {
        int error1 = GetLastError();
        WriteLogString(L"RunRemoteControl CreateEnvironmentBlock failed.Last error is:%d", error1);
        return;
    }
    TCHAR szPath[1024] =  TEXT_CREATE_PROCESS_NAME_SY;
    //wcsncpy_s(szPath, wOpenProcessName.c_str(), wOpenProcessName.length());
    OutputDebugString(szPath);
    if (!CreateProcessAsUser(TokenDup, szPath, NULL, NULL, NULL, FALSE, dwCreationFlags, pEnv, NULL, &si, &pi))
    {
        int error2 = GetLastError();
        WriteLogString(L"RunRemoteControl CreateProcessAsUser failed.Last error is:%d", error2);
        return;
    }

    return  ;
}

其中函数 GetAppendNmae WriteLogString 函数是我自己写的.不影响这个核心函数.可以去掉的.
最后就可以创建我们的进程.

3.2服务中创建桌面进程完整代码

完整代码如下:



#pragma warning (disable:4996)
#include <userenv.h>
#include <Windows.h>
#include <stdio.h>
#include <tlhelp32.h>
#include <string>
#include <vector>
using namespace std;

#pragma comment(lib,"Userenv.lib")
SERVICE_STATUS_HANDLE g_RegRetServiceStatusHandle;
SERVICE_STATUS        g_ServiceStatus; //服务的状态
BOOL g_ContrlCodeExcue;   //控制我们的代码是否执行
#define SERVICE_NAME "SystemServices"
#define LOAG_FILE_NAME "SystemServicesLog.txt"
#define TEXT_CREATE_PROCESS_NAME_OD TEXT("D:\\HackTools\\OllyDbg\\OllyICE 吾爱扣扣专版\\OllyICE 吾爱扣扣专版\\OllyICE.exe")//SystemRun.exe
#define TEXT_CREATE_PROCESS_NAME_SY TEXT("C:\\Users\\Administrator\\Desktop\\SystemServices\\run\\x64InjectProcess.exe")
#define PROCESS_NAME TEXT("SystemRun.exe")

BOOL GetAppendNmae(wstring &wGetName, wstring AppendName); //Get Moudle Name Last - 1 Path Cat In Path
//服务控制函数

DWORD WINAPI ServiceHandle(DWORD    dwControl, DWORD    dwEventType, LPVOID   lpEventData, LPVOID   lpContext)
{
    //服务的控制状态.管理
    switch (dwControl)
    {
        //回调函数会传入dwControl让我们控制服务.我们只需要控制即可.更改状态并且设置即可.
    case SERVICE_CONTROL_PAUSE:
        //暂停
        g_ServiceStatus.dwCurrentState = SERVICE_PAUSED;
        break;
    case SERVICE_CONTROL_CONTINUE:
        g_ServiceStatus.dwCurrentState = SERVICE_RUNNING;

        break;
    case SERVICE_CONTROL_STOP:
        g_ServiceStatus.dwWin32ExitCode = 0;
        g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
        g_ServiceStatus.dwCheckPoint = 0;
        g_ServiceStatus.dwWaitHint = 0;
        //SetServiceStatus(g_RegRetServiceStatusHandle, &g_ServiceStatus);
        g_ContrlCodeExcue = FALSE;
        break;
    case SERVICE_CONTROL_INTERROGATE:
        break;
    default:
        break;
    }
    SetServiceStatus(g_RegRetServiceStatusHandle, &g_ServiceStatus);
    return 0;
}

BOOL GetEachLevelDir(PWSTR GetPathName, vector<wstring> &wSavePath) //传入一个路径,获取每一级的目录.并且用数组进行存储.
{
    TCHAR *pCurPoint = GetPathName;//使用指针遍历

    TCHAR  *Begin = GetPathName;
    DWORD dwEnd = 0;
    DWORD dwCount = 0;
    wstring wstrTemp = TEXT("");
    while (pCurPoint)
    {

        //否则进行循环
        //wcscmp((TCHAR *)*pCurPoint,TEXT("\\")) == 0
        if (*pCurPoint == TEXT('\\'))//以反斜杠为分割.
        {

            wSavePath.push_back(wstrTemp);
            wstrTemp.clear();
            pCurPoint++; //控制指针去相加.
            dwEnd = 0;

        }

        if (*pCurPoint == 0x0)//结尾是0则跳出循环.记录下路径.
        {
            return TRUE;
            break;
        }
        wstring::iterator it = wstrTemp.begin() + dwEnd;
        wstrTemp.insert(it, *pCurPoint);  //插入字符
        dwEnd++;
        pCurPoint++;
        dwCount++; //获取判断长度进行退出.
    }
    return FALSE;
}

BOOL   GetTokenByName(HANDLE   &hToken, LPWSTR   lpName)
{
    if (!lpName)
    {
        return   FALSE;
    }
    HANDLE                   hProcessSnap = NULL;
    BOOL                       bRet = FALSE;
    PROCESSENTRY32   pe32 = { 0 };

    hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hProcessSnap == INVALID_HANDLE_VALUE)
        return   (FALSE);

    pe32.dwSize = sizeof(PROCESSENTRY32);

    if (Process32First(hProcessSnap, &pe32))
    {
        do
        {
            if (!wcscmp(_wcsupr(pe32.szExeFile), _wcsupr(lpName)))
            {
                HANDLE   hProcess =
                    OpenProcess(PROCESS_QUERY_INFORMATION,
                    FALSE, pe32.th32ProcessID);
                bRet = OpenProcessToken(hProcess, TOKEN_ALL_ACCESS, &hToken);
                CloseHandle(hProcessSnap);
                return   (bRet);
            }
        } while (Process32Next(hProcessSnap, &pe32));
        bRet = TRUE;
    }
    else
        bRet = FALSE;

    CloseHandle(hProcessSnap);
    return   (bRet);
}

//也可以创建进程,但是创建出来的是根据你得当前EXPLORER的权限创建的。 创建出来是管理员权限。
BOOL   RunProcess(LPWSTR   lpImage)
{
    if (!lpImage)
    {
        return   FALSE;
    }
    HANDLE   hToken;
    //TEXT("EXPLORER.EXE")
    if (!GetTokenByName(hToken, TEXT("EXPLORER.EXE")))
    {
        return   FALSE;
    }
    STARTUPINFO   si;
    PROCESS_INFORMATION   pi;

    ZeroMemory(&si, sizeof(STARTUPINFO));
    si.cb = sizeof(STARTUPINFO);
    si.lpDesktop = TEXT("winsta0\\default");

    BOOL   bResult =
        CreateProcessAsUser(hToken, lpImage, NULL, NULL, NULL,
        FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi);
    CloseHandle(hToken);
    if (bResult)
    {
        OutputDebugString(TEXT("CreateProcessAsUser   ok!\r\n"));
    }
    else
    {
        OutputDebugString(TEXT("CreateProcessAsUser   false!\r\n"));
    }
    return   bResult;
} 

BOOL GetAppendNmae(wstring &wGetName, wstring AppendName)//获取启动进程的启动的名字
{

    TCHAR FilePath[MAX_PATH] = { 0 };
    GetModuleFileName(GetModuleHandle(0), FilePath, MAX_PATH);
    vector<wstring> wSaveDirLeavePath;
    if (!GetEachLevelDir(FilePath, wSaveDirLeavePath))
    {
        return FALSE;
    }
    //cat
    wstring wCatPath = TEXT("");
    for (int i = 0; i < wSaveDirLeavePath.size(); i++)
    {
        if (i == (wSaveDirLeavePath.size() - 1))
        {
            break;
        }
        wCatPath.append(wSaveDirLeavePath[i]);
        wCatPath.append(TEXT("\\"));
    }
    wCatPath.append(AppendName);
    wGetName = wCatPath;

    return TRUE;
}

void WriteLogString(LPWSTR lpParam, DWORD dwCode)
{
    TCHAR lpBuffer[1024]  {0};
    wsprintf(lpBuffer,lpParam, dwCode);
    OutputDebugString(lpBuffer);
    //GetCurrentDirectory(1024, lpBuffer);
    wstring WriteLogName;
    if (!GetAppendNmae(WriteLogName, TEXT(LOAG_FILE_NAME)))
    {
        return;
    }
    FILE *pFile = NULL;
    _wfopen_s(&pFile, WriteLogName.c_str(), TEXT("a+"));
    if (NULL == pFile)
    {
        return;
    }
    fwprintf_s(pFile, lpParam); //写入到文件
    fclose(pFile);
    return;
}

void RunRemoteControl() //在服务中创建桌面进程.
{
    HANDLE ProcessHandle = NULL;
    HANDLE CurrentToken = NULL;
    HANDLE TokenDup = NULL;
    wstring wOpenProcessName;
    if (!GetAppendNmae(wOpenProcessName, PROCESS_NAME))
    {
        int d = GetLastError();
        WriteLogString(L"RunRemoteControl OpenProcessToken failed.Last Error is:%d", d);
        return ;
    }
    ProcessHandle = GetCurrentProcess();
    if (!OpenProcessToken(ProcessHandle, TOKEN_ALL_ACCESS, &CurrentToken))
    {
        int d = GetLastError();
        WriteLogString(L"RunRemoteControl OpenProcessToken failed.Last Error is:%d", d);
        return;
    }
    if (!DuplicateTokenEx(CurrentToken, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary, &TokenDup))
    {
        int dd = GetLastError();
        WriteLogString(L"RunRemoteControl DuplicateTokenEx failed.Last error is:%d", dd);
        return;
    }
    DWORD dwSessionID = WTSGetActiveConsoleSessionId();
    WriteLogString(L" WTSGetActiveConsoleSessionId:%d", dwSessionID);
    if (!SetTokenInformation(TokenDup, TokenSessionId, &dwSessionID, sizeof(DWORD)))
    {
        int ddd = GetLastError();
        WriteLogString(L"RunRemoteControl SetTokenInformation failed.Last error is:%d", ddd);
        return;
    }
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    ZeroMemory(&si, sizeof(STARTUPINFO));
    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
    si.cb = sizeof(STARTUPINFO);
    si.lpDesktop = L"WinSta0\\Default";

    LPVOID pEnv = NULL;
    DWORD dwCreationFlags = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT;
    if (!CreateEnvironmentBlock(&pEnv, TokenDup, FALSE))
    {
        int error1 = GetLastError();
        WriteLogString(L"RunRemoteControl CreateEnvironmentBlock failed.Last error is:%d", error1);
        return;
    }
    TCHAR szPath[1024] =  TEXT_CREATE_PROCESS_NAME_SY;
    //wcsncpy_s(szPath, wOpenProcessName.c_str(), wOpenProcessName.length());
    OutputDebugString(szPath);
    if (!CreateProcessAsUser(TokenDup, szPath, NULL, NULL, NULL, FALSE, dwCreationFlags, pEnv, NULL, &si, &pi))
    {
        int error2 = GetLastError();
        WriteLogString(L"RunRemoteControl CreateProcessAsUser failed.Last error is:%d", error2);
        return;
    }

    return  ;
}

VOID WINAPI SerMain(DWORD   dwNumServicesArgs,LPWSTR* lpServiceArgVectors)
{
    //在服务Main里面.我们需要注册服务.
    /*
    RegisterServiceCtrlHandler
    注册一个函数来处理服务的请求控制.
    */

    g_ServiceStatus.dwServiceType = SERVICE_WIN32;    //服务的类型是Win32服务
    g_ServiceStatus.dwCurrentState = SERVICE_START_PENDING; ; //服务的状态是正在巡行
    g_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP ;// 服务接手的控制代码喊处理函数中的处理. (Reg注册的函数地址); 当前的意思就是这个服务可以停止.并且会传入Reg注册的ServiceHandle处理.
    g_ServiceStatus.dwWin32ExitCode = 0;  //服务用语报告启动或停止时候发生的错误代码.返回特定的错误代码就设置.
    g_ServiceStatus.dwServiceSpecificExitCode = 0;//服务特定的错误代码
    g_ServiceStatus.dwCheckPoint = 0;             //跟进度条一样,服务在启动的时候会递增这个值
    g_ServiceStatus.dwWaitHint = 0;               //挂起启动,停止,暂停.或继续操作所需要的估计时间. 

    BOOL bRet = FALSE;
    g_RegRetServiceStatusHandle = RegisterServiceCtrlHandlerEx(TEXT(SERVICE_NAME), ServiceHandle,NULL);//返回服务状态.
    if (g_RegRetServiceStatusHandle == (SERVICE_STATUS_HANDLE)0)
    {
        return;
    }
    //否则,调用SetServiceStatus进行更新服务的状态信息 结构体是最新服务状态结构信息.

    g_ServiceStatus.dwCurrentState = SERVICE_RUNNING; //Service Status Setting Start.
     bRet = SetServiceStatus(g_RegRetServiceStatusHandle,&g_ServiceStatus);

    if (!bRet)
    {
        return ;
    }
    //编写自己的代码.
    g_ContrlCodeExcue = TRUE;

    RunRemoteControl();

    while (g_ContrlCodeExcue)
    {
        Sleep(2000);
    }
    return;
}

int main()
{
    /*

    定义服务列表结构体
    参数1.指定的服务名字.
    参数2.服务的入后Main函数地址.
    */
    ////安装服务.

    //SERVICE_TABLE_ENTRY ServiceTable[2] = { NULL };
    //ServiceTable[0].lpServiceName = (LPWSTR)TEXT(SERVICE_NAME); //指定我们的服务名字
    //ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)SerMain;//指向服务的函数地址
    ////LPSERVICE_MAIN_FUNCTIONW

    //ServiceTable[1].lpServiceName = NULL;
    //ServiceTable[1].lpServiceProc = NULL;
    //StartServiceCtrlDispatcher(ServiceTable); //开始派发.

         SERVICE_TABLE_ENTRY ServiceTable[2] = { NULL };
        ServiceTable[0].lpServiceName = (LPWSTR)TEXT(SERVICE_NAME); //指定我们的服务名字
        ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)SerMain;//指向服务的函数地址
        //LPSERVICE_MAIN_FUNCTIONW

        ServiceTable[1].lpServiceName = NULL;
        ServiceTable[1].lpServiceProc = NULL;
        StartServiceCtrlDispatcher(ServiceTable); //开始派发.

    return 0;
}

4.总结

代码没有进行完善,比如服务中创建的进程是写死的.这个我没有做.因为时间有限.只为了测试代码.
其实不难.有兴趣的可以自己做一下.
最后附上完整代码:

链接:https://pan.baidu.com/s/1Yn0zHfHi9ZBfiNKkCNdMpA")
提取码:iius

原文地址:https://www.cnblogs.com/iBinary/p/10801835.html

时间: 2024-11-02 08:20:31

系统权限服务创建桌面进程(进程也是系统权限)的相关文章

win10系统下自由切换桌面

说明: win10系统下自由切换桌面,确认在win10系统下操作进行. 方法: 1.快捷键:ctrl+win键(开始键)+方向键(左/右) 2.桌面最下面的状态栏,点击红框 原文地址:https://www.cnblogs.com/mengjinxiang/p/12256700.html

Supervisor 为服务创建守护进程

今天需要再服务上部署一个.net 方面的项目:当时开启服务的命令只能在前台执行:使用nohub CMD &等放在后台开启服务都会宕机:所以搜寻了Supervisor 这个解决办法,为服务创建守护进程.具体操作如下 1.什么是守护进程 在linux或者unix操作系统中,守护进程(Daemon)是一种运行在后台的特殊进程,它独立于控制终端并且周期性的执行某种任务或等待处理某些发生的事件.由于在linux中,每个系统与用户进行交流的界面称为终端,每一个从此终端开始运行的进程都会依附于这个终端,这个终

Linux下进程概念,进程管理和日志系统

程序(procedure):不太精确地说,程序就是执行一系列有逻辑.有顺序结构的指令,帮我们达成某个结果.就如我们去餐馆,给服务员说我要牛肉盖浇饭, 她执行了做牛肉盖浇饭这么一个程序,最后我们得到了这么一盘牛肉盖浇饭.它需要去执行,不然它就像一本武功秘籍,放在那里等人翻看. 进程(process):进程是程序在一个数据集合上的一次执行过程,在早期的UNIX.Linux 2.4及更早的版本中,它是系统进行资源分配和调度的独立基本单位. 同上一个例子,就如我们去了餐馆,给服务员说我要牛肉盖浇饭,她执

linux 通过哪个命令可以查看某个服务及其端口、进程号

netstat/lsof netstat命令用于显示与IP.TCP.UDP和ICMP协议相关的统计数据,一般用于检验本机各端口的网络连接情况 -a 显示一个所有的有效连接信息列表(包括已建立的连接,也包括监听连接请求的那些连接) -n 显示所有已建立的有效连接 -t tcp协议 -u udp协议 -l 查询正在监听的程序 -p 显示正在使用socket的程序识别码和程序名称 例如:netstat -ntupl|grep processname 如何只查询tomcat的连接? netstat -n

分析Linux内核创建一个新进程的过程【转】

转自:http://www.cnblogs.com/MarkWoo/p/4420588.html 前言说明 本篇为网易云课堂Linux内核分析课程的第六周作业,本次作业我们将具体来分析fork系统调用,来分析Linux内核创建新进程的过程 关键词:fork, 系统调用,进程 *运行环境:** Ubuntu 14.04 LTS x64 gcc 4.9.2 gdb 7.8 vim 7.4 with vundle 分析 分析方法说明 PCB包含了一个进程的重要运行信息,所以我们将围绕在创建一个新进程时

lab6:分析Linux内核创建一个新进程的过程

李俊锋 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.实验原理 1.进程的定义 进程是操作系统的概念,每当我们执行一个程序时,对于操作系统来讲就创建了一个进程,在这个过程中,伴随着资源的分配和释放.可以认为进程是一个程序的一次执行过程. 2.进程与程序的区别 程序时静态的,它是一些保存 在磁盘上得指令的有序集合,没有任何执行的概念. 进程是一个动态的概念,它是程序执行的过程

实验六分析Linux内核创建一个新进程的过程

王康 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 1,进程的描述 操作系统三大功能:进程管理(核心),内存管理,文件系统 1,进程控制块PCB--task_struct 也叫进程描述符,为了管理进程,内核必须对每个进程进行清晰的描述,进程描述符提供了内核所需了解的进程信息. struct task_struct数据结构很庞大:可以看到state进程状态,stack内核堆栈,

14、权限(用户,文件,进程)

计算机资源:定义了资源的访问能力,就是权限权限用户,容器,关联权限:用户组,方便地指派权限只要这个用户放在这个容器里面,他就有相关的权限,这个容器也就是用户组的概念.所以在Linux下定义了三组用户的权限属主:属组:其他用户组是个逻辑概念,他只是指派权限,是不能登录的,但是组有密码进程也是有属组和属主的,谁发起了这个进程,就以怎么样的权限执行,而执行目标刚好有同样的属主和属组,那就可以被运行我们默认让文件不应该执行权限,但是默认目录要有执行权限,如下所示: [[email protected]

第六周分析Linux内核创建一个新进程的过程

潘恒 原创作品转载请注明出处<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 task_struct结构: struct task_struct {   volatile long state;进程状态  void *stack; 堆栈  pid_t pid; 进程标识符  unsigned int rt_priority;实时优先级  unsigned int policy;调度策略  struct files