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

C++ 从注入的dll调用BeginPaint时失败,即使在目标应用程序中调用EndPaint之后也是如此,c++,winapi,dll,gdi,C++,Winapi,Dll,Gdi,基本上就是我的标题所说的。我试图在目标应用程序中插入一个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) {

基本上就是我的标题所说的。我试图在目标应用程序中插入一个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;
}
#包括
#包括
LRESULT回调WndProc(HWND HWND,UINT msg,WPARAM WPARAM,LPARAM LPARAM)
{
PAINTSTRUCT-ps;
开关(msg)
{
案例WM_油漆:
开始油漆(hwnd和ps);
TextOut(ps.hdc,0,0,“你好,Windows!”,15);
端漆(hwnd和ps);
打破
案例WM_结束:
窗口(hwnd);
打破
案例WM_销毁:
PostQuitMessage(0);
打破
违约:
返回DefWindowProc(hwnd、msg、wParam、lParam);
}
返回0;
}
这是我注入的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;
}
#包括
#包括
WNDPROC wpOrigProc;
HWND target_HWND=(HWND)0x909E6;//我绕着窗户走
LRESULT APIENTRY MyWndProc(HWND HWND、UINT msg、WPARAM WPARAM、LPARAM LPARAM)
{
PAINTSTRUCT-ps;
LRESULT result=CallWindowProc(wpOrigProc、hwnd、msg、wParam、lParam);
开关(msg)
{
案例WM_油漆:
开始油漆(hwnd和ps);
TextOut(ps.hdc,0,50,“那是注射的!”,18);
端漆(hwnd和ps);
打破
}
返回结果;
}
int APIENTRY DllMain(HMODULE模块,DWORD原因,LPVOID保留)
{
HHOOK-msgHook;
文件*流;
切换(原因)
{
案例DLL\u进程\u附加:
wpOrigProc=(WNDPROC)SetWindowLongPtr(target_hwnd,GWLP_WNDPROC,(LONG)MyWndProc);
打破
案例DLL\u进程\u分离:
SetWindowLong(target_hwnd,GWL_WNDPROC,(LONG)wpOrigProc);
打破
}
返回1;
}
现在,我知道问题来自BeginPaint,因为如果我使用GetDC和ReleaseDC,它会工作。如果我在开始绘制之前不调用CallWindowProc,它也可以工作


这对我来说毫无意义,因为最初的WNDPROC在他的WM_绘画结束时调用EndPaint,这意味着它不应该干扰我注入的WM_绘画。。。有什么想法吗?

EndPaint()
验证窗口,因此下一个
BeginPaint()
将获得一个没有任何可绘制(无效)区域的DC。这里讨论。

EndPaint()
验证窗口,因此下一个
BeginPaint()
将获得一个没有任何可绘制(无效)区域的DC。这里讨论。

EndPaint()
验证窗口,因此下一个
BeginPaint()
将获得一个没有任何可绘制(无效)区域的DC。这里讨论。

EndPaint()
验证窗口,因此下一个
BeginPaint()
将获得一个没有任何可绘制(无效)区域的DC。这里讨论一下。

很有意义。我想使用BeginPaint的原因是从PAINTSTRUCT获取窗口的无效部分。在不干扰CallWindowProc和目标进程的原始WNDPROC的情况下,这是可能的吗?@SoftEngi:您可以使用
GetUpdateRgn
获取窗口的当前更新区域,并将其传递到
GetDCEx
以模拟从
BeginPaint
获得的DC。这很有意义。我想使用BeginPaint的原因是从PAINTSTRUCT获取窗口的无效部分。在不干扰CallWindowProc和目标进程的原始WNDPROC的情况下,这是可能的吗?@SoftEngi:您可以使用
GetUpdateRgn
获取窗口的当前更新区域,并将其传递到
GetDCEx
以模拟从
BeginPaint
获得的DC。这很有意义。我想使用BeginPaint的原因是从PAINTSTRUCT获取窗口的无效部分。在不干扰CallWindowProc和目标进程的原始WNDPROC的情况下,这是可能的吗?@SoftEngi:您可以使用
GetUpdateRgn
获取窗口的当前更新区域,并将其传递到
GetDCEx
以模拟从
BeginPaint
获得的DC。这很有意义。我想使用BeginPaint的原因是从PAINTSTRUCT获取窗口的无效部分。在不干扰CallWindowProc和目标进程的原始WNDPROC的情况下,这是可能的吗?@SoftEngi:您可以使用
GetUpdateRgn
获取窗口的当前更新区域,并将其传递到
GetDCEx
以模拟从
BeginPaint
获得的DC,您应该使用而不是
SetWindowLongPtr(GWLP\u WNDPROC)
。请参阅。在旁注中,您应该使用而不是
SetWindowLongPtr(GWLP\u WNDPROC)
。请参阅。在旁注中,您应该使用而不是
SetWindowLongPtr(GWLP\u WNDPROC)
。请参阅。在旁注中,您应该使用而不是
SetWindowLongPtr(GWLP\u WNDPROC)
。看见