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

Живучий код

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

Спецвыпуск Xakep, номер #045, стр. 045-064-4


je l3

add edi,4

inc eax

loop l4

jmp ecx

l3:

pop esi

mov edx,dword ptr [esi+24h]

add edx,ebx

shl eax,1

add eax,edx

xor ecx,ecx

mov cx,word ptr [eax]

mov eax,dword ptr [esi+1Ch]

add eax,ebx

shl ecx,2

add eax,ecx

mov edx,dword ptr [eax]

add edx,ebx

pop esi

mov edi,esi

xor ecx,ecx

;Get 3 Addr

mov cl,3

call loadaddr

add esi,0Ch

Главный недостаток этого способа – в его чрезмерной громоздкости, ведь объем shell-кода ограничен, но, к сожалению, ничего лучшего пока не придумали. Поиск базового адреса можно и оптимизировать (что мы сейчас продемонстрируем), но от разбора экспорта никуда не уйти. Это дань, выплачиваемая за мобильность.

Огонь прямой наводкой – PEB

Из всех способов определения базового адреса наибольшей популярностью пользуется анализ PEB (Process Environment Block – блок окружения процесса) – служебной структуры данных, содержащей, кроме прочей полезной информации, базовые адреса всех загруженных модулей.

Эта популярность необъяснима и незаслужена. Ведь PEB – это внутренняя кухня операционной системы Windows NT, которой ни документация, ни включаемые файлы делиться не собираются, и лишь Microsoft Kernel Debugger обнаруживает обрывки информации. Подобная недокументированность не может не настораживать. В любой из последующих версий Windows структура PEB может измениться, как это уже неоднократно происходило, и тогда данный прием перестанет работать, а работает он, кстати говоря, только в NT. Линейка 9x отдыхает.

Так что задумайтесь: а так ли вам нужен этот PEB? Единственное его достоинство – предельно компактный код:

Определение базового адреса KERNEL32.DLL путем анализа PEB

00000000: 33C0 xor eax,eax ; eax := 0

00000002: B030 mov al,030 ; eax := 30h

00000004: 648B00 mov eax,fs:[eax] ; PEB base

00000007: 8B400C mov eax, [eax][0000C] ; PEB_LDR_DATA

0000000A: 8B401C mov eax, [eax][0001C] ; 1-й элемент InInitOrderModuleList

0000000D: AD lodsd ; следующий элемент

0000000E: 8B4008 mov eax, [eax][00008] ; базовый адрес KERNEL32.DLL

Раскрутка стека структурных исключений

Обработчик структурных исключений, назначаемый операционной системой по умолчанию, указывает на функцию KERNEL32!_except_handler3. Выяснив ее адрес, мы определим положение одной из ячеек, гарантированно принадлежащей модулю KERNEL32.DLL. Останется округлить её адрес до величины, кратной 1.0000h, и заняться поисками PE-сигнатуры по методике, изложенной выше, с той лишь разницей, что проверять доступность указателя перед обращением к нему не нужно, так как теперь он заведомо доступен.

Практически все приложения используют свои обработчики структурных исключений, и потому текущий обработчик не совпадает с назначенным операционной системой, а shell-коду потребуется раскрутить цепочку обработчиков, добравшись до самого конца. Последний элемент списка и будет содержать адрес KERNEL32!_except_handler3.

Достоинство этого приема в том, что он использует только документированные свойства операционной системы, работая на всех ОС семейства Windows исключая, разумеется, Windows 3.x, где все не так. К тому же, он довольно компактен.

Назад на стр. 045-064-3  Содержание  Вперед на стр. 045-064-5