我想从二进制文件(例如文件ELF hava 7f 45 4c 46(中获取幻数。我写了一个程序来打印出文件的幻数,但我得到了错误zsh:分段错误/魔术我应该如何解决这个问题?
int main()
{
//setlocale(LC_ALL, "Russian");
//FILE *fp;
//fopen (&fp, "/Documents/OCP/lab1test/lab1call", "rb");
FILE *fp;
long fSize;
fp = fopen("/Documents/OCP/lab1test/lab1call", "rb");
fseek (fp , 0 , SEEK_END);
fSize = ftell (fp);
rewind (fp);
char *magic_number;
magic_number=(char *)malloc(fSize+1);
//unsigned char magic_number[4];
fread(magic_number, sizeof(char), 4, fp);
printf ("A magic number of your file is:n");
//magic_number[4] = ' ';
//for (int i = 0; i < 4; i++)
printf ("%02hhx%02hhx%02hhx%02hhxn ", magic_number[0],magic_number[1], magic_number[2], magic_number[3]);
printf("n");
}
首先要做的几件事:
-
我怀疑
/Documents/OCP/lab1test/lab1call
在您的系统中是否是有效路径。通常是/home/[USER]/Documents/...
,你应该仔细检查一下。更好的是,将其作为参数传递给程序,这样您就可以在检查argc == 2
之后执行fopen(argv[1], ...)
。 -
您绝对不需要一直搜索到文件的末尾,也绝对不需要分配一个文件大小的缓冲区来读取文件开头的四个字节。简单地
fread
4字节。您可以在main
的堆栈上安全地声明一个4字节的数组。 -
你必须进行错误检查。C中几乎每个库函数都可能失败并返回错误。检查手册页面(通常只需在终端中键入
man 3 function_name
(,看看每个功能可能发生哪些错误;"好";返回值。本手册的3
部分用于库功能。如果你没有安装手册,你可以使用在线手册,比如manned.org.
话虽如此,你试图做的事情可以简化为:
int main(int argc, char **argv) {
FILE *fp;
unsigned char magic[4];
if (argc != 2) {
fprintf(stderr, "Usage: %s FILENAMEn", argv[0]);
return 1;
}
fp = fopen(argv[1], "rb");
if (fp == NULL) {
perror("fopen failed");
return 1;
}
if (fread(magic, 1, 4, fp) != 4) {
if (feof(fp))
fputs("File is less than 4 bytesn", stderr);
else
fputs("Error reading the filen", stderr);
return 1;
}
fclose(fp);
puts("The magic number of your file is:");
printf("%02hhx%02hhx%02hhx%02hhxn", magic[0], magic[1], magic[2], magic[3]);
return 0;
}
你可以这样编译然后运行你的程序:
./magic path/to/the/file
注意,如果路径包含空格,则必须用引号将其括起来,否则它将被解释为两个不同的参数:
./magic 'path/with some/spaces'