为什么这段代码容易出现缓冲区溢出?
Why is this code vulnerable to buffer overflow?
void cpy(char* b) {
char values[1024];
strcpy(b, values);
fprint(values);
}
int main(int argc, char** argv){
if(argc == 1 || strlen(argv[1]) > 1024) {
fprint("Nope!\n");
return 1;
}
cpy(argv[1]);
return 0;
}
为什么这段代码容易出现缓冲区溢出?我认为这与 "strcpy" 部分有关,但我不确定...
有什么想法吗?
我认为您使用的是 char 数组,因为没有运算符来标记数组的结尾。
问题是fprint,它不知道你的字符串什么时候结束。它应该以“\0”结尾。因此,如果您在数组中写入所有 1024 字节集的内容。 fprint命令会从内存中读取出来检查是否有'\0'... 会一直读取直到找到结束标记。
短篇小说:strcpy
上的论点被调换了。
长话短说:strcpy
将 从第二个参数复制到第一个 参数。
让我们快速分析一下。在 main
中,代码检查 argv[1]
的长度最多为 1023+1(NUL 字节)个字符。 argv[1]
然后作为第一个也是唯一的参数传递给 cpy
并在那里作为 b
.
可用
在cpy
中,还有一个未初始化的char数组,名为values
,分配为1024个字符长。
现在,strcpy
被指示从 values
复制到 b
。我们知道,b
是从argv[1]
得到的指针,因此最多有space的1024个字符。 values
保留为 1024 个字符,但未初始化。因此,它在这 1024 个字符中可能包含也可能不包含 NUL 字节。
如果它在达到 argv[1]
的边界之前恰好包含一个 NUL 字节,那么一切都很好。如果没有,可能会发生两件事:
如果 argv[1]
正好是 1023 个字符长(+ 终止 NUL 字节),越界读取(在 values
上)和写入(在 argv[1]
上)会发生的。
如果argv[1]
长度小于1023个字符,argv[1]
会发生越界写入,推而广之,[=也可能发生越界读取18=],如果程序在越界写入后仍然存在。
取决于 fprint 是什么(我的系统上没有它的联机帮助页),代码中可能还有其他问题。
void cpy(char* b) {
char values[1024];
strcpy(b, values);
fprint(values);
}
int main(int argc, char** argv){
if(argc == 1 || strlen(argv[1]) > 1024) {
fprint("Nope!\n");
return 1;
}
cpy(argv[1]);
return 0;
}
为什么这段代码容易出现缓冲区溢出?我认为这与 "strcpy" 部分有关,但我不确定...
有什么想法吗?
我认为您使用的是 char 数组,因为没有运算符来标记数组的结尾。
问题是fprint,它不知道你的字符串什么时候结束。它应该以“\0”结尾。因此,如果您在数组中写入所有 1024 字节集的内容。 fprint命令会从内存中读取出来检查是否有'\0'... 会一直读取直到找到结束标记。
短篇小说:strcpy
上的论点被调换了。
长话短说:strcpy
将 从第二个参数复制到第一个 参数。
让我们快速分析一下。在 main
中,代码检查 argv[1]
的长度最多为 1023+1(NUL 字节)个字符。 argv[1]
然后作为第一个也是唯一的参数传递给 cpy
并在那里作为 b
.
在cpy
中,还有一个未初始化的char数组,名为values
,分配为1024个字符长。
现在,strcpy
被指示从 values
复制到 b
。我们知道,b
是从argv[1]
得到的指针,因此最多有space的1024个字符。 values
保留为 1024 个字符,但未初始化。因此,它在这 1024 个字符中可能包含也可能不包含 NUL 字节。
如果它在达到 argv[1]
的边界之前恰好包含一个 NUL 字节,那么一切都很好。如果没有,可能会发生两件事:
如果
argv[1]
正好是 1023 个字符长(+ 终止 NUL 字节),越界读取(在values
上)和写入(在argv[1]
上)会发生的。如果
argv[1]
长度小于1023个字符,argv[1]
会发生越界写入,推而广之,[=也可能发生越界读取18=],如果程序在越界写入后仍然存在。
取决于 fprint 是什么(我的系统上没有它的联机帮助页),代码中可能还有其他问题。