Почему в двоичных файлах ELF байты инвертируются группами по два

Я пытаюсь создать редактор заголовков в формате ELF. При разработке я заметил, что в бинарных группах по два байта всегда инвертированы.

Вот, например, шестнадцатеричный дамп (для справки я назову его шестнадцатеричным дампом).

[email protected]:~/Documents/ElfEditor$ hexdump Test | head
0000000 457f 464c 0102 0001 0000 0000 0000 0000
0000010 0003 003e 0001 0000 07a0 0000 0000 0000
0000020 0040 0000 0000 0000 2758 0000 0000 0000
0000030 0000 0000 0040 0038 0009 0040 0022 0021
0000040 0006 0000 0004 0000 0040 0000 0000 0000
0000050 0040 0000 0000 0000 0040 0000 0000 0000
0000060 01f8 0000 0000 0000 01f8 0000 0000 0000
0000070 0008 0000 0000 0000 0003 0000 0004 0000
0000080 0238 0000 0000 0000 0238 0000 0000 0000
0000090 0238 0000 0000 0000 001c 0000 0000 0000

Например, в первых 4 байтах я ожидал 7f45 4c46, а не 457f 464c.

Когда я запускаю шестнадцатеричный дамп с аргументом -C, я получаю дамп так, как я ожидал. (Я назову этот hexdump как hexdump2 для справки).

00000000  7f 45 4c 46 02 01 01 00  00 00 00 00 00 00 00 00  |.ELF............|
00000010  03 00 3e 00 01 00 00 00  a0 07 00 00 00 00 00 00  |..>.............|
00000020  40 00 00 00 00 00 00 00  58 27 00 00 00 00 00 00  |@.......X'......|
00000030  00 00 00 00 40 00 38 00  09 00 40 00 22 00 21 00  |[email protected]@.".!.|
00000040  06 00 00 00 04 00 00 00  40 00 00 00 00 00 00 00  |[email protected]|
00000050  40 00 00 00 00 00 00 00  40 00 00 00 00 00 00 00  |@[email protected]|
00000060  f8 01 00 00 00 00 00 00  f8 01 00 00 00 00 00 00  |................|
00000070  08 00 00 00 00 00 00 00  03 00 00 00 04 00 00 00  |................|
00000080  38 02 00 00 00 00 00 00  38 02 00 00 00 00 00 00  |8.......8.......|
00000090  38 02 00 00 00 00 00 00  1c 00 00 00 00 00 00 00  |8...............|

Бинарный файл сохраняется как hexdump1, что затрудняет его чтение в C.

См. также:  Развертывание функций Firebase: ошибка 3 - в запросе есть ошибки

Еще немного дополнительной информации. Это не проблема с порядком байтов, потому что связанные данные, например целые числа, верны в формате с прямым порядком байтов в hexdump2 и неверны в hexdump1. Например, в байте смещения 0x14 начинается 32-битное Int (значение 1), в hexdump2 он правильно представлен байтами 01 00 00 00, а в hexdump1 он неверен (байты 00 01 00 00).

Итак, мои сомнения:

  1. Это нормально?
  2. Почему так происходит?
  3. Так происходит во всех дистрибутивах и архитектурах Linux?
  4. Могу ли я просто инвертировать байты во всем файле (включая остальную часть двоичного файла)?
  5. Есть ли простой или правильный способ исправить порядок байтов?

Я хотел бы сделать мою программу гибкой для работы в любом дистрибутиве или архитектуре Linux. Спасибо за помощь заранее.

Аппаратное обеспечение с прямым порядком байтов? Endianness См. Исполняемый и связываемый форматы   —  person Henry    schedule 02.07.2020

Оба шестнадцатеричных дампа верны, потому что 7F 45 действительно является представлением 457F с прямым порядком байтов. Просто в первом дампе данные отображаются как 16-битные значения, тогда как во втором дампе данные отображаются побайтно.   —  person Henry    schedule 02.07.2020

Спасибо за ответы. Когда я читаю двоичный файл на C, я тоже получаю байты, как и в hexdump1. Он тоже читает 16-битные куски (почему 16 бит, а не другое значение)? Первые 16 байтов в файле должны быть массивом беззнаковых символов. Разве массив char не должен оставаться в порядке независимо от порядка байтов?   —  person Henry    schedule 02.07.2020

Понравилась статья? Поделиться с друзьями:
IT Шеф
Комментарии: 1
  1. Henry

    Поле

    e_ident[EI_DATA]
    

    определяет порядок байтов двоичного файла elf.

    В зависимости от порядка байтов поля, размер которых больше 1, будут инвертированы или нет.

    Спасибо за ответ. Хорошо, я начинаю понимать, что это порядок байтов. Однако поведение по-прежнему для меня странное. Если посмотреть на заголовок формата ELF /usr/includes/elf.h, первые 16 байтов представляют собой массив символов без знака. Насколько я знаю (или думаю, что знаю), массив символов будет храниться в одном и том же порядке как с прямым порядком байтов, так и с прямым порядком байтов. Однако здесь он меняется группами по два байта (почему два байта). Кроме того, это 2 байта endiness изменяет место целого числа с правильного положения, как показано в 0x14. person Henry; 02.07.2020

Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: