Выполнение плоского двоичного файла в Linux

StackOverflow https://stackoverflow.com/questions/1283342

  •  16-09-2019
  •  | 
  •  

Вопрос

Есть ли способ выполнить плоское двоичное изображение в Linux, используя примерно такой синтаксис:

nasm -f bin -o foo.bin foo.asm
runbinary foo.bin
Это было полезно?

Решение

Есть ли какая-то причина, по которой вы не хотите использовать «-f elf» вместо «-f bin»?

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

Мы можем взглянуть на спецификацию ELF, и/USR/include/linux/elf.h и исполняемые файлы, созданные стандартными инструментами, чтобы выяснить, как должен выглядеть наше исполнение пустых эльфов.Но, если вы терпеливый тип, вы можете просто использовать тот, который я поставлял здесь:

 BITS 32

               org     0x08048000

 ehdr:                                                 ; Elf32_Ehdr
               db      0x7F, "ELF", 1, 1, 1, 0         ;   e_ident
       times 8 db      0
               dw      2                               ;   e_type
               dw      3                               ;   e_machine
               dd      1                               ;   e_version
               dd      _start                          ;   e_entry
               dd      phdr - $$                       ;   e_phoff
               dd      0                               ;   e_shoff
               dd      0                               ;   e_flags
               dw      ehdrsize                        ;   e_ehsize
               dw      phdrsize                        ;   e_phentsize
               dw      1                               ;   e_phnum
               dw      0                               ;   e_shentsize
               dw      0                               ;   e_shnum
               dw      0                               ;   e_shstrndx

 ehdrsize      equ     $ - ehdr

 phdr:                                                 ; Elf32_Phdr
               dd      1                               ;   p_type
               dd      0                               ;   p_offset
               dd      $$                              ;   p_vaddr
               dd      $$                              ;   p_paddr
               dd      filesize                        ;   p_filesz
               dd      filesize                        ;   p_memsz
               dd      5                               ;   p_flags
               dd      0x1000                          ;   p_align

 phdrsize      equ     $ - phdr

 _start:

 ; your program here

  filesize      equ     $ - $$

Это изображение содержит заголовок ELF, определяющий файл в качестве исполняемого файла Intel 386, без таблицы заголовков разделения и таблицы заголовков программы, содержащей одну запись.Указанная запись инструктирует загрузчик программы загружать весь файл в память (ее нормальное поведение для программы включает в себя таблицу заголовка ELF и заголовка программы в изображение памяти), начиная с адреса памяти 0x08048000 (который является адресом по умолчанию для загрузки исполнителей) и для начала выполнения кода в _start, который появляется сразу после таблицы заголовков программы.Нет.

Итак, добавим в нашу небольшую программу:

 ; tiny.asm
               org     0x08048000

 ;
 ; (as above)
 ;

_start: mov bl, 42 xor eax, eax inc eax int 0x80 filesize equ $ - $$

и попробуйте:

 $ nasm -f bin -o a.out tiny.asm
 $ chmod +x a.out
 $ ./a.out ; echo $?
 42

Другие советы

Ядро Linux может загружать несколько различных двоичных форматов — ELF является лишь наиболее распространенным, хотя формат a.out также довольно хорошо известен.

Поддерживаемые двоичные форматы контролируются тем, какие модули binfmt загружаются или компилируются в ядро ​​(они находятся в разделе «Файловая система» конфигурации ядра).Есть binfmt_flat для uClinux BFLT двоичные файлы плоского формата, которые довольно минимальны - их даже можно сжать zlib, что позволит вам сделать ваш двоичный файл еще меньше, так что это может быть хорошим выбором.

Не похоже, что Nasm изначально поддерживает этот формат, но добавить необходимый заголовок вручную довольно легко, как описывает Джим Льюис для ELF.Есть описание формата здесь.

Как минимум, Linux необходимо будет определить формат исполняемого файла, и он получит его с первых байтов.Например, если это скрипт со знаком #!, ебля.Если это ELF, это будет 0x7F 'E' 'L' 'F'.Эти магические числа будут определять обработчик при поиске.

Итак, вам понадобится заголовок с признанным магическим числом.Вы можете получить список поддерживаемых форматов shebang в /proc/sys/fs/binfmt_misc.Получение списка собственных двоичных форматов (к сожалению) немного сложнее.

бФЛТ может быть хорошим выбором.Действительно, это популярный формат встроенных исполняемых файлов.Но вы также можете сжать ELF довольно далеко. Эта статья получил исполняемый файл ELF размером до 45 байт.Тем не менее, вам придется сжимать его в основном вручную, а не с помощью инструмента.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top