x64 SEH分析

参考文献

     https://blog.csdn.net/frankiewang008/article/details/17390671

x64 SEH

    首先 try catch 不能随意使用了 因为x64程序是整个堆栈平衡  如下例子

    

A 是VS编辑器生成的
sub rsp, 48h
try{
    B();
}
catch(){
}
add rsp, 48h

B 是自定义汇编生成的(VS里的 asm)
sub rsp, 18h
    call XXX
add rsp, 18h

x64是不会对 汇编进行SEH 所以当 A调用了B, x64 SEH表里记录的 A的堆栈还是48h 而我们调用B B调用别的函数 这个时候发生异常. 因为B减去了 18h 堆栈破坏了.所以SEH就找不到对应的 except_handler了 

    解决办法

      1

           https://www.codeproject.com/Articles/1212332/bit-Structured-Exception-Handling-SEH-in-ASM

           https://docs.microsoft.com/en-us/cpp/build/exception-handling-x64?view=vs-2019

           Unwind helpers for MASM

          微软提供了伪指令 来告诉编辑器 汇编的堆栈也要被记录

          

 伪指令表

 

使用伪指令就可以避免上述问题

 2  HOOK RtlDispatchException

  当异常调用到 RtlDispatchException

   它的第二个参数是线程上下文(context) 我们把里面的 context->rsp 值修改为 上述(调用B之后未执行任何代码的堆栈地址) 别名 B栈   就OK了.

   但经过我发现实际需要改堆栈里另一个参数 偏移是 第二个参数地址+5a0 系统 win10 Microsoft Windows [版本 10.0.10586]

   有一个技巧那就是 在 RtlDispatchException 上下断.当触发到RtlDispatchException  用CE去搜索堆栈 context->rsp.就可以搜索到目标地址 一起修改就完美运行.

 作者推荐第一种办法 第二种兼容性 极其差..因为5a0会变得

  

原文地址:https://www.cnblogs.com/kuangke/p/13641033.html