从注入的 dll 调用时 BeginPaint 失败,即使在目标应用程序中调用 EndPaint 之后也是如此
BeginPaint fails when called from injected dll, even after EndPaint is called in target application
基本上就是我的标题所说的。我试图在目标应用程序中注入一个 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;
}
这是我注入的 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,这意味着它不应该干扰我的注入 WM_PAINT...有什么想法吗?
EndPaint()
验证 window,因此下一个 BeginPaint()
得到一个没有任何可绘制(无效)区域的 DC。这是关于 GetDC()/ReleaseDC() vs. BeginPaint()/EndPaint().
的讨论
基本上就是我的标题所说的。我试图在目标应用程序中注入一个 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;
}
这是我注入的 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,这意味着它不应该干扰我的注入 WM_PAINT...有什么想法吗?
EndPaint()
验证 window,因此下一个 BeginPaint()
得到一个没有任何可绘制(无效)区域的 DC。这是关于 GetDC()/ReleaseDC() vs. BeginPaint()/EndPaint().