Начинаем копать
Свой лог Др.Ватсон хранит в папке Documents&Settings\AllUsers\Документы\DrWatson, туда же попадает дамп памяти упавшего приложения. Дамп перезаписывается каждый раз, а лог по умолчанию сохраняет данные о 10 последних ошибках, в которые входят и сбои, вызванные нашими exploit'ми.
Открывем drwtsn32.log в FAR'е по <F4> и ищем строки, относящиеся к сбою в IE (см. листинг 4), произошедшему в заданное время (мы ведь не забыли посмотреть на часы, верно?)
Исключение в приложении:
Прил.: iexplore.exe (pid=884)
Время: 09.05.2006 @ 16:41:36.734
Листинг 4 при регистрации ошибки Доктор Ватсон запоминает время ее возникновения
Пропуская бесполезную информацию о запущенных процессах и загруженных динамических библиотеках, мы добираемся до дизассемблерного кода, расположенного в окрестностях сбоя exploit'а iedie2-2:
eax=0000001a ebx=0000001a ecx=01460610 edx=75b2c198 esi=01460610 edi=00000000
eip=75ad7e2e esp=0006da58 ebp=00000000 iopl=0 nv up ei pl nz na pe nc
75ad7e23 e81b000000 call DllGetClassObject+0x1f573 (75ad7e43)
75ad7e28 8bd8 mov ebx,eax
75ad7e2a 3bdd cmp ebx,ebp
75ad7e2c 740e jz DllGetClassObject+0x2806c (75ae093c)
СБОЙ -> 75ad7e2e 8b7b34 mov edi,[ebx+0x34] ds:00a7d5f0=????????
75ad7e31 c1ef02 shr edi,0x2
75ad7e34 3bfd cmp edi,ebp
75ad7e36 0f8fcf431300 jnle 75c0c20b
FramePtr ReturnAd Param#1 Param#2 Param#3 Param#4 Function Name
00000000 00000000 00000000 00000000 00000000 00000000 mshtml!DllGetClassObject
Листинг 5 фрагмент дизассемблерного листинга Др. Ватсона, описывающего сбой IEdie2-2
Давайте, как археологи, попробуем восстановить хронологию событий и выяснить, что же здесь проиcходило. Нам известно, что инструкция MOV EDI, [EBX+0X34], расположенная по адресу 75AD7E2Eh и лежащая глубоко в недрах MSHTML.DLL, вызвала исключение типа нарушение доступа, поскольку регистр EBX содержал 1Ah, то есть указывал на первый 64 Кбайт регион памяти, доступ к которому строго запрещен как раз для отлова таким некорректных указателей.
Но откуда в EBX взялись эти злощастные 1Ah? Поднимаясь по дизассемблерному листингу вверх, мы находим инструкцию MOV EBX, EAX, копирующую содержимое EAX в EBX. Значение самого же EAX возвращается функцией DllGetClassObject+0x1f573, расположенной по адресу 75AD7E43h. Важно понять, что к самой DllGetClassObject
никакого отношения она не имеет! Просто, не найдя символьной информации, Др. Ватсон взял адрес ближайшей известной ему функции и назначил его в качестве базового.
Кое-что начинает проясняться. Функция 75AD7E43h должна возвращать указатель на структуру данных, по смещению 34h от начала которой лежит еще один указатель, но накурившись exploit'а она возвратила какую-то хрень. Напоминаю, что сбой произошел при закрытии IE, то есть, когда обработка HTML-кода уже была завершена. Следовательно, сама функция 75AD7E43h тут не причем (ее можно даже не дизассемблировать) и причину следует искать в разрушении структур данных, с которыми эта функция работает.
Теперь исследуем сбой, относящийся к IEdie2-3, дизассемблерные окрестности которого выглядят так:
eax=00000000 ebx=000af334 ecx=00000428 edx=01340294 esi=01480007 edi=01481990
eip=75acc4da esp=0006dba0 ebp=0006dbcc iopl=0 nv up ei pl nz na pe nc
функция: <nosymbols>
75acc4bd 60 pushad
75acc4be 8501 test [ecx],eax ds:00000428=?????
75acc4c0 56 push esi
75acc4c1 8bf1 mov esi,ecx
75acc4c3 e8555cfcff call 75a9211d
75acc4c8 668b766c mov si,[esi+0x6c] ds:01efd5de=????
75acc4cc 6685f6 test si,si
75acc4cf 7418 jz DllGetClassObject+0x14b19 (75acd3e9)
75acc4d1 0fb7ce movzx ecx,si
75acc4d4 69c998000000 imul ecx,ecx,0x98
СБОЙ -> 75acc4da 8b8020040000 mov eax,[eax+0x420] ds:00000420=??????
75acc4e0 5e pop esi
75acc4e8 c3 ret
FramePtr ReturnAd Param#1 Param#2 Param#3 Param#4 Function Name
0006DBCC 75A92F0F 00000001 00000000 0006DC44 000AF23C mshtml!DllGetClassObject
Листинг 6 фрагмент дизассемблерного листинга Др. Ватсона, описывающего сбой IEdie2-3
Адрес сбоя совсем другой (75ACC4DAh против 75AD7E2Eh), но библиотека вся та же — MSHTML.DLL, да и хронология событий очень похожа на предыдущую. Исключение вызывает инструкция MOV EAX,[EAX+0X420]
c регистром EAX, равным нулю, возвращенным функцией 75A9211Dh (см. CALL 75A9211D), которая по идее должна возвращать указатель на объект или структуру данных, но не возвратила, а не возвратила потому, что память была разрушена!
Что же касается IEdie2-4, то он полностью повторяет листинг 6, только регистры EBX, ECX, ESI и EDI немного другие. Это, конечно, важный факт, но пока мы не знаем, как его интерпретировать.
Еще у нас имеется дамп user.dmp, сброшенный IE перед смертью. Дамп можно загрузить в отладчик WinDbg (file à open crush dump), входящий в состав DDK, однако, ничего нового мы не узнаем (см. рис. 6). Дамп — это мертвое тело, это труп программы. Команды трассировки в нем не работают и все, что мы можем — это просматривать память, стек и регистры, которые мы и так знаем (спасибо отчету Др. Ватсона). Гораздо большие перспективы отрывает дизассемблирование MSHTML.DLL и живая отладка по месту падения (just-in-time debugging), чем мы сейчас и займемся.

Рисунок 6 дамп IE, загруженный в WinDbg