进程与桌面交互

CreateProcessAsUser() windowstations 和桌面 收藏

<script type="text/javascript"> document.body.oncopy = function() { if (window.clipboardData) { setTimeout(function() { var text = clipboardData.getData("text"); if (text && text.length>300) { text = text + "/r/n/n本文来自CSDN博客,转载请标明出处:" + location.href; clipboardData.setData("text", text); } }, 100); } } </script> <script class="blogstory">function StorePage(){d=document;t=d.selection?(d.selection.type!='None'?d.selection.createRange().text:''):(d.getSelection?d.getSelection():'');void(keyit=window.open('http://www.365key.com/storeit.aspx?t='+escape(d.title)+'&u='+escape(d.location.href)+'&c='+escape(t),'keyit','scrollbars=no,width=475,height=575,left=75,top=20,status=no,resizable=yes'));keyit.focus();}</script>

以下示例代码使用户名为 " franki " 完全访问权限交互 windowstation 桌面, " winsta0//default "。 对于每个对象访问控制项 (ACE) 是基于 franki 的登录 SID。 代码执行 Cmd.exe 文件。

# define RTN_OK     0
   #define RTN_ERROR 13

   #define WINSTA_ALL (WINSTA_ACCESSCLIPBOARD  | WINSTA_ACCESSGLOBALATOMS |

   WINSTA_CREATEDESKTOP     |  WINSTA_ENUMDESKTOPS       |
   WINSTA_ENUMERATE        
|  WINSTA_EXITWINDOWS        |
   WINSTA_READATTRIBUTES   
|  WINSTA_READSCREEN         |
   WINSTA_WRITEATTRIBUTES  
|   DELETE                     |
   READ_CONTROL            
|  WRITE_DAC                 |
   WRITE_OWNER)

   
# define DESKTOP_ALL (DESKTOP_CREATEMENU      | DESKTOP_CREATEWINDOW  |
   DESKTOP_ENUMERATE        |  DESKTOP_HOOKCONTROL    |
   DESKTOP_JOURNALPLAYBACK 
|  DESKTOP_JOURNALRECORD  |
   DESKTOP_READOBJECTS     
|  DESKTOP_SWITCHDESKTOP  |
   DESKTOP_WRITEOBJECTS    
|   DELETE                  |
   READ_CONTROL            
|  WRITE_DAC              |
   WRITE_OWNER)

   
# define GENERIC_ACCESS (GENERIC_READ    | GENERIC_WRITE |
   GENERIC_EXECUTE  |  GENERIC_ALL)

   
# include <windows.h>
   #include <stdio.h>


   BOOL ObtainSid(

        HANDLE hToken
,             //  Handle to an process access token .
        PSID   
* psid              //  ptr to the buffer of the logon sid
        );

   void RemoveSid(
        PSID 
* psid                //  ptr to the buffer of the logon sid
        );

   BOOL AddTheAceWindowStation(

        HWINSTA hwinsta
,           //  handle to a windowstation
        PSID    psid             
//  logon sid of the process
        );

   BOOL AddTheAceDesktop(

        HDESK hdesk
,               //  handle to a desktop
        PSID  psid               
//  logon sid of the process
        );

   
int  main(void)
   {
        HANDLE              hToken;
        HDESK               hdesk;
        HWINSTA             hwinsta;
        PROCESS_INFORMATION pi;
        PSID                psid;
        STARTUPINFO         si;

        
//  
        
//  obtain an access token  for  the user fester
        
//  
        
if  ( ! LogonUser(
             
" franki " ,
             NULL
,
             
" franki " ,
             LOGON32_LOGON_INTERACTIVE
,
             LOGON32_PROVIDER_DEFAULT
,
             
& hToken
             ))
             
return  RTN_ERROR;

        
//  
        
//  obtain a handle to the interactive windowstation
        
//  
        hwinsta 
=  OpenWindowStation(
             
" winsta0 " ,
             FALSE
,
             READ_CONTROL 
|  WRITE_DAC
             );
        
if  (hwinsta  ==  NULL)
             
return  RTN_ERROR;

        HWINSTA hwinstaold 
=  GetProcessWindowStation();

        
//  
        
//  set the windowstation to winsta0 so that you obtain the
        
//  correct default desktop
        
//  
        
if  ( ! SetProcessWindowStation(hwinsta))
             
return  RTN_ERROR;

        
//  
        
//  obtain a handle to the  " default "  desktop
        
//  
        hdesk 
=  OpenDesktop(
             
" default " ,
             
0 ,
             FALSE
,
             READ_CONTROL 
|  WRITE_DAC  |
             DESKTOP_WRITEOBJECTS 
|  DESKTOP_READOBJECTS
             );
        
if  (hdesk  ==  NULL)
             
return  RTN_ERROR;

        
//  
        
//  obtain the logon sid of the user fester
        
//  
        
if  ( ! ObtainSid(hToken ,   & psid))
             
return  RTN_ERROR;

        
//  
        
//  add the user to interactive windowstation
        
//  
        
if  ( ! AddTheAceWindowStation(hwinsta ,  psid))
             
return  RTN_ERROR;

        
//  
        
//  add user to  " default "  desktop
        
//  
        
if  ( ! AddTheAceDesktop(hdesk ,  psid))
             
return  RTN_ERROR;

        
//  
        
//  free the buffer  for  the logon sid
        
//  
        RemoveSid(
& psid);

        
//  
        
//   close  the handles to the interactive windowstation and desktop
        
//  
        CloseWindowStation(hwinsta);

        CloseDesktop(hdesk);

        
//  
        
//  initialize STARTUPINFO structure
        
//  
        ZeroMemory(
& si ,  sizeof(STARTUPINFO));
        si
. cb         =  sizeof(STARTUPINFO);
        si
. lpDesktop  =   " winsta0/default " ;

        
//  
        
//  start the process
        
//  
        
if  ( ! CreateProcessAsUser(
             hToken
,
             NULL
,
             
" cmd.exe " ,
             NULL
,
             NULL
,
             FALSE
,
             NORMAL_PRIORITY_CLASS 
|  CREATE_NEW_CONSOLE ,
             NULL
,
             NULL
,
             
& si ,
             
& pi
             ))
             
return  RTN_ERROR;

        SetProcessWindowStation(hwinstaold); 
// set it back

        
//  
        
//   close  the handles
        
//  
        CloseHandle(pi
. hProcess);

        CloseHandle(pi
. hThread);

        
return  RTN_OK;
   }


   BOOL ObtainSid(HANDLE hToken
,  PSID  * psid)

      {
        BOOL                    bSuccess 
=  FALSE;  //  assume function will
                                                  
//  fail
        DWORD                   dwIndex;
        DWORD                   dwLength 
=   0 ;
        TOKEN_INFORMATION_CLASS tic      
=  TokenGroups;
        PTOKEN_GROUPS           ptg      
=  NULL;

        __try
             {
             
//  
             
//  determine the size of the buffer
        
//  
             
if  ( ! GetTokenInformation(
             hToken
,
             tic
,
             (LPVOID)ptg
,
             
0 ,
             
& dwLength
             ))
                  {
                  
if  (GetLastError()  ==  ERROR_INSUFFICIENT_BUFFER)
                       {
                       ptg 
=  (PTOKEN_GROUPS)HeapAlloc(
                            GetProcessHeap()
,
                  HEAP_ZERO_MEMORY
,
                  dwLength
                  );
                       
if  (ptg  ==  NULL)
                            __leave;
                       }
                   
else
                       __leave;
         }

             
//  
             
//  obtain the groups the access token belongs to
             
//  
             
if  ( ! GetTokenInformation(
                  hToken
,
             tic
,
             (LPVOID)ptg
,
             dwLength
,
             
& dwLength
             ))
                  __leave;

             
//  
             
//  determine which group is the logon sid
             
//  
             
for  (dwIndex  =   0 ; dwIndex  <  ptg -> GroupCount; dwIndex ++ )
                  {
             
if  ((ptg -> Groups[dwIndex] . Attributes  &  SE_GROUP_LOGON_ID)
                  
==   SE_GROUP_LOGON_ID)
                       {
                       
//  
                       
//  determine the  length  of the sid
                       
//  
                       dwLength 
=  GetLengthSid(ptg -> Groups[dwIndex] . Sid);

                       
//  
                       
//  allocate a buffer  for  the logon sid
                       
//  
                       
* psid  =  (PSID)HeapAlloc(
                            GetProcessHeap()
,
                  HEAP_ZERO_MEMORY
,
                  dwLength
                  );
                  
if  ( * psid  ==  NULL)
                       __leave;

                  
//  
                  
//  obtain a copy of the logon sid
                  
//  
                  
if  ( ! CopySid(dwLength ,   * psid ,  ptg -> Groups[dwIndex] . Sid))
                       __leave;

                  
//  
                  
//  break out of the loop because the logon sid has been
                  
//  found
                  
//  
                  break;
                  }
             }

             
//  
             
//  indicate success
             
//  
             bSuccess 
=  TRUE;
             }
        __finally
             {
             
//  
        
//  free the buffer  for  the token group
        
//  
             
if  (ptg  !=  NULL)
                  HeapFree(GetProcessHeap()
,   0 ,  (LPVOID)ptg);
             }

        
return  bSuccess;

   }

   void RemoveSid(PSID 
* psid)
   {
        HeapFree(GetProcessHeap()
,   0 ,  (LPVOID) * psid);
   }

   BOOL AddTheAceWindowStation(HWINSTA hwinsta
,  PSID psid)
   {

        ACCESS_ALLOWED_ACE   
* pace;
        ACL_SIZE_INFORMATION aclSizeInfo;
        BOOL                 bDaclExist;
        BOOL                 bDaclPresent;
        BOOL                 bSuccess  
=  FALSE;  //  assume function will
                                                
// fail
        DWORD                dwNewAclSize;
        DWORD                dwSidSize 
=   0 ;
        DWORD                dwSdSizeNeeded;
        PACL                 pacl;
        PACL                 pNewAcl;
        PSECURITY_DESCRIPTOR psd       
=  NULL;
        PSECURITY_DESCRIPTOR psdNew    
=  NULL;
        PVOID                pTempAce;
        SECURITY_INFORMATION si        
=  DACL_SECURITY_INFORMATION;
        unsigned 
int          i;

        __try
             {
             
//  
             
//  obtain the dacl  for  the windowstation
             
//  
             
if  ( ! GetUserObjectSecurity(
                  hwinsta
,
             
& si ,
             psd
,
                  dwSidSize
,
             
& dwSdSizeNeeded
                  ))
             
if  (GetLastError()  ==  ERROR_INSUFFICIENT_BUFFER)
                  {
                  psd 
=  (PSECURITY_DESCRIPTOR)HeapAlloc(
                       GetProcessHeap()
,
                       HEAP_ZERO_MEMORY
,
                       dwSdSizeNeeded
             );
                  
if  (psd  ==  NULL)
                       __leave;

                  psdNew 
=  (PSECURITY_DESCRIPTOR)HeapAlloc(
                       GetProcessHeap()
,
                       HEAP_ZERO_MEMORY
,
                       dwSdSizeNeeded
                       );
                  
if  (psdNew  ==  NULL)
                       __leave;

                  dwSidSize 
=  dwSdSizeNeeded;

                  
if  ( ! GetUserObjectSecurity(
                       hwinsta
,
                       
& si ,
                       psd
,
                       dwSidSize
,
                       
& dwSdSizeNeeded
                       ))
                       __leave;
         }
             
else
                   __leave;

             
//  
             
//  create a new dacl
        
//  
             
if  ( ! InitializeSecurityDescriptor(
                  psdNew
,
                  SECURITY_DESCRIPTOR_REVISION
                  ))
                  __leave;

             
//  
        
//  get dacl from the security descriptor
             
//  
             
if  ( ! GetSecurityDescriptorDacl(
                  psd
,
                  
& bDaclPresent ,
                  
& pacl ,
                  
& bDaclExist
                  ))
                  __leave;

             
//  
             
//  initialize
             
//  
             ZeroMemory(
& aclSizeInfo ,  sizeof(ACL_SIZE_INFORMATION));
             aclSizeInfo
. AclBytesInUse  =  sizeof(ACL);

             
//  
             
//  call only  if  the dacl is not NULL
             
//  
             
if  (pacl  !=  NULL)
                  {
                  
//  get the file ACL size info
                  
if  ( ! GetAclInformation(
                       pacl
,
                       (LPVOID)
& aclSizeInfo ,
                       sizeof(ACL_SIZE_INFORMATION)
,
                       AclSizeInformation
                       ))
                       __leave;
                   }

             
//  
             
//  compute the size of the new acl
             
//  
             dwNewAclSize 
=  aclSizeInfo . AclBytesInUse  +  ( 2   *
             sizeof(ACCESS_ALLOWED_ACE)) 
+  ( 2   *  GetLengthSid(psid))  -  ( 2   *
             sizeof(DWORD));

             
//  
             
//  allocate memory  for  the new acl
             
//  
             pNewAcl 
=  (PACL)HeapAlloc(
                  GetProcessHeap()
,
                  HEAP_ZERO_MEMORY
,
                  dwNewAclSize
                  );
             
if  (pNewAcl  ==  NULL)
                  __leave;

             
//  
             
//  initialize the new dacl
             
//  
             
if  ( ! InitializeAcl(pNewAcl ,  dwNewAclSize ,  ACL_REVISION))
                  __leave;

             
//  
             
//   if  DACL is present ,  copy it to a new DACL
             
//  
             
if  (bDaclPresent)  //  only copy  if  DACL was present
                  {
                  
//  copy the ACEs to  our  new ACL
                  
if  (aclSizeInfo . AceCount)
                       {
                       
for  (i = 0 ; i  <  aclSizeInfo . AceCount; i ++ )
                            {
                            
//  get an ACE
                            
if  ( ! GetAce(pacl ,  i ,   & pTempAce))
                                 __leave;

                            
//  add the ACE to the new ACL
                            
if  ( ! AddAce(
                  pNewAcl
,
                                 ACL_REVISION
,
                                 MAXDWORD
,
                                 pTempAce
,
                  ((PACE_HEADER)pTempAce)
-> AceSize
                                 ))
                                 __leave;
                             }
                        }
                  }

             
//  
             
//  add the first ACE to the windowstation
             
//  
             pace 
=  (ACCESS_ALLOWED_ACE  * )HeapAlloc(
                  GetProcessHeap()
,
                  HEAP_ZERO_MEMORY
,
             sizeof(ACCESS_ALLOWED_ACE) 
+  GetLengthSid(psid)  -
                  sizeof(DWORD
                  ));
             
if  (pace  ==  NULL)
                  __leave;

             pace
-> Header . AceType   =  ACCESS_ALLOWED_ACE_TYPE;
             pace
-> Header . AceFlags  =  CONTAINER_INHERIT_ACE  |
                                     INHERIT_ONLY_ACE      
|

                                     OBJECT_INHERIT_ACE;
             pace
-> Header . AceSize   =  sizeof(ACCESS_ALLOWED_ACE)  +

                                     GetLengthSid(psid) 
-  sizeof(DWORD);
             pace
-> Mask             =  GENERIC_ACCESS;

             
if  ( ! CopySid(GetLengthSid(psid) ,   & pace -> SidStart ,  psid))
                  __leave;

             
if  ( ! AddAce(
                  pNewAcl
,
                  ACL_REVISION
,
             MAXDWORD
,
                  (LPVOID)pace
,
                  pace
-> Header . AceSize
                  ))
                  __leave;

             
//  
             
//  add the second ACE to the windowstation
             
//  
             pace
-> Header . AceFlags  =  NO_PROPAGATE_INHERIT_ACE;
             pace
-> Mask             =  WINSTA_ALL;

             
if  ( ! AddAce(
                  pNewAcl
,
                  ACL_REVISION
,
                  MAXDWORD
,
                  (LPVOID)pace
,
                  pace
-> Header . AceSize
                  ))
                  __leave;

                  
//  
                  
//  set new dacl  for  the security descriptor
                  
//  
                  
if  ( ! SetSecurityDescriptorDacl(
                       psdNew
,
                       TRUE
,
                       pNewAcl
,
                       FALSE
                       ))
                       __leave;

                   
//  
         
//  set the new security descriptor  for  the windowstation
         
//  
         
if  ( ! SetUserObjectSecurity(hwinsta ,   & si ,  psdNew))
            __leave;

         
//  
         
//  indicate success
         
//  
         bSuccess 
=  TRUE;
             }
        __finally
             {
             
//  
             
//  free the allocated buffers
             
//  
             
if  (pace  !=  NULL)
                  HeapFree(GetProcessHeap()
,   0 ,  (LPVOID)pace);

             
if  (pNewAcl  !=  NULL)
                  HeapFree(GetProcessHeap()
,   0 ,  (LPVOID)pNewAcl);

             
if  (psd  !=  NULL)
                  HeapFree(GetProcessHeap()
,   0 ,  (LPVOID)psd);

             
if  (psdNew  !=  NULL)
                  HeapFree(GetProcessHeap()
,   0 ,  (LPVOID)psdNew);
             }

        
return  bSuccess;

   }

   BOOL AddTheAceDesktop(HDESK hdesk
,  PSID psid)
   {

        ACL_SIZE_INFORMATION aclSizeInfo;
        BOOL                 bDaclExist;
        BOOL                 bDaclPresent;
        BOOL                 bSuccess  
=  FALSE;  //  assume function will
                                                
//  fail
        DWORD                dwNewAclSize;
        DWORD                dwSidSize 
=   0 ;
        DWORD                dwSdSizeNeeded;
        PACL                 pacl;
        PACL                 pNewAcl;
        PSECURITY_DESCRIPTOR psd       
=  NULL;
        PSECURITY_DESCRIPTOR psdNew    
=  NULL;
        PVOID                pTempAce;
        SECURITY_INFORMATION si        
=  DACL_SECURITY_INFORMATION;
        unsigned 
int          i;

        __try
             {
             
//  
             
//  obtain the security descriptor  for  the desktop object
             
//  
             
if  ( ! GetUserObjectSecurity(
                  hdesk
,
                  
& si ,
                  psd
,
                  dwSidSize
,
                  
& dwSdSizeNeeded
                  ))
                  {
                  
if  (GetLastError()  ==  ERROR_INSUFFICIENT_BUFFER)
                       {
                       psd 
=  (PSECURITY_DESCRIPTOR)HeapAlloc(
                            GetProcessHeap()
,
                            HEAP_ZERO_MEMORY
,
             dwSdSizeNeeded
             );
                       
if  (psd  ==  NULL)
                            __leave;

                       psdNew 
=  (PSECURITY_DESCRIPTOR)HeapAlloc(
                            GetProcessHeap()
,
                            HEAP_ZERO_MEMORY
,
                            dwSdSizeNeeded
             );
                       
if  (psdNew  ==  NULL)
                            __leave;

                       dwSidSize 
=  dwSdSizeNeeded;

                       
if  ( ! GetUserObjectSecurity(
                            hdesk
,
                            
& si ,
                            psd
,
                            dwSidSize
,
                            
& dwSdSizeNeeded
                            ))
                            __leave;
                       }
                  
else
                       __leave;
                  }

             
//  
             
//  create a new security descriptor
             
//  
             
if  ( ! InitializeSecurityDescriptor(
                  psdNew
,
                  SECURITY_DESCRIPTOR_REVISION
                  ))
               _   _leave;

             
//  
             
//  obtain the dacl from the security descriptor
             
//  
             
if  ( ! GetSecurityDescriptorDacl(
                  psd
,
                  
& bDaclPresent ,
                  
& pacl ,
                  
& bDaclExist
                  ))
                  __leave;

             
//  
             
//  initialize
             
//  
             ZeroMemory(
& aclSizeInfo ,  sizeof(ACL_SIZE_INFORMATION));
             aclSizeInfo
. AclBytesInUse  =  sizeof(ACL);

             
//  
             
//  call only  if  NULL dacl
             
//  
             
if  (pacl  !=  NULL)
                  {
                  
//  
                  
//  determine the size of the ACL info
                  
//  
                  
if  ( ! GetAclInformation(
                       pacl
,
                       (LPVOID)
& aclSizeInfo ,
                       sizeof(ACL_SIZE_INFORMATION)
,
                       AclSizeInformation
                       ))
                       __leave;
                   }

             
//  
             
//  compute the size of the new acl
             
//  
        dwNewAclSize 
=  aclSizeInfo . AclBytesInUse  +
                            sizeof(ACCESS_ALLOWED_ACE) 
+
                            GetLengthSid(psid) 
-  sizeof(DWORD);

             
//  
             
//  allocate buffer  for  the new acl
             
//  
             pNewAcl 
=  (PACL)HeapAlloc(
                  GetProcessHeap()
,
                  HEAP_ZERO_MEMORY
,
                  dwNewAclSize
                  );
             
if  (pNewAcl  ==  NULL)
                  __leave;

             
//  
             
//  initialize the new acl
             
//  
             
if  ( ! InitializeAcl(pNewAcl ,  dwNewAclSize ,  ACL_REVISION))
                  __leave;

             
//  
             
//   if  DACL is present ,  copy it to a new DACL
             
//  
             
if  (bDaclPresent)  //  only copy  if  DACL was present
                  {
                  
//  copy the ACEs to  our  new ACL
                  
if  (aclSizeInfo . AceCount)
                       {
                       
for  (i = 0 ; i  <  aclSizeInfo . AceCount; i ++ )
                            {
                            
//  get an ACE
                            
if  ( ! GetAce(pacl ,  i ,   & pTempAce))
                                 __leave;

                            
//  add the ACE to the new ACL
                            
if  ( ! AddAce(
                                 pNewAcl
,
                                 ACL_REVISION
,
                                 MAXDWORD
,
                                 pTempAce
,
                                 ((PACE_HEADER)pTempAce)
-> AceSize
                                 ))
                                 __leave;
                             }
                        }
                  }

             
//  
             
//  add ace to the dacl
             
//  
             
if  ( ! AddAccessAllowedAce(
                  pNewAcl
,
                  ACL_REVISION
,
                  DESKTOP_ALL
,
                  psid
                  ))
                  __leave;

             
//  
             
//  set new dacl to the new security descriptor
             
//  
             
if  ( ! SetSecurityDescriptorDacl(
                       psdNew
,
                       TRUE
,
                       pNewAcl
,
                       FALSE
                       ))
                  __leave;

             
//  
             
//  set the new security descriptor  for  the desktop object
             
//  
             
if  ( ! SetUserObjectSecurity(hdesk ,   & si ,  psdNew))
                  __leave;

             
//  
             
//  indicate success
             
//  
             bSuccess 
=  TRUE;
             }
        __finally
            {
            
//  
            
//  free buffers
            
//  
            
if  (pNewAcl  !=  NULL)
                 HeapFree(GetProcessHeap()
,   0 ,  (LPVOID)pNewAcl);

             
if  (psd  !=  NULL)
                  HeapFree(GetProcessHeap()
,   0 ,  (LPVOID)psd);

             
if  (psdNew  !=  NULL)
                  HeapFree(GetProcessHeap()
,   0 ,  (LPVOID)psdNew);
             }

        
return  bSuccess;
   }





代码功能:让一个运行在SYSTEM权限下的进程与当前用户的桌面进行交互
代码:

程序代码 程序代码
#define  DESKTOP_ALL  ( DESKTOP_READOBJECTS  |  DESKTOP_CreateWINDOW  |  /
DESKTOP_CreateMENU  |  DESKTOP_HOOKCONTROL  |  DESKTOP_JOURNALRECORD  |  /
DESKTOP_JOURNALPLAYBACK  |  DESKTOP_ENUMERATE  |  DESKTOP_WRITEOBJECTS  |  /
DESKTOP_SWITCHDESKTOP  |  STANDARD_RIGHTS_REQUIRED )

#define WINSTA_ALL  ( WINSTA_ENUMDESKTOPS  |  WINSTA_READATTRIBUTES  |  /
WINSTA_ACCESSCLIPBOARD  |  WINSTA_CreateDESKTOP  |  WINSTA_WRITEATTRIBUTES  |  /
WINSTA_ACCESSGLOBALATOMS  |  WINSTA_EXITWINDOWS  |  WINSTA_ENUMERATE  |  /
WINSTA_READSCREEN  |  STANDARD_RIGHTS_REQUIRED )

#define GENERIC_ACCESS  ( GENERIC_READ  |  GENERIC_WRITE  |  GENERIC_EXECUTE  |  GENERIC_ALL )

BOOL AddAceToWindowStation ( HWINSTA hwinsta ,  PSID psid ) ;

BOOL AddAceToDesktop ( HDESK hdesk ,  PSID psid ) ;

BOOL GetLogonSID  ( HANDLE hToken ,  PSID  * ppsid ) ;

VOID FreeLogonSID  ( PSID  * ppsid ) ;

BOOL StartInteractiveClientProcess  (
    LPTSTR lpszUsername ,      // client to log on
    LPTSTR lpszDomain,      // domain of client's account
    LPTSTR lpszPassword,    // client's password
    LPTSTR lpCommandLine    // command line to execute
);


/*
int main()
{
    StartInteractiveClientProcess("test",NULL,"wrxzyl","C://Program Files//Internet Explorer//IEXPLORE.EXE http://www.zxboy.com ");
    return 0;
}
*/
BOOL StartInteractiveClientProcess (
    LPTSTR lpszUsername,    // client to log on
    LPTSTR lpszDomain,      // domain of client's account
    LPTSTR lpszPassword,    // client's password
    LPTSTR lpCommandLine    // command line to execute

{
   HANDLE      hToken;
   HDESK       hdesk = NULL;
   HWINSTA     hwinsta = NULL, hwinstaSave = NULL;
   PROCESS_INFORMATION pi;
   PSID pSid = NULL;
   STARTUPINFO si;
   BOOL bResult = FALSE;

// Log the client on to the local computer.

   if (!LogonUser(
           lpszUsername,
           lpszDomain,
           lpszPassword,
           LOGON32_LOGON_INTERACTIVE,
           LOGON32_PROVIDER_DEFAULT,
           &hToken) ) 
   {
      goto Cleanup;
   }

// Save a handle to the caller's current window station.

   if ( (hwinstaSave = GetProcessWindowStation() ) == NULL)
      goto Cleanup;

// Get a handle to the interactive window station.

   hwinsta = OpenWindowStation(
       "winsta0",                   // the interactive window station 
       FALSE,                       // handle is not inheritable
       READ_CONTROL | WRITE_DAC);   // rights to read/write the DACL

   if (hwinsta == NULL) 
      goto Cleanup;

// To get the correct default desktop, set the caller's 
// window station to the interactive window station.

   if (!SetProcessWindowStation(hwinsta))
      goto Cleanup;

// Get a handle to the interactive desktop.

   hdesk = OpenDesktop(
      "default",     // the interactive window station 
      0,             // no interaction with other desktop processes
      FALSE,         // handle is not inheritable
      READ_CONTROL | // request the rights to read and write the DACL
      WRITE_DAC | 
      DESKTOP_WRITEOBJECTS | 
      DESKTOP_READOBJECTS);

// Restore the caller's window station.

   if (!SetProcessWindowStation(hwinstaSave)) 
      goto Cleanup;

   if (hdesk == NULL) 
      goto Cleanup;

// Get the SID for the client's logon session.

   if (!GetLogonSID(hToken, &pSid)) 
      goto Cleanup;

// Allow logon SID full access to interactive window station.

   if (! AddAceToWindowStation(hwinsta, pSid) ) 
      goto Cleanup;

// Allow logon SID full access to interactive desktop.

   if (! AddAceToDesktop(hdesk, pSid) ) 
      goto Cleanup;

// Impersonate client to ensure access to executable file.

   if (! ImpersonateLoggedOnUser(hToken) ) 
      goto Cleanup;

// Initialize the STARTUPINFO structure.
// Specify that the process runs in the interactive desktop.

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

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

   bResult = CreateProcessAsUser(
      hToken,            // client's access token
      NULL,              // file to execute
      lpCommandLine,     // command line
      NULL,              // pointer to process SECURITY_ATTRIBUTES
      NULL,              // pointer to thread SECURITY_ATTRIBUTES
      FALSE,             // handles are not inheritable
      NORMAL_PRIORITY_CLASS | Create_NEW_CONSOLE,   // creation flags
      NULL,              // pointer to new environment block 
      NULL,              // name of current directory 
      &si,               // pointer to STARTUPINFO structure
      π                // receives information about new process
   ); 

// End impersonation of client.
   //dwError=GetLastError();
   RevertToSelf();

   if (bResult && pi.hProcess != INVALID_HANDLE_VALUE) 
   { 
      WaitForSingleObject(pi.hProcess, INFINITE); 
      CloseHandle(pi.hProcess); 
   } 

   if (pi.hThread != INVALID_HANDLE_VALUE)
      CloseHandle(pi.hThread);  

Cleanup: 

   if (hwinstaSave != NULL)
      SetProcessWindowStation (hwinstaSave);

// Free the buffer for the logon SID.

   if (pSid)
      FreeLogonSID(&pSid);

// Close the handles to the interactive window station and desktop.

   if (hwinsta)
      CloseWindowStation(hwinsta);

   if (hdesk)
      CloseDesktop(hdesk);

// Close the handle to the client's access token.

   if (hToken != INVALID_HANDLE_VALUE)
      CloseHandle(hToken);  

   return bResult;
}

BOOL AddAceToWindowStation(HWINSTA hwinsta,PSID psid)
{
   ACCESS_ALLOWED_ACE   *pace;
   ACL_SIZE_INFORMATION aclSizeInfo;
   BOOL                 bDaclExist;
   BOOL                 bDaclPresent;
   BOOL                 bSuccess = FALSE;
   DWORD                dwNewAclSize;
   DWORD                dwSidSize = 0;
   DWORD                dwSdSizeNeeded;
   PACL                 pacl;
   PACL                 pNewAcl;
   PSECURITY_DESCRIPTOR psd = NULL;
   PSECURITY_DESCRIPTOR psdNew = NULL;
   PVOID                pTempAce;
   SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION;
   unsigned int         i;

   __try
   {
      // Obtain the DACL for the window station.

      if (!GetUserObjectSecurity(
             hwinsta,
             &si,
             psd,
             dwSidSize,
             &dwSdSizeNeeded)
      )
      if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
      {
         psd = (PSECURITY_DESCRIPTOR)HeapAlloc(
               GetProcessHeap(),
               HEAP_ZERO_MEMORY,
               dwSdSizeNeeded);

         if (psd == NULL)
            __leave;

         psdNew = (PSECURITY_DESCRIPTOR)HeapAlloc(
               GetProcessHeap(),
               HEAP_ZERO_MEMORY,
               dwSdSizeNeeded);

         if (psdNew == NULL)
            __leave;

         dwSidSize = dwSdSizeNeeded;

         if (!GetUserObjectSecurity(
               hwinsta,
               &si,
               psd,
               dwSidSize,
               &dwSdSizeNeeded)
         )
            __leave;
      }
      else
         __leave;

      // Create a new DACL.

      if (!InitializeSecurityDescriptor(
            psdNew,
            SECURITY_DESCRIPTOR_REVISION)
      )
         __leave;

      // Get the DACL from the security descriptor.

      if (!GetSecurityDescriptorDacl(
            psd,
            &bDaclPresent,
            &pacl,
            &bDaclExist)
      )
         __leave;

      // Initialize the ACL.

      ZeroMemory(&aclSizeInfo, sizeof(ACL_SIZE_INFORMATION));
      aclSizeInfo.AclBytesInUse = sizeof(ACL);

      // Call only if the DACL is not NULL.

      if (pacl != NULL)
      {
         // get the file ACL size info
         if (!GetAclInformation(
               pacl,
               (LPVOID)&aclSizeInfo,
               sizeof(ACL_SIZE_INFORMATION),
               AclSizeInformation)
         )
            __leave;
      }

      // Compute the size of the new ACL.

      dwNewAclSize = aclSizeInfo.AclBytesInUse +
            (2*sizeof(ACCESS_ALLOWED_ACE)) + (2*GetLengthSid(psid)) -
            (2*sizeof(DWORD));

      // Allocate memory for the new ACL.

      pNewAcl = (PACL)HeapAlloc(
            GetProcessHeap(),
            HEAP_ZERO_MEMORY,
            dwNewAclSize);

      if (pNewAcl == NULL)
         __leave;

      // Initialize the new DACL.

      if (!InitializeAcl(pNewAcl, dwNewAclSize, ACL_REVISION))
         __leave;

      // If DACL is present, copy it to a new DACL.

      if (bDaclPresent)
      {
         // Copy the ACEs to the new ACL.
         if (aclSizeInfo.AceCount)
         {
            for (i=0; i < aclSizeInfo.AceCount; i++)
            {
               // Get an ACE.
               if (!GetAce(pacl, i, &pTempAce))
                  __leave;

               // Add the ACE to the new ACL.
               if (!AddAce(
                     pNewAcl,
                     ACL_REVISION,
                     MAXDWORD,
                     pTempAce,
                    ((PACE_HEADER)pTempAce)->AceSize)
               )
                  __leave;
            }
         }
      }

      // Add the first ACE to the window station.

      pace = (ACCESS_ALLOWED_ACE *)HeapAlloc(
            GetProcessHeap(),
            HEAP_ZERO_MEMORY,
            sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psid) -
                  sizeof(DWORD));

      if (pace == NULL)
         __leave;

      pace->Header.AceType  = ACCESS_ALLOWED_ACE_TYPE;
      pace->Header.AceFlags = CONTAINER_INHERIT_ACE |
                   INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE;
      pace->Header.AceSize  = sizeof(ACCESS_ALLOWED_ACE) +
                   GetLengthSid(psid) - sizeof(DWORD);
      pace->Mask            = GENERIC_ACCESS;

      if (!CopySid(GetLengthSid(psid), &pace->SidStart, psid))
         __leave;

      if (!AddAce(
            pNewAcl,
            ACL_REVISION,
            MAXDWORD,
            (LPVOID)pace,
            pace->Header.AceSize)
      )
         __leave;

      // Add the second ACE to the window station.

      pace->Header.AceFlags = NO_PROPAGATE_INHERIT_ACE;
      pace->Mask            = WINSTA_ALL;

      if (!AddAce(
            pNewAcl,
            ACL_REVISION,
            MAXDWORD,
            (LPVOID)pace,
            pace->Header.AceSize)
      )
         __leave;

      // Set a new DACL for the security descriptor.

      if (!SetSecurityDescriptorDacl(
            psdNew,
            TRUE,
            pNewAcl,
            FALSE)
      )
         __leave;

      // Set the new security descriptor for the window station.

      if (!SetUserObjectSecurity(hwinsta, &si, psdNew))
         __leave;

      // Indicate success.

      bSuccess = TRUE;
   }
   __finally
   {
      // Free the allocated buffers.

      if (pace != NULL)
         HeapFree(GetProcessHeap(), 0, (LPVOID)pace);

      if (pNewAcl != NULL)
         HeapFree(GetProcessHeap(), 0, (LPVOID)pNewAcl);

      if (psd != NULL)
         HeapFree(GetProcessHeap(), 0, (LPVOID)psd);

      if (psdNew != NULL)
         HeapFree(GetProcessHeap(), 0, (LPVOID)psdNew);
   }

   return bSuccess;

}

BOOL AddAceToDesktop(HDESK hdesk, PSID psid)
{
   ACL_SIZE_INFORMATION aclSizeInfo;
   BOOL                 bDaclExist;
   BOOL                 bDaclPresent;
   BOOL                 bSuccess = FALSE;
   DWORD                dwNewAclSize;
   DWORD                dwSidSize = 0;
   DWORD                dwSdSizeNeeded;
   PACL                 pacl;
   PACL                 pNewAcl;
   PSECURITY_DESCRIPTOR psd = NULL;
   PSECURITY_DESCRIPTOR psdNew = NULL;
   PVOID                pTempAce;
   SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION;
   unsigned int         i;

   __try
   {
      // Obtain the security descriptor for the desktop object.

      if (!GetUserObjectSecurity(
            hdesk,
            &si,
            psd,
            dwSidSize,
            &dwSdSizeNeeded))
      {
         if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
         {
            psd = (PSECURITY_DESCRIPTOR)HeapAlloc(
                  GetProcessHeap(),
                  HEAP_ZERO_MEMORY,
                  dwSdSizeNeeded );

            if (psd == NULL)
               __leave;

            psdNew = (PSECURITY_DESCRIPTOR)HeapAlloc(
                  GetProcessHeap(),
                  HEAP_ZERO_MEMORY,
                  dwSdSizeNeeded);

            if (psdNew == NULL)
               __leave;

            dwSidSize = dwSdSizeNeeded;

            if (!GetUserObjectSecurity(
                  hdesk,
                  &si,
                  psd,
                  dwSidSize,
                  &dwSdSizeNeeded)
            )
               __leave;
         }
         else
            __leave;
      }

      // Create a new security descriptor.

      if (!InitializeSecurityDescriptor(
            psdNew,
            SECURITY_DESCRIPTOR_REVISION)
      )
         __leave;

      // Obtain the DACL from the security descriptor.

      if (!GetSecurityDescriptorDacl(
            psd,
            &bDaclPresent,
            &pacl,
            &bDaclExist)
      )
         __leave;

      // Initialize.

      ZeroMemory(&aclSizeInfo, sizeof(ACL_SIZE_INFORMATION));
      aclSizeInfo.AclBytesInUse = sizeof(ACL);

      // Call only if NULL DACL.

      if (pacl != NULL)
      {
         // Determine the size of the ACL information.

         if (!GetAclInformation(
               pacl,
               (LPVOID)&aclSizeInfo,
               sizeof(ACL_SIZE_INFORMATION),
               AclSizeInformation)
         )
            __leave;
      }

      // Compute the size of the new ACL.

      dwNewAclSize = aclSizeInfo.AclBytesInUse +
            sizeof(ACCESS_ALLOWED_ACE) +
            GetLengthSid(psid) - sizeof(DWORD);

      // Allocate buffer for the new ACL.

      pNewAcl = (PACL)HeapAlloc(
            GetProcessHeap(),
            HEAP_ZERO_MEMORY,
            dwNewAclSize);

      if (pNewAcl == NULL)
         __leave;

      // Initialize the new ACL.

      if (!InitializeAcl(pNewAcl, dwNewAclSize, ACL_REVISION))
         __leave;

      // If DACL is present, copy it to a new DACL.

      if (bDaclPresent)
      {
         // Copy the ACEs to the new ACL.
         if (aclSizeInfo.AceCount)
         {
            for (i=0; i < aclSizeInfo.AceCount; i++)
            {
               // Get an ACE.
               if (!GetAce(pacl, i, &pTempAce))
                  __leave;

               // Add the ACE to the new ACL.
               if (!AddAce(
                  pNewAcl,
                  ACL_REVISION,
                  MAXDWORD,
                  pTempAce,
                  ((PACE_HEADER)pTempAce)->AceSize)
               )
                  __leave;
            }
         }
      }

      // Add ACE to the DACL.

      if (!AddAccessAllowedAce(
            pNewAcl,
            ACL_REVISION,
            DESKTOP_ALL,
            psid)
      )
         __leave;

      // Set new DACL to the new security descriptor.

      if (!SetSecurityDescriptorDacl(
            psdNew,
            TRUE,
            pNewAcl,
            FALSE)
      )
         __leave;

      // Set the new security descriptor for the desktop object.

      if (!SetUserObjectSecurity(hdesk, &si, psdNew))
         __leave;

      // Indicate success.

      bSuccess = TRUE;
   }
   __finally
   {
      // Free buffers.

      if (pNewAcl != NULL)
         HeapFree(GetProcessHeap(), 0, (LPVOID)pNewAcl);

      if (psd != NULL)
         HeapFree(GetProcessHeap(), 0, (LPVOID)psd);

      if (psdNew != NULL)
         HeapFree(GetProcessHeap(), 0, (LPVOID)psdNew);
   }

   return bSuccess;
}

BOOL GetLogonSID (HANDLE hToken, PSID *ppsid) 
{
   BOOL bSuccess = FALSE;
   DWORD dwIndex;
   DWORD dwLength = 0;
   PTOKEN_GROUPS ptg = NULL;

// Verify the parameter passed in is not NULL.
    if (NULL == ppsid)
        goto Cleanup;

// Get required buffer size and allocate the TOKEN_GROUPS buffer.

   if (!GetTokenInformation(
         hToken,         // handle to the access token
         TokenGroups,    // get information about the token's groups 
         (LPVOID) ptg,   // pointer to TOKEN_GROUPS buffer
         0,              // size of buffer
         &dwLength       // receives required buffer size
      )) 
   {
      if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) 
         goto Cleanup;

      ptg = (PTOKEN_GROUPS)HeapAlloc(GetProcessHeap(),
         HEAP_ZERO_MEMORY, dwLength);

      if (ptg == NULL)
         goto Cleanup;
   }

// Get the token group information from the access token.

   if (!GetTokenInformation(
         hToken,         // handle to the access token
         TokenGroups,    // get information about the token's groups 
         (LPVOID) ptg,   // pointer to TOKEN_GROUPS buffer
         dwLength,       // size of buffer
         &dwLength       // receives required buffer size
         )) 
   {
      goto Cleanup;
   }

// Loop through the groups to find the logon SID.

   for (dwIndex = 0; dwIndex < ptg->GroupCount; dwIndex++) 
      if ((ptg->Groups[dwIndex].Attributes & SE_GROUP_LOGON_ID)
             ==  SE_GROUP_LOGON_ID) 
      {
      // Found the logon SID; make a copy of it.

         dwLength = GetLengthSid(ptg->Groups[dwIndex].Sid);
         *ppsid = (PSID) HeapAlloc(GetProcessHeap(),
                     HEAP_ZERO_MEMORY, dwLength);
         if (*ppsid == NULL)
             goto Cleanup;
         if (!CopySid(dwLength, *ppsid, ptg->Groups[dwIndex].Sid)) 
         {
             HeapFree(GetProcessHeap(), 0, (LPVOID)*ppsid);
             goto Cleanup;
         }
         break;
      }

   bSuccess = TRUE;

Cleanup: 

// Free the buffer for the token groups.

   if (ptg != NULL)
      HeapFree(GetProcessHeap(), 0, (LPVOID)ptg);

   return bSuccess;
}


VOID FreeLogonSID (PSID *ppsid) 
{
    HeapFree(GetProcessHeap(), 0, (LPVOID)*ppsid);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值