注销远程用户(会话)

来源:互联网 发布:淘宝介入微信怎么举证 编辑:程序博客网 时间:2024/05/05 09:13

Delphi实现:

uses

WtsApi32;

//通过会话ID得到会话名称procedure GetSessionUserName(dwSessionId: dword; var UserName: string);var  bRes: boolean;  dwBufferLen: dword;  Ptr: Pointer;begin  bRes := WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, dwSessionId, WTSUserName, Ptr, dwBufferLen);  if bRes = false then  begin         UserName := '';          exit;  end;  UserName := PWideChar(Ptr);end;
//通过会话名称结束目标会话procedure ExitByUserName(str: string);var  i: integer;  sessionInfo: PWTS_SESSION_INFOW;  sessionInfoCount: dword;  dwSessionId: dword;  UserName: string;  CommandLine: string;begin  if WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, sessionInfo, sessionInfoCount) then  begin    for i := 0 to sessionInfoCount - 1 do    begin      //遍历注销状态为“活动”或者“断开”的所有目标会话       if (sessionInfo.state = WTSActive) or (sessionInfo.state = WTSDisconnected) then      begin        dwSessionId := sessionInfo.SessionId;        GetSessionUserName(dwSessionId, UserName);        if UserName = str then        begin          CommandLine := Format('LOGOFF %d', [dwSessionId]);          winexec(PAnsiChar(ansistring(CommandLine)), SW_HIDE);          Sleep(2500);        end;      end;      inc(sessionInfo);    end;  end;end;


 

 

C++实现:

//在其它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 idbool 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 idbool 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进程的PIDprintf("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作者:***\n""\t  QQ:***\n""\t声明:***!\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;}


 

原创粉丝点击