[英]segmentation fault on buffer overflow
I am having trouble to run this c code.我无法运行此 c 代码。 When I do i get segmentation fault and an error with 'return' return 0xdeadbeef;
当我这样做时,我遇到分段错误和“返回”错误返回 0xdeadbeef;
Anyone have any suggestions?有人有什么建议吗?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int lame(unsigned int size, unsigned int value){
unsigned int array1[4];
unsigned int array2[6];
array2[5] = value;
memcpy(&array1, &array2, size * sizeof(unsigned int));
return 1;
}
void awesome(){
printf("awwwwwww yeaaahhhhh! All awesome, all the time!\n");
}
main(unsigned int argc, char ** argv){
unsigned int size, value;
size = strtoul(argv[1], 0, 10);
value = strtoul(argv[2], 0, 16);
if(!lame(size, value)){
awesome();
}
else{
printf("I am soooo lame :(\n");
}
return 0xdeadbeef;
}
I said that there was "at least one bug on almost every line of your code" and now I will list them.我说过“你的代码几乎每一行都至少有一个错误”,现在我将列出它们。 If I don't have any comments on a line, there are no bugs on that line, but you also need to read up on proper code formatting and style.
如果我对某行没有任何注释,则该行没有错误,但您还需要阅读正确的代码格式和样式。
int lame(unsigned int size, unsigned int value){
unsigned int array1[4];
unsigned int array2[6];
array2[5] = value;
memcpy(&array1, &array2, size * sizeof(unsigned int));
return 1;
}
Undefined behavior on the memcpy
line if size
is larger than 4. Since size
is taken from user input, this program contains a buffer overflow vulnerability, albeit one that might be hard to exploit.如果
size
大于 4,则memcpy
行上的未定义行为。由于size
取自用户输入,因此该程序包含一个缓冲区溢出漏洞,尽管可能难以利用。 (You need to read " Smashing the Stack for Fun and Profit .") (您需要阅读“为了乐趣和利润而粉碎堆栈”。)
This function has no externally visible side effects.此功能没有外部可见的副作用。 The compiler may, and probably will, delete all of its code except the
return 1
.编译器可能并且可能会删除除
return 1
之外的所有代码。
Functions that always return the same constant value should be refactored to return void
.始终返回相同常量值的函数应该重构为返回
void
。 Functions that are not used outside the current file should be declared static
.在当前文件之外未使用的函数应声明为
static
。
void awesome(){
printf("awwwwwww yeaaahhhhh! All awesome, all the time!\n");
}
This use of printf
can be replaced by puts
. printf
这种用法可以替换为puts
。 Functions that are not used outside the current file should be declared static
.在当前文件之外未使用的函数应声明为
static
。
main(unsigned int argc, char ** argv){
The first argument to main
must have type int
, not unsigned int
. main
的第一个参数必须是int
类型,而不是unsigned int
。 The return type (which must be int
, not void
) is missing;缺少返回类型(必须是
int
,而不是void
); many compilers will tolerate this (treating it as implicitly returning int
) for backward compatibility with pre-C89 code, but it's still Wrong.为了与 C89 之前的代码向后兼容,许多编译器会容忍这种情况(将其视为隐式返回
int
),但它仍然是错误的。
unsigned int size, value;
size = strtoul(argv[1], 0, 10);
value = strtoul(argv[2], 0, 16);
Both size
and value
should be unsigned long
for consistency with what strtoul
returns. size
和value
都应该是unsigned long
以与strtoul
返回的内容保持一致。
Undefined behavior if there are fewer than two command-line arguments.如果命令行参数少于两个,则未定义行为。
Need to check both calls to strtoul
for failure.需要检查对
strtoul
两次调用是否失败。 This is nontrivial;这很重要; read the EXAMPLES section of the OpenBSD manpage for
strtoul
to learn how to do it correctly .阅读
strtoul
的 OpenBSD 联机帮助页的示例部分,以了解如何正确执行此操作。
However, props for using strtoul
rather than atoi
(which you can't check for failure) or sscanf
(which has undefined behavior on integer overflow).但是,使用
strtoul
而不是atoi
(您无法检查失败)或sscanf
(在整数溢出时具有未定义的行为)的道具。
if(!lame(size, value)){
awesome();
}
else{
printf("I am soooo lame :(\n");
}
The compiler can and will determine that lame
always returns 1, and optimize out the call to awesome
.编译器可以并且将会确定
lame
总是返回 1,并优化对awesome
的调用。 (In fact, it would be entitled to optimize out everything but the above printf
, as all control flow paths either trigger undefined behavior or they reach this printf
, and there are no other externally visible effects. The compilers I have readily to hand are not quite that clever, but they do remove the if-then-else and all the code inside lame
.) (实际上,它有权优化除上述
printf
之外的所有内容,因为所有控制流路径要么触发未定义的行为,要么到达此printf
,并且没有其他外部可见的影响。我很容易掌握的编译器不是非常聪明,但他们确实删除了 if-then-else 和lame
所有代码。)
This use of printf
can also be replaced by puts
. printf
这种用法也可以替换为puts
。
You will automatically become 23% less lame the moment you stop calling yourself lame.一旦你不再称自己为跛脚,你就会自动减少 23% 的跛脚。
return 0xdeadbeef;
The value returned by main
is meaningful. main
返回的值是有意义的。 0 means success of the overall program, any other value means some sort of failure. 0 表示整个程序的成功,任何其他值都表示某种失败。 Always return 0 unless you intend to indicate failure.
除非您打算指示失败,否则始终返回 0。 Also, only values in the range [0, 127] can be reliably received by the parent process cross-platform;
此外,父进程跨平台只能可靠地接收范围 [0, 127] 中的值;
0xdeadbeef
is Right Out. 0xdeadbeef
是正确的。
In your screenshot, main
returned void
instead of having a missing return type;在您的屏幕截图中,
main
返回void
而不是缺少返回类型; that plus a return
statement with a value should have caused the program to fail to compile .加上带有值的
return
语句应该会导致程序无法编译。 Your compiler might tolerate it in main
, though.不过,您的编译器可能会在
main
容忍它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.