C 控制安全桌面失败

问题描述 投票:0回答:1

我创建了一个从远程计算机控制鼠标和键盘的应用程序(如InputDirector)。现在我遇到的问题是无法控制安全桌面(锁屏、UAC)。
我在其他帖子中读到,我必须使用

SetThreadDesktop()
。但对我来说这不起作用。以下是我如何更新桌面的代码片段(我使用
SetCursorPos
检查 UAC 中是否有效):

if(flag_start_desk)
        {
            flag_start_desk = 0;
            POINT pt = { 0 };
            if(!GetCursorPos(&pt)) erz_output(red, LOCAL_FUNCTION_NAME, "Something went wrong to get mouse position\r\n");
            else SetCursorPos(pt.x-20, pt.y-20);

            if( (desk = OpenInputDesktop(0, 0, WRITE_OWNER) ) == NULL) 
            { 
                erz_output(red, LOCAL_FUNCTION_NAME, "OID Error: %lu\r\n", GetLastError()); 
                Beep(530, 500); 
            }
            else
            {
                erz_output(green, LOCAL_FUNCTION_NAME, "New Desktop: %llu\r\n", desk);
                if( SetThreadDesktop(desk) == 0 )
                {
                    erz_output(red, LOCAL_FUNCTION_NAME, "STD Error: %lu\r\n", GetLastError());
                    Beep(530, 500);
                }
                //CloseDesktop(desk);
                //desk = NULL;
            }
        }
  • 当我以普通用户身份调用该函数时,该函数起作用(光标移动)。当我启动 UAC 时,我收到消息
    OID Error: 5
    (ERROR_ACCESS_DENIED)。
  • 当我以管理员身份调用该函数时,我在普通桌面上得到
    STD Error: 170
    (ERROR_BUSY)。当我启动 UAC 时,我收到消息
    OID Error: 5
  • 我也将
    OpenInputDesktop(0, 0, WRITE_OWNER)
    更改为
    OpenInputDesktop(DF_ALLOWOTHERACCOUNTHOOK, 1, WRITE_OWNER)
    ,结果相同。
  • 与其他远程软件一样,我使用
    uiAccess="true"
    创建应用程序清单,并向应用程序添加数字证书。结果与上面相同,只是我不需要以管理员身份启动。
  • 我还构建了一个服务来尝试控制桌面/安全桌面,但这似乎不适用于
    SetCursorPos
  • 另一篇文章说,使用
    CreateProcessAsUser()
    启动一个控制安全桌面的子进程。结果与上面相同。但我也会分享我的剪裁。

给孩子打电话:

int loadp(void) 
{
    DWORD sessionID = WTSGetActiveConsoleSessionId();
    HANDLE hToken;
    WTSQueryUserToken(sessionID, &hToken);

    // userdata for CreateProcessAsUser
    STARTUPINFO si = { sizeof(si) };
    PROCESS_INFORMATION pi;

    // get secure desktop
    si.lpDesktop = ("winsta0\\default"); // default-Desktop

    // child app to start
    CHAR appPath[1024];
    memcpy(appPath, ("C:\\MinGW64\\bin\\proj\\TESTS\\client.exe"), 37);

    // start process witch can access secure desktop
    if (CreateProcessAsUser(hToken, appPath, NULL, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
    } else {
        printf(("Cannot start process: %d\n"), GetLastError());
    }

    CloseHandle(hToken);

    return 0;
}

感觉我在兜圈子,也许你可以帮助我。
我的目标是中止或接受 UAC 弹出窗口并在锁屏上登录。
我在 Windows 10 上工作。

c windows winapi
1个回答
0
投票

在前一个示例中,

  • 我们使用
    GetThreadDesktop
    来获取默认活动桌面设置 该线程的系统。
  • 然后使用
    SetThreadDesktop
    设置与此关联的桌面 线程到我们创建的桌面
    CreateDeskTop
    .

我们可以在windows station中切换和关闭桌面。现在,

  1. 注意,不是之前的创建过程,有一个lpDesktop选项的设置。我们将设置它来为我们的新桌面创建进程。

#define DESTOP_NAME  L"MY_DESTOP"
        hDDesk = CreateDesktop(
                        DESTOP_NAME,
                        0, 0, 0,
                        GENERIC_ALL,
                        NULL
                    );
        STARTUPINFO sti = 
                    {
                        sizeof(sti)
                    };
        sti.lpDesktop =(LPWSTR)DESTOP_NAME;

请参阅与桌面的线程连接。需要注意的是,本次连接过程中分配的桌面无法通过调用CloseDesktop函数来关闭。

  1. 然后,我们就可以为新桌面创建进程了。在此之前我们需要 判断指定进程是否正在运行 WOW64 或 Intel64 或 x64 处理器。

typedef BOOL(__stdcall* P_IsWow64Process)(HANDLE, BOOL*);
HMODULE _Kernel32 = GetModuleHandle(L"kernel32.dll");
if (_Kernel32 == 0)
{
    return FALSE;
}
P_IsWow64Process iswow64process = (P_IsWow64Process)GetProcAddress(_Kernel32, "IsWow64Process");
int bwow64 = 0;
iswow64process(GetCurrentProcess(), &bwow64);
  1. 如您所愿,我们可以在两个桌面上创建窗口并注册 通过处理箭头键的输入来控制光标的热键。这里我做了一个示例,使用F6切换到当前桌面,F7切换到新创建的桌面。 F8 返回当前桌面并关闭新桌面。 使用键盘移动光标。

温馨提示:

  • 窗口将显示在 CreateDesktop 创建的桌面上 在
    CreateDesktop
    .
  • 之后创建
  • 在使用
    CloseDeskTop
    之前,您必须切换回当前桌面。 不然你就再也回不来了。
  • 您无法使用 ALT+TAb 在桌面后切换桌面的功能 名称在 STARTUPINFO 的 lpDesktop 成员中指定 结构。除非重新启动电脑。
  • 请以管理员身份运行。

这是代码:

#include <iostream>
#include<windows.h>
 
TCHAR szAppName[] = L"TEST";
#define DESTOP_NAME  L"MY_DESTOP"   

ATOM m_HotKeyId1;
ATOM m_HotKeyId2;
ATOM m_HotKeyId3;
HDESK hDDesk;
HDESK hOld;
//HWINSTA  hWinStaThisProcess = GetProcessWindowStation();  
//HDESK hDeskOriignInput = OpenInputDesktop(0, FALSE, GENERIC_ALL); 
void OnHotKey(WPARAM wParam, LPARAM lParam)
{
    static LRESULT lRes = 0;

    if (wParam == m_HotKeyId1)
    {
        
        SwitchDesktop(hOld);
    }
    else if (wParam == m_HotKeyId2)
    {
        SwitchDesktop(hDDesk);
    }
    else if (wParam == m_HotKeyId3)
    {
        MessageBox(0, L"quit", L"caution", 0);
        PostQuitMessage(0);
        SwitchDesktop(hOld);
        BOOL res=CloseDesktop(hDDesk);
        MessageBox(0, L"failed", L"closed", 0);
    }
    return ;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    RECT rect;
    GetClientRect(hwnd, &rect);

    POINT p;
    ClientToScreen(hwnd, &p);

    RECT winrect;
    GetWindowRect(hwnd, &winrect);
//hotkey
    switch (message)
    {
    case WM_HOTKEY:
        OnHotKey(wParam, lParam);
        return 0;
    }

//cursor
    HCURSOR hCurs1, hCurs2;    // cursor handles 

    POINT pt;                  // cursor location  
    RECT rc;                   // client area coordinates 
    static int repeat = 100;     // repeat key counter 
    // 
    // Other declarations and initialization. 
    // 
    switch (message)
    {
        // 
        // Process other messages. 
        // 
    case WM_KEYDOWN:
        if (wParam != VK_LEFT && wParam != VK_RIGHT &&
            wParam != VK_UP && wParam != VK_DOWN)
        {
            break;
        }
        GetCursorPos(&pt);
        // Convert screen coordinates to client coordinates. 
        ScreenToClient(hwnd, &pt);  
        switch (wParam)
        {
            // Move the cursor to reflect which 
            // arrow keys are pressed. 
        case VK_LEFT:               // left arrow 
            pt.x -= repeat;
            break;

        case VK_RIGHT:              // right arrow 
            pt.x += repeat;
            break;

        case VK_UP:                 // up arrow 
            pt.y -= repeat;
            break;

        case VK_DOWN:               // down arrow 
            pt.y += repeat;
            break;

        default:
            return 0;
        }
        repeat++;           // Increment repeat count. 
        // Keep the cursor in the client area. 
        GetClientRect(hwnd, &rc);
        
        if (pt.x >= rc.right)
        {
            pt.x = rc.right - 100;
        }
        else
        {
            if (pt.x < rc.left)
            {
                pt.x = rc.left;
            }
        }
        if (pt.y >= rc.bottom)
            pt.y = rc.bottom - 100;
        else
            if (pt.y < rc.top)
                pt.y = rc.top;
        // Convert client coordinates to screen coordinates. 
        ClientToScreen(hwnd, &pt);
        SetCursorPos(pt.x, pt.y);
        return 0;
    case WM_KEYUP:
        repeat = 10;            // Clear repeat count. 
        return 0;
    }
    return DefWindowProc(hwnd, message, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow)
{
    hOld = GetThreadDesktop(GetCurrentThreadId());

    int result = 0;
    typedef BOOL(__stdcall* P_IsWow64Process)(HANDLE, BOOL*);
    HMODULE _Kernel32 = GetModuleHandle(L"kernel32.dll");
    if (_Kernel32 == 0)
    {
        return FALSE;
    }
    P_IsWow64Process iswow64process = (P_IsWow64Process)GetProcAddress(_Kernel32, "IsWow64Process");

    HWND hwnd;
    HWND hwnd2;
    MSG  msg;
    WNDCLASS    wndclass;

    wndclass.style = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc = WndProc;
    wndclass.cbClsExtra = 0;
    wndclass.cbWndExtra = 0;
    wndclass.hInstance = hInstance;
    wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wndclass.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
    wndclass.lpszMenuName = NULL;
    wndclass.lpszClassName = szAppName;

    if (!RegisterClass(&wndclass))
    {
        MessageBox(NULL, L"RegisterClass failed!", NULL, 0);
        return 0;
    }
    hwnd = CreateWindow(
        szAppName, szAppName,
        WS_OVERLAPPEDWINDOW,
        0, 0,
        800, 600,
        NULL, NULL, hInstance, NULL
    );
    ShowWindow(hwnd, SW_SHOW);

    hDDesk = CreateDesktop(
        DESTOP_NAME,
        0, 0, 0,
        GENERIC_ALL,
        NULL
    );
    result = SetThreadDesktop(hDDesk);

    STARTUPINFO sti = {
        sizeof(sti)
    };
    sti.lpDesktop =(LPWSTR)DESTOP_NAME;

    PROCESS_INFORMATION pi = { 0 };

    int bwow64 = 0;
    iswow64process(GetCurrentProcess(), &bwow64);
    if (bwow64)
    {
        result = CreateProcess(L"C:\\Windows\\SysWOW64\\explorer.exe", NULL, NULL, NULL, TRUE, 0, NULL, NULL, &sti, &pi);
    }
    else {
        result = CreateProcess(L"C:\\Windows\\explorer.exe", NULL, NULL, NULL, TRUE, 0, NULL, NULL, &sti, &pi);
    }

    if (result)
    {
        CloseHandle(pi.hProcess);
    }

    m_HotKeyId1 = GlobalAddAtomW(L"HotKey1") - 0xc000;
    RegisterHotKey(hwnd, m_HotKeyId1, 0, VK_F6);

    m_HotKeyId2 = GlobalAddAtomW(L"HotKey2") - 0xc000;
    RegisterHotKey(hwnd, m_HotKeyId2, 0, VK_F7);

    m_HotKeyId3 = GlobalAddAtomW(L"HotKey3") - 0xc000;
    RegisterHotKey(hwnd, m_HotKeyId3, MOD_CONTROL | MOD_SHIFT, VK_F8);

    RegisterHotKey(hwnd, m_HotKeyId3, 0, VK_F8);

    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    UnregisterHotKey(hwnd, m_HotKeyId1);
    GlobalDeleteAtom(m_HotKeyId1);

    UnregisterHotKey(hwnd, m_HotKeyId2);
    GlobalDeleteAtom(m_HotKeyId2);

    UnregisterHotKey(hwnd, m_HotKeyId3);
    GlobalDeleteAtom(m_HotKeyId3);


    return msg.wParam;
}
© www.soinside.com 2019 - 2024. All rights reserved.