Техника защиты компакт-дисков от копирования

         

Доступ посредствомчерез ASPI


Отлаженная программа–— это такая программа, для которой еще не найдены условия, в которых она откажет.

Программистский фольклор

Вот два основных недостатка интерфейса SPTI (только что описанного ранеевыше): для взаимодействия с устройством он требует наличия прав администратора и, что еще хуже, интерфейс SPTI поддерживается только операционными системами семейства NT и отсутствует вна  Windows 9x/ME. Единственный легальный способ "дотянуться" до привода CD-ROM'а под Windows 9x –— это воспользоваться 16-разрядным шлюзом, напрямую обращаясь к MS-DOS драйверу MSCDEX, который обеспечивает значительно большую функциональность, нежели Windows-драйвер. Естественно, параллельная поддержка двух семейств операционных систем требует от программиста значительных усилий, что существенно повышает себестоимость программного продукта.

Для упрощения разработки кросс-платформенных приложений фирма Adaptec разработала специальный системно-независимый интерфейс, позволяющий управлять различными SCSI-устройствами с прикладного уровня, и назвала его ASPI –— Advanced SCSI Programming Interface (хотя неофициально его расшифровывают как Adaptec SCSI Programming Interface, поскольку это больше соответствует истине).

Системонезависимость интерфейса ASPI обеспечивается двухуровневой моделью его организации: архитектурно он состоит из низкоуровневого драйвера и прикладной библиотеки-обертки. ASPI-драйвер разрабатывается с учетом специфики конкретной операционной системы и отвечает за непосредственноей управление SCSI-шиной (реальной или виртуальной –— не суть важно). Поскольку интерфейс между операционной системой и драйвероамдрайвером меняется от одной операционной системы к другой, то для сокрытия всех этих различий используется специальная ASPI-библиотека, предоставляющая единый унифицированный интерфейс для всех операционных систем.

Рассмотрим, как осуществляется внедрение ASPI-интерфейса в операционную систему на примере Windows MEe (см.  рис. 1.4.20х34).
На самом высоком уровне иерархии находятся прикладные библиотеки Wnaspi32.dll и Winaspi.dll для 32- и 16-разрядных приложений соответственно. Они экспортируют три базовых ASPI-функции: GetASPI32DLLVersion, GetASPI32SupportInfo и SendASPI32Command (причем последняя –— самая важная) и три вспомогательных: GetASPI32Buffer, FreeASPI32Buffer, TranslateASPI32Address (последняя –— только в 32-разрядной версии библиотеки).

Посредством функции DeviceIoControl они взаимодействуют с ASPI-драйвером, расположенным "ниже" и, в зависимости от версии операционной системы, называющимся либо APIX.VXD (Windows 9x), либо ASPI.SYS (Windows NT) и создающим в процессе своей инициализации устройство с непроизносимым названием MbMmDp32. Только не спрашивайте меня, как это абракадабра расшифровывается –— ответ похоронен в застенках компании Adaptec.

Замечание

В 16-разрядных приложениях взаимодействие с драйвером осуществляется через с помощьючерез функциию 1868h прерывания 2Fh., Подробности этого процесса можно узнатьузнать, дизассемблируя Winaspi.dll. Она, кстати, совсем крошечная –— всего 5  Ккилобайт.

В принципе, ничего не мешает взаимодействовать с ASPI-драйвером и напрямую –— в обход библиотеки Wnaspi32.dll. Собственно, многие разработчики защитных механизмов именно так и поступают. Достаточно лишь дизассемблировать Wnaspi32.dll и разобраться каким ASPI-командамASPI-командам, какие IOCTL-коды соответствуют (ASPI-протокол по понятным соображениям не документирован). Действительно, на функции SendASPI32Command очень легко поставить бряк[Y105] [n2k106] , и тогда хакер (hacker) мгновенно локализует защитный код. С вызовами же функции DeviceIoControl в силу их многочисленности взломщикам справиться намного труднее. К тому же начинающие ломатели защит (а таких среди хакеров –— большинство) весьма смутно представляют себе архитектуру ввода-вывода и уж тем более не разбираются в ASPI-протоколе. Впрочем, для опытных хакеров такая защита —– не преграда (подробнее см.


главу 52 "Способы разоблачения защитных механизмов").

Сам же ASPI-драйвер "подключен" к SCSI- и IDE/ATAPI- портам (рис. 1.4.4), за счет чего он позволяет управлять всеми этими устройствами (и приводами CD-ROM в том числе).



Рис. 2.1.4.54.  0x099 Архитектура подсистемы ввода-вывода Windows 98.

Клиентские модули (на данной схеме они обозначены цифрами 1, 2 и 3) посылают свои запросы[n2k107]  драйверу файловой системы –— Instable File System (обозначенному цифрой 6). В распоряжении клиентских модулей также имеются ASPI-библиотеки ASPI для 32- и 16-разрядных приложений соответственно (они обозначены цифрами 4 и 6). От всей системы они стоят особняком, поскольку разработаны независимой компанией Adaptec и представляют собой факультативные компоненты. Драйвер файловой системы перенаправляет полученный им запрос на один их следующих специализированных драйверов, среди которых присутствует и драйвер привода CD-ROM, –— CDFS.VxD, обозначенный цифрой 8. В его задачи входит поддержка файловых систем лазерных дисков, таких как-то: ISO-  9660, High  Sierra или другихе файловыхе системы. Уровнем ниже лежит Volume Tracker (цифра 14), отслеживающий смену диска в накопителе, а еще ниже находится непосредственно сам драйвер, поддерживающий данную модель CD-ROM, –— так называемый CD type specific driver, реализуемый драйвером CDVSD.VxD и среди прочих обязанностей отвечающий за назначение буквы приводу. Это и есть секторный уровень взаимодействия с диском, никаких файловых систем здесь нет и в помине. Несмотря на то, что данный драйвер специфичен для конкретной модели привода CD-ROM, он совершенно независим от его физического интерфейса, поскольку опирается на CD-ROM device SCSI'zer (цифра 21), преобразующий IOP-запросы, поступающие от вышележащих драйверов, в SRB-пакеты, направляемые нижележащим драйверам (подробнее об этом см. раздел "Доступ посредствомчерез SCSI-порта" данной главы).


Еще ниже находится SCSI CD-ROM helper (цифра 23), обеспечивающий стыковку  SCSI'zer'a-а с SCSI-портом. Сам же SCSI-port, создаваемый менеджером SCSI-портов ( цифра 26) представляет собой унифицированное системно-независимое средство взаимодействия драйверов среднего уровня с физическим (или виртуальным) оборудованием. К одному из таких SCSI-портов и подключается ASPI-драйвер (цифра 18), реализованный в файле APIX.VxD и восходящий к своим "оберткам" –— Wnaspi32.dll и Wnaspi.dll (цифры 11 и 12 соответственно). Ниже SCSI-менеджера расположены драйверадрайвераы мини-портов, переводящие SCSI-запросы в язык конкретной интерфейсной шины. В частности, драйвер, обеспечивающий поддержку IDE-устройств, реализован в файле ESDI_506.PDR (цифра 29). Естественно, при желании мы можем общаться с IDE-устройствами и через IDE/ATAPI-порты (цифра 25), реализованные все тем же драйвером ESDI_506.PDR (ASPI-драйвер по соображениям производительности именно так, собственно, и поступает). Левую часть блок-схемы, изображающую иерархию драйверов прочих дисковых устройств мы не рассматриваем, т. к. она не имеет никакого отношения к теме нашего обсуждения.

Для программирования под ASPI требуются как минимум две вещи: ASPI-драйвер и ASPI-SDK. Драйвер можно бесплатно скачать с сервера самой Adaptec (ею разработаны драйверадрайвераы для следующих операционных системы: MS-DOS, Novell, Windows 9x, Windows NT/W2K/XP), а вот SDK [Y108] [n2k109] с некоторого момента распространяется за деньги. И хотя его стоимость чисто символическая (что-то около 10$, если мне не изменяет память), неразвитость платежных систем в России превращает процесс покупки в довольно затруднительное дело. Однако все необходимое для работы (документация, заголовочные файлы, библиотеки) можно позаимствовать из… Windows MEe DDK [n2k110] (кстати, входящего в состав DDK для Windows 2000). Так что, если у вас уже есть Windows 20002K DDK, вам не о чем беспокоиться.


В противном случае попробуйте обратиться к MSDN[Y111] [n2k112] , распространяемой вместе с Microsoft Visual Studio 6.0. Здесь вы найдете документацию и заголовочные файлы, ну а недостающие библиотеки из соответствующих DLL (Dynamic Link Library)[n2k113]  можно получить и самостоятельно (lib.exe с ключом /DEF), либо же вовсе обойтись без них, загружая все необходимые функции через LoadLibrary[Y114] /GetProcAddress.

Поскольку ASPI-интерфейс хорошо документирован (руководство по программированию насчитывает порядка 35 листов), то его освоение не должно вызвать никаких непреодолимых проблем (во всяком случае, после знакомства с SPTI). К тому же, в Windows MEe DDK входит один законченный демонстрационный пример использования ASPI, найти который можно в папке "\src\win_me\block\wnaspi32\". Несмотря на досадный суффикс "Me", он отлично уживается и с другими операционными системами, как-то: Windows 98, Windows 2000, Windows XP и т. д.

Впрочем, реализован этот пример на редкость "криво" и с большим количеством ошибок, а его наглядность такова, что менее наглядного примера для демонстрации ASPI пожалуй и не подобрать! Уж лучше исследовать исходные тексты программы CD slow, которые можно легко найти в Интернете (однако она написана на ассемблере, а с ассемблером знаком не всякий).

Кратко перечислим основные недочеты демонстрационного примера aspi32ln.c:

q      Вво-первых, это не консольная программа, а относящаяся кно [n2k115] GUI'вая (Graphical User Interface) — графическому интерфейсу пользователя'ая,[n2k116]  а потому большая часть ее кода к интерфейсу ASPI вообще никакого отношения не имеет.

q      Во-вторых, используется единая функция для получения уведомлений сразу от выполнения двух команд: SCSI_INQUIRY и SCSI_READ10, причем последняя в половине случаев заменена своей константой 0x28, что тоже не способствует ее пониманию.



q      В-третьих, накопители на CD- ROM программой поддерживаются лишь частично. Плохо спроектированная архитектура программы не позволила разработчикам осилить поставленную перед ними задачу. Поэтому ветка, отвечающая за чтение с приводов CD-ROM в функции ASPI32Post, специальным образом закомментирована. Если же наложенную блокировку убрать, то при чтении будет происходить ошибка, поскольку программа ориентирована лишь на те накопители, чей размер сектора составляет 0x200 (512) байт. Приводы CD-ROM дисков, чей сектор вчетверо больше, очевидно, к этой категории не относятся и, чтобы не переписывать всю программу целиком, единственное, что можно сделать –— это увеличить размер запрашиваемого блока данных до 0х800 (2048) байт (с жестких дисков будет считываться по четыре сектора за раз, что вполне допустимо).

q      Наконец, В-пятыхВ четвертых[Y117] , инкремент (т. е. вычисление адреса следующего считываемого блока) реализован неверночерез одно место и поэтому вообще не работоспособен.

Ладно, не будет увлекаться критикой сопроводительных примеров (даже плохой программный код все же лучше, чем совсем ничего) и перейдем непосредственно к изучению ASPI-интерфейса, а точнее –— его важнейшей команды SendASPI32Command, обеспечивающей передачу SRB-блоков устройству (со всеми остальными командами вы без труда справитесь и самостоятельно).

Структура SRB_ExecSCSICmd[Y118] ,[n2k119]  в которую, собственно, и упаковывается SRB-запрос, как две капли воды похожа на структуру SCSI_PASS_THROUGH_DIRECT. Во всяком случае, между ними больше сходства, чем различий (листинг 1.4.11). Вот, взгляните сами:

Листинг 2.1.4.11. Структура SRB_ExecSCSICmd

typedef struct

{

      BYTE SRB_Cmd;                   // ASPI command code = SC_EXEC_SCSI_CMD

      BYTE SRB_Status                 // ASPI command status byte

      BYTE SRB_HaId;                  // ASPI host adapter number



      BYTE SRB_Flags;                 // ASPI request flags

      DWORD SRB_Hdr_Rsvd;             // Reserved, MUST = 0

      BYTE SRB_Target;                // Target's SCSI ID

      BYTE SRB_Lun;                   // Target's LUN number

      WORD SRB_Rsvd1;                 // Reserved for Alignment

      DWORD SRB_BufLen;               // Data Allocation Length

      LPBYTE SRB_BufPointer;          // Data Buffer Pointer

      BYTE SRB_SenseLen;              // Sense Allocation Length

      BYTE SRB_CDBLen;                // CDB Length

      BYTE SRB_HaStat;                // Host Adapter Status

      BYTE SRB_TargStat;              // Target Status

      LPVOID SRB_PostProc;            // Post routine

      BYTE SRB_Rsvd2[20];             // Reserved, MUST = 0

      BYTE CDBByte[16];               // SCSI CDB

      BYTE SenseArea[SENSE_LEN+2];    // Request Sense buffer

}

SRB_ExecSCSICmd, *PSRB_ExecSCSICmd;

Обратите внимание: для взаимодействия с устройством вам совершенно незачем знать его дескриптор! Достаточно указать его физический адрес на шине (т. е. правильно заполнить поля SRB_HaId и SRB_Target)…. а как их узнать? Да очень просто: достаточно разослать по всем физическим адресам команду INQUIRY (код 12h). Устройствао, реально (и/или виртуально) подключенные к данному порту вернут идентификационную информацию (среди прочих полезных данных содержащую и свое имя), а несуществующие устройства не вернут ничего и операционная система "отрапортует" об ошибке.

Простейшая программа опроса устройств может выглядеть, например, так как показано в листинге 1.4.12.:

Листинг  2.1.4.12. Последовательный опрос портов на предмет наличия подключенных к ним устройств

#define MAX_ID              8

#define MAX_INFO_LEN        48

SEND_SCSI_INQUITY()

{

      #define MAX_LUN       8      // макс. возможное кол-во логических устройств

      BYTE      AdapterCount;

      DWORD     ASPI32Status;

      unsigned char buf[0xFF];



      unsigned char str[0xFF];

      unsigned char CDB[ATAPI_CDB_SIZE];

      long a, real_len, adapterid, targetid;

     

      // получаем кол-во адаптеров на шине

      ASPI32Status = GetASPI32SupportInfo();

      AdapterCount = (LOBYTE(LOWORD(ASPI32Status)));

     

      // готовим CDB-блок

      memset(CDB, 0, ATAPI_CDB_SIZE);

      CDB[0] = 0x12;               // INQUIRY

      CDB[4] = 0xFF;               // размер ответа

     

      // спамим порты в надежде найти тех, кто нам нужен

      for (adapterid = 0; adapterid < MAX_LUN; adapterid++)

      { // внимание! нельзя здесь ^^^^^^^^^^^^^ использовать AdapterCount,

        // как это рекомендуется в некоторых руководствах, поскольку номера

        // адаптеров устройств далеко не всегда идут вплотную друг к другу,

        // и если в нумерации возникает "разрыв", одно или более устройств

        // останутся необнаруженными

     

            for (targetid = 0; targetid < MAX_ID; targetid++)

            {

                  a = SEND_ASPI_CMD(adapterid, targetid, CDB,

                            ATAPI_CDB_SIZE, 0, buf, 0xFF, ASPI_DATA_IN);

                  if (a == SS_COMP)

                  {

                        real_len=(buf[4]>MAX_INFO_LEN)?buf[4]:MAX_INFO_LEN;

                        memcpy(str,&buf[8],real_len);str[real_len]=0;

                        printf("%d.%d <-- %s\n",adapterid, targetid, str);

                  }     

            }

      }

}

Результат работы программы на компьютере автора выглядит так, как показано в листинге 1.4.13 (обратите внимание, что адреса устройств, подключенных к виртуальной SCSI-шине, созданной драйвером ASPI, могут и не соответствовать их физическим адресам; в данном случае, привод PHILIPS висящий на физическом IDE-порту с номером 0, попал на виртуальный порт с номером 1, поскольку нулевой порт занят драйвером Virtual Clone CD, при удалении последнего из системы, соответствие виртуальных и физических адресов полностью восстанавливается, однако ручаться за это нельзя).


Первая слева цифра в листинге — adapter ID, следующая за ней — target ID.:

Листинг 2.1.4.13. Устройства, подключенные к компьютеру автора. Первая слева цифра –— adapter ID, следующая за ней –— target ID.

0.0 <-- ELBY    DVD-ROM         1.0

1.0 <-- IBM-DTLA-307015         TX2O

1.1 <-- PHILIPS CDRW2412A       P1.55VO1214DM10574

2.0 <-- ST380011A               3.06

2.1 <-- TEAC    CD-W552E        1.09

3.0 <-- AXV     CD/DVD-ROM      2.2a

3.1 <-- AXV     CD/DVD-ROM      2.2a

3.2 <-- AXV     CD/DVD-ROM      2.2a

Другое немаловажное достоинство ASPI-интерфейса по сравнению с SPTI состоит в поддержке асинхронного режима обработки запросов. Отдав запрос на чтение такого-то количество секторов, вы можете продолжить выполнение своей программы, не дожидаясь, пока процесс чтения секторов полностью не завершится. Конечно, для достижения аналогичного результата при использовании интерфейса SPTI достаточно всего лишь создать еще один поток, но… это уже не так элегантно и красиво. Демонстрационный пример программы, осуществляющей "сырое" чтение сектора с CD-диска показан в листинге 1.4.14.

Листинг 2.1.4.141414. [\etc\RAW.CD.READ\aspi32.raw.c]. Демонстрационный Пример программы, осуществляющийосуществляющей "сырое" чтение сектора с CD-диска

#include "scsidefs.h"

#include "wnaspi32.h"

void ASPI32Post (LPVOID);

#define F_NAME                  "raw.sector.dat"

/* ASPI SRB packet length */

#define ASPI_SRB_LEN      0x100

#define RAW_READ_CM             0xBE

#define WHATS_READ              0xF8      // Sync & All Headers & User Data

 // + EDC/ECC

#define PACKET_LEN              2352

//#define WHATS_READ      0x10            // User Data

//#define PACKET_LEN      2048

#define MY_CMD                  RAW_READ_CMD

HANDLE hEvent;

//-[DWORD READ_RAW_SECTOR_FROM_CD]---------------------------------------------



//            функция читает один или несколько секторов с CD-ROM в "сыром"

//            (RAW) виде, согласно переданным флагам

//

//      ARG:

//      adapter_id      -      номер шины (0 - primary, 1 - secondary)

//      read_id         -      номер устройства на шине (0 - master, 1 - slaeyer)

//      buf             -      буфер, куда читать

//      buf_len         -      размер буфера в байтах

//      StartSector     -      с какого сектора читать, считая от нуля

//      N_SECTOR        -      сколько секторов читать \

//      flags           -      что читать (см. спецификацию на ATAPI)

//

//      RET:

//                      -      ничего не возвращает

//

//      NOTE:

//            - функция возвращает управления до завершения выполнения запроса,

//              поэтому на момент выхода из нее, содержимое буфера с данными еще

//              пусто, и реально он заполняется только при вызове функции

//              ASPI32Post (вы можете модифицировать ее по своему усмотрению)

//              для сигнализации о завершении операции рекомендуется использовать

//              события (Event)

//

//            - функция работает и под 9x/ME/NT/W2K/XP и _не_ требует для себя

//              прав администратора. Однако ASPI-драйвер должен быть установлен.

//-----------------------------------------------------------------------------

READ_RAW_SECTOR_FROM_CD(int adapter_id,int read_id,char *buf,int buf_len,

                           int StartSector,int N_SECTOR,int flags)

{

      PSRB_ExecSCSICmd SRB;

      DWORD      ASPI32Status;

     

      // выделяем память для SRB-запроса

      SRB = malloc(ASPI_SRB_LEN); memset(SRB, 0, ASPI_SRB_LEN);

     

      // ПОДГОТОВКА SRB-блока

      SRB->SRB_Cmd          = SC_EXEC_SCSI_CMD;          // выполнить SCSI команду

      SRB->SRB_HaId         = adapter_id;                // ID адаптера

      SRB->SRB_Flags        = SRB_DIR_IN|SRB_POSTING;    // асинхр. чтение данных

      SRB->SRB_Target       = read_id;                   // ID устройства



      SRB->SRB_BufPointer   = buf;                       // сюда читаются данные

      SRB->SRB_BufLen       = buf_len;                   // длина буфера

      SRB->SRB_SenseLen     = SENSE_LEN;                 // длина SENSE-буфера

      SRB->SRB_CDBLen       = 12;                        // размер ATAPI-пакета

 

      SRB->CDBByte [0]      = MY_CMD;                    // ATAI-команда

      SRB->CDBByte [1]      = 0x0;                       // формат CD - любой

 

                            // номер первого сектора

      SRB->CDBByte [2]      = HIBYTE(HIWORD(StartSector));

      SRB->CDBByte [3]      = LOBYTE(HIWORD(StartSector));

      SRB->CDBByte [4]      = HIBYTE(LOWORD(StartSector));

      SRB->CDBByte [5]      = LOBYTE(LOWORD(StartSector));

 

                            // кол-во читаемых секторов

      SRB->CDBByte [6]      = LOBYTE(HIWORD(N_SECTOR));

      SRB->CDBByte [7]      = HIBYTE(LOWORD(N_SECTOR));

      SRB->CDBByte [8]      = LOBYTE(LOWORD(N_SECTOR));

      SRB->CDBByte [9]      = flags                // что читать?

      SRB->CDBByte [10]     = 0;                   // данные подканала не нужны

      SRB->CDBByte [11]     = 0;                   // reserverd

      // адрес процедуры, которая будет получать уведомления

      SRB->SRB_PostProc     = (void *) ASPI32Post;

      // посылаем SRB-запрос устройству

      SendASPI32Command(SRB);

      // возвращаемся из функции _до_ завершения выполнения запроса

      return 0;

}

//----------------------------------------------------------------------------

//      эта callback-функция вызывается самим ASPI и получает управление при

//      завершении выполнения запроса или же при возникновении ошибки.

//      в качестве параметра она получает указатель на экземпляр структуры

//      PSRB_ExecSCSICmd, содержащей всю необходимую информацию (статус, указатель

//      на буфер и т.д.)

//----------------------------------------------------------------------------



void ASPI32Post (void *Srb)

{

      FILE *f;

      // наш запрос выполнен успешно?

      if ((((PSRB_ExecSCSICmd) Srb)->SRB_Status) == SS_COMP)

      {

            // ЭТОТ КОД ВЫ МОЖЕТЕ МОДИФИЦИРОВАТЬ ПО СВОЕМУ УСМОТРЕНИЮ

            //-------------------------------------------------------

            // записывает содержимое сектора в файл

            // внимание! PSRB_ExecSCSICmd) Srb)->SRB_BufLen содержит не актуальную

            // длину прочитанных данных, а размер самого буфера. если количество

            // байт, возвращенных устройством, окажется меньше размеров буфера, то

            // его хвост будет содержать мусор! здесь мы используем поле SRB_BufLen

            // только потому, что при вызове функции SendASPI32Command тщательно

            // следим за соответствием размера буфера количеству возвращаемой нам

            // информации

            if (f=fopen(F_NAME, "w"))

            {

                  // записывает сектор в файл

                  fwrite(((PSRB_ExecSCSICmd) Srb)->SRB_BufPointer,1,

                  ((PSRB_ExecSCSICmd) Srb)->SRB_BufLen, f);

                  fclose(f);

            }

            // кукарекаем и "размораживаем" поток, давая понять, что процедура

            // чтения закончилась

            MessageBeep(0); SetEvent(hEvent);

            //--------------------------------------------------------

      }

}

main(int argc, char **argv)

{

      void *p; int buf_len, TIME_OUT = 4000;

     

      if (argc<5)

      {

            fprintf(stderr,"USAGE:\n\tRAW.CD.READ.EXE adapter_id"\

            ", read_id, StartSector, n_sec\n"); return 0;

      }

     

      // вычисляем длину буфера и выделяем для него память

      // ВНИМАНИЕ: таким образом можно юзать только до 64КБ

      // если же вам требуются буфера больших объемов,

      // используйте функцию GetASPI32Buffer

      buf_len = PACKET_LEN*atol(argv[4]); p = malloc(buf_len);



     

      // создаем событие

      if ((hEvent = CreateEvent(NULL,FALSE,FALSE,NULL)) == NULL) return -1;

     

      // читаем один или несколько секторов с CD

      READ_RAW_SECTOR_FROM_CD(atol(argv[1]), atol(argv[2]),p,buf_len,

                        atol(argv[3]), atol(argv[4]),WHATS_READ);

     

      // ждем завершения выполнения операции

      WaitForSingleObject(hEvent, TIME_OUT);

     

      return 0;

}

Откомпилировав этот пример и запустив его на выполнение, убедитесь, что он успешно работает как под Windows 9x, так и под Windows NT, причем не требуя у вас наличия прав администратора! С одной стороны, это, бесспорно хорошо, но с другой… наличие ASPI-драйвера создает огромную "дыру" вс системе безопасности, позволяя зловредным программам вытворять с вашим оборудованием все, что угодно. Заразить MBR (Master Boot Record) — главную загрузочную запись — /boot-сектора? Пожалуйста! Уничтожить информацию со всего диска целиком –— да проще этого ничего нет! Поэтому, если вы заботитесь о собственной безопасности –— удалите ASPI32-драйвер со своего компьютера (для этого достаточно удалить файл ASPI.SYS из каталога WINNT\System32\Drivers). Разумеется, сказанное относиться только к NT, поскольку в операционных системах Windows 9x прямой доступ к оборудованию можно заполучить и без этого.


Содержание раздела