我如何运行我的应用程序而UAC对话框窗口中显示?我的、对话框、应用程序、窗口中

2023-09-04 00:10:39 作者:淡淡de小永远

我有我在。NET写了一份申请。它需要保持运行并访问该UAC对话框打开窗户上,并与使用键盘和鼠标事件,桌面交互桌面。

I have an application that I wrote in .NET. It needs to remain running and have access the desktop that the UAC dialog windows open on and interact with that desktop using keyboard and mouse events.

这有点像一个VNC程序。想象一下,你正在运行的VNC程序和UAC窗口弹出,你希望你的VNC程序仍然能够控制的桌面与它的UAC窗口的,以便用户可以移动鼠标点击UAC对话框上的OK按钮。谁能告诉我,我怎么会去这样做?

It's sort of like a VNC program. Imagine you are running a VNC program and a UAC window pops up, you want your VNC program to still be able to control the desktop with the UAC window in it so that the user can move the mouse and click the OK button on the UAC dialog. Can anyone tell me how I would go about doing that?

感谢

推荐答案

我会建议你通过阅读的文档。我猜想,也许你​​可以打开的窗口站和连接你的过程,但我不是很熟悉Windows的这个区域。

I would suggest you start by reading the documentation. I would guess that maybe you could open the window station and attach your process to it, but I am not very familiar with this area of Windows.

编辑1:

在Windows XP中,我能够通过OpenDesktop的系统上运行时访问安全桌面(从Winlogon);在安全桌面上的ACL只允许访问SYSTEM帐户。打开后,我可以列举在上面的窗口,但当时只有极少数。也许你可以设置窗口钩子,并听取创造特定的对话框。我不知道,如果Vista的改变了这种模式,所以也许它不会工作;我没有一个Vista的机器在我面前再次进行测试。

In Windows XP I was able to access the secure desktop ("winlogon") via OpenDesktop when running as SYSTEM; the ACL on the secure desktop allows access only to the SYSTEM account. After opening it I could enumerate the windows on it, though there were only a handful. Perhaps you could set a window hook and listen for creation of the specific dialog. I'm not sure if Vista changed this model, so maybe it won't work; I don't have a Vista machine in front of me to test against.

编辑2:

好吧,我得到了一些主要工作(在Windows 7测试)。首先,你必须有运行的系统服务。从该服务,您需要启动在用户的会话一个单独的应用程序。要做到这一点,列举所有寻找WINLOGON.EXE的进程,打开它的道理,和CreateProcessAsUser。指定WinSta0 \ Winlogon中为STARTUPINFO的lpDesktop参数。现在你有作为SYSTEM运行在用户的会话了Winlogon中桌面上的进程。在新的过程中,你可以做任何你想要的;我做了一个快速测试与EnumDesktopWindows,我能得到的窗口类和文本的各种UAC相关的窗口($$$安全UAP后台窗口,$$$安全UAP背景伪造客户端窗口,等等)。我不知道如何确定显示UAC提示时,虽然;作为一个快速黑客,你可以只运行一个循环每隔100毫秒寻找UAC窗口或东西。我可以粘贴一些code。如果这将有助于。

Ok, I got something that mostly works (tested on Windows 7). First you have to have a service running as SYSTEM. From that service, you need to launch a separate application in the user's session. To do this, enumerate all the processes looking for winlogon.exe, open its token, and CreateProcessAsUser. Specify "WinSta0\Winlogon" for the lpDesktop parameter of STARTUPINFO. Now you have a process running as SYSTEM in the user's session on the "Winlogon" desktop. In the new process you can do whatever you want; I did a quick test with EnumDesktopWindows and I was able to get the window class and text for various UAC related windows ("$$$Secure UAP Background Window", "$$$Secure UAP Background Fake Client Window", etc). I'm not sure how to determine when a UAC prompt is being displayed, though; as a quick hack you could just run a loop every 100 ms looking for UAC windows or something. I could paste some code if it would help.

编辑3:

确定。我已经写了一个Win32服务,它采用下列参数:

Ok. I have written a Win32 service that takes the following parameters:

/安装 - 安装服务 /卸载 - 卸载服务 /服务 - 作为服务运行;通过供应链管理调用 /客户端 - 运行作为一个客户端;通过CreateProcessAsUser调用

/install - installs the service /uninstall - uninstalls the service /service - runs as a service; invoked via SCM /client - runs as a client; invoked via CreateProcessAsUser

唯一有趣的code是在/服务/客户端模式。

The only interesting code is in the /service and /client modes.

在/服务模式是通过EnumProcesses和GetModuleFileNameEx寻找WINLOGON.EXE列举正在运行的进程。当它找到一个它会打开它的令牌,并通过CreateProcessAsUser推出自己在/客户端模式:

In /service mode it enumerates the running processes via EnumProcesses and GetModuleFileNameEx looking for "winlogon.exe". When it finds one it opens its token and launches itself in /client mode via CreateProcessAsUser:

HANDLE hProcess = ...;
// winlogon.exe runs as SYSTEM in user's session; we need to run the same way
HANDLE hToken = NULL;
if(OpenProcessToken(hProcess, TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY, &hToken))
{
    TCHAR szCommandLine[MAX_PATH];
    GetModuleFileName(NULL, szCommandLine, MAX_PATH);
    PathQuoteSpaces(szCommandLine);
    // run in /client mode
    _tcscat_s(szCommandLine, MAX_PATH, _T(" /client"));
    STARTUPINFO StartupInfo;
    ZeroMemory(&StartupInfo, sizeof(STARTUPINFO));
    StartupInfo.cb = sizeof(STARTUPINFO);
    // run on the Winlogon desktop
    StartupInfo.lpDesktop = _T("WinSta0\\Winlogon");
    PROCESS_INFORMATION ProcessInformation;
    ZeroMemory(&ProcessInformation, sizeof(PROCESS_INFORMATION));
    if(CreateProcessAsUser(hToken, NULL, szCommandLine, NULL, NULL, FALSE, 0, NULL, NULL, &StartupInfo, &ProcessInformation))
    {
        CloseHandle(ProcessInformation.hThread);
        ProcessInformation.hThread = NULL;
        CloseHandle(ProcessInformation.hProcess);
        ProcessInformation.hProcess = NULL;
    }
    CloseHandle(hToken);
    hToken = NULL;
}

在/客户端模式下,点击通过一堆的FindWindow和FindWindowEx呼吁UAC提示是按钮。您可以使用间谍+ +找出窗口的层次结构。

In /client mode it clicks the "Yes" button on the UAC prompt via a bunch of FindWindow and FindWindowEx calls. You can use Spy++ to figure out the window hierarchy.

HWND hWnd = ...;
HWND hWndButton = FindWindowEx(hWnd, NULL, _T("Button"), NULL);
if(hWndButton != NULL)
{
    // see if this is the "Yes" button
    TCHAR szText[32];
    if(GetWindowText(hWndButton, szText, 32) && _tcsicmp(szText, _T("&Yes")) == 0)
    {
        // click it
        SendMessage(hWndButton, BM_CLICK, 0, 0);
    }
}

我考这个问题的方法是要坚持睡眠(5000);在/客户端code。然后,我启动该服务,并立即做一些事情触发UAC提示(即运行regedit)。 5秒钟后/客户端code会醒来,发现并点击是按钮。您可以运行的Winlogon桌面上的其他进程; CMD.EXE和spyxx.exe(间谍++)是最有用的。不幸的是,Explorer.exe的表现出很多的Winlogon桌面上运行时的问题,是不是很有用。要到Winlogon桌面可以运行regedit,然后Alt + Tab切换到其他应用程序。如果你想获得看上你可以写你自己的桌面切换程序(使用SwitchDesktop功能),所以你不必触发UAC提示才能到Winlogon桌面。如果你想获得真正看中的,你可以设置一个全局窗口钩子监视窗口创建;当UAC对话框是将要显示你可以prepare点击它的是按钮。我没有把它想象中的那么远,虽然。

The way I test this is to stick a Sleep(5000); in the /client code. Then I start the service and immediately do something that triggers a UAC prompt (i.e. run regedit). After 5 seconds the /client code will wake up and find and click the "Yes" button. You can run other processes on the Winlogon desktop; cmd.exe and spyxx.exe (Spy++) are most useful. Unfortunately, explorer.exe exhibits a lot of problems when running on the Winlogon desktop and isn't very useful. To get to the Winlogon desktop you can run regedit and then Alt+Tab to switch to the other application. If you want to get fancy you can write your own desktop switching utility (using the SwitchDesktop function) so you don't have to trigger a UAC prompt to get to the Winlogon desktop. If you want to get really fancy you can set a global window hook to monitor window creation; when the UAC dialog is about to be displayed you can prepare to click its "Yes" button. I didn't take it quite that far, though.