微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

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

我目前正在研究实现向量异常处理程序 (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,arg4)
    if (exception_offset == arg1) { \
        5_lines_of_code .... \
        return EXCEPTION_CONTINUE_EXECUTION; \
    } 


#define FUNCTION_3(arg1,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_REGISTER5);

# 1719 lines like that

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

使用调试器一切正常。使用 Windbg 一切正常。

没有调试器 - 应用程序静崩溃。

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

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

我尝试过:

  • 注释掉相同的函数调用(以确保它不是函数实现错误)-> 只有数量很重要
  • 禁用优化
  • 将堆栈大小增加到 140 Mb
  • 使用静态 MSVC 分析检查未初始化或归零的变量 - 没有。
  • 在互联网上阅读类似案例。
  • 用于调试的文件日志

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

因此问题:

  • 有没有办法在没有调试模式的情况下从崩溃中获取更多信息?
  • 有没有办法表示如此大量的调用,这样代码会很快,但不会使堆栈过载?注意:所有函数调用都根据发生异常的偏移量提供不同的参数,因此分组将减少非常小的调用量。
  • 如果您遇到此类问题以进行调试,您的下一步是什么?

谢谢并希望得到您的帮助。

解决方法

好的,我解决了这个问题:

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?