DLL 中的大向量异常处理程序导致程序在没有调试器的情况下崩溃

Large Vectored Exception Handler in DLL is causing program to crash without debugger

我目前正在开发实现矢量异常处理程序 (VEH) 的 DLL(Windows 10,x64)。它导出函数是为了附加到可执行文件,仅此而已。在附加 VEH 期间,它还使用以下代码片段计算基本偏移量:

uint64_t GetModuleBase(const char *modname)
{
    HANDLE hModSnap;
    MODULEENTRY32 pe32;
    void *bs = NULL;

    // Take a snapshot of all processes in the system.
    hModSnap = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, GetCurrentProcessId() );
    if( hModSnap == INVALID_HANDLE_VALUE )
    {
        return NULL;
    }

    // Set the size of the structure before using it.
    pe32.dwSize = sizeof( MODULEENTRY32 );

    if( !Module32First( hModSnap, &pe32 ) )
    {
        CloseHandle( hModSnap );     // Must clean up the snapshot object!
        return NULL;
    }

    do
    {
        if (!StrCmpI(pe32.szModule, modname)) {
            bs = pe32.modBaseAddr;
            break;
        }
    } while( Module32Next( hModSnap, &pe32 ) );

    CloseHandle( hModSnap );

    return (uint64_t)bs;
}

在异常处理程序中,我只处理代码为“0xc000001d”的异常,在其他情况下,VEH 将执行返回给程序。

在VEH中注册的内部处理函数我有以下结构(简化):

#define FUNCTION_1(arg1, arg2, arg3, arg4)
    if (exception_offset == arg1) { \
        5_lines_of_code .... \
       return EXCEPTION_CONTINUE_EXECUTION; \
    }


#define FUNCTION_2(arg1, arg2, arg3, arg4)
    if (exception_offset == arg1) { \
        5_lines_of_code .... \
        return EXCEPTION_CONTINUE_EXECUTION; \
    } 


#define FUNCTION_3(arg1, arg2, arg3, arg4) 
    if (exception_offset == arg1) { \
        5_lines_of_code .... \
        return EXCEPTION_CONTINUE_EXECUTION; \
    } \

...

# 15 functions like that.

FUNCTION_1(0x192385, CPU_REGISTER1, CPU_REGISTER2);
FUNCTION_2(0x145685, CPU_REGISTER3, CPU_REGISTER4);
FUNCTION_3(0x456685, CPU_REGISTER1, CPU_REGISTER5);

# 1719 lines like that

我收到来自 MSVC 的警告:函数使用“81340”字节的堆栈:超过 /analyze:stacksize“16384”。考虑将一些数据移动到堆中。

使用调试器一切正常。使用 Windbg,一切都按预期工作。

没有调试器 - 应用程序无声地崩溃。

更深入的调查表明它注册了 DLL,开始执行甚至调用处理程序几次,但是有不同的异常代码(从 0x8 开始......这是调试代码),所以 VEH 代码 returns在早期阶段。在正常的应用程序操作期间,我可以看到相同偏移量的相同代码,顺便说一句。

当该函数调用的数量大约为 1400 次左右时,一切都运行良好(如果我评论其中的一部分,不管是哪一个,只要我减少数量)

我试过:

这些都没有任何效果。我猜,这是一个超载的堆栈。

因此问题:

谢谢你,希望得到你的帮助。

好的,我能够解决问题:

  1. 选择了不同的调试器 - x64dbg。惊人的调试器,它附加到启动的进程而不是在调试模式下启动它。
  2. 这允许在进程初始化期间识别堆栈溢出问题。
  3. 我已经为此应用了快速修复,因为我正在制作原型:使用 editbin /F stacksize 修改应用程序的 .exe 文件以增加它。
  4. 一切正常。