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

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

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

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


Простейшая ассемблерная программа elf_libc.S

.text

.global main

main:

pushl $len

pushl $msg

pushl $1

call write

addl $12, %esp

ret

.data

msg: .ascii "hello,elf\n"

len = . - msg

Чтобы вдохнуть в ассемблерный файл жизнь, его необходимо прогнать через транслятор, чем мы сейчас и займемся:

$ gcc -o elf_libc elf_libc.S

$ ./elf_libc

hello,elf

На диске образуется файл elf_libc, победоносно выводящий "hello,elf" на экран, но занимающий при этом целых 12,096 байт (при трансляции под FreeBSD – 4,270). Ну и монстр! Куда это годится?! А все потому, что компилятор самовольно прицепил символьную информацию, которая нам совершенно ни к чему. К счастью, ее очень легко отрезать штатной утилитой strip.

$ strip elf_libc

Файл сразу же похудел до 2,892 байт (под FreeBSD — до 2,744), полностью сохранив свою работоспособность. С таким размером уже можно жить (особенно под FreeBSD, где у мыщъха установлена старая версия компилятора). Естественно, сама операционная система тут ни при чем.

А теперь, отказавшись от услуг gcc, попробуем собрать файл вручную. Под FreeBSD это осуществляется так:

$ as -o elf_libc.o elf_libc.S

$ ld -s -o elf_libc /usr/lib/crt1.o elf_libc.o -lc

На диске образуется файл elf_libc размером всего 2,108 байт, что на 636 байт короче сборки gcc с последующим стрипаньем символьной информации. То есть "ручная" сборка намного эффективнее!

C Linux'ом и Solaris'ом в этом плане сложнее, да и не совсем понятно, где у них расположен стартовый код. Но это еще полбеды. Стартовый код содержит дикие зависимости, влекущие за собой дополнительные библиотеки, находящиеся в самых непредсказуемых местах. Что же делать? Приходится обращаться за помощью к gcc. Уж он-то наверняка знает, где расположены его библиотеки. Ассемблируем файл транслятором as и передаем полученный elf_libc.o на компоновку компилятору gcc. Стрипаем символьную информацию и получаем те же самые 2,892 байт, что и при автоматической сборке.

$ as -o elf_libc.o elf_libc.S

$ gcc elf_libc.o -o elf_libc

$ strip elf_libc

Выходит, что "полуавтоматическая" сборка под Linux'ом дает тот же самый результат, что и автоматическая, поэтому никакого смысла работать руками здесь нет.

Отладка ассемблерных программ

Редкая программа начинает работать сразу же после запуска. Практически всегда она содержит ошибки, требующие отладки. Высокоуровневые программисты находятся в более выгодном положении, поскольку значительная часть ошибок отсеивается компилятором еще на стадии трансляции, к тому же сам синтаксис языка делает программу более выразительной. Одиночные ассемблерные команды в отрыве от своего окружения — абсолютно бессмысленны, и обнаружить ошибку путем визуального просмотра листинга очень тяжело.

Назад на стр. 090-110-1  Содержание  Вперед на стр. 090-110-3
Hosted by uCoz