Vista下服务与桌面互交

Vista下服务与桌面互交

     本来在Vista之前服务与桌面互交是一件很容易的事情,自从Vista把服务都挪到Session 0 中运行去而且不可以跨Session之后,问题就复杂了许多,有时候我就在想这些问题是否真的不得不解决而且似乎对于安全并未带来多大提升的更改总是让人头疼,Google了一些文档,抄袭了不少代码我是如下实现的

 这个函数抄自winehq网站,顺便不得不说一下winehq的代码是很值得参考的

 1  BOOL WINAPI EnablePrivilege(LPSTR lpPrivilegeName, BOOL bEnable)
 2  {
 3      TOKEN_PRIVILEGES Privileges;
 4      HANDLE hToken;
 5      BOOL bResult;
 6       if  ( ! OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY,  & hToken))
 7        return  FALSE;
 8 
 9      Privileges.PrivilegeCount  =   1 ;
10      Privileges.Privileges[ 0 ].Attributes  =  (bEnable)  ?  SE_PRIVILEGE_ENABLED :  0 ;
11 
12       if  ( ! LookupPrivilegeValue(NULL, lpPrivilegeName,
13                               & Privileges.Privileges[ 0 ].Luid))
14      {
15       CloseHandle(hToken);
16        return  FALSE;
17      }
18 
19      bResult  =  AdjustTokenPrivileges(hToken, FALSE,  & Privileges,  0 , NULL, NULL);
20 
21      CloseHandle(hToken);
22 
23       return  bResult;
24  }

 

EnablePrivilege用来提升本进程权限,因为我们的核心思路是用CreateProcessAsUser创建进程到需要互交的Session,

 

     // 保证拥有权限
EnablePrivilege(SE_TCB_NAME, TRUE); 
    EnablePrivilege(SE_CHANGE_NOTIFY_NAME, TRUE);
    EnablePrivilege(SE_INCREASE_QUOTA_NAME, TRUE);
    EnablePrivilege(SE_ASSIGNPRIMARYTOKEN_NAME, TRUE);

// 获取当前进程的灵牌
        HANDLE hTokenThis  =  NULL;
        HANDLE hTokenDup 
=  NULL;
        HANDLE hThisProcess 
=  GetCurrentProcess();
        OpenProcessToken(hThisProcess, TOKEN_ALL_ACCESS, 
& hTokenThis);
// 复制令牌
        DuplicateTokenEx(hTokenThis, MAXIMUM_ALLOWED,NULL, SecurityIdentification, TokenPrimary,  & hTokenDup);
// 枚举所有Session,本来还有一个WTSGetActiveConsoleSessionId,不过这个函数在win2000下只有Server版本安装WTS才可以
        PWTS_SESSION_INFO pSInfo;
        DWORD pCInfo 
=   0 ;
        WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE,
0 , 1 , & pSInfo, & pCInfo);
        DWORD dwSessionId 
=   0 ;
        
for  ( int  i = 0 ;i < pCInfo;i ++ )
        {
            
if  (pSInfo[i].State  ==  WTSActive)
            {
                dwSessionId 
=  pSInfo[i].SessionId;
                
break ;
            }
        }
        
// DWORD dwSessionId = WTSGetActiveConsoleSessionId();
// 替换令牌,关键地方,我们并不需要以Session用户创建进程,只需要替换令牌就可以了
        SetTokenInformation(hTokenDup, TokenSessionId,  & dwSessionId,  sizeof (DWORD));

        STARTUPINFO si 
=  { 0 };
        PROCESS_INFORMATION pi 
=  { 0 };
        si.cb 
=   sizeof (si);
        si.lpDesktop 
=   " WinSta0//Default " ;
        DWORD dwCreationFlag 
=  NORMAL_PRIORITY_CLASS  |  CREATE_NEW_CONSOLE  |  CREATE_UNICODE_ENVIRONMENT;
        
char     pPath[MAX_PATH * 2 ];
        GetModuleFileName(NULL,pPath,
sizeof (pPath));
        strcat(pPath,
"  -work " );
        LPVOID pEnv;
        CreateEnvironmentBlock(
& pEnv,hTokenDup,FALSE);
        
if  ( ! CreateProcessAsUser(hTokenDup,NULL,pPath,NULL,NULL,FALSE,dwCreationFlag,pEnv,NULL, & si, & pi))
        {
//  
//              int p = GetLastError();
//              p = 0;
        }
        WaitForSingleObject(pi.hProcess,INFINITE);
        CloseHandle(hTokenDup);
        CloseHandle(hTokenThis);

这样我们的程序就可以和桌面互交了,这只是核心,其余牵涉多用户切换这些还需要另外考虑

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值