0

我一直在为 Linux 编写一个 NASM 程序。我希望能够从我为 SIGFPE 建立的信号处理程序中返回到正常的代码路径。精简后的示例代码是:

section .text

global _start
_start:                  ; --- Enter the program ---
   mov      ebx,8        ; Load the signal to handle (SIGFPE)
   mov      ecx,.handle  ; Load the handler address
   mov      eax,48       ; Load the syscall number for signal
   int      0x80         ; Establish the handler
   mov      ebx,0        ; Prepare a divisor for SIGFPE
   idiv     ebx          ; Divide edx:eax by 0
   mov      ebx,0        ; Set exit status 0 (shouldn't get here)
   jmp      .exit        ; Exit the program

.handle:                 ; --- Handle a divide exception ---
   mov      ebx,31       ; Set exit status 31 (instead of real handling)

.exit:                   ; --- Exit the program ---
   mov      eax,1        ; Load the syscall number for exit
   int      0x80         ; Exit back to the system

幻数是为了代码的紧凑性。

在 idiv 指令之前,esp 是0xffffcc00. 在信号处理程序的入口处, esp 是0xffffc52c. 相当多的东西已经放在堆栈上!有大量关于 __NR_sigreturn 的信息。我没有运气尝试使用它。处理程序中的一条ret指令只是让我回到 idiv 指令,这次没有处理程序。

关于我可以在.handle标签上做什么以安全返回主线的任何想法?

(我知道 sigaction 是可用的,但我想了解在这种情况下发生了什么。)

4

1 回答 1

1

一个简单的ret将返回以重新尝试错误指令。当使用sigactionflag 注册信号处理程序时SA_SIGINFO,第三个参数是指向 a 的指针,ucontext_t其中包含保存的状态,可以更改。

于 2015-09-03T21:36:33.590 回答