Издательский дом ООО "Гейм Лэнд"ЖУРНАЛ ХАКЕР #90, ИЮНЬ 2006 г.

Самый маленький эльф

Крис Касперски ака мыщъх

Хакер, номер #090, стр. 090-110-7


int 80h ; // exit(0);

filesize equ $ - $$

 

Транслируем его тем же путем, что и раньше, и получаем 98 байт! Самое интересное, что под Linux'ом этот файл еще и работает, а вот FreeBSD, увы, шуток с перекрытием заголовков не понимает.

Но 98 байт это еще не предел! Переписав "несущий" код, легендарный хакер Юрий Харон с ходу сократил его еще на 2 байта, сказав при этом: "...а вот дальше уже думать надо, но лень". Харон использовал прямую засылку константы в стек командой "PUSH 1", занимающий всего два байта — "6Ah 01h", которую коварный NASM растянул до целых 5-ти байт "68h 01h 00h 00h 00h", поэтому пришлось прибегнуть к прямой машиннокодовой вставке директивой dw. Также Харон использовал могучую инструкцию LEA, о существовании которой нельзя забывать (а вот мыщъх забыл и проиграл).

Заключение

Мы прошли длинный путь и добились впечатляющих результатов. 96 байт для программы "hello,elf" – это успех, которым можно гордиться. Если убрать перекрытие заголовков, мы получим 100 байт, но тогда файл будет работать как под Linux, так и под FreeBSD. Но цепная реакция оптимизации на этом еще не заканчивается. Кто из читателей примет вызов и сократит файл хотя бы еще на один байт?

INFO

Процесс обучения программированию на ассемблере под UNIX погружен в эротический полумрак, в котором, как и в первую ночь с женщиной, приходится действовать наугад.

INFO

В тестировании принимали участие: Knoppix 3.8 и FreeBSD 4.5.

CD/DVD

На прилагаемом к журналу компакт-диске, помимо исходных кодов elf*.{S,asm}, ты сможешь найти полную версию этой статьи.

От редактора

Воодушевленный успехами мыщъха, я решил посмотреть, каким будет объем исполняемых файлов в OpenBSD. "Влет" ручная сборка асмовых исходников не прошла. После детального разбора "man 5 elf" выяснилось, что сырец нужно помечать специальным образом с помощью секции ".note.openbsd.ident". Это своеобразная подсказка для ядра, которая позволяет при загрузке двоичных файлов избежать дополнительных проверок и отключить эмуляцию бинарной совместимости. Вот так должна выглядеть "нэйтивная" секция файла openelf.S:

Андрей Матвеев

.section ".note.openbsd.ident", "a"

.p2align 2

.long 0x8

.long 0x4

.long 0x1

.ascii "OpenBSD\0"

.long 0x

.p2align 2

Что интересно, без строчки <.section ".note.openbsd.ident", "a"> сборка проходит, но при запуске вылетает ошибка со следующим сообщением:

% ./openelf

zsh: operation not permitted: ./openelf

Да, не фонтан. Немного поразмыслив, в любом шестнадцатеричном редакторе (например, "hexedit ./openelf") производим изящный финт хвостом, модифицируя содержимое первой строчки openelf с:

00000000 7F 45 4C 46 01 01 01 00 00 00 00 00 00 00 00 00 .ELF............

на:

00000000 7F 4F 4C 46 01 01 01 01 01 00 00 00 00 00 00 00 .OLF............

После сохранения изменений снова запускаем подопытный бинарик:

% ./openelf

hello, elf

Магия эльфов :).

Назад на стр. 090-110-6  Содержание