注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

BCB-DG's Blog

...

 
 
 

日志

 
 

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

2010-03-09 13:56:54|  分类: Delphi |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
pt007@vip.sina.com

//在其它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")

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) return false;
    lstrcpy(username, pBuffer);
    WTSFreeMemory(pBuffer);
    return true;
}

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) return false;
    lstrcpy(domain,pBuffer);
    WTSFreeMemory(pBuffer);
    return true;
}

HANDLE GetProcessHandle(LPSTR szExeName)
{       
    PROCESSENTRY32 Pc = { sizeof(PROCESSENTRY32) };
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0);
    if (Process32First(hSnapshot, &Pc))
    {
        do
        {
            if (!stricmp(Pc.szExeFile, szExeName))
            {   
                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, "名称:在任意的远程桌面的session中运行指定的程序,须要具有system权限\n"
                    "环境:Win2003 + Visual C++ 6.0\n"
                    "作者:pt007@vip.sina.com\n"
                    "session 1 c:\\win2003\\system32\\svchosts.exe //在会话1里面运行程序!\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); */
        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 = 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;
}
  评论这张
 
阅读(1147)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017