在什么条件下我需要为x86-64汇编函数设置SEH展开信息?

Bee*_*ope 6 windows x86 x86-64 nasm seh

64位Windows ABI定义了一种通用的异常处理机制,我认为这种机制在C++异常和结构化异常之间共享,即使在其他语言如C语言中也是如此.

如果我正在编写一个x86-64汇编例程来编译nasm并链接到C或C++库中,那么在生成展开信息等方面我需要在Windows上做些什么?

我不打算直接在汇编代码中生成任何异常,但我认为如果用户提供的缓冲区无效,代码可能会获得访问冲突等.

我希望尽可能少地编写这个以使其工作,特别是因为它似乎nasm对生成展开信息的支持很差,并且使用MASM不是这个跨平台项目的选项.我确实需要使用(因此保存和恢复)非易失性寄存器.

Ray*_*hen 8

作为一般规则,Windows x64要求所有功能都提供展开信息.唯一的例外是叶函数,它rsp不修改任何非易失性寄存器,也不修改任何非易失性寄存器.

  • 系统假定缺少展开信息意味着该函数是一个不修改`rsp`或任何非易失性寄存器的叶子.它将尝试通过将`rip`恢复到堆栈顶部的值来解除异常,而不是恢复被调用者保存寄存器.现在结果未定义,因为您正在使用垃圾数据. (3认同)
  • 例如,在修改非易失性寄存器和 rsp 的叶函数中不提供展开信息的后果是什么?我认为它只会在异常时崩溃而不是尝试解除,或者是否存在其他后果,例如中断或异步任务处理的堆栈破坏问题? (2认同)
  • 它未定义但仍受过程安全边界的限制.也许突然出现在`rip`中的值恰好落在有效(但不相关)函数的中间,此时堆栈展开尝试调用甚至没有激活记录的函数的except处理程序.此时,您正在有效地执行随机代码,并且行为是不可预测的.如果你很幸运,你会立即崩溃.如果你运气不好,程序会设法在一个损坏的状态下跛行.如果你非常不走运,它会安装恶意软件. (2认同)
  • @raymond - 是的,这就是我已经做的,因为它很简单。真正的问题是“nasm”不直接支持“.pdata”的生成,因此您只能手动删除展开信息。 (2认同)