Visual C++ 里的异常处理
微软Visual C++是Win32最广泛使用的编译器,因此Win32反向器对其内部工作非常熟悉。能够识别编译器生成的粘合代码有助于快速集中于程序员编写的实际代码。它还有助于恢复程序的高级结构。我将集中讨论MSVC编译程序中的堆栈布局、异常处理和相关结构。假设对汇编程序、寄存器、调用约定等有一定的了解。
名词解释:
- Stack frame---堆栈帧,函数使用的堆栈段的片段。通常包含函数参数、返回调用方地址、保存的寄存器、局部变量和其他特定于此函数的数据。在x86(和大多数其他架构)上,调用者和被调用者堆栈帧是连续的。
- Frame pointer---帧指针,指向堆栈帧内固定位置的寄存器或其他变量。通常堆栈帧中的所有数据都是相对于帧指针寻址的。在x86上,它通常是ebp,通常指向返回地址的正下方。
- Object---对象,(C++)类的一个实例。
- Unwindable Object---不可逆转的对象,具有自动存储类说明符的本地对象,在堆栈上分配,超出范围时需要销毁。
- Stack UInwinding---堆栈展开:当控制由于异常而离开作用域时,自动销毁此类对象。
win32里C/C++异常分类
在C或C++程序中可以使用两种类型的异常。
- SEH异常(来自“结构化异常处理”)。也称为Win32或系统异常。著名的Matt Pietrek文章[1]详尽地介绍了这些内容。它们是C程序唯一可用的例外。编译器级别的支持包括关键字try、except、finally和其他一些关键字。
- C++异常(有时称为“EH”)。在SEH之上实现,C++异常允许任意类型的抛出和捕获。C++的一个非常重要的特点是在异常处理过程中自动堆栈展开,而MSVC使用一个非常复杂的底层框架来保证它在所有情况下都能正常工作。
栈基本布局
在下图中,内存地址从上到下递增,因此堆栈“向上”增长这是在IDA中表示堆栈的方式,与大多数其他出版物相反。 最基本的堆栈帧如下所示:
- 上一篇: 仅通过转储来排除内存泄漏
- 下一篇: 使用Java中的InputStream读取文件数据