Обзор эксплойтов Крис Касперски ака мыщъх Хакер, номер #092, стр. 092-050-7 00104B6 push dword ptr [eax] 00104B8 call sub_2C1EB 00104BD mov edi, eax ***** old.lst 00104B6 push dword ptr [eax] 00104B8 call sub_2C10D 00104BD mov edi, eax Очевидно, что здесь вызывается одна и та же процедура (кто не верит — может посмотреть код самой процедуры), но утилитам сравнения этого ведь не объяснишь. А свой собственный скрипт писать лень. К тому же обнаруживается довольно странное поведение компилятора, иногда меняющего порядок следования команд в новой версии драйвера: Листинг 4: Странное изменение порядка следования команд в разных версиях файлов ***** new.lst 016C91 mov edx, ecx 016C93 shr eax, 10h 016C96 shl edx, 10h 016C99 or eax, edx ***** old.lst 016C91 mov edx, ecx 016C93 shl eax, 10h 016C96 shr edx, 10h 016C99 or eax, edx То же самое происходит и с регистрами: Листинг 5: Странное изменение выбора регистров в разных версиях файлов ***** new.lst 01381B xor ecx, ecx 01381D mov ch, al 01381F mov cl, ah 013821 mov [esi+0Eh], cx ***** old.lst 01381B xor ecx, ecx 01381D mov cl, ah 01381F mov ch, al 013821 mov [esi+0Eh], cx А ведь это еще не самое страшное! Поскольку в начале каждой строки стоит ее адрес, то при «раздвижке» одной или нескольких функций оставшаяся часть файла трактуется как «измененная», хотя в действительности изменились только адреса. Какой же выход? Копируем old.lst в old-1.lst, загружаем его в FAR по <F4> и, удерживая клавишу <ALT> (вместо <SHIFT>), вертикальными блоками отрезаем все операнды инструкций и адреса, стоящие в начале строки. Аналогичную операцию проделываем и над new.lst. В результате чего получаем два симпатичных файла вида: push mov call Пропускаем их через FC с обязательным выводом номеров строк (за это отвечает ключ /N), иначе мы потом не найдем соответствующие им адреса в old.lst/new.lst файлах, и с замиранием сердца наблюдаем за процессом. Конечно, мы получим много ложных срабатываний, уже приведенных в листинге 4. Но их очень легко отсеять чисто визуально — меняется лишь порядок следования команд, но сам шаблон остается неизменным. А вот и первое действительное различие: Листинг 7: Реальное различие между старой и новой версией драйвера ***** old1.lst 024127: mov 024128: cmp ***** new1.LST 024127: mov 024128: call 024129: mov 024130: cmp В прежней версии TCPIP.SYS никакого call'а не было! А ну-ка заглянем в дизассемблерный текст, открыв old.lst/new.lst файлы и перейдя к строке 24127. Листинг 8: Сравнение дизассемблерных листингов двух версий TCPIP.SYS 01DF18 mov d,[esi+20h], 1988Bh mov d,[esi+20h], 1988Bh 01DF1F call PsGetCurrentProcessId call PsGetCurrentProcessId 01DF24 mov [esi+28h], eax mov [esi+28h], eax call PsGetCurrentProcessId mov [esi+2Ch], eax 01DF27 cmp [ebp+NewIrql], 2 cmp [ebp+NewIrql], 2 01DF2B mov [edi+8], esi mov [edi+8], esi 01DF2E jbe short loc_1DF40 jbe short loc_1DF48 01DF30 push asc_1DE7C; "Lock problems!!\n" push asc_1DE7C;"Lock problems!!\n" 01DF35 call DbgPrint call DbgPrint 01DF3A pop ecx pop ecx 01DF3B call DbgBreakPoint call DbgBreakPoint |