Сокрытие процессов является интересной и
одной из самых обсуждаемых тем в
программировании. Эта статья о том, как Win32-приложение
может скрыть свой собственный процесс из
списка задач. Это может быть использовано
для сокрытия процесса не только из списка
по Ctrl+Alt+Del, но и из списков независимых task
viewer'ов (таких, как ProcDump(G-RoM, Lorian & Stone) или
ProcessExplorer(SysInternals)). Пути для того, чтобы
сделать это в различных системах, весьма
различаются. Для платформы 9x способ один, а
для NT - совсем другой. Это связано с тем, что
ядра Windows NT и Windows 9x весьма отличаются.
Сокрытие процесса в Windows 98\Me.
В Windows 9x мы достигаем нашей цели простым
перехватыванием основных Toolhelp32 API функций:
Process32First и Process32Next. Если hook-процедура решает,
что одна из Toolhelp32 API функций запрашивает наш
процесс, мы просто выполняем следующий
вызов Process32Next на следующий TH32 хендл.
К тому же мы затираем процесс из списка по
Ctrl+Alt+Del, используя недокументированную, но
хорошо известную функцию RegisterServiceProcess:
BOOL STDCALL RegisterServiceProcess(DWORD dwProcessID,BOOL bHide);
ProcDump, LordPE, ProcessExplorer успешно обманываются.
Недостаток лишь в том, что MS Spy++ показывает в
своем списке окна нашего процесса. Но Spy++ не
может получить дополнительную информацию о
процессе, кроме его PID.
Сокрытие процесса в Windows NT\2000.
В Windows NT путь для сокрытия процесса более
мудреный. Поскольку ring3-процесс не имеет
почти никаких прав, мы передаем наши
действия в драйвер режима ядра.
В драйвере мы перехватываем NtQuerySystemInformation.
При перехвате нас интересует параметр
SystemInformationClass. Он должен быть равен 5. Затем
нужно изменить структуру SYSTEM_PROCESS_INFORMATION
таким образом, чтобы она указывала на
следующий процесс. Нет необходимости
изменять всю структуру. Достаточно лишь
увеличить член структуры SizeOfBlock блока
процесса перед блоком нашего процесса. Эта
ловушка не предполагает переадресации
входной точки NtQuerySystemInformation. Вместо этого
модифицируется ServiceDescriptorTable, чей адрес
можно взять из структуры, адресованной
NtOsKrnl!KeServiceDescriptorTable:
SSDT STRUCT
pSSAT LPVOID ? ; System Service Address Table
Obsolete DWORD ? ; API ID
dwAPICount DWORD ?
pSSPT LPVOID ? ; System Service Parameter Table
SSDT ENDS
Из-за того, что API ID различен в каждой
системе NT и в каждом сервис-паке, нам
придется определять API ID функции
NtQuerySystemInformation. Для этого мы передаем адрес
NtDll!NtQuerySystemInformation в драйвер, который
возвращает API ID:
NtDll!NtQuerySystemInformation:
mov eax, 97h ; EAX == Native API ID
lea edx, [esp + arg_0] ; EDX -> список аргументов
int 2Eh ; выполняем вызов Native API
retn 10h
Native API ID - это индекс в цепочке адресов,
находящейся в NtOsKrnl!KeServiceDescriptorTable. SSDT.pSSAT. Мы
просто изменяем адрес целевой функции на
линейный адрес нашей hook-процедуры. В нашем
случае: pSSAT[0x97].
Итог
Итак, мы рассмотрели два разных способа
сокрытия процесса. У каждого есть свои
достоинства и недостатки. Один общий
недостаток у обоих способов: окна процесса
видны в MS Spy++.
Достоинства сокрытия процесса в Windows 9x:
программе не нужны никакие внешние файлы (драйвер,
например) и готовая библиотека легко
встраивается в программу и легко
используется. Процесс не видно нигде, кроме
Spy++.
Недостаток сокрытия процесса в Windows 9x: не
работает в Windows 95.
Достоинство сокрытия процесса в Windows NT:
процесс не видно нигде.
Недостатки сокрытия процесса в Windows NT: не
работает в Windows XP и выше. Используется
драйвер. А значит есть внешний sys-файл. Также
для установки драйвера необходимо иметь
права администратора. Драйвер видно в
Диспетчере устройств, раздел "Драйверы
устройств не Plug and Play":
- Библиотека
и ее исходник для сокрытия процесса под
Windows 98\Me (Assembler). - Драйвер
и его исходник для сокрытия процесса под
Windows NT\2000 (Assembler). - Программа
управления драйвером(установка/удаление/запуск/остановка). - Демонстрационная
программа с исходником (Visual C++ 6.0).
Демо тестировалась на Windows 98\Me\2000.
Материалы для статьи брались из описания к yoda's
Invisibility.
Special thanks to y0da.