我有一个要求,我必须使用 Win Api 阻止外国应用程序的屏幕截图有没有办法做到这一点?

问题描述

我尝试使用 SetwindowdisplayAffinity() 但它总是返回 false。我不知道在哪里挂钩这个功能。 我不确定我们是否可以操纵外国窗口。我们可以吗?。如果我们可以在窗口动态变化时将这个函数挂到哪里。

解决方法

使用 DLL 注入将 SetWindowDisplayAffinity 注入应用程序。首先,您需要确保为外部应用进程提供以下 Access Rights

PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ

然后创建一个DLL并调用函数SetWindowDisplayAffinity + WDA_EXCLUDEFROMCAPTURE

BOOL APIENTRY DllMain( HMODULE hModule,DWORD  ul_reason_for_call,LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    {
        HWND window = FindWindow(NULL,L"test.txt - Notepad"); //get your app window handle
        SetWindowDisplayAffinity(window,WDA_EXCLUDEFROMCAPTURE);
    }
    break;
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

使用另一个进程将这个dll注入目标进程:

#include <windows.h>
#include <iostream>
BOOL InjectDll(DWORD dwPid,LPCWSTR szDllPath)
{
    DWORD dwMemSize;
    HANDLE hProc;
    LPVOID lpRemoteMem,lpLoadLibrary;
    BOOL bRet = FALSE;
    if ((hProc = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ,FALSE,dwPid)) != NULL)
    {
        dwMemSize = (wcslen(szDllPath) + 1) * sizeof(WCHAR);
        if ((lpRemoteMem = VirtualAllocEx(hProc,NULL,dwMemSize,MEM_COMMIT,PAGE_READWRITE)) != NULL)
        {
            if (WriteProcessMemory(hProc,lpRemoteMem,(LPCVOID)szDllPath,NULL))
            {
                lpLoadLibrary = GetProcAddress(GetModuleHandleW(L"kernel32.dll"),"LoadLibraryW");
                HANDLE hThread = CreateRemoteThread(hProc,(LPTHREAD_START_ROUTINE)lpLoadLibrary,NULL);
                if (hThread != NULL)
                {
                    WaitForSingleObject(hThread,INFINITE);
                    bRet = TRUE;
                }
            }
            VirtualFreeEx(hProc,MEM_RELEASE);
        }
            
    }
    CloseHandle(hProc);
    return bRet;
}
int main()
{
    HWND window = FindWindowW(NULL,L"test.txt - Notepad"); //get your app window handle
    DWORD pid = 0;
    GetWindowThreadProcessId(window,&pid);
    InjectDll(pid,L"C:\\Path\\DllName.dll");
    return 0;
}

注意dll、进程和目标进程的位版本(x86/x64)必须相同。