【问题标题】:Magic number in files Linux. C programmingLinux 文件中的幻数。 C 编程
【发布时间】:2022-01-05 21:28:21
【问题描述】:

我想从二进制文件(例如文件 ELF hava 7f 45 4c 46)中获取幻数。我写了一个程序来打印出文件的幻数,但我得到了错误 zsh: segmentation fault ./magic.我应该如何解决这个问题?

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] = '\0'; 
    //for (int i = 0; i < 4; i++) 
    printf ("%02hhx%02hhx%02hhx%02hhx\n ", magic_number[0],magic_number[1], magic_number[2], magic_number[3]);  
    printf("\n"); 
}   

【问题讨论】:

  • 你不需要基于整个文件大小的这么大的 malloc。如果您只从文件中读取前 4 个字节,则只能 malloc 4 个字节。想象一下,如果您正在读取小于 4 字节的文件,并且现在您使用基于该文件大小的 malloc(例如:只有 2B),您的指针会被分配 2B 并且您试图在 fread 中存储 4 个字节,这可能会导致段错误.
  • 在 gdb 之类的调试器中运行它(在使用 -g 选项编译以获取二进制文件中的调试信息之后),以查看它在哪里得到了段错误。
  • 检查fpfopen之后是否不为NULL
  • /Documents 看起来不是有效路径。对所有函数调用进行基本的错误检查,在这种情况下特别是 fopen
  • 你也可以使用简单的数组char magic_number[4]而不用malloc。

标签: c linux magic-numbers


【解决方案1】:

先说几件事:

  1. 我怀疑/Documents/OCP/lab1test/lab1call 是您系统上的有效路径。通常是/home/[USER]/Documents/...,你应该仔细检查一下。更好的是,将它作为参数传递给您的程序,这样您就可以在检查argc == 2 之后执行fopen(argv[1], ...)

  2. 您绝对不需要一直寻找到文件的末尾,并且您绝对不需要分配一个缓冲区来读取文件的整个大小,而只是在开头读取四个字节 文件。只需fread 4 个字节。您可以在main 的堆栈上安全地声明一个 4 字节数组。

  3. 您必须进行错误检查。几乎 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 FILENAME\n", 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 bytes\n", stderr);
        else
            fputs("Error reading the file\n", stderr);
        return 1;
    }

    fclose(fp);
    
    puts("The magic number of your file is:");
    printf("%02hhx%02hhx%02hhx%02hhx\n", magic[0], magic[1], magic[2], magic[3]);

    return 0;
}

你可以像这样编译然后运行你的程序:

./magic path/to/the/file

请注意,如果路径包含空格,则必须将其括在引号中,否则它将被解释为两个不同的参数:

./magic 'path/with some/spaces'

【讨论】:

    猜你喜欢
    • 2014-06-11
    • 2017-07-08
    • 2018-02-16
    • 2017-09-22
    • 2016-07-13
    • 2015-05-04
    • 2012-10-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多