使用 GDI 注入 DLL导致记事本崩溃
我有一个 Visual Studio 解决方案,其中包含一个 DLL 和一个 EXE。我的程序设置了一个全局 WH_CALLWNDPROC
挂钩。钩子过程由 DLL 定义。我已经验证 DLL 是否已正确注入到我感兴趣的所有进程中。DLL 导出一些过程,这些过程是在头文件中定义的,而不是在 DEF 文件中定义的。 EXE自动加载DLL并调用DLL中的方法来设置挂钩。加载 DLL 时,DllMain
设置一个内部 HMODULE
变量,其中包含 DLL 的模块句柄。当 EXE 调用 installHook 过程时,DLL 设置挂钩。这一切都运行良好。
当我的挂钩过程收到 WM_SIZING
消息时,它会执行另一个内部过程,该过程应该使用 GDI+ 在窗口的客户端 DC
上绘制某些内容。使用标准 GDI 工作。但是,GDI+(我需要使用)不起作用:当我尝试调整窗口大小时,Graphics::Graphics(HDC)
构造函数会导致任何程序崩溃。以下是导致崩溃的代码片段:
void myFaultyProcedure(HWND hWnd) {
RECT wndRect;
GetWindowRect(hWnd,&wndRect);
unsigned int wndWidth=wndRect.right-wndRect.left;
unsigned int wndHeight=wndRect.bottom-wndRect.top;
HDC hDc;
PAINTSTRUCT ps;
ULONG_PTR gdiplusToken;
GdiplusStartupInput gdiplusStartupInput;
GdiplusStartup(&gdiplusToken,&gdiplusStartupInput,NULL);
hDc=BeginPaint(hWnd,&ps);
Graphics graphics(hDc); // I think that this causes the program to crash
delete &graphics;
EndPaint(hWnd,&ps);
ReleaseDC(hWnd,hDc);
GdiplusShutdown(gdiplusToken);
}
该代码计算给定窗口的宽度和高度,获取 DC,启动 GDI+,创建 Graphics 对象,删除 Graphics 对象,释放 DC,然后关闭 GDI+。我无法想象为什么程序会因为这些行而崩溃。记事本和 Windows 资源管理器都崩溃(Windows 资源管理器窗口与 Windows 资源管理器外壳位于不同的进程中)。
谢谢!
I have a Visual Studio solution which consists of a DLL and an EXE. My program sets a global WH_CALLWNDPROC
hook. The hook procedure is defined by the DLL. I have verified that the DLL gets properly injected into all the processes I am interested in. The DLL exports a few procedures, which are defined in a header file, not in a DEF file. The EXE automatically loads the DLL and calls a method in the DLL to set the hook. When the DLL is loaded, DllMain
sets an internal HMODULE
variable which contains the DLL's module handle. When the EXE calls the installHook
procedure, the DLL sets the hook. All this works fine.
When my hook procedure receives a WM_SIZING
message, it executes another internal procedure, which is supposed to use GDI+ to draw something on the window's client DC
. Using standard GDI works. However, GDI+ (which I need to use) does not work: the Graphics::Graphics(HDC)
constructor causes the any program to crash as soon as I try to resize the window. Here is a snippet of the code that causes the crash:
void myFaultyProcedure(HWND hWnd) {
RECT wndRect;
GetWindowRect(hWnd,&wndRect);
unsigned int wndWidth=wndRect.right-wndRect.left;
unsigned int wndHeight=wndRect.bottom-wndRect.top;
HDC hDc;
PAINTSTRUCT ps;
ULONG_PTR gdiplusToken;
GdiplusStartupInput gdiplusStartupInput;
GdiplusStartup(&gdiplusToken,&gdiplusStartupInput,NULL);
hDc=BeginPaint(hWnd,&ps);
Graphics graphics(hDc); // I think that this causes the program to crash
delete &graphics;
EndPaint(hWnd,&ps);
ReleaseDC(hWnd,hDc);
GdiplusShutdown(gdiplusToken);
}
The code calculates the width and height of a given window, gets a DC, starts GDI+, creates a Graphics object, deletes the Graphics object, releases the DC, and shuts down GDI+. I cannot image why programs would crash because of these lines. Notepad and Windows Explorer both crash (The Windows Explorer window is in a separate process from the Windows Explorer Shell).
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
很确定是下一行
让你的代码崩溃了。
delete
仅当指针由new
获取时才应使用,这里您在堆栈上给它一些东西。对堆栈分配的变量调用删除是没有意义的。为了确保 Graphics 实例在调用 GdiplusShutdown 之前被销毁,您可以引入一个新的作用域:
Pretty sure it is the next line
that is making your code blow up.
delete
should only be used if the pointer was obtained bynew
, here you're giving it something on the stack. Calling delete on a stack allocated variable makes no sense.To ensure that the Graphics instance is destroyed before GdiplusShutdown is called you can introduce a new scope: