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 }
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 }