я действительно могу использовать 8-битный адрес для сопоставления файла ELF? - PullRequest
0 голосов
/ 01 ноября 2018

Итак, я пытаюсь разобрать исполняемый файл и сказать, является ли он файлом ELF или нет, вот что я сделал:

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

Поскольку я работаю на 64-битной машине, я считаю, что uint64_t является подходящим типом для возвращаемого значения mmap, однако, когда я делаю это, strcmp завершается неудачно. Мне удалось решить эту проблему, используя вместо этого uint8_t, но я не уверен, что это правильный подход. Есть ли проблемы, если я храню 64-битный адрес в 8-битной переменной?

1 Ответ

0 голосов
/ 01 ноября 2018

Указатель всегда будет иметь правильный размер для машины. Например. на 64-битной машине размер указателя будет 64-битным. То, на что это указывает, полностью зависит от вас. Поскольку вы смотрите на это как на байтовый массив, правильно использовать указатель на 8-битные данные, т.е. uint8_t *mapped_file. Это не 8-битный указатель, а указатель (64-битный в вашем случае) на массив 8-битных данных.

Обратите внимание, что при сравнении строк strcmp будет использовать строку с нулем в конце. Если байт, следующий за «ELF», не равен нулю, произойдет сбой. Вместо этого используйте strncmp, где вы можете указать длину сравнения, которая будет ограничена 3 байтами.

Причиной сбоя вашего кода является то, что вы указываете массив из 64-битных значений. Таким образом, в сравнении mapped_file[0] != 0x7f вы фактически сравниваете 64-битное (первые 8 байт файла) значение с 0x7f. Точно так же ваше смещение на &mapped_file[1] будет фактически начинаться с 9-го байта, а не 2-го.

...