未捕获 WM_PAINT 中的访问冲突 [英] access violation in WM_PAINT not caught

查看:19
本文介绍了未捕获 WM_PAINT 中的访问冲突的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为了测试这个问题,我编写了一个最小的 Windows 应用程序.如果我在 WM_PAINT 处理程序中强制访问冲突,这个异常永远不会到达调试器.如果在没有调试器的情况下启动,访问冲突也不会出现.通常,您应该会看到 Windows 错误报告对话框.

再深入一点,似乎 user32.dll 中的某些东西可以捕获所有传入的异常.这是正常行为吗?我能以某种方式控制它吗?捕获所有异常不是一种安全风险吗?至少它很烦人.

这是在 Vista 64 上的 32 位和 64 位应用程序.在 XP 上,异常似乎按预期处理.其他窗口消息也有同样的问题.也许所有这些?

WM_PAINT 处理程序:

case WM_PAINT:hdc = BeginPaint(hWnd, &ps);*(int*)0 = 0;EndPaint(hWnd, &ps);休息;

解决方案

作为一种解决方法,我删除了窗口过程中所有已注册的异常处理程序.好丑.

<前>LRESULT 回调 window_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ){//获取线程信息块NT_TIB* tib;__asm {mov EAX, FS:[18h]mov [tib], EAX}//旧的异常处理程序列表_EXCEPTION_REGISTRATION_RECORD* old_exception_handler = tib->ExceptionList;//删除除默认处理程序之外的所有异常处理程序while( tib->ExceptionList->Next != (_EXCEPTION_REGISTRATION_RECORD*)-1 ) {tib->ExceptionList = tib->ExceptionList->Next;}LRESULT 结果 = DefWindowProc( hwnd, uMsg, wParam, lParam );//恢复旧的异常处理程序tib->ExceptionList = old_exception_handler;返回结果;}

To test this problem I have written a minimal windows application. If I force an access violation in the WM_PAINT handler this exception never gets to the debugger. If started without debugger the access violation also does not show up. Usually you should get the Windows Error Reporting dialog.

Digging a bit deeper it seems that something in user32.dll catches all incoming exceptions. Is this normal behavior? Can I control this somehow? Isn't catching all exceptions a security risk? At least it is annoying as hell.

This is with a 32- and 64-bit application on Vista 64. On XP the exception seems to be handled as expected. Other windows messages have the same problem. Maybe all of them?

The WM_PAINT handler:

case WM_PAINT:
    hdc = BeginPaint(hWnd, &ps);
    *(int*)0 = 0;
    EndPaint(hWnd, &ps);
    break;

解决方案

As a workaround I remove all registered exception handlers in my window procedure. Quite ugly.

LRESULT CALLBACK window_proc( 
    HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
    // get thread information block
    NT_TIB* tib;
    __asm {
        mov EAX, FS:[18h]
        mov [tib], EAX
    }
    // old exception handler list
    _EXCEPTION_REGISTRATION_RECORD* old_exception_handler = tib->ExceptionList;
    // remove all exception handler with exception of the default handler
    while( tib->ExceptionList->Next != (_EXCEPTION_REGISTRATION_RECORD*)-1 ) {
        tib->ExceptionList = tib->ExceptionList->Next;
    }

    LRESULT result = DefWindowProc( hwnd, uMsg, wParam, lParam );

    // restore old exception handler
    tib->ExceptionList = old_exception_handler;

    return result;
}

这篇关于未捕获 WM_PAINT 中的访问冲突的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆