Жизнь после BSOD Крис Касперски и Жирный Хомяк Хакер, номер #085, стр. 085-114-6 Путь второй - репаминг страниц. Отображаем физический адрес страницы, в которой лежит KeBugCheckEx, на виртуальное адресное пространство своего процесса посредством вызова функции NtMapViewOfSection, назначая все необходимые нам права. Репаминг осуществляется исключительно на уровне ядра, но к отображенной странице можно обращаться даже из прикладного уровня. Красота! По этой схеме работают многие брандмауэры и другие программы, нуждающиеся в перехвате ядерных функций, например, rootkit'ы. Подробности здесь: http://www.stanford.edu/~stinson/misc/curr_res/nt_hooking.txt. Путь третий - сброс флага WP в регистре cr0. Это достаточно грязный трюк с целой свитой противопоказаний и рекламаций, однако для наших целей он вполне подходит. Используем его как самый простой и быстрый вариант, умещающийся всего в 3-х (!) машинных командах: [код, отключающий защиту ядра от записи] mov eax, cr0 ; грузим управляющий регистр cr0 в регистр eax and eax, 0FFFEFFFFh; сбрасываем бит WP, запрещающий запись mov cr0, eax ; обновляем управляющий регистр cr0 Соответственно, чтобы включить защиту, этот самый бит WP нужно установить, что и делают следующие машинные команды: [код, включающий защиту ядра] mov eax, cr0 ; грузим управляющий регистр cr0 в регистр eax or eax, 10000h ; сбрасываем бит WP, запрещающий запись mov cr0, eax ; обновляем управляющий регистр cr0 Политически корректная программа должна не просто отключать/включать защиту от записи, а запоминать текущее состояние бита WP перед его изменением, а затем восстанавливать его обратно, иначе можно непроизвольно включить защиту в самый неподходящий момент, серьезно навредив вирусу или rootkit'у. Закоротить функцию KeBugCheckEx можно разными путями. Самое правильное (и надежное!) - определить ее адрес путем разбора таблицы импорта, но это слишком долго, муторно, нудно и утомительно. Гораздо проще подставить готовые адреса, жестко прописав их в своей программе. Минус этого решения в том, что на других компьютерах она работать не будет. Стоит установить (или удалить) какой-то ServicePack, перейти на другую версию системы, как все адреса тут же изменятся, и произойдет сплошной завис. Тем не менее, имея исходные тексты драйвера под рукой, его всегда можно исправить и перекомпилировать. Так что для домашнего использования такое решение вполне допустимо. Главная тонкость в том, что мы не должны трогать первый байт функции KeBugChekEx, поскольку его уже потрогал SoftICE и весь вытрогал. Так же поступают и другие хакерские программы (например, API-шпионы), помещая сюда команду INT 03 (опкод CCh), предварительно сохранив прежнее содержимое где-то в другом месте. ОК, пропустим первую команду (PUSH EBP) и начнем внедрение со второй. Чтобы сбалансировать стек в противовес PUSH EBP, говорим POP EAX, а затем либо jmp на RET 14h, либо сам RET 14h. Последний вариант короче и элегантнее. Реализуется он так: [код, закорачивающий KeBugCheckEx] mov dword ptr DS:[8042BF14h+1], 14C258h Здесь: 8042BF14h - адрес начала функции KeBugCheckEx (на всех машинах разный), 1 - длина инструкции PUSH EBP, а 14C258h - машинный код, представляющий собой последовательность двух команд: POP EAX (58h)/RET 14h (C2h 14h 00h). |