system进程启动普通用户进程调研

system进程启动普通用户进程

关键函数是CreateProcessAsUser

主要思路是先取得目的用户的token,然后用上面的函数启动

1、从explorer中取token

BOOL GetTokenByName(HANDLE &hToken,LPSTR 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(!strcmp(_strupr(pe32.szExeFile),_strupr(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);
}

BOOL RunProcess(LPCSTR lpImage)
{
    if(!lpImage)
    {
        return FALSE;
    }
    HANDLE hToken;
    if(!GetTokenByName(hToken,"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("CreateProcessAsUser ok!\r\n");
    }
    else
    {
        OutputDebugString("CreateProcessAsUser false!\r\n");
    }
    return bResult;
}

这种方式的缺点是,如果当前有多个用户登陆,则进程中会有多个explorer进程,需额外控制从哪个explorer中取token

2、从当前活动的session中查询token,再启动

BOOL RunProcess1(LPCSTR lpImage, LPSTR lpCmd = "")
{
    if(!lpImage)
    {
        return FALSE;
    }

    DWORD dwSID =  WTSGetActiveConsoleSessionId(); 
    HANDLE hToken;
    WTSQueryUserToken(dwSID, &hToken);

    STARTUPINFO si;
    PROCESS_INFORMATION pi;

    ZeroMemory(&si, sizeof(STARTUPINFO));
    si.cb= sizeof(STARTUPINFO);
    si.lpDesktop = TEXT("winsta0\\default");
    //si.dwFlags = STARTF_USESHOWWINDOW;
    //si.wShowWindow = SW_HIDE;

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

这种方式相对于上一种就是可以创建一个当前活动用户的进程,但在使用过程中发现,如果以非system用户调用WTSQueryUserToken,可能会失败

3、CreateProcessAsUser的命令行参数问题

在实际使用中,想给新进程传递参数,一直没传对,后来才发现,CreateProcessCreateProcessAsUser中,cmdline参数的使用比较特别,要注意

比较保险的两种用法是

  • appname参数置空,cmdline参数为完整命令行,这种用法的限制在于,cmdline长度最大为MAX_PATH
  • appname参数为要启动的程序的完整路径,cmdline参数为完整命令行,这种用法的好处是,长度可以达到32K(MSDN中写的,未试验),限制在于,一定要使用完整命令行,包括要启动的程序的路径。因为该函数不会将appname和cmdline拼在一起

另外需注意的一点是,cmdline在函数调用期间,值会被修改,不能使用常量

转载于:https://www.cnblogs.com/fatterbetter/p/4203094.html

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值