在任意的遠程桌面的session中運行指定的程序


//在其它session中(如遠程桌面的session)運行指定的程序,需要具有system權限,可以在任意的桌面里運行指定程序

#include <windows.h>
#include <stdio.h>
#include <process.h>
#include <Tlhelp32.h>
#include <tchar.h>
#include <psapi.h>
#include <stdio.h>
#include <STDLIB.H>
#include <tlhelp32.h> 
#include <WtsApi32.h>
#pragma comment(lib, "WtsApi32.lib")
#pragma  comment (lib,"psapi")


// Get username from session id
bool GetSessionUserName(DWORD dwSessionId, char username[256])
{
        LPTSTR pBuffer = NULL;
        DWORD dwBufferLen;
        
        BOOL bRes = WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, dwSessionId, WTSUserName, &pBuffer, &dwBufferLen);
        
        if (bRes == FALSE)
                return false;
        
        lstrcpy(username ,pBuffer);
        WTSFreeMemory(pBuffer);
        
        return true;
}

// Get domain name from session id
bool GetSessionDomain(DWORD dwSessionId, char domain[256])
{
        LPTSTR pBuffer = NULL;
        DWORD dwBufferLen;
        
        BOOL bRes = WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, dwSessionId, WTSDomainName, &pBuffer, &dwBufferLen);
        
        if (bRes == FALSE)
        {
                printf("WTSQuerySessionInformation Fail!\n");
                return false;
        }
        
        lstrcpy(domain,pBuffer);
        WTSFreeMemory(pBuffer);
        
        return true;
}



HANDLE GetProcessHandle(LPSTR szExeName)  //遍歷進程PID

{  
        
        PROCESSENTRY32 Pc = { sizeof(PROCESSENTRY32) };  
        
        HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0);  
        
        if(Process32First(hSnapshot, &Pc)){  
                
                do{  
                        
                        if(!stricmp(Pc.szExeFile, szExeName)) {   //返回explorer.exe進程的PID
                                printf("explorer's PID=%d\n",Pc.th32ProcessID);
                                return OpenProcess(PROCESS_ALL_ACCESS, TRUE, Pc.th32ProcessID);  
                                
            }  
                        
                }while(Process32Next(hSnapshot, &Pc));  
                
    }  
        
        
        
        return NULL;  
} 


//輸出幫助的典型方法:
void Usage (void)
{
        fprintf(stderr,"===============================================================================\n"
                "\t名稱:在任意的遠程桌面的session中運行指定的程序,需要具有system權限\n"
                "\t環境:Win2003 + Visual C++ 6.0\n"
                "\t作者:pt007@vip.sina.com\n"
                "\t  QQ:7491805\n"
                "\t聲明:本軟件由pt007原創,轉載請注明出處,謝謝!\n"
                "\n"
                "\t使用方法:\n"
                "\tsession 1 c:\\win2003\\system32\\svchosts.exe //在會話1里面運行程序!\n"
                 "===============================================================================\n");
}

int main(int argc, char **argv) 
{ 
    

  if(argc==1) //遍歷所有的session

  {// 函數的句柄

     HMODULE hInstKernel32    = NULL;

     HMODULE hInstWtsapi32    = NULL;

// 這里的代碼用的是VC6,新版的SDK已經包括此函數,無需LoadLibrary了。
     typedef DWORD (WINAPI *WTSGetActiveConsoleSessionIdPROC)();

     WTSGetActiveConsoleSessionIdPROC WTSGetActiveConsoleSessionId = NULL;

     hInstKernel32 = LoadLibrary("Kernel32.dll");

if (!hInstKernel32)

{

    return FALSE;

}


   WTSGetActiveConsoleSessionId = (WTSGetActiveConsoleSessionIdPROC)GetProcAddress(hInstKernel32,"WTSGetActiveConsoleSessionId");

if (!WTSGetActiveConsoleSessionId)

{

   return FALSE;

}


// WTSQueryUserToken 函數,通過會話ID得到令牌

   typedef BOOL (WINAPI *WTSQueryUserTokenPROC)(ULONG SessionId, PHANDLE phToken );

   WTSQueryUserTokenPROC WTSQueryUserToken = NULL;

   hInstWtsapi32 = LoadLibrary("Wtsapi32.dll");

if (!hInstWtsapi32)

{

   return FALSE;

}


   WTSQueryUserToken = (WTSQueryUserTokenPROC)GetProcAddress(hInstWtsapi32,"WTSQueryUserToken");

if (!WTSQueryUserToken)

{

   return FALSE;

}




//遍歷3389登錄的session:
/*
typedef struct _WTS_SESSION_INFO {
        DWORD                  SessionId;
        LPTSTR                 pWinStationName;
        WTS_CONNECTSTATE_CLASS State;
}WTS_SESSION_INFO, *PWTS_SESSION_INFO;
*/
   WTS_SESSION_INFO *sessionInfo = NULL;
   DWORD sessionInfoCount;
   char domain1[256];
   char username1[256];
   BOOL result = WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &sessionInfo, &sessionInfoCount);

   unsigned int userCount(0);
int num=0;
for(unsigned int i = 0; i < sessionInfoCount; ++i)
{
        if( (sessionInfo[i].State == WTSActive) || (sessionInfo[i].State == WTSDisconnected) )
                
        {   
                printf("session %d information:\n",num++);
                printf("\tsessionInfo.SessionId=%d\n",sessionInfo[i].SessionId);
                GetSessionDomain(sessionInfo[i].SessionId, domain1); //獲得Session Domain
                printf("\tSession Domain = %s\n",domain1); 

            GetSessionUserName(sessionInfo[i].SessionId,username1);
                printf("\tSession user's name = %s\n",username1); 

                userCount++;
        }
  }
   printf("session's number:%d\n\n",userCount);
     Usage();
   //printf("example:\n\tsession 1 c:\\win2003\\system32\\svchosts.exe //在會話1里面運行程序!\n");
   //printf("程序說明:在其它session中(如任意的遠程桌面的session中)運行指定的程序,需要具有system權限\n");
   WTSFreeMemory(sessionInfo); //釋放
  
  }
   else if(argc==3) //session 1 c:\win2003\temp\klog.exe
  {

  
// 得到當前登錄用戶的令

/*HANDLE hTokenDup = NULL;
bRes = WTSQueryUserToken(dwSessionId, &hTokenDup);

if (!bRes)

{
        printf("WTSQueryUserToken Failed!%d\n",GetLastError());
        
        return FALSE;
        
}*/



/*bRes = ImpersonateLoggedOnUser(hTokenDup);

if (!bRes)

{
        printf("ImpersonateLoggedOnUser!%d\n",GetLastError());

return FALSE;

}*/


//MessageBox(NULL,"test2","test1",MB_OK);
//system("winver.exe");

HANDLE hThisProcess = GetCurrentProcess(); // 獲取當前進程句柄

        //HANDLE   hThisProcess   = GetProcessHandle("EXPLORER.EXE");   
        //if(hThisProcess   ==   NULL) 
// return   0; 

// 打開當前進程令牌

HANDLE hTokenThis = NULL;
HANDLE hTokenDup = NULL;

OpenProcessToken(hThisProcess, TOKEN_ALL_ACCESS, &hTokenThis);



// 復制一個進程令牌,目的是為了修改session id屬性,以便在其它session中創建進程



DuplicateTokenEx(hTokenThis, MAXIMUM_ALLOWED,NULL, SecurityIdentification, TokenPrimary, &hTokenDup);
//獲取活動session id,這里要注意,如果服務器還沒有被登錄而使用了遠程桌面,這樣用是可以的,如果有多個session存在,
//不能簡單使用此函數,需要枚舉所有session並確定你需要的一個,或者干脆使用循環,針對每個session都執行后面的代碼

//SetTokenInformation(hTokenDup, TokenSessionId, &dwSessionId, sizeof(DWORD)); //把session id設置到備份的令牌中
DWORD dwSessionId=atoi(argv[1]); //與會話進行連接
bool bRes;
bRes=SetTokenInformation(hTokenDup, TokenSessionId, &dwSessionId, sizeof(DWORD));


if (!bRes)
         
{
         printf("SetTokenInformation!%d\n",GetLastError());
         return FALSE;
}

// 好了,現在要用新的令牌來創建一個服務進程。注意:是“服務”進程!如果需要以用戶身份運行,必須在前面執行LogonUser來獲取用戶令牌


STARTUPINFO si;

PROCESS_INFORMATION pi;

ZeroMemory(&si, sizeof(STARTUPINFO));

ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));

si.cb = sizeof(STARTUPINFO);

si.lpDesktop = "WinSta0\\Default";



LPVOID pEnv = NULL;

DWORD dwCreationFlag = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE; // 注意標志

//CreateEnvironmentBlock(&pEnv, hTokenDup, FALSE); // 創建環境塊

// 創建新的進程,這個進程就是你要彈出窗口的進程,它將工作在新的session中
   char path[MAX_PATH];
   lstrcpy(path,argv[2]);
   CreateProcessAsUser(hTokenDup, NULL, (char *)path, NULL, NULL, FALSE, dwCreationFlag, pEnv, NULL, &si, &pi);
  }
    return 0;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM