zoukankan      html  css  js  c++  java
  • 在任意的远程桌面的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;
    }
    
  • 相关阅读:
    Python学习笔记之操作yalm
    Python学习笔记之多线程
    Python学习笔记之网络编程
    Python学习笔记之面对象与错误处理
    Python学习笔记之装饰器
    Python学习笔记之内置模块
    Python学习笔记之函数与正则
    PAT甲级1049. Counting Ones
    PAT甲级1045. Favorite Color Stripe
    PAT甲级1034. Head of a Gang
  • 原文地址:https://www.cnblogs.com/FCoding/p/2572280.html
Copyright © 2011-2022 走看看