#include <stdio.h>
void f2(){}//no code
void f1(){
int b=3,c=7;
c=b+c;
f2();//f2 call
printf("B\n");
}
int main (void) {
int a=3;
a=a+1;
f1();//f1 call
printf("A\n");
return 0;
}
在f2函数中编写一段代码,它将改变上述C程序的控制。根据上面的代码,控制从main函数转到f1函数,f1到f2,然后再从f2返回到f1,f1到main。但是,你只需要在f2函数中编写一些代码,这将直接将你的控制从f2移动到main,因此输出将仅为“A”而不是“BA”。F1函数在执行期间不能被多次调用。您不能修改f1和main函数。您不能在f2函数中编写任何类似printf语句(无论是在C还是在汇编中)。输出“A”应仅从main函数打印
我无法解决,也不知道该怎么做。
1条答案
按热度按时间m1m5dgzv1#
您可以通过不返回
f1
(或main
)来实现这一点。只需执行main
* 会执行的操作,然后退出:不幸的是,这违反了“A必须仅由
main
函数输出”的要求,所以你 * 将 * 必须有一些严肃的内部知识,并执行堆栈操作。这是有风险的,而且令人难以置信的不可移植。这个想法是分析在退出
f1
之前堆栈指针的值,并将代码放入f2
中,将其设置为该值。这样,当退出f2
时,返回点将位于main
而不是f1
。它可以像这样简单:
其中
<value>
是需要计算的值。请注意,
asm
代码也需要根据您的环境进行定制。由于您没有提供CPU架构(或其他具体细节),因此我使用了上面的神话CPU,带有load
指令和sp
寄存器。假设你的
f2
编译代码看起来像这样(注解是我添加的):f1
看起来像:你需要做的是在点1放置一些东西,这样它就会像在点2一样返回。在这段代码中,可以通过向
rbp
添加一个值来实现,正好足够回退:call f2
推送的返回值;和push rbp
在f2
的开始。我还没有做过深入的分析来确认这是要添加的正确值,但它给了你基本的想法。无论如何,它可能需要根据你的情况进行定制,因为它取决于编译器,调用约定,CPU选择,优化级别等因素。