Как выбрать режим разборки для кода загрузчика? - PullRequest
0 голосов
/ 14 февраля 2020

Допустим, у меня есть код сборки загрузчика для отладки, который использует .code16 и .code32 для определения кодов для различных режимов процессора, в котором он работает. Архитектура, для которой предназначен этот загрузчик, является 64-битной (x86 ) CPU.

Теперь какой режим следует использовать во время разборки (с помощью таких инструментов, как objdump, gdb и т. Д. c.)? i8086? i386? x86-64?

Согласно моему пониманию и наблюдению, мы должны использовать их комбинацию в зависимости от того, какой фрагмент кода мы анализируем (.code16, .code32), поскольку это дает ожидаемые результаты (для меня) ).

Например:

.code16
mov %ax, %bx
mov %ecx, %edx

.code32
mov %eax, %ebx
mov %cx, %dx

Скомпилировано так:

$ as -o test.o test.S. #16-bit and 32-bit code packed in 64-bit elf, default 64 since host is 64-bit

Сборка для 16-битного режима ЦП. Секция 16-битного кода отображается нормально, а секция 32-битного кода испорчена.

$ objdump -m i8086 -d test.o

test.o:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <.text>:
   0:   89 c3                   mov    %ax,%bx
   2:   66 89 ca                mov    %ecx,%edx
   5:   89 c3                   mov    %ax,%bx
   7:   66 89 ca                mov    %ecx,%edx

Анализ в 32-битном режиме. Теперь 32-битная секция coe идеально разбирается, хотя 16-битная секция кода испорчена.

$ objdump -m i386 -d test.o

test.o:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <.text>:
   0:   89 c3                   mov    %eax,%ebx
   2:   66 89 ca                mov    %cx,%dx
   5:   89 c3                   mov    %eax,%ebx
   7:   66 89 ca                mov    %cx,%dx

Пожалуйста, подтвердите, если стратегия идеальна, иначе, пожалуйста, исправьте меня, каков наилучший метод при разборке код смешанной сборки (16,32,64 бит).

Ответы [ 2 ]

2 голосов
/ 14 февраля 2020

У дизассемблера нет возможности узнать, что должно быть 16-битным или 32-битным кодом, поэтому вам нужно указать это явно. Например, с помощью objdump:

> objdump -m i8086 --stop-address 0x5 -D test.o

test.o:     file format pe-i386


Disassembly of section .text:

00000000 <.text>:
   0:   89 c3                   mov    %ax,%bx
   2:   66 89 ca                mov    %ecx,%edx

> objdump -m i386 --start-address 0x5 -D test.o

test.o:     file format pe-i386


Disassembly of section .text:

00000005 <.text+0x5>:
   5:   89 c3                   mov    %eax,%ebx
   7:   66 89 ca                mov    %cx,%dx
   a:   90                      nop
   b:   90                      nop

Поскольку вы используете это с загрузчиками, вы также можете использовать опцию --adjust-vma:

> objdump -m i8086 --adjust-vma 0x7c00 --stop-address 0x7c05 -D t457.o

t457.o:     file format pe-i386


Disassembly of section .text:

00007c00 <.text>:
    7c00:       89 c3                   mov    %ax,%bx
    7c02:       66 89 ca                mov    %ecx,%edx

Если вы не собираете бинарный загрузчик, тогда вы можете рассмотреть возможность размещения различных типов кода в разных разделах, чтобы упростить выбор части для разбора (-j опция objdump).

Другие дизассемблеры командной строки имеют такие опции, как это, например, опция ndisasm -k.

0 голосов
/ 14 февраля 2020

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

Например, в Определите версию вашего языка Я показываю все 3 способа разбора этого блока машинного кода; все 3 одинаково действительны и дают разные результаты намеренно. (Это машинный код полиглота, такой как x86-32 / x86-64 фрагмент машинного кода полиглота, который обнаруживает 64-битный режим во время выполнения? )


Если у вас есть разные блоки код в реальном случае, предположительно, вы захотите взглянуть на 16-битную разборку для 16-битных частей и 32-битную разборку для 32-битных частей. Или просто прочитайте источник. Или попросите вашего ассемблера сгенерировать листинг, например nasm -l /dev/stdout -fbin foo.asm. Затем вы получите «машинный код» для каждой строки исходного кода в зависимости от того, для какого режима вы указали ассемблеру для сборки.

GAS также может составлять списки с помощью as -a или gcc -c -Wa,-a (-Wa передает дополнительные параметры непосредственно ассемблеру).

В список включены только машинный код с шестнадцатеричным кодом и исходный код строка (включая комментарии), а не dis сборка. Поэтому, если вы использовали такие приемы, как .byte, для ручного кодирования инструкции, вы не увидите, как процессор будет ее интерпретировать. Для этого см. Ответ Росса или используйте отладчик.

$ as -a foo.s -o foo.o   # still creates an output file as normal
GAS LISTING foo.s                       page 1


   1                    .code16
   2 0000 89C3              mov %ax, %bx
   3 0002 6689CA           mov %ecx,   %edx  # comment
   4              
   5                    .code32
   6 0005 89C3            mov %eax, %ebx     # comment 1
   7 0007 6689CA          mov %cx, %dx       # comment 2

GAS LISTING foo.s                       page 2


NO DEFINED SYMBOLS

NO UNDEFINED SYMBOLS

В левом столбце указан адрес.

(я изменил ваш источник, чтобы изменить интервал и добавить комментарии, чтобы дважды убедитесь, что это просто дамп исходной строки, а не дизассемблирование.)

Листинги GAS по умолчанию равны stdout, с -ahls опциями листинга gas man page . Не существует -h «источника высокого уровня» для рукописных asm-файлов, эта опция предназначена для составления списков из вывода компилятора, но это нормально. Есть опции опций для столбцов / нумерации страниц, такие как --listing-lhs-width=number


Вы также можете использовать эмулятор со встроенным отладчиком (например, BOCHS), чтобы показать разборку в режиме, в котором находится процессор в настоящее время в . BOCHS знает о режимах, сегментации реального режима и так далее. Это, вероятно, ваш лучший выбор, чтобы убедиться, что правильные инструкции действительно выполняются. (Вы можете захотеть источник в другом окне; IDK, если BOCHS может прочитать отладочную информацию / источник.)

...