Самый маленький эльф Крис Касперски ака мыщъх Хакер, номер #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 Магия эльфов :). |