Serge Pachkovsky Новосибирск Введение в методы защиты от копирования Содержание 0. Пролог 1. Защита от копирования, основанная на ключевом диске 1.1 Запись на гибкий диск методом MFM 1.1.1 Разделение данных 1.1.2 Поле синхронизации и байт ID 1.1.3 Общий формат дорожки 1.2 Контроллер Intel 8272A гибкого диска 1.2.1 Регистры 8272A 1.2.2 Сводка команд 8272A 1.2.3 Описание команд 8272A 1.2.4 AT-Контроллер гибкого диска 1.2.5 "Нормальный" формат гибкого диска PC 1.3 Времянезависимые способы защиты от копирования 1.3.1 Внешний или пропущенный сектор 1.3.2 Слабая запись данных 1.3.3 Данные в промежутке 1.3.4 Секторы без адресной метки данных 1.3.5 Секторы без адресной метки ID 1.3.6 Секторы с адресной меткой ID плохого сектора 1.3.7 Поле данных, перекрывающее адресную метку индекса 1.3.8 Дорожки с разными параметрами 1.3.9 Данные, перекрывающие промежуток 1.3.10 Параноидальные идеи 1.4 Способы защиты, опирающиеся на временные параметры 1.4.1 Проверка чередования секторов на дорожке 1.4.2 Измерение времени передачи данных 1.5 Защита с применением специального оборудования 1.5.1 Модифицированный MFM метод 1.5.2 Потерянные дорожки 1.5.3 Нестандартная скорость передачи 1.6 Примеры различных реализаций защиты 1.6.1 IBM Filing Assistant 1.6.2 SuperLok 1.6.3 Cops CopyLock II 1.6.4 PC Shield 2. Защита, опирающаяся на жесткий диск 2.1 Защита на уровне чипа 2.2 Защита на уровне BIOS 2.2.1 Изменение чередования секторов 2.2.2 Изменение номеров секторов 2.2.3 Неиспользуемые области диска 2.3 Защита на уровне DOS 2.3.1 Зависимость от номера кластера 2.3.2 Неиспользуемые (зарезервированные) области диска 2.3.3 Неиспользуемые (вследствие округления кластера) области диска 3. Защита, опирающаяся на системную плату и систему BIOS 3.1 Способы, базирующиеся на данных 3.2 Способы, базирующиеся на временных параметрах Словарик Приложение A. Простая программа для 8272A Приложение B. Простое упражнение по использованию HDC Приложение C. Как определить номер нужного кластера Приложение D. Доступ к данным за концом файла Приложение E. Как различить системные платы Пролог Нижеследующий трактат по методам защиты от копирования почти полностью основан на моих собственных опытах с программным обеспечением для защиты от копирования и на общении с моими коллегами. Поэтому любые приводимые здесь утверждения не могут рассматриваться как истина в последней инстанции (да и как истина вообще). Этот документ есть НЕ руководство по развитию способов защиты от копирования, но краткое введение по ее взламыванию. Всякий, использующий сей документ или примеры к нему для разработки защищенного программного или аппаратного обеспечения нарушает лицензию на его использование. Правовые аспекты защиты от копирования здесь не рассматриваются. Как бы то ни было, Вы можете использовать сведения из этого опуса только в соответствие с законом. Если в этих законах не упоминается программное обеспечение (как в Советском Союзе), Вы всегда должны иметь в виду моральные соображения. Я не могу нести ответственности за любое неправильное использование этого документа или прилагаемых к нему кодов. Вы можете заметить, что эти предлагаемые вариации на тему защит довольно скудны количественно и не всегда современны. (Например, блокировка параллельного порта, используемая в большинстве популярных устройств защиты, вообще не рассматривалась). Учитывая географическое положение Новосибирска, это трудно рассматривать как мою вину. Любой труд такого рода всегда опирается на поддержку других энтузиастов, поскольку один не в состоянии купить все (или любую, потому что они продаются за твердую валюту) новые из программ защит от копирования. Так, я хочу принести свои самые искренние благодарности всем тем людям, которые предоставили мне программы защиты для PC. В заключение я прошу извинения за мой далекий от хорошего английский.* Я приму любые замечания по организации и стилю сего документа. Serge Pachkovsky Новосибирск 6 июня 1991 --------------------------------------- * Космополит хренов - прим. переводчика 1. Защита от копирования, основанная на ключевом диске Этот тип (вернее, типы) защиты от копирования так же стар, как сам компьютер PC. Годы развития и усложнения аппаратного обеспечения увеличили количество методов защиты. Хотя недавно появилась блокировка параллельного порта, а защита при помощи гибкого диска кажется устаревшей, она обладает по меньшей мере двумя очевидными достоинствами. Во-первых, ключевой диск может одновременно использоваться как дистрибутивный, и, во-вторых, этот тип защиты очень дешев (но при этом вмешательство в него затруднительно). Так, ключевой диск до сих пор может широко использоваться для распостранения программного обеспечения индивидуального потребления. На мой взгляд, в Советском Союзе защита посредством ключевого диска пока доминирует. Для понимания способов защиты посредством контроллера гибкого диска (FDC), нужна некоторая осведомленность относительно основных операций и данных FDC. Позвольте нам здесь рассмотреть их. (Кстати, разделы 1.1 и 1.2 большей частью основаны на следующих документах фирмы Intel: "An intelligent Data Base System Using the 8272", "8272 Singe/Double Density Floppy Disk Controller Data Sheet", "8272A Single/Double Density Floppy Disk Controller".) 1.1 Запись на гибкий диск методом MFM Модифицированный метод частотной модуляции (MFM) для записи на гибкий диск был впервые использован в IBM System 34, часто он называется "запись двойной плотности". Термину "запись одинарной плотности" прямо соответствует метод частотной модуляции (FM) IBM 3740, который использует 4 mс для записи одного бита данных. Изначальный метод MFM использовал один бит в 2 mс ячейке, но для гибких дисков IBM PC было использовано 4 mс. Таким образом, неформатируемая емкость одной дорожки составляет 6.1 KБайт. Так называемые диски высокой плотности (HD) PC просто соответствуют 2 mс для одного бита, т.е. действительной спецификации метода MFM. 1.1.1 Разделение данных Запись данных методом FM была проста: начало каждой ячейки задавалось при помощи так называемого синхробита, а сам бит данных записывался по центру ячейки (см. рис 1.1.1a). Такой способ позволял легко разделять биты данных, однако было весьма расточительно использовать два изменения частоты для хранения одного бита данных. Тем не менее, полное удаление синхробитов сделало бы данные, содержащие большие последовательности нулей, нечитаемыми из-за случайных изменений скорости вращения диска и колебаний контроллера. │ ┌┐ ┌┐ │ ┌┐ │ │ ││ ││ │ ││ │ │ ││ ││ │ ││ │ ──────┼───────────────────────┼───────────────────────┼───── '1' '0' Рис 1.1.1a Запись данных методом FM. Для обхода этих недостатков в методе MFM большая часть синхробитов была удалена согласно следующему правилу: синхробит у края ячейки записывается только в том случае, если в предыдущей ячейке не было записано бита данных и не будет записываться бит данных в текущей ячейке. (См. рис. 1.1.1b). При таком кодировании разделение бит данных становится более трудной задачей, но почти полное удаление ов стоит того. │ |┌┐ │ |┌┐ │ | │ ┌┐ | │ │ |││ │ |││ │ | │ ││ | │ │ |││ │ |││ │ | │ ││ | │ ──────┼───────────┼───────────┼───────────┼───────────┼───── '1' '1' '0' '0' Рис 1.1.1b Запись данных методом MFM. Как легко видеть, декодирование данных при обоих методах зависит от начальной позиции битовой ячейки. Например, если мы переместим начало битовой ячейки к прерывистой линии на рис 1.1.1b, вместо последовательности '1100' получим '0010'. Поэтому во избежание двусмысленностей при декодировании бит данных каждое поле данных на дорожке должно снабжаться полем синхронизации. 1.1.2 Поле синхронизации и байт ID Поле синхронизации по методу MFM состоит из 96 нулевых битов (т.е., ячеек с таймерным битом без бита данных) и следующих за ними 3 байтов A1H (10100001B). Нулевые биты служит для нормального выравнивания ячеек данных, а байты A1H иденфицируют начало собственно байтов данных. Хотя целых 12 байтов записывается контроллером во время форматирования (это значение нельзя изменить программно), только 1 байт (8 бит) действительно необходим для синхронизации битовых ячеек. Остальные 11 пишутся "на всякий случай". Поле синхронизации по методу FM проще - оно состоит из только 48 нулевых битов. (Хотя и здесь контроллеру нужны только 8 бит, а остальные просто придают уверенности). Различные поля данных (пользователя и вспомогательные) могут различаться посредством одного байта, следующего непосредственно за полем синхронизации. Этот байт не может смешаться с пользовательскими данными, поскольку этот байт (и только этот байт) записывается с использованием нестандартного размещения синхробитов. К сожалению, я располагаю информацией об соответствующих синхробитах только для метода FM. Байт ID, используемый по методу MFM, похоже подобен здесь описанному. (Заметьте, что в поле данных первым записывается бит MSB). байт ID Таймер Наименование поля FC D7 Индексная адресная метка FE C7 Адресная метка ID сектора FB C7 Данные сектора F8 C7 Удаленные данные FE C7 ID плохой дорожки Хотя в документации фирмы Intel поле синхронизации всегда упоминается как часть предшествующего промежутка, мы склонны рассматривать его как часть следующего поля данных. 1.1.3 Общий формат дорожки Стартовой точкой для всех операций на гибком диске служит физическая индексная метка, которая порождается индексным отверстием в дискетте. Полный формат дорожки флоппи диска, начинающийся от физической индексной метки, может быть описан следующим образом: - Физическая адресная метка - Доиндексный промежуток (GAP 5) - Индексная адресная метка (IAM) - Послеиндексный промежуток (GAP 1) Для n от 1 до N-1, где N - количество секторов на дорожке: - ID сектора n - После ID промежуток (GAP 2) - Данные сектора n - Промежуток после данных(GAP 3) Для последнего сектора на дорожке: - ID сектора - После ID промежуток (GAP 2) - Данные сектора - Завершающий промежуток (GAP 4) Индексная адресная метка (которая не используется для каких-либо целей 8272A) имеет некоторые отличия от поля синхронизации: взамен байта A1H используется C2H (11000010b), который следует за ID байтом со значением FCH (11111100b). Поле ID сектора содержит байт FEH, за которым следуют байты со значениями C,H,R,N, где C означает номер цилиндра, H - номер головки, R - номер сектора и N - код размера сектора. Эти байты (включая FEH) проверяются посредством 16-ти битового циклического избыточного кода (CRC), о котором ниже. Размер поля данных в секторе может быть вычислен как 128 * 2^N, т.е., N=0 означает размер данных в 128 байт, N=1 - 256 байт, N=2 - 512 байт, и т.д. C=H=R=N=FFH означают плохую дорожку. Поле данных содержит байт FBH, следующий за 128 * 2^N байтами информации и два байта CRC. CRC как ID сектора, так и поля данных вычисляется при помощи полинома x^16 + x^12 + x^5 + 1 с начальным значением FFH (как всегда, первым MSB) 1.2 Контроллер Intel 8272A гибкого диска Говорят, что оригинальный FDC PC был выполнен на чипе Intel 8272. Конечно, это мог быть и любой аналогичный чип - 8272A, NEC mPD765 и т.д. Я никогда не видел такого PC, так что не могу точно сказать, так ли это. Тем не менее, ввиду поддержания совместимости на уровне регистров (хороший стиль!) с первыми PC, все более современные контроллеры почти те же с точки зрения программирования. Команды 8272A выполняются в три последовательные фазы: фаза команды, фаза выполнения и фаза результата. Во время командной фазы процессор получает инструкции о том, что ему надлежит делать. Во время фазы выполнения контроллер производит запрошенные действия. Все передачи пользовательских данных должны быть сделаны во время фазы выполнения. За фазой выполнения следует фаза результата, когда контроллер возвращает информацию о состоянии. Несмотря на то, что во время фазы команды или фазы результата запрошенные FDC данные могут надолго задерживаться (данные могут запоминаться во внутренних регистрах 8272A), все запросы FDC во время выполнения должны удовлетворяться немедленно, иначе FDC выдает ошибку переполнения данных и завершает операцию. Более точно говоря, запрашиваемые данные не могут быть задержаны больше чем на время передачи 8 бит данных. Следовательно, на 360KБ дисководе, который действует со скоростью 250K (1K здесь = 1000) бит в секунду (KBPS), FDC будет передавать байт данных каждые 32 mс или 31250 байт в секунду. Хотя сам 8272A может работать как в режиме DMA, так и в режиме неактивного DMA, только относительно быстрый процессор способен выполнять передачу данных на такой скорости. Существующие FDC в не-DMA режиме для дисков двойной плотности требуют по крайней мере 80286 на 6 MHz, а AT-диски высокой плотности могут проглотить и все 10 MHz 80286 процессора. 1.2.1 Регистры 8272A Чип 8272A взаимодействует с CPU через два регистра: главный регистр состояния (MSR) и регистр данных (DR). MSR только читается. DR может быть прочитан или записан, что определяется битом RQM в регистре MSR. Назначение битов в MSR приведено на рис 1.2.1a. ┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┐ │ RQM │ DIO │ NDM │ CB │ D3B │ D2B │ D1B │ D0B │ └──┬──┴──┬──┴──┬──┴──┬──┴──┬──┴──┬──┴──┬──┴──┬──┘ │ │ │ │ │ │ │ └──── дисковод 0 занят │ │ │ │ │ │ └────────── дисковод 1 занят │ │ │ │ │ └──────────────── дисковод 2 занят │ │ │ │ └────────────────────── дисковод 3 занят │ │ │ └──────────────────────────── FDC занят │ │ └────────────────────────────────── режим не-DMA │ └──────────────────────────────────────── ввод/вывод данных └────────────────────────────────────────────── запрос ведущего Рис 1.2.1a Главный регистр состояния 8272A. Бит DxB устанавливается в 1, когда дисковод выполняет команду поиска или рекалибровки. Бит CB устанавливается, когда FDC выполняет операцию чтения или записи. Бит NDM устанавливается, когда FDC находится в фазе выполнения и операции DMA невозможны (Это означает, что больше данные не могут поступать или читаться из DR). Бит DIO = 1, когда CPU читает данные из DR и DIO = 0 если CPU посылает данные в DR. Бит RQM = 1 показывает, что DR готов передать следующий байт. Направление передачи зависит от значения бита DIO. 8272A запоминает текущий номер цилиндра для каждого присоединенного к к нему дисковода. Поскольку дисковод не может отличить один цилиндр от другого (исключая цилиндр 0), это необходимо для выполнения операции поиска, которая переводит FDC в режим пошагового движения. Все эти регистры сбрасываются при сбросе FDC (но дисковод не возвращается на дорожку 0 при сбросе). Другие важные внутренние регистры содержат время перехода с дорожки на дорожку, время разгрузки головки и время загрузки головки (cм. спецификацию команд). 1.2.2 Сводка команд 8272A Команды 8272A могут быть разбиты на три группы: передачи данных, контроля дисковода и диагностики. Передача данных включает чтение данных, чтение удаленных данных, запись данных, запись удаленных данных и три команды сканирования: на равно, на меньше или равно, на больше или равно. Контроль дисковода включает команды рекалибровки, поиска, определения состояния дисковода, определения состояния прерывания и форматирования дорожки. Команды чтения ID и чтения дорожки могут рассматриваться как диагностические. Все команды с неверным первым байтом рассматриваются как неправильные. Команды 8272A могут быть легко идентифицированы по младшему нибблу первого байта команды согласно таблице 1.2.2 (хотя некоторые из таких команд могут быть неверны). Таблица 1.2.2. Коды операций 8272A. x1 Сканирование на равно x2 Чтение дорожки x3 Определение параметров x4 Получение состояние дисковода x5 Запись данных x6 Чтение данных x7 Рекалибровка x8 Получение состояние прерывания x9 Запись удаленных данных / сканирование на меньше или равно xA Чтение ID xC Чтение удаленных данных xD Форматирование дорожки / сканирование на больше или равно xF Поиска Последовательность выполнения команды 8272A состоит из следующих шагов: 0. Если в операции используется DMA, программный канал 2 8237A устанавливается в режим передачи одиночных байтов. (Кстати, сигнал TC из DMA приводит к немедленному завершению операции FDC.) 1. Для каждого байта команды, ожидая пока бит RQM не станет 1, проверяется бит DIO: значение 0 говорит о том, что FDC готов принять команду, 1 сообщает, что случилось одно из двух: либо ваша команда не распознана FDC (и следующее чтение из DR вернет вам 80H), либо что вы уже переслали все данные FDC (и также то, что ваша команда неверна). Если ваша команда не имеет фазы выполнения и результата (команда Определить), ваши действия на этом прекращаются. 2. Если вы используете FDC в не-DMA режиме и команда передает данные во время фазы выполнения (чтение, запись, форматирование), вы должны на этом шаге ожидать, пока бит NDM не станет = 0. Пока NDM не равен 0, для каждого считанного или записываемого байта вы должны ждать установки бита RQM, после чего только писать в (или читать из) DR следующий байт. Если вы используете для передачи режим DMA (или не передаете данные вообще), просто переходите на шаг 3. 3. Об окончании фазы выполнения сигнализирует IRQ 6 (INT 0EH). Вы можете либо разрешить прерывания 8272A и отслеживать их в своей программе обработки прерывания, либо непрерывно опрашивать регистр запроса прерываний (IRR) 8259A. Если команда не имеет фазы выполнения (Получение состояния дисковода), переходите на шаг 4. 4. В фазе результата вы читаете состояние команды из FDC посредством байта RQM (следует при этом быть уверенным, что DIO = 1). 8272A может вернуть вплоть до 3 байтов состояния (которые см. ниже) с другими данными, которые изменяются от команды к команде. ┌───────────┬─────┬─────┬─────┬─────┬─────┬─────┐ │ IC │ SE │ EC │ NR │ H │ DS1 │ DS0 │ ST0 └───────────┴─────┴─────┴─────┴─────┴─────┴─────┘ ┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┐ │ EN │ 0 │ DE │ OR │ 0 │ ND │ MW │ MA │ ST1 └─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘ ┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┐ │ 0 │ CM │ DD │ WC │ SH │ SN │ BC │ MD │ ST2 └─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘ ┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┐ │ FT │ WP │ RDY │ T0 │ TS │ H │ DS1 │ DS0 │ ST3 └─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘ Fig 1.2.2 Байты состояния 8272A 0-3 ST0. IC - Код прерывания: 00 - Нормальное завершение команды. 01 - Ненормальное завершение команды (Операция может быть в порядке, следует проверить другие коды состояния) 10 - Неверная команда. 11 - Ненормальное завершение команды (сигнал готовности диска изменился во время выполнения). SE - Операция поиска закончена. EC - Сбой оборудования (сигнал ошибки поступает от устройства или цилиндр 0 не найден после 77 пульсов во время рекалибровки). NR - Нет готовности (Дисковод выдает неготовность во время чтения или записи или сторона 1 была запрошена у одностороннего диска). H - Адрес головки. DS0, DS1 - Код дисковода. ST1. EN - Ошибка конца дорожки (FDC пытается получить доступ к сектору за последним сектором на дорожке). Этот флаг устанавливается в 1 (и, следовательно, IC будет равно 01) если FDC читает сектор, указанный в параметре EOT команды и сигнал TC имеет низкий уровень, так каждая операция чтения в не-DMA режиме будет завершаться с ошибкой EN. DE - Ошибка данных. AM сектора или данные сектора имеют неверную сумму CRC. OR - Ошибка переполнения. Или 8272A не успевает посылать CPU, или DMA обслуживаться в указанный интервал времени (32 mс для дисковода на 360KБ), что к потере данных. ND - Сектор не найден. Указанный сектор не найден за время двух оборотов диска (т.е., индексное отверстие было обнаружено два раза после начала операции). Для многосекторной передачи двухоборотный таймаут отслеживается для каждого сектора отдельно. NW - Ошибка по защите от записи. Обнаружен сигнал защиты от записи во время операции записи или форматирования. MA - Пропуск адресной метки. Адресная метка сектора или данных не найдена. ST2. CM - Контрольная метка. AM удаленных данных обнаружена во время команды чтения или AM данных обнаружена во время команды чтения удаленных данных и при этом бит SK был не установлен. DD - Ошибка данных. Неверный CRC данных сектора. DE при этом также устанавливается. WC - Ошибка адреса цилиндра. Адрес цилиндра на дорожке не соответствует указанному адресу цилиндра. SH - Сканирование выполнено. Условие команды сканирования выполнено. SN - Условие команды сканирования не выполнено. BC - Ошибка плохой дорожки. То же, что и WC, но адрес цилиндра на дорожке равен FFH. MD - Ошибка пропущенной AM данных. Бит MA также устанавливается. ST3. FT - Неисправность. Дисковод указывает на неисправность. WP - Защита от записи. RDY - Сигнал готовности дисковода. На PC и AT подсистемах гибкого диска этот бит всегда установлен, независимо от того готов ли дисковод (и установлен ли он вообще). T0 - Сигнал нулевой дорожки. TS - Две стороны. На PC и AT подсистемах гибкого диска этот бит всегда будет равен 0. 1.2.3 Описание команд 8272A Здесь я привожу все команды 8272A в том порядке, в каком они приводятся в таблице команд 8272A руководства по 8272A фирмы Intel. Конечно, этого описания недостаточно для создания драйвера гибкого диска. Для получения полной информации см. руководство фирмы Intel или приложение A в качестве простого примера. Чтение данных ───────────── Команда: MT MFM SK 0 0 1 1 0 └─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘ 0 0 0 0 0 HDS DS1 DS0 └─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘ C/H/R/N/EOT/GPL/DTL Выполнение: Чтение полей данных на дорожке. Результат: ST0/ST1/ST2/C/H/R/N MT указывает на продолжение операции чтения на дорожке 1 того же цилиндра. SK указывает FDC пропустить поля удаленных данных. HDS указывает номер используемой в операции головки. DS1,DS0 назначает номер дисковода. C/N/R/N ID начального сектора. EOT количество секторов на дорожке. GPL длина межсекторного промежутка. DTL должно быть FFH для MFM. Чтение ID сектора ───────────────── Команда: 0 MFM 0 0 1 0 1 0 └─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘ 0 0 0 0 0 HDS DS1 DS0 └─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘ Выполнение: Чтение первого корректного ID сектора. (Первый здесь значит "первый обнаруженный от текущего положения головки", а не "первый после физической адресной метки"). Результат: ST0/ST1/ST2/C/H/R/N Чтение удаленных данных ─────────────────────── Команда: MT MFM SK 0 1 1 0 0 └─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘ 0 0 0 0 0 HDS DS1 DS0 └─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘ C/H/R/N/EOT/GPL/DTL Выполнение: Читается поле удаленных данных на дорожке. Результат: ST0/ST1/ST2/C/H/R/N SK указывает FDC пропустить поля данных. Чтение дорожки ────────────── Команда: 0 MFM SK 0 0 0 1 0 └─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘ 0 0 0 0 0 HDS DS1 DS0 └─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘ C/H/R/N/EOT/GPL/DTL Выполнение: Чтение поля данных на дорожке. Результат: ST0/ST1/ST2/C/H/R/N Эта команда читает поля данных не считаясь со значениями C/H/R/N записанными в ID сектора. Поля данных, у которых отсутствует правильный ID могут быть прочитаны с помощью этой команды. Хотя документация фирмы Intel указывает, что команда чтения дорожки прекращается тогда, когда нет вообще не найдены поля данных на дорожке или счетчик секторов превысит значение EOT, эта команда прекращается тогда, когда не найдена адресная метка данных после адресной метки ID сектора с плохим CRC. Команда чтения дорожки принимает ЛЮБОЕ значение N, таким образом можно читать межсекторный промежуток (или всю дорожку, если N достаточно велико) вместе данными сектора. Сектора будут прочитаны в порядке появления их под головкой чтения/записи, т.е. если дорожка была отформатирована на 8 512-байтных секторов (с чередованием 1:1), и вы начали команду чтения дорожки с R = 1, N = 3, EOT = 4, сектора 1, 3, 5 и 7 будут прочитаны. Запись данных ───────────── Команда: MT MFM 0 0 0 1 0 1 └─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘ 0 0 0 0 0 HDS DS1 DS0 └─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘ C/H/R/N/EOT/GPL/DTL Выполнение: Запись поля данных на дорожку. Результат: ST0/ST1/ST2/C/H/R/N Запись удаленных данных ─────────────────────── Команда: MT MFM 0 0 1 0 0 1 └─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘ 0 0 0 0 0 HDS DS1 DS0 └─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘ C/H/R/N/EOT/GPL/DTL Выполнение: Запись поля удаленных данных на дорожку. Результат: ST0/ST1/ST2/C/H/R/N Форматирование дорожки ────────────────────── Команда: MT MFM 0 0 1 1 0 1 └─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘ 0 0 0 0 0 HDS DS1 DS0 └─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘ N/SC/GPL/D Выполнение: Команда форматирует дорожку с SC секторами размером N. Сектора заполняются байтом D. Значения C/H/R/N для каждого записываемого ID сектора задаются пользователем (как в команде записи данных) Результат: ST0/ST1/ST2/C/H/R/N Кстати: GPL = 0 понимается как 100H. Сканирование на равно ───────────────────── Команда: MT MFM SK 1 0 0 0 1 └─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘ 0 0 0 0 0 HDS DS1 DS0 └─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘ C/H/R/N/EOT/GPL/STP Выполнение: Поле данных на дорожке читается и сравнивается побайтно с данными из CPU или DMA. Если условие сканирования не удовлетворено, то сканирование продолжается с сектора R+STP. Результат: ST0/ST1/ST2/C/H/R/N Сканирование на меньше или равно ─────────────────-────────────── Команда: MT MFM SK 1 1 0 0 1 └─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘ 0 0 0 0 0 HDS DS1 DS0 └─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘ C/H/R/N/EOT/GPL/STP Выполнение: Поле данных на дорожке читается и сравнивается побайтно с данными из CPU или DMA. Если условие сканирования не удовлетворено, то сканирование продолжается с сектора R+STP. Результат: ST0/ST1/ST2/C/H/R/N Сканирование на больше или равно ──────────────────────────────── Команда: MT MFM SK 1 1 1 0 1 └─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘ 0 0 0 0 0 HDS DS1 DS0 └─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘ C/H/R/N/EOT/GPL/STP Выполнение: Поле данных на дорожке читается и сравнивается побайтно с данными из CPU или DMA. Если условие сканирования не удовлетворено, то сканирование продолжается с сектора R+STP. Результат: ST0/ST1/ST2/C/H/R/N Рекалибровка ──────────── Команда: 0 0 0 0 0 1 1 1 └─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘ 0 0 0 0 0 0 DS1 DS0 └─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘ Выполнение: Рекалибровка указанного дисковода. Все 4 дисковода могут быть рекалиброваны одновременно. 8272A может выполнять операцию чтения или записи на любом другом дисководе. Так, команда получения состояния прерывания используется для того, чтобы отличить прерывание, вызванное завершением рекалибровки от прерывания, вызванного завершением операции. FDC не разрешает выполнение какой-либо операции на рекалибруемом дисководе, пока состояние прерывания не укажет на прерывание по завершению поиска. Получить состояние прерывания ───────────────────────────── Команда: 0 0 0 0 1 0 0 0 └─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘ Результат: ST0/C (Кстати: когда IC = 10 (неверна команда), значение C не возвращается). 8272A генерирует запрос на прерывание, если происходит какое-либо из следующих событий: a) Началась фаза результата для команд чтения/записи/ форматирования/сканирования. b) Изменился сигнал готовности одного из дисководов. c) Завершился поиск/рекалибровка. d) Запрос передачи не-DMA данных. Процедура обслуживания прерывания легко различает эти события: if NDM = 1 then запрос передачи данных else if CB = 1 then началась фаза результата else if SE = 0 then изменился сигнал готовности else конец поиска или рекалибровки Назначить ───────── Команда: 0 0 0 0 0 0 1 1 └─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘ SRT HUT └───────────────────────┴───────────────────────┘ HLT ND └─────────────────────────────────────────┴─────┘ SRT Интервал шага. Устанавливает минимальную задержку между двумя шаговыми импульсами дисковода. (1-16 mс, SRT = 0FH соответствует 1 mс). Старые дисководы PC поддерживали 3 или 4 mс, некоторые сейчас управляются за 2 или 1 mс. HUT Время разгрузки головки. Задержка между завершением операции чтения/записи и подьемом головки. (16-240 mс, HUT=0 соответствует 16 mс). Обычно устанавливается 240 mс. HLT Время загрузки головки. Задержка между командой загрузки головки и началом операции чтения/записи. (2-254 mс, HLT=1 означает 2 mс). Обычно равно 2 mс. ND 0: режим DMA. 1: режим не-DMA. Все таймеры внутри 8272A фактически синхронизированы с сигналом WR CLK, так что все указанные здесь значения корректны при 500 KHz WR CLK или скорости передачи данных в 500 KBPS. Уменьшение частоты WR CLK влечет удлинение всех внутренних задержек. Sense Drive Status ────────────────── Команда: 0 0 0 0 0 1 0 0 └─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘ 0 0 0 0 0 HDS DS1 DS0 └─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘ Результат: ST3 Seek ──── Команда: 0 0 0 0 1 1 1 1 └─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘ 0 0 0 0 0 HDS DS1 DS0 └─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘ C См. рекалибровку. 1.2.4 AT-Контроллер гибкого диска Контроллер гибких дисков оригинального PC и XT был способен работать с четырьмя дисководами. FDC AT, хотя и совместим с ним на уровне регистров, может работать только с двумя, так что возможна установка двух FDC в AT. Большинство клонов BIOS'а не поддерживает второй FDC, и сам я никогда не проверял IBM AT или IBM BIOS. Первый FDC использует адреса в промежутке 3F0-3F7, второй FDC в промежутке 370-377. Вся приводимая здесь информация о первом FDC также может использоваться и ко второму с соответсвующим изменением ссылок на другие адреса. 8272A (или его более интегрированные эквиваленты) использует порты 3F4 (MSR) и 3F5 (DR). Как вы уже могли видеть, 8272A сам не может управлять двигателем дисковода, этой цели служит регистр 3F2 (регистр цифрового вывода) (см. рис 1.2.4a). ┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┐ │ D │ C │ B │ A │ IE │ EC │ DS1 │ DS0 │ └──┬──┴─────┴─────┴──┬──┴──┬──┴──┬──┴──┬──┴──┬──┘ └────────┬────────┘ │ │ └──┬──┘ │ │ │ └───── Выбор дисковода │ │ └────────────── Контроллер разрешен │ └──────────────────── Прерывания разрешены └─────────────────────────────────── Двигатель разрешен Рис 1.2.4a Регистр цифрового вывода (3F2H). Биты DS1 и DS0 цифрового регистра вывода не принимают во внимание биты DS, указанные в команде 8272A, так что можно сменить дисковод прямо по ходу выполнения команды. Хотя это рискованные действия, много методов защиты от копирования используют эту особенность. Сброс бита EC в нуль сбрасывает контроллер, таким образом, любая операция (например, форматирование дорожки или запись данных) может быть прервана в любой момент. (Хотя нужно принимать специальные меры, чтобы выполнить внезапное завершение без вибраций). Бит IE предназначен для использования в многоконтроллерных системах. Поскольку все FDC используют одно и то же IRQ 6 и канал 2 DMA неактивный контроллер может (или не может - не могу сказать) поддерживать в этой линии низкий уровень, таким образом предотвращая другими контроллерами использование системного сервиса. Бит разрешения двигателя дисковода также может использоваться при защите (См. 1.4.2). Второй добавочный регистр - это 3F7 (регистр состояния дискетты). (Этого регистра нет в старых XT, но он часто обнаруживается в современных клонах). По моим сведениям, только два младших бита имеют значение при записи и один старший бит при чтении. При записи в 3F7 могут быть заданы скорости передачи: 00 - 500 KBS (MFM) 01 - 300 KBS (MFM) 10 - 250 KBS (MFM) 11 - 125 KBS (FM) Три первых значения (от 00 до 10) упоминаются в руководствах IBM. Хотя последнее значение не документировано, оно работает на любом FDC AT и мне не пришлось столкнутся с трудностями при его использовании. (Эта скорость передачи предназначена для дисков одинарной плотности в 360 KБ дисководе). Значения от 00 до 10 предназначены для использования для MFM-дискетт, поскольку они используют для длины такта 1/4 длины цикла. 125 KBS использует для такта 1/8 длины цикла. Поскольку FDC AT не имеет таймера для передачи со скоростью 175 KBS в режиме FM, диски одинарной плотности не могут быть записаны на дисководе высокой плотности (360 RPM). Однако, благодаря высокой сопротивляемости к ошибкам данных, записанных в режиме FM, диски одинарной плотности до сих пор могут быть прочитаны в 360 RPM дисководе. FM-дискетты могут быть прочитаны и записаны на 360KБ (300 RPM) дисководе. При чтении 3F7 указывает изменении состояния дисковода: установлееный бит 7 ( TEST AL, 80H ) означает, что дискетта была сменена. Индикатор смены носителя сбрасывается после первого поиска цилиндра, отличного от нулевого. Очевидно использование в методах защиты от копирования при участии регистра 3F7 возможности регулирования положения битовой ячейки. Поскольку FDC переключается на новую скорость передачи почти мгновенно, переключение скорости передачи в рассчитанный момент времени сдвигает битовую ячейку на небольшую часть его длины. Эта технология позволяет читать любую часть дорожки, при условии, что по меньшей мере одно правильное поле данных существует и позиция интересующей части приблизительно известна. 1.2.5 "Нормальный" формат гибкого диска PC Первые стандартные гибкие диски PC использовались как односторонние или двусторонние с 40 дорожками. Согласно спецификации фирмы Intel, они имели 8 секторов длиной 512 байт на дорожке, таким образом, использовалось 4096 байт (65%) из 6250 байт неформатируемой емкости дорожки. Сектора на дорожке были расположены последовательно (чередование 1:1), как и во всех других стандартных форматах. Более современные дискетты используют 9 и 10 секторов на дорожке или 74% и 82% дискового пространства соответственно. Теоретический предел емкости форматируемой дорожки двойной плотности составляет около 89.2% (5575 байт или 10.89 секторов на дорожке). Такое приращение емкости гибкого диска стало возможным благодаря высокой стабильности скорости вращения в современных дисководах. Хотя отклонения в 2.5% от номинального разрешены IBM, я никогда не видел дисковод со скоростью вращения, выходящей за пределы 0.2% от номинала. Такая стабильность позволяет уменьшить длину межсекторного промежутка. К примеру, если возможные отклонения в скорости вращения составляют ё2.5%, можно зарезервировать межсекторный промежуток, достаточный для размещения сектора любой длины. Предполагается, что диск был отформатирован на дисководе с самой наивозможно медленной скоростью вращения, но может может корректироваться на дисководах с более быстрой скоростью вращения. В этом случае можно зарезервировать по меньшей мере (512+62) * (2*2.5%) байт для межсекторного промежутка (62 - это размер минимального заголовка сектора в формате MFM). Это в результате дает минимальный промежуток в 29 байт, следовательно, формат 10 секторов на дорожке вполне хорош для таких отклонений. В порядке поддержки совместимости (по меньшей мере, частичной) с 40 дорожечным форматом на 80 дорожечном HD дисководе, он пропускает все нечетные дорожки. Поэтому 360K-диски записанные на 360K дисководе, всегда могут быть прочитаны в HD дисководе, но 360K-диски, записанные на HD дисководе могут быть несовместимы с 360K дисководом. Поскольку ключевые дискетты почти всегда готовятся на 360K дисководе, мы далее пропустим все форматы высокой плотности. 1.3 Времянезависимые способы защиты от копирования Здесь мы рассмотрем методы пометки защищенных гибких дисков, которые могут быть проверены без использования устройств, отличных от FDC. Эти способы работают на любом системном оборудовании с совместимым FDC. Кстати: когда я упоминаю какой-либо побитовый копировщик, это упоминание может относится не к последней версии. Во всяком случае, эти версии может быть в это время просто не существовали. Я имею копии (нелегальные копии, как указано в предисловии) Copy II - PC release 7.10, CopyWrite September 1988 edition и TeleDisk v 2.11. Заметьте: Термин "не может быть воспроизведен" по отношению к тому или другому способу пометки защищенного диска означает не наличие физических ограничений в аппаратуре PC, но пределы моих знаний по этому вопросу. Я буду признателен всем, кто расширит эти пределы. 1.3.1 Внешний или пропущенный сектор Ввиду того, что первые гибкие диски MS-DOS имели участок неиспользованного пространства на дорожке, это было использовано как очевидная идея для хранения на дорожке добавочных секторов вместе со стандартными секторами MS-DOS. Даже в хорошо упакованном формате 10 секторов на дорожку находится место для одного 256-байтного сектора. Другим местом может служить для добавочных секторов может быть дорожка 41, которая не используется DOS, но доступна на большинстве дисководов. На 80 дорожечном устройстве, дополнительные сектора может быть скрыты на нечетных дорожках. Сейчас этот способ пометки не может рассматриваться как хорошая защита от копирования, поскольку внешние сектора могут быть легко найдены командой чтения ID сектора. Любой из представленных на рынке побитных копировщиков (CopyWrite, CopyIIPC, TeleDisk, и т.д.) может это сделать. (Но в тоже время сектора на нечетных дорожках не могут быть найдены подобными программами). Для рассмотрения более тонких вариаций этой схемы см. секции 1.3.4-1.3.8. 1.3.2 Слабая запись данных Это другой старый добрый метод защиты данных, который проявляется в в кажущемся различии данных во время последовательных операций чтения (слабые данные). Слабые данные могут появится в одном из двух случаев: либо данные попадают в цифровой "район неуверенности", либо посредством длинной серии нулевых данных и пропущенных синхробитов. В первом случае, на решение FDC может повлиять случайный шум. Во другом случае, случайные вариации в скорости вращения могут привести к сдвигу битовой ячейки относительно синхронизации. (Такие данные не могут быть записаны без аппаратных изменений в FDC, и мы не обсуждаем это здесь). Один хороший способ создания слабых данных состоит в помещении их на дефектную поверхность. Тогда слабые данные не могут исчезнуть после команды записи данных сектора. К сожалению (даже!), заводские дефекты на поверхностях сейчас редко встречаются, поэтому они производятся вручную. Я видел всякие разновидности этой технологии, от дисков, исцарапанных ржавым гвоздем, до осторожного испарения поверхностного слоя при помощи инфракрасного лазера мощностью 1 kVA. Как бы то ни было, но более трудно обстоит дело с программным обеспечением. Слабые биты данных могут быть созданы также и программным путем. Первый подход состоит в манипулировании битами выбора дисковода в регистре цифрового вовода (3F2H). К примеру, если вы желаете создать слабый байт на дисководе A:, начните операцию записи, подождите, пока желаемый байт будет передан на дисковод (но не FDC!) и повторяйте загрузку в цифровой регистр значений 1DH (выбор дисковода 1) и 1CH (выбор дисковода 0) пока байт будет передаваться. Такие действия приводят к тому, что все данные (включая синхробиты), записанные на диск, попадают в район "неуверенности". Второй подход состоит в выполнении почти техже самых операций с регистром управления дискеттой (3F7H). Переключение скорости передачи приводит к потере бит данных и синхробитов и деформирует их форму, также приводя к помещению их в район "неуверенности". Обнаружив слабые данные, побитовый копировщик оказывается перед интересной дилеммой: то ли последовательность слабых битов является неопознанным дефектом поверхности и операцию следует повторять пока не будут восстановлены подлинные данные, или же это метка защиты, которая должна быть воспроизведена во всей красе? Из всех встреченных мной побитовых копировщиков, только CopyWrite оказался способен справится со слабыми данными, и хотя он конвертирует один слабый байт где-то в 10-12 байт, так подлинная метка может быть легко обнаружена и на копии. Вообщем, слабые данные не такая плохая вещь для дешевой защиты и, они, что очевидно, всплывают в доморощенном (советском) программном обеспечении. 1.3.3 Данные в промежутке Можно легко запомнить небольшое количество данных в промежутке после поля данных сектора (в GAP 3). При условии, что сектор не переписывается, метка может находится в промежутке как угодно долго. Наибольшее количество байт данных, которое может быть размещено в GAP 3 задается значением GPL в команде форматирования дорожки. Проверка такой метки проста (по крайней мере для первого сектора на дорожке) - команда чтения дорожки с N на единицу большим, чем актуальное значение в ID сектора загружает данные из промемутка в память. Запись данных в промежуток является более тонкой процедурой. Предположим, некто желает записать 10 байт данных в промежуток после первого 512-байтного сектора на дорожке 0 стороны 0. Во-первых, он должен отформатировать дорожку 0, задав длину первого сектора кодом 3 (1024 байта) в ID сектора, но указать код 2 в параметрах форматирования. Затем он должен начать операцию записи в этот фиктивный сектор, но остановить ее после передачи 526 байт (512 байт - данные сектора + 2 байта CRC + 10 байт данных в промежутке + 4 байта для сохранения границы). Затем он должен начать операцию форматирования дорожки с кодом длины 2 (и в параметре форматирования и в ID сектора) и прекратить ее где-то внутри GAP 2 (ID сектора уже записан, но поле данных еще не достигнуто). Обе операции (форматирования и записи) могут быть остановлены одним из двух способов сброса контроллера: либо посылкой 0 в регистр цифрового вывода, 3F2H), либо сменой выбранного дисковода (см. 1.3.2). К сожалению, могут быть иногда трудности при различении между "пустым" промежутком и промежутком, содержащим данные защиты. Старые дисководы имеют относительно большой период ослабления сигнала записи, так что промежуток, записанный на таком устройстве, будет заполнен случайным мусором, который может быть неверно интерпретироваться как данные защиты. Эти трудности могут возрасти, если создатель системы защиты использует слабые биты (1.3.2) внутри промежутка с данными защиты. Среди упомянутых копировщиков только CopyWrite способен обнаружить данные в промежутке. Одно странное исключение составляет первый сектор дорожки 0 на стороне 0, который предусмотрительно игнорируется CopyWrite как место размещения данных в промежутке. 1.3.4 Секторы без адресной метки данных Сектора без адресной меткки данных могут порождаться при игнорировании ошибки AM данных (устанавливаются биты MA в ST0 и MD в ST2) во время операции чтения и записи данных. Команда чтения ID сектора завершается нормально на таком секторе. Сохранение сектора без AM данных требует простой операции форматирования, которая должна быть остановлена после записи AM ID сектора, но раньше записи AM данных (как в 1.3.3). Особой заботы требуют ранее созданные AM данных, которые могут быть удалены с диска либо электромагнитным путем, либо при помощи предварительного форматирования с другой скоростью передачи. Альтернативный способ (который не работает для первого сектора на дорожке) состоит в следующем: во-первых, форматируется дорожка со значением GPL, выбранным так, чтобы разместить поле данных там, где AM поля данных начнется на результирующем диске. Во-вторых, переформатируется дорожка с желаемым значением GPL, и операция останавливается перед записью AM сектора. 1.3.5 Секторы без адресной метки ID Секторы без AM ID сектора могут получены следующим способом: форматирование дорожки, запись кода длины N+1 для сектора перед интересующим. Потом чтение этого фиктивного сектора и запись его обратно, операция прекращается когда AM ID сектора уже переписана, а AM данных не тронута. Таким образом вы получили сектор без AM ID. Такой сектор НЕ может быть извлечен какой бы то ни было операцией FDC без всяких исключений. Его не может быть, обычно говорят, чтение любой командой проходит без особых забот, так что он почти не существует. Ни один из проверяемых копировщиков не был способен обнаружить такой сектор (но любой аппаратный копировщик может быть способен его воспроизвести), так что пропущенная AM ID cектора может рассматриваться как хорошая защита. Тем не менее, трудности проверки делают появление такой метки в "живой" защите в высшей степени неправдоподобным. (Но см. 1.3.10). 1.3.6 Секторы с адресной меткой ID плохого сектора Эта метка отличается от рассмотренной в 1.3.5 только степенью испорченности AM ID. В данном случае FDC все же способен обнаружить AM ID, но при проверке CRC оказывается ошибочным. Метка такого рода не может быть найдена командой чтения ID сектора, но при установленном бите DE в ST1 и сброшенном бите DD в ST2 во время выполнения команды чтения сектора с известными значениями C/H/R/N проверка не представляет проблемы. Сектор с плохой AM ID тем не менее обнаруживается и в команде чтения дорожки. Когда точные значения C/H/R/N не известны, они могут быть получены следующим способом: зная точно положение поля данных из интервалов времени, можно приблизительно рассчитать место AM ID и прочитать ее, используя способ выравнивания битовой ячейки (см. 1.2.4). Ценной для создателей защит от копирования модификацией этой метки является метка с неверным CRC ID сектора и отсутствующей AM данных. Такой сектор приведет к завершению команды чтения дорожки, тем самым предотвращая обнаружение копировщиком расположенной после метки данного типа "нормальной" метки. Для получения плохой AM ID, нужно остановить операцию форматирования во время записи CRC AM ID сектора. (Позвольте мне снова заметить, что внутренний буфер FDC составляет что-то около 3 байт, так что контроллер начинает записывать CRC не тогда, когда последний байт ID считан из DR, а некоторое время после этого). CopyWrite обнаруживает сектора с плохой AM ID и копирует их. 1.3.7 Поле данных, перекрывающее адресную метку индекса Защитная метка такого типа появится тогда, когда кто-нибудь спросит: что будет делать FDC, если указанная в команде форматирования дорожки общая длина данных немного больше того, что способна вместить дорожка? Рассмотрим следующие результаты, полученные при форматировании дискетты DD в дисководе HD на 13H 256-байтных секторов с различными значениями 3 (Смещение сектора измерялось относительно индексного отверстия). Замечу, что период обращения используемого дисковода составлял 166.52 mс. Таблица 1.3.7 ┌───────────────┬────────────────────┬──────────────────────┐ │значение GAP 3 │ смещение сектора 1 │ смещение сектора 13H │ │ │ начало │ начало конец │ ├───────────────┼────────────────────┼──────────────────────┤ │ 01H │ 3.849 │ 156.981 165.46 │ │ 08H │ 3.844 │ 160.334 2.29 │ │ 10H │ пропущен │ 164.180 6.14 │ │ 14H │ пропущен │ пропущен │ │ 18H │ пропущен │ 1.519 10.00 │ └───────────────┴────────────────────┴──────────────────────┘ Здесь можно видеть, что есть небольшой участок дорожки, который не используется данными сектора. (Обычно этот участок используется под адресную метку индекса). Этот участок может быть перекрыт последним сектором на дорожке (как показано на строке 2 таблицы 1.3.7), но если данные последнего сектора перекрываются с началом дорожки слишком сильно, сектор 1 будет удален (строка 3). Если начало поля данных последнего сектора пройдет над индексным отверстием (строка 4), контроллер запишет GAP 4 после следующего появления индексного отверстия, что приведет к перезаписи всех существующих секторов на дорожке. Если же начало AM ID сектора проходит над индексным отвестием (строка 5 таблицы), этот сектор будет записан, но предварительно будут переписаны все предыдущие сектора. Сектор, проходящий над IAM, может вызвать большие проблемы для побитовых копировщиков, не подозревающих о его существовании, поскольку много защитных меток создается посредством повторения команды форматирования, которая уничтожает данные в секторе над IAM. Не один из проверяемых копировщиков не был способен воспроизвести такой сектор (т.е., сохранить и данные сектора и местоположение сектора), так что метки этого рода могут широко использоваться в советских системах защиты от копирования. 1.3.8 Дорожки с разными параметрами Как мы увидели в предыдущем разделе, FDC игнорирует IAM в начале дорожки, так что сектор может находиться на дорожке на любом месте. Ввиду этого очевидная идея состоит в том, чтобы разделить дорожку на части, записанные при разной скорости передачи данных. (Это лучше сделать не переключая скорость передачи данных во время операции форматирования, а посредством двух последовательных форматирований на различных скоростях). К примеру, можно иметь на нулевой дорожке 9 секторов по 512 байт, записанных при скорости 300 KBPS (дисковод HD) и один 512-байтный сектор, записанный при скорости 500 KBPS. (Это на дорожке качественной дискетты, а на дисках двойной плотности при использовании высокой скорости передачи не следует помещать данные так далеко). Хотя различные скорости передачи данных всецело относятся к AT, метку, подобную вышеприведенной, можно создать используя форматирование как по методу FM, так и по методу MFM (т.е., к примеру 9 MFM-секторов и один FM) на PC и XT. Ни один из проверенных битовых копировщиков не смог воспроизвести такую разноскоростную дорожку, так что это пока весьма хороший способ. Тем не менее, я до сих пор не видел защиты, опирающейся на подобную дискеттную метку. 1.3.9 Данные, перекрывающие промежуток Сейчас мы перейдем к самому популярному (и, возможно, самому лучшему) способу защиты от копирования, который использует данные, перекрывающие промежуток. Поскольку все ID секторов и поля данных синхронизируются раздельно, две битовых ячейки в двух последовательных полях могут быть произвольно сдвинуты. Подобный сдвиг может вызываться случайными вариациями в WR CLK и скорости вращения, таким образом, они не могут быть проконтролированны. (Конечно, можно вообразить АНАЛОГОВОЕ копирующее устройство способное это сделать. Но я никогда ни о чем подобном не слышал.) Любая операция чтения дорожки с достаточно большой длиной кода (говорят, 6) дает "след на дорожке". Количество различных "следов" можно грубо оценить следующим образом: предположим, что каждое место соприкосновения различно синхронизированных полей может иметь два различных состояния (очевидно, что это недооценка). На дорожке обычной дискетты двойной плотности имеется 19 таких мест (9 ID AM, 9 AM данных, 1 IAM), так что количество различных "следов" на каждой дорожке по меньшей мере 2^19 ў 500 000. Чтобы поставить перед аналоговым копирующим устройством более трудную задачу, можно расширить длину кода (говорят до 7). Это не увеличит количество "следов", но захватит дорожку более одного раза. Поскольку лучшие из устройств могут начать и остановит операцию в любом месте, это может привести к частичному разрушению данных. Такая метка имеет одно ограничение на использование защищенного диска: ключевая дорожка не может быть перезаписана. Другой, менее интересной, разновидностью этой идеи является чтение AM ID следующего сектора через GAP 3 и проверка, изменилась ли она. Такая проверка запрещает запись только в один сектор на дорожке. Очевидно, создатели защит не ограничиваются извлечением "следов" посредством команды чтения дорожки (и, таким образом, доступом к "железу" на уровне чипа). Можно просто добавить фиктивный сектор с длиной кода 6 или 7 в конец дорожки, и эту работу может выполнить BIOS. Ни одна из этих проверок не может быть воспроизведена на стандартном оборудовании PC. И все же, много программ, использующих вторую разновидность этого способа, посредством расширения GAP 3 после интересующего сектора и записи AM ID, это может быть реализовано как чтение через промежуток,так и в этот промежуток. Если программа не проверяет точно расположение сектора на дорожке, она вполне может принять такую "копию" ключевого диска. 1.3.10 Параноидальные идеи Все ранее рассмотренные способы защиты предоставляют возможность неразрушающей проверки меток. Здесь же позвольте мне представить метку защиты, которая не может быть проверена или обнаружена копировщиками без предварительной записи на ключевой диск. Вспомните сектор без AM ID (пункт 1.3.5). Что мы получим, если нет других секторов на интересующей дорожке (или по крайней мере записанных при той же скорости передачи)? Такой сектор не может быть прочитан, до тех пор, пока не будет проведена операция форматирования дорожки, которая снабдит ID AM. Любой пошаговый доступ внутрь программы при помощи отладчика приведет к разрушению метки защиты, поскольку крайне важное время остановки операции форматирования будет изменено из-за отладчика. Этот простой пример показывает, что возможны метки защиты, которые не могут быть вытащены с ключевого диска без разрушения части его содержимого или без знания тонкостей способа защиты. 1.4 Способы защиты, опирающиеся на временные параметры Все PC оснащаются относительно хорошим чипом таймера, Intel 8253 или его функциональным эквивалентом. Работая с частотой 1 193 180 Гц, он позволяет измерять интервалы времени с разрешением 840 наносекунд (т.е. он может измерить время выполнения ОДНОЙ команды деления на 16 МГц-ном 386, которое может составлять до 2.4 мс). Такой таймер более чем соответствует требованиям измерения интервалов времени для гибкого дисковода (передача одного байта данных на самой быстрой из возможных скоростей (500 KBS) занимает 16 мс), так что точность подобных измерений ограничивается не разрешением таймера, а случайными колебаниями скорости вращения диска. 1.4.1 Проверка чередования секторов на дорожке Измерение времени завершения последовательно выполненных комманд чтения дорожки может указать точную позицию каждого сектора на дорожке. В отношении бит данных Вы можете определить позицию сектора с точностью по меньшей мере в один бит. Поскольку контроллер при выполнении команды форматирования дорожки управляет позицией с разрешением в байт, то при этом невозможно воспроизвести так точно, как нужно, расположение секторов. Таким образом, одно только расположение секторов можно использовать как метку защиты. Однако проверка такой метки очень чувствительна к скорости процессора и стабильности вращения дисковода и часто такая проверка бракует и оригинальный ключевой диск. Таким образом, позиция сектора обычно используется как дополнение к другой (другим) меткам защиты. (См. 1.3.9). 1.4.2 Измерение времени передачи данных Cкорость передачи данных FDC задается регистром управления дискеттой (3F7H) только при инициализации, или, другими словами, задается частота, используемая FDC в процессе декодирования битов. Специальная аналоговая схема, именуемая фазозапорной петлей (PLL), регулирует скорость так, чтобы поступали неискаженные биты данных. PLL выдерживает по меньшей мере 4% отклонения от номинальной частоты (разрешенное отклонение скорости вращения составляет ё2%). На практике, PLL будет копировать с 10% отклонениями для MFM дисководов и почти 100% для FM. Скорость прибытия бит данных определяется угловой плотностью данных и скоростью вращения дисковода, так для определения характеристики диска (угловой плотности данных) нужно измерить скорость передачи содержимого одного сектора и скорость вращения. Максимальная точность такого измерения может быть легко оценена: один 512-ти байтовый сектор будет передан на на частоте 500 KBS за 8.2 мс, разрешение таймера в 0.84 mс дает относительную точность в 0.01%. Относительная ошибка в определении скорости вращения тем меньше, чем меньше порядок величины. Имеется 10 факторов, влияющих на величину отклонения и 0.1% кажется вполне разумной оценкой. Так, все накопители на гибких дисках PC подразделяются на 40 (2*2%/0.1%) различных групп, и дискетты, записанные на дисководах одной группы, можно легко отличить от дискетт, записанных на дисководах другой группы. К сожалению (в данном случае!), большинство современных дисководов попадают в область отклонений ё0.2% и, таким образом, в 4 группы вместо 40, почти исключая этим все "защиты". Некоторые FDC (например мой старый 1986 WD HDC/FDC) позволяют сделать такую простую штуку с выводным регистром 3F2H: выдать 0CH в 3F2H (остановить мотор дисковода A:), подождать 10 мс, выдать 1CH в 3F2H (включить мотор дисковода A:) и сразу выполнить операцию записи. Скорость вращения дисковода будет слегка меньше номинальной около 20 мс, что позволяет записать один сектор. Мой новый IDE HDC/FDC 1990 года, однако, ожидает пока скорость вращения достигнет номинальной, задерживая операцию записи. Интересные вариации этого способа могут быть использованы при небольших модификациях аппаратуры PC (см. 1.5.3). 1.5 Защита с применением специального оборудования Я не специалист по аппаратуре, используемой для защиты от копирования, так что нижеобсуждаемое здесь почти полностью опирается на слухи и умозрительные рассуждения. 1.5.1 Модифицированный MFM метод Чип FDC Intel 8272A не имеет программного контроля над величинами GAP1, GAP2 и GAP5, но до сих пор принимает дискетты с этими промежутками, отличающимися от стандартных величин и способен измерять действительную величину этого промежутка. Например, GAP2 (промежуток после ID) может быть измерен либо при помощи команды чтения дорожки с кодом длины, больше действительной длины сектора, либо измеряя различия во времени завершения команд чтения ID сектора и чтения данных. Дискетты с различным значением промежутка могут быть созданы для PC на компьютерах других типов, которые имеют контроль над этими параметрами. (Я слышал, что некоторые из систем фирмы DEC делают нечто подобное.) 1.5.2 Потерянные дорожки Некоторые из флоппи контроллеров/дисководов могут более точно управлять положением головки чтения/записи. (Я уверен, что требуемые для этого аппаратные изменения не слишком велики.) Сначала это может быть сделано не с целью защиты от копирования, а для того, чтобы иметь возможность читать дискетты, записанные на плохо отрегулированном дисководе. (Кстати, я слышал, что FDC ICL имеет такую возможность.) Следовательно, ключевой диск для таких машин может иметь нестандартно расположенную дорожку (и программу, способную определить это). Такой диск не может быть проверен на других машинах, так что подобный способ может иметь только ограниченное применение. 1.5.3 Нестандартная скорость передачи Как мы рассмотели в 1.4.2 FDC допускает значительные изменения в угловой плотности данных на дорожке (и способен ее измерить). Небольшие изменения FDC или дисковода дают возможность непосредственно контролировать частоту генератора WR CLK или скорость вращения дисковода и это дает возможность записывать данные на несколько нестандартной (но до сих пор приемлемой для большинства контроллеров) скорости передачи данных. Некоторые из изготовителей аппаратного обеспечения (например, научного оборудования со встроенными микрокомпьютерами) делают это специально, чтобы "заарканить" покупателей. (Я видел 3-х дюймовые дисководы с 360 RPM, которые были несовместимы ввиду этого с "нормальными" 3-х дюймовыми дисководами на 300 RPM.) 1.6 Примеры различных реализаций защиты Сведения по внутренней организации различных схем защиты, рассматриваемые здесь, опираются на мои личные эксперименты с программами защиты (если другое не указано), так что эти сведения не могут рассматриваться как законченные и не могут раскрыть всех аспектов и всех версий обсуждаемых программ защиты. Все обсуждаемые программы защиты исследовались при помощи Copy Unprotector Toolkit (C.U.T.). 1.6.1 IBM Filing Assistant Эта очень простая и открытая защита датируется 1986 годом. Она не имеет какого-либо практического значения и упомянута здесь единственно ради демонстрации развития систем защиты на протяжении последних лет. Эта программа "защиты" проверяет присутствие сектора 8FH с кодом длины 2 на 39-ой дорожке 1-ой стороны ключевой дискетты. Больше никаких проверок не проводится. Поскольку первая версия CopyWrite была выпущена в 1985 году (и была способна копировать такие метки), только надежда на дубовость "этих русских обезьян" может оправдать появление такой защиты. 1.6.2 SuperLok Superlok-диск, который я смог получить датируется 10 октября 1986 года. Защищенный диск содержит три дорожки, "ненормально" размеченные (и все на нулевой стороне). Первой из них была 5-ая дорожка, которая имела необычное чередование и два сектора с короткими данными, так что идентификаторы секторов образовали следующую последовательность (все значения шестнадцатиричные): 05/00/01/02, 05/00/06/02, 05/00/8A/03, 05/00/02/02, 05/00/07/02, 05/00/65/03, 05/00/03/02, 05/00/08/02, 05/00/04/02, 05/00/09/02, 05/00/05/02 Как оказывается, SuperLok не проверяет эту дорожку вообще, так что она является разновидностью ловушки для любопытного исследователя. Второй защищенной дорожкой на дискетте является дорожка 12H. Она содержит сектор со скрытой адресной меткой (см. 1.3.6) с ID 7B/46/05/00, который SuperLok проверяет посредством команды чтения данных. Другая проверка защиты на этой дорожке совершается командой чтения дорожки с кодом длины 6 (один 8192-байтовый сектор) и 3 (два 4096-байтовых сектора). 16-ти битовая контрольная сумма рассчитывается в обоих случаях и сравнивается с запомненным значением (см. 1.3.9). Третья защищенная дорожка содержит четыре специальных сектора. Первый из них имеет скрытую AM сектора и не имеет AM данных, что служит для предотвращая обнаружения других секторов. Три сектора имеют скрытую AM: 21/47/05/00, A5/86/81/04 и EB/76/EE/04. После их проверки SuperLok выполняет чтение дорожки с кодом 6 и 3, после чего вычисляет 16-ти битовые контрольные суммы. Таким образом, SuperLok представлет собой хорошую защиту от копирования. Ни один из проверенных копировщиков не оказался способен скопировать защищенный диск "дословно" без модификации областей данных SuperLok (и равно, внутренних данных программы). Вероятно, такое "буквальное" копирование просто невозможно (см. 1.3.9). Позднее я имел возможность бросить взгляд на SuperLok-диск, датированный 1990 годом. Проверка скрытой AM сектора была удалена (?), доступ к метке защиты через чтение дорожки был заменен (?) на добавочный сектор с кодом длины 6 при том же самом конце дорожки. Весь (?) доступ к дискетте был сделан при помощи BIOS. 1.6.3 Cops CopyLock II COPS CopyLock II опирается в защите на измерение временных интервалов. Она использует добавочный сектор 00/00/6A/01 на дорожке 0 стороны 0 для сохранения значений данных защиты. (COPS CopyLock позволяет повысить уровень реализации программы защиты без соответствующего повышения уровня защищенности ключевой дискетты, так как она не может запомнить более данных, чем серийный номер в теле программы). Второй добавочный сектор располагается на нулевой дорожке (00/00/F6/02), имеет частично перекрытую IAM, использутся для проверки перекрытия AM 1-го ID промежутка (см. 1.3.9). В порядке предотвращения обхода защиты а-ля 1.3.9, CopyLock проверяет позиции всех (?) секторов на дорожке посредством измерения времени выполнения команд чтения ID сектора. Дорожки с 1 по 6 весьма сходны: они имеют два добавочных сектора в конце дорожки: XX/00/14/01, который не используется (?) и XX/00/13/02, который перекрывает IAM и проверяется подобно 00/00/F6/02. Дорожки с 7 по 9 имеют один добавочный сектор (XX/00/14/01) каждая. Эти сектора не используются (?). На исследуемой дискетте я обнаружил дефект поверхности на дорожке 32 стороны 1, но CopyLock не проверяет его наличие, так что я не думаю, чтобы это была другая метка защиты. Это еще один пример хорошей схемы защиты, хотя это достигается другими способами, чем в 1.6.2. И все же, при помощи C.U.T. я смог сделать ради интереса незащищенную версию программы (это был Парадиск СП ПараГраф) за время около двух часов. Я не думаю, что развитие CopyLock уменьшит это время. Хотя я имею копию COPS CopyLock III, у меня до сих пор не было времени для ее изучения, так что мне продолжает так казаться ... 1.6.4 PC Shield Эта (доморощенная) схема защиты изобретена Алексом Симкиным. Ее появление сопровождалось большой рекламой в советских средствах массовой информации. Я имел возможность исследовать с полдюжины версий этого продукта и, таким образом, проследить постепенное развитие программы. Первая версия PC Shield использовала простую метку сектора, перекрывающую IAM исключительно на нулевой дорожке. Это одурачивало почти всех копировщиков, которые определяли эту метку как укороченные данные (половина сектора после индексного отверстия, не так ли?) и таким образом разрушали ее. Но все же эта метка может быть легко записана при помощи обычного обращения к BIOS (не говоря уже о новых версиях копировщиков), и таким образом, защита будет взломана. Следующим шагом был доступ к AM ID первого сектора через промежуток (влияние COPS?). Сначала код длины 2 (512 байт) был выбран для этого добавочного сектора. Эта метка может быть взломана способом, описанным в 1.3.9 (хотя там ничего более, кроме запроса к BIOSу). И сейчас, последний шаг - код длины сектора увеличен до 6 (влияние SuperLok?), что затрудняет (но не делает все же невозможным) воспроизведение этой метки посредством BIOSа. Очевидно, это не препятствие для хорошей программы копирования, и C.U.T. легко изображает такую метку. Дальнейшее развитие этой схемы защиты может пойти двумя путями: включение проверки расположения сектора (как в 1.6.3) или чтение всей дорожки через промежуток (как в 1.6.2). Второй путь, хотя и требует для целей защиты целой дорожки, кажется более вероятным, поскольку такое развитие не требует доступа к FDC на уровне чипа (все версии PC Shield, известные мне, используют для доступа к дискетте исключительно уровень BIOSа). 2. Защита, опирающаяся на жесткий диск Защита по ключевой дискетте предоставляет хороший уровень секретности, но она очень утомительна и сильно надоедает в ежедневном использовании, расточительна по отношению к дисководу и может быть легко разрушена при неправильном обращении. Поэтому большая часть защищенных пакетов может инсталлироваться на жесткий диск, используя в качестве защиты либо метку на жестком диске (что рассматривается в этой главе), либо особенности основной платы (глава 3). Ввиду существования различных типов физических интерфейсов жесткого диска, метки на жестком диске обычно являются "наименьшим общим знаменателем" различных возможностей и более открыты для вмешательства. 2.1 Защита на уровне чипа В высшей степени маловероятно, чтобы встретился этот уровень доступа к жесткому диску, так что мы лишь кратко обсудим WDC (контроллер винчестера) AT, исходя из моего небольшого личного опыта. Доступ к первому WDC AT может осуществляться по адресам 1F0-1F7 и 3F6 (этот порт находится и в адресном пространстве первого FDC AT, что хорошо иллюстрирует аппаратное противоречие в системе между FDC и WDC, выполненными на различных платах). Второй WDC AT захватывает адреса 170-177 и 376. WDC AT использует IRQ 14 (int 76h в MS-DOS) и НЕ использует DMA. Структура WDC AT выглядит очень похожей на операции чипа Intel 82062 в расширенном режиме с 4 байтами ECC (кода коррекции ошибки), добавленными к каждому сектору. (К сожалению, я имею лишь улучшенный информационный листок на 82062, так что нижеприводимое описание не может быть точным или исчерпывающим.) 1F0 - регистр данных, используется для чтения/записи содержимого сектора (512 байт). Хотя доступ к данным сектора может осуществляться пословно, только байты являются единственно приемлемой формой для записи ECC. 1F1 - чтение: регистр флагов ошибки ┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┐ │ BBD │ CRC │ 0 │ ID │ 0 │ AC │ TK0 │ DM │ └──┬──┴──┬──┴─────┴──┬──┴─────┴──┬──┴──┬──┴──┬──┘ │ │ │ │ │ └─── AM данных не найдена │ │ │ │ └───────── плохая рекалибровка: │ │ │ │ дорожка 0 не найдена │ │ │ └─────────────── команда прервана │ │ └─────────────────────────── ID AM не найден │ └─────────────────────────────────────── непонятая ошибка или │ AM данных не найдена └───────────────────────────────────────────── обнаружен плохой блок Рис. 2.1a Регистр флагов ошибки (1F1) 1F1 - запись: начало прекращения записи текущего цилиндра / 4, 0FFH запрещает использование этого. 1F2 - регистр подсчета секторов. Используется для задания количества секторов для передачи в многосекторных операциях - 1, т.е. значение 1 означает два сектора. WDC может корректно обрабатывать больше секторов, чем помещается на одной дорожке, соответственно корректируя номер головки и цилиндра. Во время операции форматирования дорожки указывается количество секторов, располагаемых на одной дорожке (0FFH соответствует 255 секторам). 1F3 - регистр количества секторов. Во время операции форматирования дорожки задает значения GAP 1 и GAP 3 (см. описание метода MFM в 1.1.3) минус 3 байта. 1F4 - 8 младших бит номера цилиндра. (Tech Help! 4.0 здесь неправ) 1F5 - 2 старших бита номера цилиндра (используются биты 0-1). Некоторые из контроллеров допускают использование более чем двух битов в этом регистре, поддерживая таким образом жесткие диски более чем с 1023 цилиндрами, но, во всяком случае, большинство BIOSов использует только эти два старших бита. 1F6 - выбор сектора/дисковода/головки. ┌─────┬───────────┬─────┬───────────────────────┐ │ EXT │ SIZE │ DRV │ HEAD │ └──┬──┴────┬──────┴──┬──┴─────┴─────┼─────┴─────┘ │ │ │ └──────────── головка (0-15) │ │ └─────────────────────────── привод (0-1) │ └───────────────────────────────────── код длины сектора: │ 00 = 256 байт │ 01 = 512 байт │ 10 = 1024 байт │ 11 = 128 байт └───────────────────────────────────────────── 0: используется CRC 1: используется ECC Рис. 2.1b SDH (Sector/Drive/Head) регистр (1F6). В оригинальной спецификации 82062 было зарезервировано 3 бита для поля выбора головки и 2 бита для выбора дисковода, но эти значения были проигнорированы внешними схемами, так что реально это не имеет значения. 1F7 - чтение: регистр состояния ┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┐ │BUSY │READY│ WF │ SC │ DRQ │ ECC │ CIP │ERROR│ └──┬──┴──┬──┴──┬──┴──┬──┴──┬──┴──┬──┴──┬──┴──┬──┘ │ │ │ │ │ │ │ └─── сумма ошибок (OR │ │ │ │ │ │ │ всех битов в 1F1) │ │ │ │ │ │ └───────── команда выполняется │ │ │ │ │ └─────────────── данные ECC-корректны │ │ │ │ └───────────────────── запрос данных (буфер │ │ │ │ ожидает данные) │ │ │ └─────────────────────────── поиск завершен │ │ └───────────────────────────────── плохая запись │ └─────────────────────────────────────── WDC готов └───────────────────────────────────────────── WDC занят (все другие биты при этом некорректны) Рис. 2.1c Регистр состояния (1F7) 1F7 - запись: регистр команды. Сюда записывается код команды. Набор команд FDC AT (который перекрывает набор 82062), используемый для работы с жестким диском, включает следующие команды: 0 0 0 1 R3 - R0 Возврат на дорожку 0 └─────┴─────┴─────┴─────┴───────────────────────┘ 0 1 1 1 R3 - R0 Поиск └─────┴─────┴─────┴─────┴───────────────────────┘ 0 0 1 0 I M E T Чтение сектора └─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘ 0 0 1 1 0 M E T Запись сектора └─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘ 0 1 0 0 0 0 0 0 Просматривать ID └─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘ 0 1 0 1 0 0 0 0 Форматирование └─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘ 1 0 0 1 0 0 0 0 Диагностика └─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘ 1 0 0 1 0 0 0 1 Установка параметров └─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘ дисковода R3-R0 определяют шаговую скорость дисковода, которая составляет 0.035+0.5*R мс для частоты 5 MHz. (Мои эксперименты с WDC AT показали, что это значение игнорируется контроллером, который позиционируем головку чтения/записи на максимально возможной скорости, используя аппаратный интерфейс завершения поиска). I = 0 запрос прерывания на DRQ активен, так же как после завершения команды, I = 1 запрещает прерывания активного DRQ. M = 1 задает многосекторную передачу, количество секторов указывается в регистре подсчета секторов. E = 1 запрещает корректировку данных и пропускает 4 байта ECC после данных сектора. T = 0 разрешает повторную попытку передачи, т.е., если указанный сектор не был найден после 6 оборотов, WDC выполняет автоматически команду просмотра ID, корректирует внутренний номер цилиндра, выполняет поиск, если это необходимо, и повторяет операцию. При T = 1 генерируется ошибка, если указанный сектор не был найден после двух оборотов. 3F6 - запись: регистр режимов. Запись 02h снимает WDC IRQ 14 с с системной шины, 00h резюмирует нормальные операции. 04h сбрасывает контроллер. Способ форматирования WDC гораздо менее гибкий, чем у 8272, и допускает произвольное задание лишь номера сектора. Хотя AM ID содержит, как положено, значения номера цилиндра, головки и код длины сектора, они извлекаются из командных регистров WDC и не могут быть напрямую указаны. Поскольку все команды WDC (исключая команду поиска ID) имеют подразумеваемые характеристики поиска, эти значения весьма трудно модифицировать. Характеристики WDC AT, будучи, очевидно, благоприятны для нормальных операций на компьютере, сокращают возможные проверки для защиты от копирования к добавочному/пропущенному сектору (см. 1.3.1) и порядку следования секторов (см. 1.4.1). Коррекция данных ECC позволяет дополнить способы защиты жесткого диска третьим вариантом, при котором бит данных изменяется в заданной позиции, и скрывается посредством ECC. Все эти метки могут быть генерированы и проверены при использовании для доступа к диску уровня BIOSа, и, таким образом, доступ к WDC на уровне чипов не имеет достаточных выгод, оправдывающих отсутствие совместимости. 2.2 Защита на уровне BIOS Очевидно, это базовый уровень для защиты жесткого диска. Достаточное обеспечение скрытности от прослеживания TSR программами, цепляющихся к прерыванию 13H, может быть достигнуто в этом случае просмотром обработчика int 13H до тех пор, пока не будет найдена точка входа в BIOS (см. пример в приложении B). Другим способом обхода сторожей является возможно точное измерение интервалов времени при опрнделенном чередовании секторов. 2.2.1 Изменение чередования секторов Этот метод весьма схож с описанным в 1.4.1 для дискетт методом. В отличие от флоппи, где сектора, как правило, расположены последовательно (чередование 1:1), сектора на жестком диске при низкоуровневом форматировании часто располагаются так, чтобы обеспечить возможно большую скорость передачи данных. Вследствии этого на жестком диске труднее заметить метку чередования, чем на дискетте. 2.2.2 Изменение номеров секторов Этот метод повторяет описанный в 1.3.1. Однако сектора на жестком диске обычно плотно подогнаны, так что добавляя сектор с нестандартным номером, придется удалить один из секторов данных. Такая ситуация может быть легко обнаружена. 2.2.3 Неиспользуемые области диска На уровне BIOSа есть две неиспользуемые области почти на любом жестком диске: в самом начале диска и в самом конце. Первый сектор каждого жесткого диска (по меньшей мере, исключая SCSI или ESDI) используется под таблицу разделов, тогда как другие сектора нулевого цилиндра на дорожке 0 не используются по схеме расположения разделов фирм IBM и Microsoft. Однако эта область может быть использована программами, осуществляющими собственное разбиение на разделы. К примеру, DiskManager (dmdrvr.bin) использует сектор 0/0/8 для расширенной таблицы разделов, Olivetty MS-DOS начинает первый раздел DOS с сектора 0/0/2, и т.д. Вторая неиспользуемая область состоит из пользовательского диагностического цилиндра, который является следующим после последнего цилиндра диска на AT и последним на машинах типа находится PS/2. (Но они все же совместимы, не так ли?) Все записанное здесь имеет очень небольшие шансы на долгое существование, поскольку любая низко-уровневая тестовая программа имеет право распоряжаться этой дорожкой, как ей нужно. (Norton DiskTreet и Gibbson Research's SpinRite определяют оптимальное значение параметра чередования здесь, я проверял). 2.3 Защита на уровне DOS Защита на уровне BIOSа предоставляет не так много альтернатив, и DOS пока имеет удобные (и относительно переносимые) способы доступа к разделам DOS (использование int 25h/26h, функции ExtendedOpen (6Ch) в DOS 4.0+), которые могут быть использованы для защиты от копирования. Структура файловой системы DOS общеизвестна, так что я только кратко обозначу наиболее важные ее части. Сектор 0 - загрузочный сектор. Он содержит код, который загружает операционную систему и таблицу, описывающую характеристики раздела, такие как количество секторов, размер кластера, количество FAT, количество возможных файлов в корневом каталоге. Таблица размещения файлов (FAT), следующая далее, содержит 12-ти или 16-ти битовые значения для каждой единицы распределения дискового пространства (кластера), показывающие номер следующего кластера в цепочке. Обычно более чем одна (две) FAT присутствуют на диске, для пущей уверенности в сохранности данных. (Хотя DOS не обрабатывает копии FAT раздельно, а просто записывает первую FAT в дополнительных областях дублируя любую ошибку в первой копии FAT во все остальные, так что уверенность здесь на самом деле воображаемая). Корневой каталог (следующий после последней копии FAT) содержит таблицы размером в 32 байта для каждого файла в каталоге. Эта таблица содержит имя файла, размер и дату последней модификации файла и номер его начального кластера. Другие директории по этому методу распределяются как обычные файлы. 2.3.1 Зависимость от номера кластера Стандартные средства DOS не позволяют контролировать положение файла кластер за кластером, так что эта информация может быть использована для закодирования образа программы и/или данных. Номер стартового кластера может быть получен вызовом функции 11H стиля CP/M (FindFirst via FCB). (Вызов CP/M может быть скрыт от большей части сторожей посредством far call по адресу 0:0C0h с кодом функции в CL вместо AL.) Найти номера других кластеров можно просматривая FAT (См. пример в приложении C). 2.3.2 Неиспользуемые (зарезервированные) области диска В действительности имеется только одна такая область со смещением 0Ch в таблице описания файла (длиной 10 байт). К сожалению, эта область часто используется "совместимыми с DOS" операционными системами. К примеру, Digital Research DOS использует это поле для сохранения файлового пароля, PC-MOS/386 (Software Links) сохраняет здесь ID владельца файла, права доступа и дату и время создания файла. Другой неиспользуемой областью, которая может существовать на диске, является остаток последнего сектора в FAT 1, который резервируется DOS (и равно копируется во все остальные копии FAT). 2.3.3 Неиспользуемые (вследствие округления кластера) области диска Поскольку DOS распределяет дисковое пространство покластерно (каждый кластер содержит 2^N секторов), а размер файла измеряется в байтах, большинство файлов имеет неиспользуемый (и обычно невидимый на уровне файловой системы) хвост, который может быть использован для целей защиты. Странная накладка в DOS, которая позволяет просмотреть (функция DOS 42h) данные за концом файла, делает доступ к этому хвосту файла достаточно простым для высокоуровневых языков. (См. приложение D). 3. Защита, опирающаяся на системную плату и систему BIOS Другой частью PC, которая вместе с гибкими и жестким диском, всегда доступна для защиты от копирования, является системная плата. Хотя сейчас материнские платы изготавливаются сериями по много тысяч почти каждая из них имеет (или приобретает) индивидуальные качества. 3.1 Способы, базирующиеся на данных Каждая системная плата имеет собственный BIOS. Это может использоваться для защиты от копирования, хотя мы можем предположить, что в первую очередь это используется производителями аппаратного обеспечения, а не независимыми изготовителями программ.(Так, напичканный партией зашифрованных и недокументированных функций и таблиц системный BIOS, который так любовно взлелеян "голубым гигантом", есть разновидность защиты от копирования). Другой доступной областью данных на системной плате является энергонезависимая память CMOS, которая, как правило имеет порцию (с полдюжины байт) неиспользуемого пространства. Некоторые платы (к примеру, C&T) могут под CMOS память часть системного адресного пространства ROM памяти, вызывая таким образом появление "программного обеспечения, перепрограммирующего системный ROM BIOS". 3.2 Способы, базирующиеся на временных параметрах Более интересный способ защиты опирается на измерение внутренних временных характеристик системной платы. Три основные подсистемы доступны для таких измерений: CPU, память, подсистема ввода/вывода (См. приложение E). Фактические различия могут оказаться неожиданно большими (См. таблицу 3.2). ┌─────────────────────┬────────────┬─────────────┬───────────┐ │ Система │ CPU │ Память │ I/O │ ├─────────────────────┼────────────┼─────────────┼───────────┤ │ 25 MHz 80386 (A) │ 35972 │ 24576 │ 47292 │ │ 25 MHz 80386 (B) │ 35972 │ 24576 │ 49154 │ │ 20 MHz 80386 │ 44958 │ 30112 │ 59990 │ │ 12 MHz 80286 │ 3544 │ 41018 │ 46646 │ └─────────────────────┴────────────┴─────────────┴───────────┘ Таблица 3.2 Параметры системных плат четырех разных машин. Значения, показанные в таблице 3.2, являются усредненными, и получены после многократного запуска программы из приложения E. Действительные значения могут отличаться от означенных выше приблизительно на ё4. Системы (A) и (B) имеют два последовательных серийных номера, но могут быть легко отличимы друг от друга по временной характеристике ввода/вывода (Порт 0Ch, использовался первый контроллер DMA). Следует также заметить, что интервал времени ввода/вывода очень чувствителен к режиму процессора (реальный или защищенный), а временные параметры CPU и памяти почти одинаковы в обоих режимах. Словарик 82062 Контроллер винчестера (Intel WDC) 8237A Контроллер прямого доступа к памяти (Intel DMA controller) 8253 Микросхема таймера (Intel timer chip) 8259A Контроллер прерываний (Intel interrupt controller) 8272A Контроллер гибкого диска (Intel FDC) BC Ошибка плохой дорожки (bad track error), бит в ST2 BIOS Базовая система ввода/вывода (Basic Input/Output System) CB Контроллер занят (Controller busy), бит в MSR Cluster Единица распределения (кластер) в файловой системе, см. 2.3 CM Контрольная метка (Control mark), бит в ST2 CPU Процессор (Central Processing Unit), это - 8086, 80286,... CRC Циклический избыточный код (Cyclic Redundancy Code) DxB Дисковод х занят (Drive x busy), бит в MSR DD Ошибка данных (Data error), бит в ST2 DE Ошибка данных (Data error), бит в ST1 DIO Данные ввода/вывода (Data Input/Output), бит в MSR DMA Прямой доступ к памяти (Direct Memory Access) Double Density Двойная плотность, см. MFM DR Регистр данных (Data Register) 8272A. См. 1.2.1 DTL Длина передаваемых данных (Data transfer length), параметр команды 8272A. См. 1.2.3 EC Проверка оборудования (Equipment check), бит в ST0 ECC Код коррекции ошибки (Error correction code) EN Ошибка конца дорожки (End of track error), бит в ST1 EOT Конец дорожки (End of track), параметр команды 8272A. См. 1.2.3 FAT Таблица размещения файлов (File allocation table). См. 2.3 FDC Контроллер гибкого диска (Floppy disc controller). См. 1.1 FM Частотная модуляция (Frequency modulation). См. 1.1 FT Повреждение (Fault), бит в ST3. GPL Длина промежутка (Gap length), параметр команды 8272A. См. 1.2.3 HDC Контроллер жесткого диска (Hard Disk Controller) HLT Время загрузки головки (Head load time), параметр команды 8272A. См. 1.2.3 HUT Время разгрузки головки (Head unload time), параметр команды 8272A. См. 1.2.3 IAM Адресная метка индекса (Index address mark). См. 1.1.3 IC Код прерывания (Interrupt code), 2 бита в ST0 IRR Регистр запроса прерывания (Interrupt request register) 8259A. IRQ Сигнал запроса прерывания (Interrupt request signal) JV Совместное предприятие (Joint Venture) Kb Килобайт, 1024 байт KBPS Килобит в секунду (Thousands of bits per second) LSB Наименьший значащий бит (Least significant bit) MA Пропуск адресной метки (Missing address mark), бит в ST1 MD Пропуск адресной метки данных (Missing data address mark), бит в ST2 MFM Модифицированная частотная модуляция (Modified frequency modulation). См. 1.1 MSB Наибольший значащий бит (Most significant bit) MSR Главный регистр состояния (Main Status Register) 8272A. См. 1.2.1 ND Сектор не найден (Sector no found), бит в ST1 или не DMA (non-DMA), параметр команды 8272A. См. 1.2.3 NDM Передача в режиме не DMA (non-DMA transfer), бит в MSR NR Нет готовности (Not ready), бит в ST0 NW Ошибка записи на защищенную дискету (Write protect error), бит в ST1 OR Ошибка переполнения (Overrun error), бит в ST1 PLL Петля задержки фазы (Phase locked loop), цепь FDC. См. 1.4.2 RDY Готовность, бит в ST3 RPM Оборотов в минуту (Revolutions per minute) RQM Запрос главного (Request for master), бит в MSR RWC Уплотнение текущей записи (Reduce write current), способ, используемый при записи методом MFM. SC Счетчик секторов (Sector count), параметр команды 8272A. См. 1.2.3 SE Поиск окончен (Seek ended), бит в ST0 SH Успех поиска (Scan Hit), бит в ST2 Single Density Одинарная плотность. См. FM SN Безуспешный поиск (Scan not satisfied), бит в ST2 SRT Интервал шага (Step rate interval), параметр команды 8272A. См. 1.2.3 ST0, ST1, Байты состояния (Status bytes) 0-3 8272A. ST2, ST3 См. 1.2.2 STP Значение шага (Step value), параметр команды 8272A. См. 1.2.3 T0 Дорожка (Track) 0, бит в ST3 TC Конец счета (Terminal count) - сигнал, выдаваемый 8237A когда счетчик передачи в канале достигает нуля. TS Две стороны (Two sided), бит в ST3 WC Невеный адрес цилиндра (Cylinder address error), бит в ST2 WDC Контроллер винчестера (Winchester disk controller) WP Защита от записи (Write protect), бит в ST3 Приложение A. Простая программа для 8272A Текст программы содержится в файле test_fdc.c. Для компиляции достаточно Turbo C 2.0 и Turbo Assembler (любая версия). Минимально необходимая для запуска этой программы конфигурация состоит из машины 8 MHz/0 WS 80286 по крайней мере с одним дисководом. Программой тестируется дисковод, указанный в параметре программы (0 - A:, 1 - B:). Этот тест может быть использован и для второго FDC, следует лишь заменить FDC_BASE в исходном файле на 0x370. Команда 'T' (Анализировать дорожку) будет некорректно работать на дисководах со скоростью 300 RPM (360K, 720K, 1.44M) пока REVOLUTION_TIME в исходном тексте не будет заменено на 200L*2*1193 (но тогда она будет некорректно работать с дисководами на 1.2M). Приложение B. Простое упражнение по использованию HDC Текст программы находится в файле hd_scan.c, которому достаточно TC 2.0 и TASM для компиляции. Программе нужен ID дисковода (80 для первого дисковода, 81 для второго). Если программа виснет после выдачи сообщения: "Cyls = XXX, Heads = XXX, Sectors = XXX", то все программы кеширования диска должны быть удалены из памяти перед запуском этого теста. Приложение C. Как определить номер нужного кластера Текст программы содержится в файле cluster.c, так же требуется TC 2.0 и TASM для его компиляции. В качестве параметра задается полное имя файла (т.е., включая дисковод и имя каталога, так же и для файлов в текущем каталоге). Хотя эта программа была проверена под версиями MS DOS 3.20, 3.30, 4.00 и 5.00 (beta), она может не работать в других версиях MS DOS или в совместимых системах, поскольку реализована, опираясь на недокументированный DiskInfoBlock. Приложение D. Доступ к данным за концом файла Текст программы находится в файле tail.c. Хотя любой соответствующий ANSI компилятор его воспринимает, этот пример реализован на базе недокументированного применения функции seek() и может не работать с компиляторами, отличными от TC 2.0. Приложение E. Как различить системные платы Текст программы содержится в файле sysboard.c, для компиляции требуется TC 2.0 и TASM. Текущее значение параметра INSTRUCTIONS (16384) может приводить к переполнению счетчика времени на машинах ниже, чем 20 MHz 80386. Перевел Максим Петров, г. Оренбург