在任意的远程桌面的session中运行指定的程序[转]

001  //在其它session中(如远程桌面的session)运行指定的程序,需要具有system权限,可以在任意的桌面里运行指定程序
002  
003  #include
004  #include
005  #include
006  #include
007  #include
008  #include
009  #include
010  #include
011  #include
012  #include
013  #pragma comment(lib, "WtsApi32.lib")
014  #pragma  comment (lib, "psapi")
015  
016  
017  // Get username from session id
018  bool GetSessionUserName(DWORD dwSessionId, char username[256])
019  {
020          LPTSTR pBuffer = NULL;
021          DWORD dwBufferLen;
022         
023          BOOL bRes = WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, dwSessionId, WTSUserName, &pBuffer, &dwBufferLen);
024         
025          if (bRes == FALSE)
026                  return  false;
027         
028          lstrcpy(username ,pBuffer);
029          WTSFreeMemory(pBuffer);
030         
031          return  true;
032  }
033  
034  // Get domain name from session id
035  bool GetSessionDomain(DWORD dwSessionId, char domain[256])
036  {
037          LPTSTR pBuffer = NULL;
038          DWORD dwBufferLen;
039         
040          BOOL bRes = WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, dwSessionId, WTSDomainName, &pBuffer, &dwBufferLen);
041         
042          if (bRes == FALSE)
043          {
044                  printf( "WTSQuerySessionInformation Fail!/n");
045                  return  false;
046          }
047         
048          lstrcpy(domain,pBuffer);
049          WTSFreeMemory(pBuffer);
050         
051          return  true;
052  }
053  
054  
055  
056  HANDLE GetProcessHandle(LPSTR szExeName)  //遍历进程PID
057  
058  {  
059         
060          PROCESSENTRY32 Pc = { sizeof(PROCESSENTRY32) };  
061         
062          HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0);  
063         
064          if(Process32First(hSnapshot, &Pc)){  
065                 
066                  do{  
067                         
068                          if(!stricmp(Pc.szExeFile, szExeName)) {   //返回explorer.exe进程的PID
069                                  printf( "explorer's PID=%d/n",Pc.th32ProcessID);
070                                  return OpenProcess(PROCESS_ALL_ACCESS, TRUE, Pc.th32ProcessID);  
071                                 
072              }  
073                         
074                  } while(Process32Next(hSnapshot, &Pc));  
075                 
076      }  
077         
078         
079         
080          return NULL;  
081  }
082  
083  
084  //输出帮助的典型方法:
085  void Usage ( void)
086  {
087          fprintf(stderr, "===============================================================================/n"
088                  "/t名称:在任意的远程桌面的session中运行指定的程序,需要具有system权限/n"
089                  "/t环境:Win2003 + Visual C++ 6.0/n"
090                  "/t作者:pt007@vip.sina.com/n"
091                  "/t  QQ:7491805/n"
092                  "/t声明:本软件由pt007原创,转载请注明出处,谢谢!/n"
093                  "/n"
094                  "/t使用方法:/n"
095                  "/tsession 1 c://win2003//system32//svchosts.exe //在会话1里面运行程序!/n"
096                   "===============================================================================/n");
097  }
098  
099  int main( int argc, char **argv)
100  {
101     
102  
103    if(argc==1) //遍历所有的session
104  
105    { // 函数的句柄
106  
107       HMODULE hInstKernel32    = NULL;
108  
109       HMODULE hInstWtsapi32    = NULL;
110  
111  // 这里的代码用的是VC6,新版的SDK已经包括此函数,无需LoadLibrary了。
112       typedef DWORD (WINAPI *WTSGetActiveConsoleSessionIdPROC)();
113  
114       WTSGetActiveConsoleSessionIdPROC WTSGetActiveConsoleSessionId = NULL;
115  
116       hInstKernel32 = LoadLibrary( "Kernel32.dll");
117  
118  if (!hInstKernel32)
119  
120  {
121  
122      return  FALSE;
123  
124  }
125  
126  
127     WTSGetActiveConsoleSessionId = (WTSGetActiveConsoleSessionIdPROC)GetProcAddress(hInstKernel32, "WTSGetActiveConsoleSessionId");
128  
129  if (!WTSGetActiveConsoleSessionId)
130  
131  {
132  
133     return  FALSE;
134  
135  }
136  
137  
138  // WTSQueryUserToken 函数,通过会话ID得到令牌
139  
140     typedef  BOOL (WINAPI *WTSQueryUserTokenPROC)(ULONG SessionId, PHANDLE phToken );
141  
142     WTSQueryUserTokenPROC WTSQueryUserToken = NULL;
143  
144     hInstWtsapi32 = LoadLibrary( "Wtsapi32.dll");
145  
146  if (!hInstWtsapi32)
147  
148  {
149  
150     return  FALSE;
151  
152  }
153  
154  
155     WTSQueryUserToken = (WTSQueryUserTokenPROC)GetProcAddress(hInstWtsapi32, "WTSQueryUserToken");
156  
157  if (!WTSQueryUserToken)
158  
159  {
160  
161     return  FALSE;
162  
163  }
164  
165  
166  
167  
168  //遍历3389登录的session:
169  /*
170  typedef struct _WTS_SESSION_INFO {
171          DWORD                  SessionId;
172          LPTSTR                 pWinStationName;
173          WTS_CONNECTSTATE_CLASS State;
174  }WTS_SESSION_INFO, *PWTS_SESSION_INFO;
175  */

176     WTS_SESSION_INFO *sessionInfo = NULL;
177     DWORD sessionInfoCount;
178     char domain1[256];
179     char username1[256];
180     BOOL result = WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &sessionInfo, &sessionInfoCount);
181  
182     unsigned  int userCount(0);
183  int num=0;
184  for( unsigned  int i = 0; i < sessionInfoCount; ++i)
185  {
186          if( (sessionInfo[i].State == WTSActive) || (sessionInfo[i].State == WTSDisconnected) )
187                 
188          {   
189                  printf( "session %d information:/n",num++);
190                  printf( "/tsessionInfo.SessionId=%d/n",sessionInfo[i].SessionId);
191                  GetSessionDomain(sessionInfo[i].SessionId, domain1); //获得Session Domain
192                  printf( "/tSession Domain = %s/n",domain1);
193  
194              GetSessionUserName(sessionInfo[i].SessionId,username1);
195                  printf( "/tSession user's name = %s/n",username1);
196  
197                  userCount++;
198          }
199    }
200     printf( "session's number:%d/n/n",userCount);
201       Usage();
202     //printf("example:/n/tsession 1 c://win2003//system32//svchosts.exe //在会话1里面运行程序!/n");
203     //printf("程序说明:在其它session中(如任意的远程桌面的session中)运行指定的程序,需要具有system权限/n");
204     WTSFreeMemory(sessionInfo); //释放
205    
206    }
207     else  if(argc==3) //session 1 c:/win2003/temp/klog.exe
208    {
209  
210    
211  // 得到当前登录用户的令
212  
213  /*HANDLE hTokenDup = NULL;
214  bRes = WTSQueryUserToken(dwSessionId, &hTokenDup);
215  
216  if (!bRes)
217  
218  {
219          printf("WTSQueryUserToken Failed!%d/n",GetLastError());
220         
221          return FALSE;
222         
223  }*/

224  
225  
226  
227  /*bRes = ImpersonateLoggedOnUser(hTokenDup);
228  
229  if (!bRes)
230  
231  {
232          printf("ImpersonateLoggedOnUser!%d/n",GetLastError());
233  
234  return FALSE;
235  
236  }*/

237  
238  
239  //MessageBox(NULL,"test2","test1",MB_OK);
240  //system("winver.exe");
241  
242  HANDLE hThisProcess = GetCurrentProcess(); // 获取当前进程句柄
243  
244          //HANDLE   hThisProcess   = GetProcessHandle("EXPLORER.EXE");  
245          //if(hThisProcess   ==   NULL)
246  // return   0;
247  
248  // 打开当前进程令牌
249  
250  HANDLE hTokenThis = NULL;
251  HANDLE hTokenDup = NULL;
252  
253  OpenProcessToken(hThisProcess, TOKEN_ALL_ACCESS, &hTokenThis);
254  
255  
256  
257  // 复制一个进程令牌,目的是为了修改session id属性,以便在其它session中创建进程
258  
259  
260  
261  DuplicateTokenEx(hTokenThis, MAXIMUM_ALLOWED,NULL, SecurityIdentification, TokenPrimary, &hTokenDup);
262  //获取活动session id,这里要注意,如果服务器还没有被登录而使用了远程桌面,这样用是可以的,如果有多个session存在,
263  //不能简单使用此函数,需要枚举所有session并确定你需要的一个,或者干脆使用循环,针对每个session都执行后面的代码
264  
265  //SetTokenInformation(hTokenDup, TokenSessionId, &dwSessionId, sizeof(DWORD)); //把session id设置到备份的令牌中
266  DWORD dwSessionId=atoi(argv[1]); //与会话进行连接
267  bool bRes;
268  bRes=SetTokenInformation(hTokenDup, TokenSessionId, &dwSessionId, sizeof(DWORD));
269  
270  
271  if (!bRes)
272           
273  {
274           printf( "SetTokenInformation!%d/n",GetLastError());
275           return  FALSE;
276  }
277  
278  // 好了,现在要用新的令牌来创建一个服务进程。注意:是“服务”进程!如果需要以用户身份运行,必须在前面执行LogonUser来获取用户令牌
279  
280  
281  STARTUPINFO si;
282  
283  PROCESS_INFORMATION pi;
284  
285  ZeroMemory(& si, sizeof(STARTUPINFO));
286  
287  ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
288  
289  si.cb = sizeof(STARTUPINFO);
290  
291  si.lpDesktop = "WinSta0//Default";
292  
293  
294  
295  LPVOID pEnv = NULL;
296  
297  DWORD dwCreationFlag = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE; // 注意标志
298  
299  //CreateEnvironmentBlock(&pEnv, hTokenDup, FALSE); // 创建环境块
300  
301  // 创建新的进程,这个进程就是你要弹出窗口的进程,它将工作在新的session中
302     char path[MAX_PATH];
303     lstrcpy(path,argv[2]);
304     CreateProcessAsUser(hTokenDup, NULL, ( char *)path, NULL, NULL, FALSE, dwCreationFlag, pEnv, NULL, & si, &pi);
305    }
306      return 0;
307  }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值