Издательский дом ООО "Гейм Лэнд"ЖУРНАЛ ХАКЕР #80, АВГУСТ 2005 г.

Ручная троянизация

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

Хакер, номер #080, стр. 080-120-3


[системные вызовы и библиотечные функции]

Бацилла должна как-то взаимодействовать с внешним миром: открывать файлы, устанавливать сетевые соединения, выводить ругательные сообщения и т. д. Обычно для этого используется прямой вызов API-функций. Но это не лучший вариант. Намного удобнее использовать высокоуровневые библиотечные функции, доставшиеся бацилле в наследство от дрозофилы. Согласитесь, намного удобнее открывать файл с помощью _fopen, чем CreateFile. Одних только аргументов в последнем случае потребуется миллион!

Библиотечные функции легко распознаются при помощи IDA Pro. И если мы запихнем нашу дрозофилу под этот замечательный дизассемблер мы увидим, что адрес функции _fopen равен 401988h, значит, ее вызов будет выглядеть приблизительно так:

push aRb ; "rb" указатель на строку с режимом открытия файла

push aName ; указатель на имя файла (аргументы заносятся справа налево)

call 401988h ; вызываем функции _fopen

add esp, 8 ; удаляем аргументы из стека

Однако использовать библиотечные функции можно только после того, как отработает Start-Up (стартовый код), иначе у нас ничего не получится. В этом нам вновь поможет IDA Pro, распознающая функцию main (WinMain) языков C/C++ и паскалевскую процедуру Begin. В notepad'е вызов главной функции расположен по адресу 1006571h. Здесь находится call 100299Eh, где 100299Eh - адрес WinMain. Для внедрения дрозофилы, достаточно изменить call 100299Eh на свой адрес, в смысле адрес бациллы.

А что делать, если библиотечные функции не распознаны или среди них нет той, что нужна нам? Тогда можно обратиться к импорту дрозофилы и поискать там. В IDA Pro это делается так: View -> Open Subview -> Imports.

В нашем случае, например, адрес функции MessageBoxW равен 01001204h. На самом деле, это еще не сам адрес, а только указатель на него, инициализируемый на стадии загрузки, а потому вызов функции будет выглядеть так:

xor eax,eax ; обнуляем eax

push 30h ; uType

push lpCaption ; lpCaption

push lpText ; lpText

push eax ; hWnd

call dword [1001204h] ; вызываем функции MessageBoxW

Но в некоторых случаях, в импорте искомой функции нет. Что тогда? Есть два пути: использовать связку LoadLibrary\GetProcAddress или сканировать импорт вручную. Оба этих способа уже рассматривались в статье «Живучий код: техника написания переносимого shell-кода», опубликованной в Спеце, посвященном ошибке переполнения буфера (август 2004 года).

[память в кредит]

Кодовая секция недоступна для записи. Где же дрозофила будет хранить свои переменные? Проще всего воспользоваться стандартной Сишной функций malloc или API-функций VirtualAlloc для выделения памяти из кучи. Причем выделенную память можно даже не освобождать - при закрытии приложения Windows сделает это самостоятельно.

Назад на стр. 080-120-2  Содержание  Вперед на стр. 080-120-4