【发布时间】:2015-09-28 06:20:40
【问题描述】:
我正在尝试通过更改此代码中函数的返回地址来更改程序执行流程:
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)。然后我使用kill -SIGCONT <PID> 命令向程序发送SIGCONT 信号。现在程序必须中断在f 中执行while(true) 并执行s 函数。在s 函数中,我定义了b 以在运行时堆栈中找到s 函数的返回地址*(&b+3)。我尝试使用*(&b+3) = *(&b+3) + 4 更改此值,以便当它返回f 时,跳过while(true) 的执行并执行printf("f exit\n")。但它一直卡在while,我不知道如何使它工作。
注意:我通过将 *(&b+3) 与之前 __builtin_return_address(0) 返回的值进行比较,验证了它是返回地址。
函数体 main 和 f 必须保持不变。
谢谢。
【问题讨论】:
-
您有理由这样做吗?您可以使用更便携的方法,例如
setjmp(3)/longjmp(3)或在信号处理程序中使用标志。 -
s的返回地址不在f内——它在调度信号的任何运行时函数中。 -
我正在尝试在 SIGCONT 进入时模拟分支故障。程序必须停留在
while(true),直到信号到来并执行s。然后s应该通过更改其返回地址来实现。默认情况下,s的返回地址是f中的while(true),我想将其更改为其他位置,例如printf("f exit\n");。感谢您的帮助
标签: c++ g++ signals callstack activation-record