我正在尝试编写一个C程序来演示写入堆栈的不同区域以在运行时更改程序的执行。
我有这个程序:
#include<stdio.h>
int* useless_function (int x) {
int* somewhere_in_the_stack = &x;
int* another_place = &x + 5;
return (int*)((long int)(*another_place)) - 3;
}
int main () {
int step = 3;
int* q = useless_function(50);
printf("%d %d\n",&step,q);
//printf("%d %d\n",&step,*q);
}
试图做到这一点。基本上,useless_function返回局部变量的地址&#39; step&#39;在堆栈的主函数中。当我在我的机器上编译并执行程序时,printf打印出相同的内存地址,用于“步骤”和“步骤”。并且&#39; q&#39;然而在我评论的时候,我试图顺从&#39; q&#39;我遇到了分段错误。但是,我可以在没有段错误的情况下*(&amp; step)。
我尝试使用此选项&#39; -fno-stack-protector&#39;进行编译,但它不起作用。
答案 0 :(得分:0)
这完全不正确,但可能在32位平台上运行。
#include<stdio.h>
int* useless_function (int x) {
int* somewhere_in_the_stack = &x;
int* another_place = &x + 5;
指向int。
的指针 return (int*)((long int)(*another_place)) - 3;
因此(* another_place)是一个int。然后你把它投成long int。如果地址不适合int(并且通常不适合),则丢失部分地址。然后结果是符号扩展的。你会看到的......
}
int main () {
int step = 3;
int* q = useless_function(50);
printf("%d %d\n",&step,q);
如果您使用了正确的格式说明符(%p),您会看到截断。有趣的是,即使没有-Wall,gcc也会对这个问题发出警告,所以我更加困惑的是,为什么在解决报告的问题之前你会问这个问题。
最后,一个有趣的事实是printf(&#34;%p \ n&#34;,指针);除非指针的类型为char *或void *。
,否则会触发未定义的行为