Trey
Trey

Reputation: 554

can I really use an 8-bit address to map an ELF file?

So I'm trying to parse an executable and tell whether it's an ELF file or not, here's what I did:

    uint64_t *mapped_file = mmap(NULL, st.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);

    if (mapped_file[0] != 0x7f || strcmp(&mapped_file[1], "ELF"))
    {
        fprintf(stderr, "%s is not an ELF file\n", argv[1]);
        exit(EXIT_FAILURE);
    }

Since I'm on a 64-bit machine I reckon that uint64_t is the appropriate type for the return value of mmap, however when I do this strcmp fails. I managed to solve this by using uint8_t instead but I'm not sure this is a valid approach. Are there any problems if I store a 64-bit address in a 8-bit variable?

Upvotes: 1

Views: 193

Answers (1)

waterjuice
waterjuice

Reputation: 839

A pointer will always be the correct size for the machine. E.g. on a 64bit machine the pointer size will be 64-bit. What it points to is entirely up to you. Because you are looking at this as a byte array, the correct thing is to use pointer to 8-bit data, i.e. uint8_t *mapped_file. This is not an 8-bit pointer, but a pointer (64-bit in your case) to an array of 8-bit data.

Note with your string compare, strcmp will use a 0-terminated string. Unless the byte following "ELF" is a zero this will fail. Instead use strncmp where you can specify the length of the comparison to be restricted to 3 bytes.

The reason your code is failing is because you are specifying an array of 64bit values. So in the comparison mapped_file[0] != 0x7f you are actually comparing the 64bit (first 8 bytes of file) value to 0x7f. Similarly your offset at &mapped_file[1] will actually be starting at the 9th byte, not the 2nd.

Upvotes: 3

Related Questions