从设置EIP = 00000000的指令中恢复

时间:2012-01-20 14:58:01

标签: assembly crash x86

虽然搞乱了一些x86 asm,但我想知道一个错误导致EIP被设置为00000000或另一个不存在的内存位置的情况。是否可以通过SEH或类似的错误处理机制捕获这些情况并恢复执行? (假设堆栈,堆和寄存器没有被删除)

2 个答案:

答案 0 :(得分:2)

在它发生之前没有很好的方法可以捕获它,但你可以尝试的一件事是检查堆栈(ESP和/或EBP处的内存)并检查指向代码的指针。

如果导致此问题的指示是call,那么您很幸运 - ESP处的双字将是返回地址,紧跟在违规者之后。

如果它是jmp,则机会较小,但你仍然可以寻找可能的执行痕迹。

最糟糕的情况是,这是由带有ret的{​​{1}}引起的 - 通常此时堆栈完全是假的。您仍然可以检查其他寄存器的值,可能其中一个寄存器将包含一个可能为您提供一些线索的指针,并且您扫描整个堆栈区域以查找堆栈帧图案,如in this post所述。

答案 1 :(得分:0)

您最有可能,也可能是最安全的“解决方案”是使用setjmp / longjmp(或CONTEXT)可以安全返回的流程状态的快照存储在流程的唯一位置,但不可触及,例如FS / GS / ES段,与PEB的存储方式相似。这样可以正确恢复所有寄存器,而不会留下太多可能的漏洞。

当然这对于像游戏这样的东西来说是错误的(取决于爆炸发生的确切位置),但是对于像文字处理器这样的东西,或者说轻微状态丢失不是主要问题的应用程序,它应该可以正常工作(这提醒旧的Dev-C ++ IDE,曾经崩溃过所有其他文件,但不知何故仍然继续运行,尽管它确保了一个“致命”的例外,它无法从...恢复。)。