Winlogon screen capturing in Windows 7/10

泄露秘密 提交于 2019-12-13 17:17:09

问题


I need to capture a winlogon screen in WinXP/Win7/10. For WinXP I'm using a mirror driver and a standard methodic like this:

...
extern "C" __declspec(dllexport) void SetActiveDesktop() {
    if ( currentDesk != NULL )
        CloseDesktop( currentDesk );

    currentDesk = OpenInputDesktop( 0, FALSE, GENERIC_ALL );
    BOOL ret = SetThreadDesktop( currentDesk );
    int LASTeRR = GetLastError();
}

extern "C" __declspec(dllexport) HBITMAP CaptureAnImage(
    int width, 
    int height,
    int bitsPerPixel )
{
    HBITMAP hbmScreen;
    LPTSTR bih = NULL;
    HDC hdcMemDC = NULL;

    int colorDepth = GetCurrentColorDepth();

    if ( bitsPerPixel > colorDepth && colorDepth > 0 )
        bitsPerPixel = colorDepth;

    // Checks a current HDC
    if ( currHdc == NULL ) {
        SetActiveDesktop();
        currHdc = GetDcMirror();
    }

    if ( prevHdc != currHdc ) {
        prevHdc = currHdc;
    }

    // Check an application instance handler
    if ( appInstance == NULL )
        appInstance = GetModuleHandle(NULL);

    // Creates a compatible DC which is used in a BitBlt from the window DC
    hdcMemDC = CreateCompatibleDC( currHdc ); 

    if( hdcMemDC == NULL )
    {
        return NULL;
    }

    // Defines bitmap parameters    
    bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    bi.bmiHeader.biWidth = width;
    bi.bmiHeader.biHeight = height;
    bi.bmiHeader.biPlanes = 1;
    bi.bmiHeader.biBitCount = bitsPerPixel;

    // Creates a bitmap with defined parameters 
    hbmScreen = CreateDIBSection( hdcMemDC, &bi, DIB_RGB_COLORS, (VOID**)&lpBitmapBits, NULL, 0 );

    if ( hbmScreen == NULL ) {
        return NULL;
    }

    // Select the compatible bitmap into the compatible memory DC.
    SelectObject(hdcMemDC,hbmScreen);

    // Bit block transfer into our compatible memory DC.
    if(!BitBlt(hdcMemDC, 
        0,0, 
        width, height,
        currHdc, 
        0,0,
        SRCCOPY))
    {
        SetActiveDesktop();
        currHdc = GetDC(NULL);//GetDcMirror();      
        hdcMemDC = CreateCompatibleDC( currHdc );

        // Creates a bitmap with defined parameters 
        hbmScreen = CreateDIBSection( hdcMemDC, &bi, DIB_RGB_COLORS, (VOID**)&lpBitmapBits, NULL, 0 );

        if(!BitBlt(hdcMemDC,
            0,0, 
            width, height,
            currHdc,
            0,0,
            SRCCOPY )) 
        {
            DeleteDC( hdcMemDC ); 
            return hbmScreen;
        }
    }

    if (DeleteDC( hdcMemDC ) == FALSE ) {
        return NULL;
    }

    return hbmScreen;
}

And luckily it works on WinXP. But in case of win7/win10 I've a quite different situation:

SetThreadDesktop function after switching to winlogon always returns FALSE with an error 5 ( access denied ) I tried to change a strategy:

  • First of all program creates a list of all of existing window stations and their desktops.
  • After that program "polls" all of WINSTAs and HDESKs and saves screenshots on a disk.

    I tried to launch this program under 3 modes:

    • as an Administrator
    • as a service with enabled desktop interaction.
    • at winlogon desktop using CreateProcess flags ( in this case program simply crashes )

And result was the same. What I'm doing wrong? Should I try a Desktop Duplication API?

Thanks in advance for your responses!


回答1:


As Winlogon is a secure desktop you have to run your application under LOCAL_SYSTEM account to access it.

Example: a windows service that runs under LOCAL_SYSTEM that launches an user application (that captures the screen) in a console session.

In your code there is no check for the return value of OpenInputDesktop which may be NULL with error code 5 (access denied).

Check this answer as well for more information



来源:https://stackoverflow.com/questions/43520385/winlogon-screen-capturing-in-windows-7-10

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!