Из всех перехватчиков 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 ничего не даст.
Комментариев нет:
Отправить комментарий