среда, 10 ноября 2010 г.

Все MSR hooker's делают это

Из всех перехватчиков sysenter работающих через перезапись MSR_SYSENTER_EIP, я не видел ни одного правильно написанного.

Ну то есть они конечно работали, перехватывали, но тем не менее своим перехватом они делали возможным создать условие для Denial of Service атаки, то есть к банальному BSOD'у.

Теорию я описывать не буду, да там по сути и описывать нечего, все тривиально, а вот суть атаки опишу:

push EFLAGS_TF
popfd
sysenter

То есть, выполняем sysenter с взведенным TF флагом.

Далее, при неправильно написанном MSR перехватчике будет бсод.

Чтобы разобраться, почему так происходит нужно взглянуть на обработчик Single-step trap'а:

_KiTrap01:
...

// проверяется EIP при исключении, и если он равен KiFastCallEntry, прыгаем на TF_Dispatch


.text:00467393                 mov     ecx, [ebp+68h]     // KTRAP_FRAME.Eip
.text:00467396                 cmp     ecx, offset _KiFastCallEntry
.text:0046739C                 jz      TF_Dispatch

...

// а в нем переустанавливаем KTRAP_FRAME.Eip в KiFastCallEntry2 и прыгаем на общий код выхода из interrupt/exception:

.text:00467268 TF_Dispatch:
.text:00467268                 mov     dword ptr [ebp+68h], offset _KiFastCallEntry2
.text:0046726F                 and     byte ptr [ebp+71h], 0FEh
.text:00467273                 jmp     Kei386EoiHelper@0

Т.е. ядро имеет специальный case для обработки ситуации при single step на sysenter, перенаправляя управление на KiFastCallEntry2.
Самописные MSR hooker's этого не делают, и в этом их ошибка.

Правильно написанный MSR hooker должен пропатчить ядро, т.е. заменить
cmp     ecx, offset _KiFastCallEntry на cmp     ecx, offset _YourFastCallEntry в KiTrap01.

Интересно как в софтверных компаниях разруливают подобные ситуации, ведь баги подобные этим не обнаружит ни один тестер, как бы хорош он не был. Да и code review ничего не даст.

Комментариев нет:

Отправить комментарий