信号处理函数调用歧义

时间:2016-02-01 00:44:55

标签: c signals atoi

当我在战争游戏中解决其中一个问题时,我在C中遇到了一个奇怪的信号函数行为。就我的理解而言,

void (*signal(int sig, void (*func)(int)))(int)

sig是遇到调用处理函数func时的信号编号。 我试图找到漏洞的代码就是这个

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>

void catcher(int a)
{
    setresuid(geteuid(),geteuid(),geteuid());
    printf("WIN!\n");
    system("/bin/sh");
    exit(0);
}

int main(int argc, char **argv)
{
    if (argc != 3 || !atoi(argv[2]))
            return 1;
    signal(SIGFPE, catcher);
    return abs(atoi(argv[1])) / atoi(argv[2]);
}

我的任务是执行从捕获器函数执行的shell,这意味着无论如何我能够引导我的控制流来运行捕获器函数 - 我完成了。我发现的一个方法是使用atoi函数接受整数减去最小32位有符号整数即-2,147,483,647的事实,因此我们可以做的是将第一个参数提供为-2,147,483,649和第二个参数为-1,最终将导致值2,147,483,649传递给atoi并导致SIGFPE。这种方法实际上也很好。

我怀疑的是,即使我们使用上述方法,也会在使用signal()函数之后执行return语句。那么当atoi的使用中存在SIGFPE时,程序是如何通过一条指令向后运行并启动catcher()处理函数的呢?

1 个答案:

答案 0 :(得分:1)

  

当atoi的使用中存在SIGFPE时,程序如何通过一条指令向后运行并启动catcher()处理函数?

没有。 signal(SIGFPE, catcher);告诉Linux内核,“嘿,如果我得到SIGFPE,请致电catcher,好吗?”

然后当你的程序获得SIGFPE时,就像你问的那样,内核确保调用catcher - 而不是杀死你的程序,这是你通常会做的事情,如果你没有要求它致电catcher