← На главную

Брайан Райтер уместил ELF в 76 байт

24.06.2026 02:30 · hackernews

Брайан Райтер, автор знаменитого 45-байтного ELF-файла, вернулся к своей задаче. Многие критики справедливо заметили: то, что он создал, Linux просто «принимает за ELF», но формально файл нарушает спецификацию. Райтер решил ответить и сделать всё «по правилам», сохранив минимальный размер.

Он откатился к версии размером 91 байт — корректному ELF, но слишком большому. Первый трюк, разрешённый спецификацией, — наложение структур. ELF-заголовок и таблица программных заголовков могут пересекаться. Райтер наложил phdr прямо внутрь ehdr, сэкономив 8 байт — получилось 83 байта.

Дальше — игра с полями. Спецификация требует обнулять почти все поля, кроме p_paddr. Его содержимое «не определено». Райтер запихнул туда первый байт программы (xor eax, eax) и короткий jmp на продолжение. Ещё минус 2 байта — 81 байт.

Следующий ход — смена адреса загрузки. Вместо стандартного 0x08048000 он выбрал 0x2AB30000. Почему? Потому что в старший байт адреса (2A) он поместил код mov bl, 42. Это позволило убрать jmp и переставить команды. Размер упал до 79 байт.

Чтобы записать оставшуюся часть программы, пришлось прыгнуть через поле p_filesz (размер файла) в p_memsz (размер в памяти). p_memsz может быть больше p_filesz, так что это законно. Получилось 76 байт — программа целиком помещается внутри заголовков и таблицы.

Но это не предел. Райтер заменил jmp на cmp eax, imm32 — пятибайтную инструкцию, которая на один байт заходит в p_paddr, а четыре байта операнда «перекрывают» p_filesz». Это позволило переместитьinc eax` обратно и сделать размер виртуальной памяти разумным (32 КБ вместо 8 МБ).

Итог: 76-байтный исполняемый файл, полностью соответствующий спецификации ELF. Однако осталась одна проблема. В коде используется прямой системный вызов int 0x80 (exit). Это не часть официального ABI — номера системных вызовов могут меняться. Для идеального соответствия стандарту нужно вызывать функцию _exit из libc, что потребует возврата к механизму динамической линковки. Но это уже тема для следующей статьи.

Читать оригинал →