SEH на службе у контрреволюции Крис Касперски aka мыщъх Спецвыпуск Xakep, номер #045, стр. 045-048-4 Путь второй: зарегистрировать свой собственный SEH-фрейм. Как же мы сможем что-то зарегистрировать в системе, если еще не перехватили управления? – воскликнешь ты. Указатель на текущий обработчик всегда содержится в одном и том же месте – в первом двойном слове TIB'а, лежащего по адресу fs:[00000000h], и псевдофункцией poke его вполне реально перезаписать. Пусть вас не смущает наличие сегментного регистра FS – вся память, принадлежащая процессу, отображается на единое адресное пространство, и до TIB'а можно дотянуться и через другие сегментные регистры, например, через тот же DS, используемый процессором по умолчанию. Естественно, при адресации через DS TIB будет располагаться совсем по другому смещению, и, чтобы его узнать, придется прибегнуть к услугам отладчика. Ты можешь использовать Soft-Ice, Microsoft Kernel Debugger или любой другой отладчик по своему вкусу. Сначала необходимо определить значение селектора, загруженного в регистр FS. В Soft-Ice за это отвечает команда "CPU" (если Soft-Ice настроен правильно, то все основные регистры автоматически отображаются в верхней части окна). Затем, просматривая таблицу глобальных дескрипторов, содержимое которой выводит команда "GDI", находим соответствующий ему базовый адрес. Для первого потока процесса на всех NT-подобных системах он равен FFDFF00h, а все последующие потоки уменьшают его на 1000h, то есть мы получаем ряд указателей вида 7FFDE000h, 7FFDD000h, 7FFDC000h... В любом случае, протестировать вашу машину не помешает (вдруг какая-то версия NT поведет себя иначе?). Протокол работы с отладчиком приводится ниже. ЛИСТИНГ Определение адреса указателя на текущий SEH-фрейм :cpu Processor 00 Registers ---------------------- CS:EIP=0008:8046455B SS:ESP=0010:8047381C EAX=00000000 EBX=FFDFF000 ECX=FFDFF890 EDX=00000023 ESI=8046F870 EDI=8046F5E0 EBP=FFDFF800 EFL=00000246 DS=0023 ES=0023 FS=0030 GS=0000 :gdt Sel. Type Base Limit DPL Attributes GDTbase=80036000 Limit=03FF 0008 Code32 00000000 FFFFFFFF 0 P RE 0010 Data32 00000000 FFFFFFFF 0 P RW 001B Code32 00000000 FFFFFFFF 3 P RE 0023 Data32 00000000 FFFFFFFF 3 P RW 0028 TSS32 80295000 000020AB 0 P B 0030 Data32 FFDFF000 00001FFF 0 P RW 003B Data32 00000000 00000FFF 3 P RW Обрати внимание: FFDFF000h – это не адрес текущего SEH-фрейма. Это – указатель на фрейм. Сам же фрейм должен быть сформирован непосредственно в shell-коде, а в FFDFx000h занесен указатель на него (см. картинку). Затем остается лишь совершить что-нибудь недозволенное или же пустить все на самотек, дождавшись, пока исковерканная переполнением программа не вызовет исключения естественным путем, и тогда наш SEH-обработчик немедленно получит управление. Остальное, как говорится, дело техники. Подавление аварийного завершения приложения Независимо от того, каким путем shell-код захватил управление, он может зарегистрировать свой собственный обработчик структурных исключений. Это делается приблизительно так: |