为什么下面的代码不会生成“分段错误”?在窗户上?
#include <stdio.h>
#include <string.h>
void bad() {
printf("Oh shit really bad~!\r\n");
}
void foo() {
char overme[4] = "WOW";
*(int*)(overme+8) = (int)bad;
}
int main() {
foo();
}
在32位linux中它会产生分段错误,但在windows中不会。为什么?
#include <stdio.h>
#include <string.h>
void bad() {
printf("Oh shit really bad~!\r\n");
}
void foo() {
char overme[4] = "WOW";
*(int*)(overme+8) = (int)bad;
}
int main() {
foo();
}
In 32bit linux it generates segmentation fault,but in windows not.Why?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
因为未定义的行为确切意味着:未定义。未定义但会导致错误,但未定义,意味着任何事情都可能发生。
有时任何事情都可能按预期工作。当然,这并不意味着它是一件好事,因为它可能停止在新的编译器或操作系统或运行时库中按预期工作,甚至根据星期几或阶段月亮。
ISO 标准规定了一个定义良好的程序将如何运行,而不规定一个未定义的程序将如何运行,只是说它可以做任何它喜欢的事情。
对于特定情况,您必须检查编译器生成的汇编代码,以了解为什么它不会破坏您的堆栈。 Linux 可能会在您要覆盖的位置存储相当重要的信息(例如
main
的返回地址),而 Windows 则存储一些相对良性的信息(例如main< 的返回代码)。 /代码>)。
Because undefined behaviour means exactly that: undefined. Not defined-but-will-cause-error, but undefined, meaning that anything can happen.
And sometimes that anything may be that it works as expected. That doesn't make it a good thing, of course, since it may stop working as expected with a new compiler or operating system or runtime library or even based on the day of the week or phase of the moon.
The ISO standards mandate how a well defined program will behave, they do not mandate how an undefined one will, other than to say it can do anything it darn well pleases.
For the specific case, you would have to examine the assembler code generated by the compiler to see why it's not trashing your stack. It's possible that Linux stores a rather vital piece of information at the location you're overwriting (like the return address from
main
) while Windows stores something relatively benign (like the return code frommain
).