通过信号和返回地址更改程序执行流程

时间:2015-07-09 17:55:05

标签: c++ g++ signals callstack activation-record

我试图通过更改此代码中函数的返回地址来更改程序执行流程:

void s(int signum) {
    int b = 1;
    *(&b+3) = *(&b+3) + 4;
}

void f() {
    while(true);
    printf("f exit\n");
}

int main() {
    signal( SIGCONT, s );

    f();

    printf("end of prog");

    return 0;
}

为此,我调用f函数。所以它被卡在while(true)。然后我使用SIGCONT命令向程序发送kill -SIGCONT <PID>信号。现在程序必须中断在while(true)中执行f并执行s功能。在s函数中,我定义b以查找运行时堆栈中s函数的返回地址*(&b+3)。我尝试使用*(&b+3) = *(&b+3) + 4更改此值,以便在返回f时,跳过执行while(true)并执行printf("f exit\n")。但它一直停留在while,我不知道如何使这项工作。

注意:我通过将*(&amp; b + 3)与之前的__builtin_return_address(0)返回的值进行比较来验证*(&amp; b + 3)作为返回地址。

函数体mainf必须保持不变。

感谢。

1 个答案:

答案 0 :(得分:0)

解决方案是以某种方式告诉while循环事情发生了变化。 例如

volatile int flag = 0 ;

void s(int signum) {
    int b = 1;
    __sync_fetch_and_add( &flag, 1 ) ;
}

void f() {
    while(__sync_fetch_and_add( &flag, 0 ) == 0);
    printf("f exit\n");
}

添加原子内在函数(函数__sync_fetch_and_add)以避免优化循环。我不确定简单的易变性就足够了。我自己也在等待评论......