SEH的机制

异常处理程序或 __except 块,可以根据 *filter-expression* 值响应或消除异常。

终止处理程序或 __finally 块,无论异常是否导致终止,都始终调用这两者

这两种类型的处理程序是不同的,但会通过称为“展开堆栈”的过程紧密关联。 发生结构化异常时,系统将查找当前处于活动状态的最新安装的异常处理程序。 该处理程序可以执行以下三个操作之一:

识别异常的异常处理程序可能不在异常发生时正在运行的函数中。 它可能在堆栈上高得多的函数中。 当前正在运行的函数和堆栈帧上的所有其他函数都将终止。 在此过程中,堆栈会展开。 也就是说,已终止函数的局部非静态变量会从堆栈中清除。

当它展开堆栈时,操作系统将调用你为每个函数编写的任何终止处理程序。 通过使用终止处理程序清理资源,否则资源将由于异常终止而保持打开状态。 如果你已输入了关键部分,可以在终止处理程序中退出它。 程序将要关闭时,你可以执行其他维护任务,如关闭和删除临时文件。

CTF中SEH的使用

Windows中有一个机制叫异常处理机制,当出现异常的时候操作系统会先把异常抛给调试器并停止在该指令位置,如果没有调试器就会抛给SEH来处理,SEH实现的原理是内部是一个SEH链表包含了一系列异常处理函数,当有异常类添加进来的时候操作系统会把异常添加到SEH链表里面,然后当异常出现的时候遍历异常类看看有没有对应的异常处理,如果该异常没有异常处理则直接程序崩溃。

所以对于此方面的处理,由于出题人会将我们的关键代码,放入SEH断下来之后,从而实现了代码的隐藏,所以处理此类题目我们的思路就是,就是去寻找出题人隐藏的代码,其中有两方面,一方面就是观察主程序的汇编,对于jmp要特别主要,大多数,就会出现一个莫名的jmp跳过了一大段的内容,这是因为使用了SEH处理机制,将SEH断入,就会执行我们那跳过的代码。所以我们只需修改跳转即可,另外如果主程序没有而是在其他地方调用,这就需要我们进行动态调试了,通过动态调试确定我们数据被修改的地方,也能找到被出题人隐藏的代码