我是stackoverflow的新手,所以我提前为我犯的任何错误道歉。
我最近遇到过这个C拼图。该计划如下。
#include<stdio.h>
void change()
{
}
int main()
{
printf("\nHello");
change();
printf("\nHai");
printf("\nHow are you?");
return 0;
}
预期的输出是,
Hello
Hai
How are you?
问题要求我们通过在函数change()
中添加一些代码来更改输出Hello
How are you?
您不应该在main()中进行任何更改。
我试图通过避免语句printf(“\ nHai”)来更改存储在堆栈内存中的函数change()的返回地址。但是当我使用gcc编译时,我遇到了错误。
我在change()中添加的代码如下所示。
void change()
{
char ch;
*(&ch+10)+=20;
}
使用
固定添加到ch(10和20)的值objdump -d ./a.out
我希望收到一些解决问题的建议。提前感谢您的时间和耐心。
答案 0 :(得分:2)
你很亲密。以下是x86-64上的linux。
main.c中:
#include <stdio.h>
void change()
{
char dummy;
/* skip local variable and rbp */
*(long*)(&dummy + sizeof(dummy) + sizeof(long*)) += 0x40055e - 0x400554;
}
int main()
{
printf("Hello\n");
change();
printf("Hi\n");
printf("How are you?\n");
return 0;
}
输出:
$ gcc -fno-stack-protector -o main main.c
$ ./main
Hello
How are you?
来自objdump我们得到:
40054f: e8 c8 ff ff ff callq 40051c <change>
-> 400554: bf 1a 06 40 00 mov $0x40061a,%edi
400559: e8 92 fe ff ff callq 4003f0 <puts@plt>
-> 40055e: bf 1e 06 40 00 mov $0x40061e,%edi
400563: e8 88 fe ff ff callq 4003f0 <puts@plt>
过程:
首先在main.c
中使用一个小的任意差异。然后编译并运行objdump -d main
以获取实际的偏移并更新main.c
与它们的区别。
答案 1 :(得分:1)
以下代码应达到预期效果。
#include<stdio.h>
#include <stdlib.h>
void change()
{
printf("\nHow are you?");
exit(0);
}
int main()
{
printf("\nHello");
change();
printf("\nHai");
printf("\nHow are you?");
return 0;
}
此代码将导致程序打印“Hello”然后执行change()函数,该函数将打印“你好吗?”在换行符上然后退出程序。 exit()函数是c标准库的一部分,可以看作Here