使用 GDI 注入 DLL导致记事本崩溃

发布于 2024-10-03 12:37:04 字数 1342 浏览 3 评论 0原文

我有一个 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

冬天旳寂寞 2024-10-10 12:37:04

很确定是下一行

 delete &graphics;

让你的代码崩溃了。 delete 仅当指针由 new 获取时才应使用,这里您在堆栈上给它一些东西。对堆栈分配的变量调用删除是没有意义的。

为了确保 Graphics 实例在调用 GdiplusShutdown 之前被销毁,您可以引入一个新的作用域:

{
   Graphics g(...);
   g.DoStuff();
   ...
} // g is destroyed here
GdiplusShutdown(...)

Pretty sure it is the next line

 delete &graphics;

that is making your code blow up. delete should only be used if the pointer was obtained by new, 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:

{
   Graphics g(...);
   g.DoStuff();
   ...
} // g is destroyed here
GdiplusShutdown(...)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文