Ряд идей, изложенных в этой статье, помогут вам защитить ПО от несанкционированного копирования.

Существует весьма много простых и устойчивых признаков, которые можно было бы использовать для "привязки" программ к конкретным экземплярам IBM-совместимых ПК. И все же всякое оборудование несет следы технологии производства, делающие его уникальным. Параметры устройств ПК, зависящие от технологии изготовления, обычно имеют динамический характер и не обладают абсолютной воспроизводимостью. Их программное выявление и измерение подчас оказывается непростым делом. С определенными сложностями приходится сталкиваться и при попытке доступа к не используемым операционной системой областям памяти, в которых контролирующая часть защищенной программы (КЧЗП) может хранить свои данные. Рассмотрим способы решения указанных программных проблем и методы измерений параметров оборудования.

Создание ключевых меток

Метка за концом файла

При распределении дискового пространства операционные системы, использующие файловую систему MS-DOS, оперируют только с кластерами, состоящими из групп смежных секторов. Размер сектора в этой системе не может быть меньше 128 байт (обычно 512 байт). Число секторов в кластере зависит от вида магнитного носителя, но всегда равно степени числа 2. Уточнить параметры диска можно с помощью функции 1Ch прерывания 21h.

Вызов: AH = 1Ch DL = номер логического диска
 (0 = текущий, 1 = A:, 2 = B:,...) int 21h
 Возврат: AL = секторов в кластере CX = размер
 сектора в байтах DX = число кластеров
 на диске DS:BX = адрес идентификатора
 формата диска.

В соответствии с официальной документацией идентификатор формата диска является копией байта описателя среды носителя из таблицы распределения файлов (FAT). На самом деле это начало первой из несмежных областей, в которую загружается копия самой FAT. Способ определения параметров текущего диска приведен в листинге 1.

В общем случае размер файла не кратен размеру сектора и тем более кластера, поэтому за концом файла остается свободная область. Она недоступна для стандартных средств MS-DOS,и ее удобно использовать для хранения метки КЧЗП. Создать метку за концом файла можно с помощью программы, приведенной в листинге 2. Возможный способ доступа к такой метке демонстрируется в листинге 3.

Использование метки тома в каталоге

Древовидная система каталогов является основой файловой системы MS-DOS. Корневой каталог создается в процессе форматирования и представляет ряд смежных секторов. Положение и размеры корневого каталога фиксированы. Подчиненные каталоги являются собой файлами специального вида и создаются/модифицируются по мере необходимости в процессе функционирования системы.

Каталог любого уровня состоит из 32-байтовых элементов оглавления. Структура элемента оглавления приведена в табл. 1. Каждый непустой элемент оглавления -- это метка тома либо ссылка на файл/каталог последующего уровня. Логически каталог ограничен первым своим пустым элементом, имя которого начинается двоичным нулем. Резервная 10-байтовая область, следующая за байтом атрибутов, не контролируется известными версиями MS-DOS и обычно заполняется двоичными нулями.

Таблица 1. Структура элемента оглавления

Смещение Длина Назначение
08 Имя файла/каталога/метки тома с пробелами справа
83Расширение имени файла/каталога/метки тома
111Атрибуты файла/каталога/метки тома
1210 Резерв (может быть использована КЧЗП)
222Время создания файла/каталога/метки тома
242Дата создания файла/каталога/метки тома
262Номер первого кластера файла/каталога
284Размер файла

Байт атрибутов имеет структуру, показанную на рис. 1. Неиспользуемые старшие биты байта атрибутов содержат нули.

Метка тома создается в корневом каталоге при форматировании диска.

Отсутствие в составе MS-DOS прямых средств для работы с метками тома позволяет использовать такие метки в качестве устойчивого признака для КЧЗП. Удобен считающийся устаревшим метод управляющего блока файла (FCB). Операционная система поддерживает как обычные, так и расширенные блоки FCB. Структура FCB представлена в табл. 2. Использование расширенного варианта позволяет получить доступ к байту атрибутов.

Таблица 2. Структура управляющего блока файла (FCB)

(в круглых скобках указаны смещения полей расширенных блоков)

Смещение Длина Заполнение Назначение
(0)1User OpenФлаг FFh расширения FCB
(1)5User OpenРезерв [содержит двоичные нули]
(6)1User OpenАтрибуты файла/каталога/метки тома
0 (7)1User OpenНомер логического диска [0 = текущий]
1 (8)8User OpenИмя файла/каталога/метки тома
9 (16)3User OpenРасширение файла/каталога/метки тома
12 (19) 2 User I/OНомер текущего блока
14 (21)2 DOS, User I/OРазмер записи
16 (23)4DOSРазмер файла из каталога
20 (27)2DOSДата файла из каталога
22 (29) 10DOSРабочая область [содержит номер текущего кластера]
32 (39)1 User I/OНомер текущей записи для последовательного доступа
33 (40)4 User I/OНомер текущей записи для прямого доступа

Для создания файла или метки тома методом FCB используется функция 16h системного прерывания 21h. Эта функция не поддерживает создание каталогов и позволяет записать не более одной метки тома. Обращение к функции выглядит следующим образом:

Вызов:   AH = 16h
         DS:DX = адрес неоткрытого FCB
         int 21h
Возврат: AL = код завершения (00h = файл,
 метка тома создана,
         FFh = ошибка записи файла или 
метки тома)

Пример использования этой функции для создания метки тома текущего диска показан в листинге 4.

Системная функция 11h позволяет искать файл, каталог или метку тома. Она работает с текущим каталогом диска. В задаваемом имени и расширении допускается использование символов подстановки "?" и "*". При успешном завершении поиска происходит заполнение соответствующих полей управляющего блока файла. Обращение к функции 11h имеет следующий вид:

Вызов:   AH = 11h
         DS:DX = адрес неоткрытого FCB
Возврат: AL = код результата поиска (00h
 = файл/каталог/метка тома найдены,
         FFh = ошибка поиска)

Использование функции 11h для обнаружения заданной метки тома текущего диска показано в листинге 5.

"Длинная" запись

Одной из особенностей жесткого диска является возможность доступа к четырем байтам циклического контрольного кода обнаружения и исправления ошибок ECC (Error Correction Code). Этот код вычисляется как остаток от деления сдвинутого влево двоичного числа, называемого информационным полиномом, на фиксированное двоичное число, называемое порождающим полиномом. В качестве информационного полинома берется последовательность нулей и единиц содержимого данного сектора. Величина сдвига фиксирована и равна двоичной степени порождающего полинома. Для IBM-контроллеров жестких дисков порождающий полином имеет вид 10001000000100001b. Степень этого полинома равна 16. По этой причине два старших байта контрольного кода ECC стандарта IBM всегда равны нулю. Запись в эти байты ненулевых данных, например значения счетчика оставшихся запусков, полностью нарушает работу схемы коррекции ошибок, делая такие сектора абсолютно недоступными MS-DOS.

Получить доступ к расширенному сектору жесткого диска, включающему четыре байта кода циклического контроля ECC, можно через функции "длинного" чтения/записи прерывания 13h BIOS:

Вызов:   AH = 0Ah/0Bh (код операции "длинного"
 чтения/записи)
         AL = число расширенных секторов
 (516 байт)
         CH = биты 0..7 номер цилиндра
         CL = биты 8..9 номера цилиндра и
              биты 0..5 номера начального сектора
         DH = номер головки
         DL = номер жесткого диска (80h,
 81h, ...)
         ES:BX = адрес буфера данных
         int  13h
Возврат: CF = 1, если произошла ошибка,
 в этом случае
         AH = статус завершения операции, иначе
         CF = 0 и
         AL = число фактически переданных
 секторов

Ключевая информация и счетчик числа оставшихся запусков могут быть записаны в сектор 3 стороны 0 цилиндра 0 жесткого диска (см. листинг 6). Из всех секторов этой дорожки резервируется только сектор 1 под главную загрузочную запись. Остальные сектора остаются свободными и могут быть использованы схемами защиты, а также... вирусами. Проверка перед записью позволяет убедиться, что выбранный сектор доступен и не используется другими схемами защиты. Проверка осуществляется обычным чтением сектора через BIOS:

Вызов:   AH = 02h/03h (код операции чтения/
записи сектора любого диска)
         AL = число пересылаемых секторов
         CH = биты 0..7 номер цилиндра
         CL = биты 8..9 номера цилиндра и
              биты 0..5 номера начального
 сектора
         DH = номер головки
         DL = номер диска (00h..7Fh - гибкий
 диск,
              80h..FFh - жесткий диск)
         ES:BX = адрес буфера ввода/вывода
         int  13h
Возврат: CF = 1, если произошла ошибка,
 в этом случае
         AH = статус завершения операции, иначе
         CF = 0 и
         AL = число фактически переданных
 секторов

Доступ к информации созданного сектора показан на примере в листинге 7.

Измерение динамических параметров

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

Каналы выполняют деление базовой частоты таймера 1,193182 МГц (1/4 частоты телевизионного стандарта NTSC). Коэффициент деления в каждом канале программируется отдельно. Для измерения временных интервалов можно использовать каналы 0 и 2. С точки зрения программирования каждый канал таймера представляет собой четыре 8-битовых регистра, адреса которых даны в табл. 3.

Таблица 3. Порты регистров интервального таймера

Регистр таймераНомер порта
канал 0 канал 1 канал 2
Регистр управляющего байта 43h43h43h
Входной регистр счетчика ("задвижка") 40h 41h 42h
Выходной регистр счетчика40h 41h 42h

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

Работает таймер следующим образом. В состоянии счета каждый импульс уменьшает значение счетчика, значение которого отслеживается выходным регистром. Обнуление счетчика сопровождается импульсом на его выходе, который вызывает перезагрузку делителя из входного регистра ("задвижки") и продолжение счета.

Запись команды в управляющий регистр "защелкивает" канал таймера. Из этого состояния он выводится чтением выходного регистра или записью нового значения делителя в "задвижку". Чтение не изменяет содержимого счетчика, запись вызывает его мгновенную перезагрузку. Измерение временных параметров желательно проводить при запрещенных аппаратных прерываниях. Прерывания отменяются установкой в единицу разрядов маски 8-битового порта чтения/записи 21h программируемого контроллера прерываний 8259A. При использовании канала 0 таймера обязательно восстановление стандартного нулевого значения его делителя, стандартного режима 3 канала и, возможно, прежнего значения счетчика.

Время выполнения фрагмента программы

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

Определение временных параметров развертки

Управление видеосистемой IBM-совместимых компьютеров построено на микросхеме контроллера дисплея 6845 фирмы Motorola. Состояние схем развертки отображается в доступные только для чтения 8-битовые регистры, выведенные в соответствующие порты 03BAh (для монохромного адаптера) и 03DAh (для цветного адаптера). Представляющие интерес разряды этих регистров показаны в табл. 4.

Таблица 4. Разряды регистров состояния дисплея

Порт Разряд (бит) Состояние
03BAh Mono 0 1 = обратный ход по строке

0 = рабочий ход по строке
7 1 = обратный ход по кадру

0 = рабочий ход по кадру
03DAh

Color

0 1 = обратный ход по строкам или кадрам

0 = рабочий ход обеих разверток
31 = обратный ход по кадру (вертикали)

0 = рабочий ход по кадру (вертикали)

Пример программы для измерения параметров кадровой развертки цветного дисплея представлен в листинге 9. Таким же образом измеряются и параметры разверток монохромного дисплея. Однако процедура измерения параметров строчной развертки цветного дисплея оказывается сложнее из-за отсутствия прямой индикации ее состояния. Способ решения проблемы представлен в листинге 10. Для предотвращения "зависания" компьютера перед использованием приведенных программ необходимо определить тип установленного видеоадаптера. Соответствующую информацию нетрудно извлечь из тех же регистров состояния 03BAh и 03DAh, как это показано в листинге 11.

Определение частоты вращения жесткого диска

Частота вращения жесткого диска является его уникальной характеристикой. Для проведения соответствующих измерений необходим маркер оборота. В IBM-совместимых компьютерах таким маркером является сигнал индекса, который выводится в регистр состояния контроллера, связанный с портом 01F7h для первого диска и 0177h для второго. Назначение разрядов регистра состояния показано на рис. 4. Использование регистра для определения параметров жесткого диска иллюстрируется программой, приведенной в листинге 12.

Определение времени перемещения головок винчестера

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

Вызов:   AH = 0Ch
         CH = биты 0..7 номера цилиндра
         CL = в битах 0..1 биты 8..9 номера
 цилиндра
         DH = номер головки
         DL = номер жесткого диска (80h,
 81h, ...)
         int  13h
Возврат: CF = 1 при ошибке
         AH = статус завершения операции

Измерения, как всегда, проводятся при маскированных аппаратных прерываниях. Пример программы замера времени перемещения головок жесткого диска представлен в листинге 13.

Использование серийного номера жесткого диска IDE

Контроллеры дисков стандарта IDE обычно содержат уникальный номер, который можно использовать для их идентификации. Пример соответствующей программы приведен в листинге 14. Интересно, что таким способом иногда удается обнаружить серийный номер и в контроллерах жестких дисков, выполненных по другим стандартам. Однако при этом возможно "зависание" компьютера, предупредить которое можно сбросом дисковой подсистемы с помощью функции 00h прерывания 13h:

Вызов:   AH = 00h
         int  13h
Возврат: сброс дисковой подсистемы

***

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

ОБ АВТОРЕ

Василий Владимирович Текин -- программист, контактный тел.: (095) 915-06-59.