c++ - 从注入(inject)的 dll 调用时 BeginPaint 失败,即使在目标应用程序中调用 EndPaint 之后也是如此

标签 c++ winapi dll gdi

基本上就是我的标题所说的。我试图在目标应用程序中注入(inject)一个 dll,以便在目标应用程序每次收到 WM_PAINT 消息时显示内容。有我的目标的 WNDPROC:

#include <windows.h>
#include <stdio.h>

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    PAINTSTRUCT ps;

    switch(msg)
    {
        case WM_PAINT: 
            BeginPaint(hwnd, &ps); 
            TextOut(ps.hdc, 0, 0, "Hello, Windows!", 15); 
            EndPaint(hwnd, &ps); 
        break;
        case WM_CLOSE:
            DestroyWindow(hwnd);
        break;
        case WM_DESTROY:
            PostQuitMessage(0);
        break;
        default:
            return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    return 0;
}

这是我注入(inject)的dll:

#include <Windows.h>
#include <stdio.h>

WNDPROC wpOrigProc;
HWND target_hwnd = (HWND)0x909E6; // HWND of the window I'm detouring

LRESULT APIENTRY MyWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    PAINTSTRUCT ps;

    LRESULT result = CallWindowProc(wpOrigProc, hwnd, msg, wParam, lParam);

    switch(msg)
    {
        case WM_PAINT: 
            BeginPaint(hwnd, &ps);
            TextOut(ps.hdc, 0, 50, "That was injected!", 18);
            EndPaint(hwnd, &ps);
        break;
    }

    return result; 
}

int APIENTRY DllMain(HMODULE module, DWORD reason, LPVOID reserved)
{
    HHOOK msgHook;
    FILE* stream;

    switch (reason)
    {
    case DLL_PROCESS_ATTACH:
        wpOrigProc = (WNDPROC)SetWindowLongPtr(target_hwnd, GWLP_WNDPROC, (LONG)MyWndProc);
        break;

    case DLL_PROCESS_DETACH:
        SetWindowLong(target_hwnd, GWL_WNDPROC, (LONG)wpOrigProc); 
        break;
    }

    return 1;
}

现在,我知道问题出在 BeginPaint,因为如果我改用 GetDC 和 ReleaseDC,它就会起作用。如果我不在 BeginPaint 之前调用 CallWindowProc,它也会起作用。

这对我来说毫无意义,因为原始 WNDPROC 在他的 WM_PAINT 末尾调用 EndPaint,这意味着它不应该干扰我注入(inject)的 WM_PAINT...有什么想法吗?

最佳答案

EndPaint() 验证窗口,因此下一个 BeginPaint() 获得一个没有任何可绘制(无效)区域的 DC。这是关于 GetDC()/ReleaseDC() vs. BeginPaint()/EndPaint() 的讨论.

关于c++ - 从注入(inject)的 dll 调用时 BeginPaint 失败,即使在目标应用程序中调用 EndPaint 之后也是如此,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29154476/

相关文章:

c++ - 指纹调用导致 C++ 中的段错误

c++ - 最小化递归函数中的变量拷贝

java - Maven shade插件打包DLL

c++ - 如何使 createprocess 重新定向输入成功,我已成功获得重新定向输出结果

c - GCC 编译的 Win32 程序在系统 DLL 调用期间崩溃

windows - 如何创建 DLL 初始化例程?

c++ - 在 32 位 gdb 工具上调试 64 位 C++ 应用程序

c++ - 在 C++ 中根据运行时字符串选择模板

windows - 使用WINAPI找出特殊文件上的进程事件句柄(锁定)

C WINAPI recv() 在接收到所有数据之前返回 0