Reputation: 554
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
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