Magic number in files Linux. C programming

1.2k Views Asked by At

I want to get the Magic Number from a binary file (for example file ELF hava 7f 45 4c 46). I wrote a program to print out the magic number of the file but i get the error zsh: segmentation fault ./magic. How should I fix this?

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"); 
}   
1

There are 1 best solutions below

0
Marco Bonelli On

A few things first:

  1. I doubt that /Documents/OCP/lab1test/lab1call is a valid path on your system. It's usually /home/[USER]/Documents/..., you should double check that. Even better, pass it as an argument to your program so you can do fopen(argv[1], ...) after checking that argc == 2.

  2. You definitely do not need to seek all the way to the end of the file, and you definitely do not need to allocate a buffer the entire size of the file only to read four bytes at the beginning of the file. Simply fread 4 bytes. You can safely declare a 4-byte array on the stack of main.

  3. You must do error checking. Almost every library function in C can fail and return an error. Check the manual page (usually simply type man 3 function_name in your terminal) and see which errors can happen for each function and which is a "good" return value. The section 3 of the manual is for library functions. If you don't have the manual installed you can use an online one like for example manned.org.

With this said, what you're trying to do can be simplified down to:

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;
}

You can compile and then run your program like this:

./magic path/to/the/file

Beware that if the path contains spaces you will have to enclose it in quotes otherwise it will be interpreted as two different arguments:

./magic 'path/with some/spaces'