此子程序需要三个用户输入:文本字符串,文件路径和1位标志。它将文件加载到缓冲区中,然后按该顺序将标志和文件缓冲区附加到充当有效负载的char数组中。它返回有效负载和原始用户字符串。
我收到一个错误,其中我在文件缓冲区,标志和有效负载上执行的某些字符串操作似乎破坏了user_string所在的内存。我通过将strcat(flag,buffer)
交换为{{1}来修复了该错误。 }(这是我本来打算写的),但对于导致此错误的原因,我仍然感到困惑。
通过阅读文档(https://www.gnu.org/software/libc/manual/html_node/Concatenating-Strings.html,https://www.gnu.org/software/libc/manual/html_node/Concatenating-Strings.html),我的猜测是strcpy(payload,flag)
扩展了 strcat
字符串to
个字节到未受保护的内存中,该文件内容将加载到缓冲区中的文件内容复制到缓冲区溢出中。
我的问题是:
-
我的猜测正确吗?
-
是否有办法可靠地防止这种情况发生?用
strlen(to)
检查来捕获这种东西是不可靠的,因为它不会始终返回明显错误的东西。您需要一个长度为if(){}
的字符串,并得到一个filelength+1
的字符串。 -
奖金/无关:调用变量而不进行任何运算是否会产生计算成本/缺点/影响?
filelength+1
注意:从主程序中删除此部分会导致/*
user inputs:
argv[0] = tendigitaa/four
argv[1] = ~/Desktop/helloworld.txt
argv[2] = 1
helloworld.txt is a text file containing (no quotes) : "Hello World"
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <string.h>
int main (int argc,char **argv) {
char user_string[100] = "0";
char file_path[100] = "0";
char flag[1] = "0";
strcpy(user_string,argv[1]);
strcpy(file_path,argv[2]);
strcpy(flag,argv[3]);
/*
at this point printfs of the three declared variables return the same as the user inputs.
======
======
a bunch of other stuff happens...
======
======
and then this point printfs of the three declared variables return the same as the user inputs.
*/
FILE *file;
char * buffer = 0;
long filelength;
file = fopen(file_path,"r");
if (file) {
fseek(file,SEEK_END);
filelength = ftell(file);
fseek(file,SEEK_SET);
buffer = malloc(filelength);
printf("stringcheck1: %s \n",user_string);
if (buffer) {
fread(buffer,1,filelength,file);
}
}
long payloadlen = filelength + 1;
char payload[payloadlen];
printf("stringcheck2: %s \n",user_string);
strcpy(payload,flag);
printf("stringcheck3: %s \n",user_string);
strcat(flag,buffer);
printf("stringcheck4: %s \n",user_string); //bug here
free(buffer);
printf("stringcheck5: %s \n",user_string);
payload; user_string; //bonus question: does this line have any effect on the program or computational cost?
return 0;
}
/*
printf output:
stringcheck1: tendigitaa/four
stringcheck2: tendigitaa/four
stringcheck3: tendigitaa/four
stringcheck4: lo World
stringcheck5: lo World
*/
4出现段错误,而不是返回“ lo World”。该行为在其他方面是等效的。