ЭЛЕКТРОННАЯ БИБЛИОТЕКА КОАПП
Сборники Художественной, Технической, Справочной, Английской, Нормативной, Исторической, и др. литературы.



     Название:
        КАК ЗАЩИТИТЬ ИНФОРМАЦИЮ
     (пособие по борьбе с хакерами)

     авторы:           С.П.Расторгуев
                       А.Е.Долгин
                       М.Ю.Потанин

     Редакторы:        гл.редактор А.Н.Перевозчиков
                       лит.редактор Ю.Ф.Филатов
                       редактор  В.А.Алексеев

                 СОДЕРЖАНИЕ

О программах-отмычках, взломанных файлах и несанкционированном
копировании

Идентификация пользователя: "СВОЙ" - "ЧУЖОЙ"?

Может ли компьютер стать графологом?

Как защититься от "размножения"

Защита от исследований.

Самомодификация программ - эффектно и полезно

Исполняемый модуль - что можно сделать без исходных текстов?

Как очистить прогармму от вирусов и пристыкованных защит

Проверка усвоенного

Анонс вместо заключения

Приложение 1. Словарь терминов

Приложение 2. Программа DLOCK ver. 2.0

                           ДИСКЕТЫ
  "Очистка" исполняемого модуля, удаление пристыкованных
механизмов: вирусов, защит, реклам и т.д..директорий \EXEB
  Дизассемблер (ИСХОДНЫЕ ТЕКСТЫ)..........директорий \DIS
  "Склейка" задач (ИСХОДНЫЕ ТЕКСТЫ).......директорий \KL
  Корректировка (ИСХОДНЫЕ ТЕКСТЫ).........директорий \KORR
  Восстановление векторов прерывания......директорий \PTRACE
  Самомодифицирующиеся программы: исходные тексты..........
..........................................директорий \GIB
  Идентификация по клавиатурному почерку..директорий \IDEN
  Защита от исследования..................директорий \DLOCK
  Защита от несанкционированного копирования...............
..........................................директорий \DCOP
  Примеры на сообразительность............директорий \PRIM

                             0. ВВЕДЕНИЕ
     В редакцию журнала "ТЕХНИКА-МОЛОДЕЖИ" нередко приходили письма с
просьбой публиковать компьютерные программы. Однако массовый
научно-художественный журнал не мог давать специфические материалы.
Поэтому было решено издать приложение, укомплектованное дискетой:
прочитал, и тут же запустил программу с дискеты. А тематика самая
разная - от алгоритмов игр и борьбы с вирусами до справочных
материалов по операционным системам, распространенным программам и
периферийному оборудованию (например, как подключить принтер и
сконструировать собственные шрифты). Ну а первые выпуски посвятили
защите информации. Все алгоритмы, рассчитанные на непосредственное
применение в работе, можно использовать и как пособие в практических
занятиях. Это актуально, ведь учебников по способам пресечения
информационного воровства до сих пор не существовало.

        О ПРОГРАММАХ-ОТМЫЧКАХ, ВЗЛОМАННЫХ ФАЙЛАХ И
             НЕСАНКЦИОНИРОВАННОМ КОПИРОВАНИИ
          (предисловие к серии приложения "ТМ")
     Компьютеры стремительно проникают во все сферы нашей жизни. Но с
ростом автоматизации перед рядовым пользователем возникает и целый
букет проблем, о существовании которых он даже не подозревал.
    Начнем с "защиты информации" - тема выбрана не случайно. Несмотря
на недавно принятый Закон о защите программ и баз данных, нелегальное
копирование, компьютерные диверсии (вирусы, "бомбы", "троянские
кони"), а также количество финансовых преступлений с использованием
вычислительной техники - не уменьшаются. Поэтому сохранность
информации является проблемой номер один не только у нас, но и во всем
мире. Ее усугубляют отсутствие элементарных знаний у большинства
пользователей, владеющих лишь простейшими навыками копирования файлов,
выработанная с годами привычка никогда не покупать программы и
кажущаяся легкость бесплатного добывания дорогостоящего программного
обеспечения.
     Впрочем, для любителей головоломок и нестандартных решений тема
защиты информации интересна сама по себе. Динамичность и сложность, в
сочетании с краткостью применяемых алгоритмов, возможность
предугадывать действия потенциальных хакеров ("взломщиков" программ)
роднят ее с увлекательными играми, основанными на интеллектуальном
поединке двух противников.
     Как предупредить покушения на информацию? Можно ограничить доступ
к ней посторонним, встроить в компьютер замок, отключающий клавиатуру,
поставить сейф для дискет, вставить в один из разъемов ПК парольную
"заглушку"... Из всего арсенала организационных, технических и
программно-аппаратных средств выделим чисто программные. Они просты в
тиражировании, технологичны в изготовлении и применении, не требуют
каких-либо производстводственных мощностей, в то же время обеспечивают
достаточный уровень защищенности. Впрочем, надежность в этом случае
определяется знанием последних достижений общей теории
программирования и умением разработчика использовать специальные
приемы. Естественно, что новинки систем охраны влекут и
совершенствование способов "взлома" - извечное противоборство "щита и
меча".
    Вот некоторые из наиболее популярных приемов защиты.
    Преобразование ФОРМАТА ДИСКЕТЫ - наиболее простой путь
предотвращения ее копирования средствами DOS. Даже незначительные
изменения в структуре или расположении системных таблиц или каталога
приводят к тому, что дискета становится непонятной "операционке".
Можно "перепутать" адреса секторов, на которых расположены защищаемые
файлы; пометить отдельные кластеры, занятые данными, как сбойные;
переделав запись в BOOT-секторе, изъять из доступного системе
пространства несколько треков (дорожек); в конце-концов - просто
применить иную структуру, взяв за основу аналог из других операционных
систем (например, RT-11 от ДВК). Разумеется, работать с такой дискетой
сможет только специальная программа, полностью заменяющая стандартные
функции ввода-вывода.
     Одним из способов ШИФРАЦИИ данных является их архивация по
специальным алгоритмам, что позволяет к тому же и сэкономить место на
магнитном носителе. Правда, сами кодирующие блоки программ оказываются
слабым местом. Их исследование под отладчиком или дизассемблером
позволяет хакеру понять алгоритм шифрации и повторить его. Поэтому
особенно актуальна ЗАЩИТА ОТ ИССЛЕДОВАНИЯ. Важную роль здесь играет
стиль программирования. В отличие от общепринятых "наглядности" и
"структурности", для охранных механизмов следует применять
"изощренность", то есть такой стиль, который позволит получить сложный
и запутанный исполняемый модуль. Еще лучше - если он будет
саморазворачивающимся в процессе работы (программа "дописывает" свои
части, отсутствующие на винчестере). Очень полезными могут оказаться
приемы, о которых журнал "ТМ" рассказывал в 1986 - 1988 годах в
разделе "Клуб электронных игр" (использование кода оператора в
качестве операнда, набора констант по прямому назначению и как
подпрограммы, передача управления в середину сложной двух-трехбайтовой
команды, проход "своим ходом" через данные и другие хитрости, не
только экономящие память, но и запутывающие алгоритм).
     Но это пассивная защита, а в качестве активной - рекомендуем
ПРЕСЕКАТЬ ПОПЫТКИ ИССЛЕДОВАНИЯ ИЛИ НЕСАНКЦИОНИРОВАННОГО "РАЗМНОЖЕНИЯ":
периодически определять контрольную сумму всех кодов образа задачи в
процессе работы (не "отрезан" ли какой-либо блок); сравнивать
свободную память с тем объемом ОЗУ, к которому программа привыкла или
приучена (не запущены ли паралельно резидентные "отмычки"); проверять
вектора прерываний (нет ли их перехватов); используя компьютерный
таймер, контролировать время прохождения отдельных частей (выявление
"остановов" и "потактового режима" отладчика).
     Изучение операционных систем, аппаратных особенностей ЭВМ
позволяет выделить индивидуальные отличия и использовать их для
НАСТРОЙКИ НА КОНКРЕТНУЮ ПЭВМ, СИСТЕМУ или ДИСКЕТУ, что делает
программное обеспечение непереносимым без санкции разработчика.
Правда, в архитектуре большинства компьютеров не существует аппаратной
особенности, анализ которой помог бы выделить одну машину из серии
таких же. Зато динамические характеристики различных частей (вращение
винчестера и дисководов, скорость обращения к оперативной памяти и
реакции клавиатуры) и их соотношения между собой индивидуальны, хотя и
не очень устойчивы. Для повышения надежности рекомендуется
использовать аппарат математической статистики. Вы не знакомы с ней?
Мы снабдим вас необходимыми алгоритмами. Кстати, передаваемые в
комплекте с лицензионными программами специальные электронные
устройства, искусственно создающие аппаратную уникальность конкретной
машины (так называемые "заглушки", которые подключаются к одному из
разъемов ПЭВМ и по предусмотренному автором ПО запросу выдают
парольную комбинацию байт), не всегда эффективны. Хакеры, используя
принцип спаривания компьютеров, отслеживают на втором все передаваемые
"заглушкой" сигналы, чтобы затем для несанкционированных копий
повторить их программой-"псевдозаглушкой".
     Простой царапиной можно пометить дискету - сделать точно такую же
на другой дискете невозможно, а охранный механизм по характеру и
местоположению сбойных блоков (или их отсутствию) легко определит
подмену. (Но и с этим хакеры успешно справляются: особый драйвер
дисковода перехватывает поступающую информацию и заменяет ее на
выявленную предварительным тестом с ключевой дискеты.)
     Надежную ИДЕНТИФИКАЦИЮ ПОЛЬЗОВАТЕЛЯ можно провести по почерку
(скорость, привычки в использовании основных или вспомогательных
частей клавиатуры, "любимые" комбинации клавиш при альтернативных
вариантах, выполнение "сдвоенных" и "строенных" нажатий одной или
двумя руками и т.д.), по росписи с использованием мышки, с помощью
психологических тестов и паролей.
      ПОИСК И УНИЧТОЖЕНИЕ ПОХИЩЕННОЙ ИНФОРМАЦИИ осуществляется
специальными резидентными драйверами (находящимися в памяти даже после
выгрузки пакета), которые постоянно контролируют операции
ввода-вывода, "просматривают" другие директории винчестера и дискет,
вставленных в дисководы. По сути это практическое применение вирусных
механизмов для защиты. Отдельных читателей может шокировать такой
способ охраны. Однако, если речь идет о важной информации и вирус
настроен исключительно на уничтожение украденных данных, то криминала
нет. Даже сторож яблоневого сада вооружается ружьем, так что же
говорить о допустимых средствах борьбы с утечкой интеллектуальных
ценностей?
     Это далеко не полный перечень различных вариантов
"предохранения". Однако следует учесть: их применение нередко мешает
работе легальных пользователей, поэтому включение того или иного
способа в защитный механизм требует тщательной оценки всех
положительных и отрицательных сторон.
     Каждый алгоритм обладает своей степенью НАДЕЖНОСТИ. Как
показывает опыт - 98 процентов "любознательных" программистов
отступятся от защиты, если она гарантирует: невозможность копирования
дискет с двух - трех попыток распространенными средствами типа COPY
II-PC, COPYWRITE или UNLOCK; невозможность разобраться в алгоритме
стартовых блоков программы с помощью известных отладчиков и
дизассемблеров (удача же на первых шагах, наоборот, подхлестнет
"спортивный" интерес); уникальность применяемых систем (если на один и
тот же "замок" закрыты программы разных авторов, то с ним стоит и
повозиться). А если к тому же пакет решает специальные задачи (не
интересен широкому кругу пользователей) и обходится дешевле, чем
оплата профессионального хакера, - то можно быть спокойным, "краж" не
будет.
     Но, предположим, перед неким хакером все же поставили такую цель.
К сожалению, пока не существует объективных критериев оценки
надежности того или иного алгоритма либо их комбинаций, зато из
субъективных можно взять за основу - время, которое понадобится для
"взлома". Шансы того, что защита целиком будет вскрыта, могут быть
подсчитаны на основании следующих параметров: вероятность наличия у
хакера спецсредств копирования и анализа защищенных программ; объем и
степень популярности примененной системы охраны; насколько интересна
сама программа другим пользователям; стоимость программы и системы
защиты.
     Обеспечение БЕЗОПАСНОСТИ В ЛОКАЛЬНЫХ СЕТЯХ, пожалуй, самая
сложная проблема. Она не решается автоматически, даже если на каждой
ПЭВМ все обстоит благополучно, но системе в целом должного внимания не
уделялось. Да и сам подход к построению защиты иной. Сначала
необходимо разобраться: во-первых, к каким блокам имеющейся информации
доступ должен быть максимально открыт (общая часть), ограничен
(дополнительные сведения) или полностью закрыт (управление сетью,
списки абонентов и их паролей); во-вторых, какие способы проникновения
в базы данных возможны для легальных корреспондентов, включая сетевые
серверы, и для хакеров. Теоретически всегда допустима ситуация, когда
два защитившиеся друг от друга абонента контактируют с третьим через
общие устройства - тут-то и возникают любопытные варианты похищения
или порчи данных. Поистине неоценим зарубежный опыт борьбы и с
сетевыми вирусами, автономно живущими в узловых компьютерах и
накапливающими передаваемую информацию. Но поскольку сети в нашей
стране только начинают развиваться, теория и практика их безопасности
разработаны пока недостаточно.
     Решение некоторых из этих проблем - вы найдете в этом выпуске
приложения "ТМ", а остальные - в последующих.

           1. ИДЕНТИФИКАЦИЯ ПОЛЬЗОВАТЕЛЯ: "СВОЙ" - "ЧУЖОЙ"?
     Почерк уникален, это знают все. Но немногие догадываются, что в
общении с компьютером индивидуальность пользователя проявляется также:
скорость, привычка использовать основную или дополнительную часть
клавиатуры, характер "сдвоенных" и "строенных" нажатий клавиш,
излюбленные приемы управления компьютером..., с помощью которых можно
выделить конкретного человека среди всех работавших на данной машине.
И ничего удивительного, - это сродни способности меломанов различать
на слух пианистов, исполняющих одно произведение.
    Как же выявить индивидуальные особенности клавиатурного почерка?
Также, как и при графологической экспертизе: нужны эталонный и
исследуемый образцы текста. Лучше, если их содержание будет одинаковым
(так называемая, парольная или ключевая фраза). Разумеется, по
двум-трем, даже по десяти нажатым клавишам отличить пользователя
невозможно, нужна статистика.
     При наборе ключевой фразы компьютер позволяет зафиксировать много
различных параметров, но для идентификации наиболее удобно
использовать время, затраченное на ввод отдельных букв. А повторив
ввод фразы несколько раз, в результате будем иметь множество временных
интервалов для каждого символа. На базе полученных значений всегда
можно рассчитать среднее время ввода каждого символа, допустимое
отклонение от среднего, и хранить эти результате в качесте эталонов
для каждого пользователя.
      Уникальные особенности клавиатурного почерка выявляются двумя
методами: по набору ключевой фразы или по "свободному" тексту. Каждый
обязательно имеет режимы настройки и идентификации. При настройке
определяются и запоминаются эталонные характеристики ввода
пользователем ключевых фраз, например, время, затраченное на отдельные
буквы. А в режиме идентификации, после исключения грубых ошибок,
эталонное и полученное множества сопоставляются (проверяется гипотеза
о равенстве их центров распределения).
    Обе методики различаются лишь выбором парольной фразы. В первом
случае это всегда одно и то же, а во втором - самый разнообразный
текст, что имеет свои преимущества, позволяя получать те же
характеристики незаметно, не акцентируя внимание пользователя на
парольной фразе. Впрочем, на выбор схемы проверки влияет тематика
защищаемого ПО. Предположим, некий владелец фирмы, желая узнать
текущий финансовый оборот, запустил программу бухгалтерского учета, а
компьютер, вместо короткой справки с коммерческой и потому секретной
информацией, предлагает набрать 2 - 3 странички "свободного текста",
дабы убедиться, что перед ним действительно директор или главбух. То
есть, здесь лучше применить метод "парольной фразы". С другой стороны,
лицо, имеющее допуск к секретам, может работать с такой программой
целый день, время от времени отлучаясь от компьютера, а чтобы в этот
момент злоумышленники не воспользовались раскрытой системой,
желательно периодически проводить "негласную проверку" (просьба
перенабрать "пароль" через каждые полчаса будет слишком назойлива).
    Правильной идентификации помогает также рисунок почерка. Под этим
понимается ряд значений, представляющих собой разность между соседними
временными интервалами - своего рода "производная" по почерку,
показывающая относительные замедления или ускорения при работе с
клавиатурой. Характеристика достаточно индивидуальна, что
подтверждается рядом экспериментов.

                   НАСТРОЙКА
    Для определения эталонных характеристик пользователя необходимо
выбрать ключевую фразу. Желательно, чтобы буквы были равномерно
распределены по клавиатуре, например: "Внимание - идентификация
пользователя по клавиатурному почерку". Затем раз десять набрать ее на
клавиатуре, определить время, затраченное на ввод каждой буквы, и
исключить грубые ошибки (те значения, которые резко выделяются из
каждой десятки имеющихся). Рассчитать и запомнить величины
математического ожидания (M), дисперсии (S) и число наблюдений (n).
Эти значения и называются эталонными (на блок-схеме - с индексом "э").
Блок-схема алгоритма режима настройки приведена на рис. 1.1.

                ИДЕНТИФИКАЦИЯ ПО НАБОРУ КЛЮЧЕВОЙ ФРАЗЫ
    Определение математических параметров пользователя (на блок-схеме:
M, S и n с индексом "и") при его идентификации проводится аналогично,
как и в режиме настройки. Единственное отличие - множества по каждому
символу будут состоять из меньшего количества значений (если фразу
набирают несколько раз) или даже из единичных величин (при однократном
наборе). Затем сравниваются дисперсии двух множеств (эталонного и
только что расчитанного) и величины математического ожидания - равны
ли, то есть совпадают ли центры распределения этих двух совокупностей.
Разумеется, полного равенства не будет, потому алгоритм заканчивается
оценкой вероятности того, что пользователь - тот же (если она больше
50%, то все несоответствия можно отнести за счет случайных факторов).
Алгоритмы обоих вариантов набора ключевой фразы приведены на
блок-схемах - рис. 1.2 (неоднократный) и рис. 1.3 (однократный).

                 ИДЕНТИФИКАЦИЯ ПО "СВОБОДНОМУ" ТЕКСТУ
    В отличие от первого метода, здесь получаемый ряд значений сильно
отличается от эталона (любой символ "ключа" даже если и встретится, то
окажется не на "своем" месте). Поэтому при составлении множеств в
качестве базисных используются величины, которые можно подобрать и в
ключевой, и в случайной фразах, например, - время между нажатием двух
клавиш в одинаковых сочетаниях (если слово эталона "Внимание", то в
свободном тексте ищем "Вн", "ни", "им" и т.д. и определяем размер
паузы, прошедшей с момента нажатия "В" до нажатия "н"), считая, что
пользователь будет переносить руку от одной клавиши к другой одинаково
в обоих случаях (при настройке и идентификации).
    А сравнение математического ожидания и дисперсии с эталонными
такое же, как и раньше (если базисные величины двух множеств выбраны
правильно, то они хорошо коррелируют), но прежде необходимо исключить
грубые ошибки, которых в данном случае будет больше.
    Приведенные методы достаточно просты и опираются на известные
разделы математической статистики [1-3], в различных вариациях они
используются во многих системах. Разумеется, можно воспользоваться
дисперсионным, регрессионным и другими видами анализа и усложнить
решения, доведя их до совершенства. Но это усложнит и жизнь
пользователя, ведь затруднительно каждый раз перед началом работы
вводить солидные куски парольных текстов.
     Вполне естественно, что с течением времени характеристики
пользователя меняются. Поэтому рекомендуется после каждой успешной
идентификации корректировать эталоны по формуле Mи=(n*Mэ+X)/(n+1), где
Mи, Mэ - характеристики исправленного и эталонного множеств, X -
величина, полученная в ходе идентификации, n - количество опытов,
вошедших в эталонное множество.

                     ДРУГИЕ СПОСОБЫ ИДЕНТИФИКАЦИИ
     Люди по разному воспринимают происходящие события. Предложи за
короткое время прикинуть количество точек или гласных букв в длинных
словах, размеры горизонтальных и вертикальных линий, - сколько
испытуемых, столько и мнений.
    Эти особенности человеческой психики также подходят для
идентификации. Правда, в зависимости от состояния и самочувствия
человека полученные значения будут "плавать", поэтому в практике
разумнее положиться на интегральный подход, когда итог подводится по
нескольким проверкам, учитывая и работу с клавиатурой. Результирующий
тест мог бы быть таким: на экране, на несколько секунд, появляются
вертикальные линии. Их размер и количество случайны. Пользователь
набирает соответствующие, на его взгляд, цифры. Таким образом,
выясняем: характеристики клавиатурного почерка, оцениваем память
(насколько указанные длина и число линий близки к действительности),
внимание и точность подсчета (насколько длина одной линии правильно
сопоставлена с соседней). Сравниваем результаты с эталоном. В этом
методе не так важны ошибки в определении размеров, главное - чтобы они
повторялись и при настройке, и при идентификации.

x 3                   БЛОК-СХЕМА РЕЖИМА
                      "НАСТРОЙКА"

                     Выбрать ключевую      START
               фразу, буквы которой равно-
                  мерно "расбросаны" по
                        клавиатуре
                              і
              ЪДДДДДДДДДДДДДДДБДДДДДДДї
              інабрать ее n раз       і
              АДДДДДДДДДДДДДДДВДДДДДДДЩ
                              і
              ЪДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДї
              іопределить время, затраченное на ввод од-ГДДДДДДДДДї
              іной буквы: X =(tS1T, tS2T, ..., tSiT, ..., tSnT),і         і
              ігде X - множество, определяющее одну из  і         і
              ібукв; tSiT - время ввода этого символа при і         і
              іi-том повторе                            і         і
              АДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДЩ         і
                              і                                   і
              ЪДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДї          і
              іпреобразовать неупорядоченную последова-і          і
              ітельность X в упорядоченную Y, где Y =  і          і
              і= (yS11T, yS2T, ..., ySiT, ..., ySnT); ySiT < ySi+1T,і          і
              іт.е. предыдущее значение меньше послед. і          і
              АДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДЩ          і
                              і                                   і
              ЪДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДї         і
              іпринять значения: j = 1, mim = 2, max = nГДї       і
              АДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДЩ і       і
                              і                           і       і
              ЪДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДї  і       і
              іисключить из множества Y значение ySjT    і  і       і
              АДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДЩ  і       і
                              і                           і       і
              ЪДДДДДДДДДДДДДДДБДДДДДДДДї                  і       і
              і   Si=minT                ГДДДДДДДДДДДДДДДДДДЕДДДДДДїі
              іM=   (ySiT)/(n-1)         і                  і      іі
              і   Si=maxT                і                  і      іі
              ГДДДДДДДДДДДДДДДДДДДДДДДДґ                  і      іі
              і    ДДДДДДДДДДДДДДДДї   і                  і      іі
              і     Si=minT              і                  і      іі
              іS=     (ySiT-M)S2T/(n-2)    і                  і      іі
              і     Si=maxT              і                  і      іі
              ГДДДДДДДДДДДДДДДДДДДДДДДДґ                  і      іі
              іT=(ySjT-M)/S              і                  і      іі
              АДДДДДДДДДДДДДДДВДДДДДДДДЩ                  і      іі
                              і                           і      іі
              ЪДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДї        і      іі
              іпо таблице Стьюдента (т. 1.2) для і        і      іі
              іp=0.95 и (n-2) определить Z       і        і      іі
              АДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДЩ        і      іі
                              і                           і      іі
                                     да       ЪДДДДДДДДДї і      іі
                            T > F    ДДДДДДДДДґn = n - 1ГДЩ      іі
                                              АДДДДДДДДДЩ        іі
                              інет                               іі
                              і            ЪДДДДДДДДДДДДДДДДДДДї іі
                                     да    іySjT обратно включитьі іі
                            j = n    ДДДДДДґв множество Y и пе-ГДЩі
                                           іренумеровать его   і  і
                              інет         АДДДДДДДДДДДДДДДДДДДЩ  і
                              і                                   і
              ЪДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДї            і
              ізапомнить полученные MS1T, SS1T, и nS1T и   і            і
              іперейти ко второй (следующей) букве   і            і
              АДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДЩ            і
                              і                                   і
                                                                  і
                            это не       да                       і
                       последняя буква  ДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
                            фразы?

                              інет
                              і
              ЪДДДДДДДДДДДДДДДБДДДДДДДДї
              і    Si=1T                 і
              іMSэT=   (ySiT)/(nSэT)         і
              і    Si=kT                 і
              ГДДДДДДДДДДДДДДДДДДДДДДДДґ
              і    ДДДДДДДДДДДДДДДДї   і
              і     Si=1T                і
              іSSэT=     (ySбT-MSэT)S2T/(nSэT-1) і
              і     Si=kT                і
              ГДДДДДДДДДДДДДДДДДДДДДДДДґ
              ігде k - количество букв і
              ів ключевой фразе; э -   і
              іиндекс эталоных значенийі
              АДДДДДДДДДДДДДДДВДДДДДДДДЩ
                              і

                       принять математическое
                  ожидание (MSэT), дисперсию (SSэT) и
                и число наблюдений (nэ) за эталон
                       данного пользователя
                                             END

                   рис. 1.1

                    БЛОК-СХЕМА РЕЖИМА
         "ИДЕНТИФИКАЦИЯ ПО МНОЖЕСТВЕННОМУ
                  НАБОРУ КЛЮЧЕВОЙ ФРАЗЫ"

                     Вывести на экран      START
               ключевую фразу и предложить
                  пользователю набрать
                         ее n раз
                              і
              ЪДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДї
              ірасчитать математическое ожиданиеі
              і(MS1иT) и дисперсию (SS1иT) по алгорит-і
              іму "НАСТРОЙКА" (рис. 1.1)        і
              АДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДЩ
                              і
              ЪДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДї
              ірасчитать функцию F-распределенияі
              і F=SS1эT/SS1иT, где SS1эT - эталонная дис-і
              іперсия,     SS1иT - дисперсия режимаі
              іидентификации                    і
              АДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДЩ
                              і
              ЪДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДї
              іпо таблице F-распределения (1.3) і
              і  для КS1эT= КS1иT = к-1 определить Z, і
              ігде к - длина ключевой фразы     і
              АДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДЩ
                              і
                                        да      ЭТО ПОСТОРОННИЙ
                            Z > F    ДДДДДДДДД     ЧЕЛОВЕК

                              інет                     END
                              і
              ЪДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДї
              іопределение степени надежности        і
              і    ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДїі
              іSS1xT= (SS1эTS02T*(nS1эT-1)+SS1иTS02T*(nS1иT-1))/(nS1эT+nS1иT-2) і
              ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
              і               ДДДДДДДДДДДї           і
              іTS1xT=іMS1эT-MS1иTі/SS1xT* 1/nS1эT + 1/nS1иT            і
              ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
              іпо т. 1.1 для p=0.95 и (n-2) находим Zі
              АДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДЩ
                              і
                                        да      ЭТО ПОСТОРОННИЙ
                            TS1xT > Z   ДДДДДДДДД     ЧЕЛОВЕК

                              інет                     END
                              і

                       P=R/n, где R - количество
                  удачных наборов фразы, n - общее
                количество идентификаций, P - вероят-
                  ность того, что пользователь -
                          автор эталонов
                                               END

                   рис. 1.2

                    БЛОК-СХЕМА РЕЖИМА
             "ИДЕНТИФИКАЦИЯ ПО ЕДИНИЧНОМУ
                  НАБОРУ КЛЮЧЕВОЙ ФРАЗЫ"

                     Вывести на экран      START
               ключевую фразу и предложить
                 пользователю набрать ее

                              і
              ЪДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДї
              іопределить время, затраченное на ввод од-і
              іной буквы: X =(tS11T, tS12T, ..., tS1iT, ..., tS1kT),і
              ігде X - множество, определяющее одну из  і
              ібукв; tS1iT - время ввода i-того символа    і
              іфразы, состоящей из k букв               і
              АДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДЩ
                              і
              ЪДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДї
              іпреобразовать последовательность X по   і
              івозрастанию и разбить ее на L равных ин-ГДДДДДДДДДДДДДДДДї
              ітервалов (в каждом должно быть примерно і                і
              і5 значений):      YS11T,..., YS1jT,..., YS1LT    і                і
              АДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДЩ                і
                              і                                         і
                              і                                         і
              ЪДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДї                і
              іопределить количество значений, попавшихі                і
              ів каждый интервал: NS11T,..., NS1jT,..., NS1LT   і                і
              АДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДЩ                і
                              і                ЪДДДДДДДДДДДДДДДДДДДї    і
                                        да     іпересчитать размер і    і
                           NS1jT < 5    ДДДДДДДДДДґинтервала (L - 1)  ГДДДДЩ
                                               АДДДДДДДДДДДДДДДДДДДЩ
                              інет
                              і
              ЪДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДї
              ірасчитать вероятность, что все значения tS1iT,і
              іпринадлежащие j-тому интервалу, попадают в ГДДДДДї
              іаналогичный интервал эталонного множества: і     і
              і           YS1jT - MS1эT        YS1j+1T - MS1эT        і     і
              і   PS1jT = Ф(ДДДДДДДД)/2 - Ф(ДДДДДДДДД)/2     і     і
              і             SS1эT               SS1эT           і     і
              і(значение функции Ф(X) находим по табл.1.4)і     і
              ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ     і
              і     S1j=LT (NS1jT - k * PS1jT)S02T                    і     і
              іT =    (ДДДДДДДДДДДДДДДД)                  і     і
              і     S0j=1T    k * PS1jT                         і     і
              ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ     і
              іпо табл. 1.5 для a=0.01 и (L-3) находим V  і     і
              АДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ     і
                              і                                 і
                                        да                      і
                            TS1jT > V   ДДДДДДДДДДї                і
                                               і                і
                              інет             і                і
                              і                і                і
                     ЪДДДДДДДДБДДДДДДї   ЪДДДДДБДДДДДДДДДДї     і
                     іЭТОТ СИМВОЛ ПО-і   іЭТОТ СИМВОЛ НЕ  і     і
                     іПАЛ В ДОВЕРИТЕ-і   іПОПАЛ В ДОВЕРИ- і     і
                     іЛЬНЫЙ ИНТЕРВАЛ і   іТЕЛЬНЫЙ ИНТЕРВАЛі     і
                     АДДДДДДДДВДДДДДДЩ   АДДДДДВДДДДДДДДДДЩ     і
                              ГДДДДДДДДДДДДДДДДЩ                і
                              і                                 і
                            это не       да                     і
                       последняя буква  ДДДДДДДДДДДДДДДДДДДДДДДДЩ
                            фразы?

                              інет
                              і

                       P=R/k, где R - количество
                  символов, попавших свой доверитель-
                ный интервал; P - вероятность того,
                  что пользователь - автор эталонов
                                                  END

                   рис. 1.3

x 3#                БЛОК-СХЕМА ПРОВЕРКИ ГИПОТЕЗЫ:
             "МНОЖЕСТВО ПОДЧИНЯЕТСЯ НОРМАЛЬНОМУ
                     ЗАКОНУ РАСПРЕДЕЛЕНИЯ"

                     Исходные данные:           START
            Xi - элемент множества; k - его размер;
               M, S - расчитанные оценки матема-
                тического ожидания и дисперсии

                              і
              ЪДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДї
              іпреобразовать последовательность X по   і
              івозрастанию и разбить ее на L равных ин-ГДДДДДДДДДДДДДДДДї
              ітервалов (в каждом должно быть примерно і                і
              і5 значений):      YS11T,..., YS1jT,..., YS1LT    і                і
              АДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДЩ                і
                              і                                         і
                              і                                         і
              ЪДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДї                і
              іопределить количество значений, попавшихі                і
              ів каждый интервал: NS11T,..., NS1jT,..., NS1LT   і                і
              АДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДЩ                і
                              і                ЪДДДДДДДДДДДДДДДДДДДї    і
                                        да     іпересчитать размер і    і
                           NS1jT < 5    ДДДДДДДДДДґинтервала (L - 1)  ГДДДДЩ
                                               АДДДДДДДДДДДДДДДДДДДЩ
                              інет
                              і
              ЪДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДї
              ірасчитать вероятность, что все значения XS1iT,і
              іпринадлежат j-тому интервалу:              і
              і           YS1jT - M         YS1j+1T - M         і
              і   PS1jT = Ф(ДДДДДДДД)/2 - Ф(ДДДДДДДДД)/2     і
              і             S                S            і
              і(значение функции Ф(X) находим по табл.1.4)і
              ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
              і     S1j=LT (NS1jT - k * PS1jT)S02T                    і
              іT =    (ДДДДДДДДДДДДДДДД)                  і
              і     S0j=1T    k * PS1jT                         і
              ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
              іпо табл. 1.5 для a=0.01 и (L-3) находим V  і
              АДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
                              і

                                        да
                            TS1jT > V   ДДДДДДДДДДї
                                               і
                              інет             і
                              і                і
                         ГИПОТЕЗА           ГИПОТЕЗА
                          ВЕРНА             НЕ ВЕРНА
                                END             END

                   рис. 1.4

                                                          Таблица 1.1
                   Значения t-распределения Стьюдента P.
         ЪДДДДВДДДДДДДДДДВДДДДДДДДДДДДДВДДДДДВДДДДДДДДДДДВДДДДДДДДДДї
         і\ P і  0.95    і    0.99     і\  P і    0.95   і   0.99   і
         іn \ і          і             і n \ і           і          і
         ГДДДДЕДДДДДДДДДДЕДДДДДДДДДДДДДЕДДДДДЕДДДДДДДДДДДЕДДДДДДДДДДґ
         і 4  і 2.78     і    4.60     і 16  і   2.12    і   2.92   і
         і 5  і 2.57     і    4.03     і 17  і   2.11    і   2.90   і
         і 6  і 2.45     і    3.71     і 18  і   2.10    і   2.88   і
         і 7  і 2.37     і    3.50     і 19  і   2.09    і   2.861  і
         і 8  і 2.31     і    3.36     і 20  і   2.086   і   2.845  і
         і 9  і 2.26     і    3.25     і 25  і   2.064   і   2.797  і
         і10  і 2.23     і    3.17     і 30  і   2.045   і   2.756  і
         і11  і 2.20     і    3.11     і 40  і   2.023   і   2.708  і
         і12  і 2.18     і    3.06     і 50  і   2.009   і   2.679  і
         і13  і 2.16     і    3.01     і 70  і   1.996   і   2.649  і
         і14  і 2.15     і    2.98     і 80  і   1.991   і   2.640  і
         і15  і 2.13     і    2.95     і100  і   1.984   і   2.627  і
         АДДДДБДДДДДДДДДДБДДДДДДДДДДДДДБДДДДДБДДДДДДДДДДДБДДДДДДДДДДЩ

                                                           Таблица 1.2
                  Значения t-распределения Стьюдента  P.
         ЪДДДДВДДДДДДДДДДВДДДДДДДДДДДДДВДДДДДВДДДДДДДДДДДВДДДДДДДДДДї
         і\ P і  0.95    і    0.99     і\  P і    0.95   і   0.99   і
         іn \ і          і             і n \ і           і          і
         ГДДДДЕДДДДДДДДДДЕДДДДДДДДДДДДДЕДДДДДЕДДДДДДДДДДДЕДДДДДДДДДДґ
         і 5  і 3.04     і    5.04     і 16  і   2.20    і   3.04   і
         і 6  і 2.78     і    4.36     і 17  і   2.18    і   3.01   і
         і 7  і 2.62     і    3.96     і 18  і   2.17    і   2.98   і
         і 8  і 2.51     і    3.71     і 20  і   2.145   і   2.932  і
         і 9  і 2.43     і    3.54     і 25  і   2.105   і   2.852  і
         і10  і 2.37     і    3.41     і 30  і   2.079   і   2.802  і
         і11  і 2.33     і    3.31     і 40  і   2.048   і   2.742  і
         і12  і 2.29     і    3.23     і 50  і   2.030   і   2.707  і
         і13  і 2.26     і    3.17     і 70  і   2.009   і   2.667  і
         і14  і 2.24     і    3.12     і 80  і   2.003   і   2.655  і
         і15  і 2.22     і    3.08     і100  і   1.994   і   2.639  і
         АДДДДБДДДДДДДДДДБДДДДДДДДДДДДДБДДДДДБДДДДДДДДДДДБДДДДДДДДДДЩ

                                                          Таблица 1.3
              F-распределение для уровня значимости a=0.05.
         ЪДДДДДДВДДДДВДДДДВДДДДВДДДДВДДДДВДДДДВДДДДВДДДДВДДДДВДДДДї
         іk1=k2=  1  і  2 і  3 і  4 і  5 і  6 і  7 і  8 і  9 і 10 і
         і      ГДДДДЕДДДДЕДДДДЕДДДДЕДДДДЕДДДДЕДДДДЕДДДДЕДДДДЕДДДДґ
         іРезульі161 і19.0і9.28і6.39і5.05і4.28і3.79і3.44і3.18і2.97і
         і тат  і    і    і    і    і    і    і    і    і    і    і
         ГДДДДДДЕДДДДЕДДДДЕДДДДЕДДДДЕДДДДЕДДДДЕДДДДЕДДДДЕДДДДЕДДДДґ
         іk1=k2=  10 і 20 і 30 і 40 і 50 і 60 і 70 і 80 і 90 і100 і
         іРезульГДДДДЕДДДДЕДДДДЕДДДДЕДДДДЕДДДДЕДДДДЕДДДДЕДДДДЕДДДДґ
         і тат  і2.97і2.12і1.84і1.69і1.60і1.55і1.50і1.46і1.42і1.39і
         АДДДДДДБДДДДБДДДДБДДДДБДДДДБДДДДБДДДДБДДДДБДДДДБДДДДБДДДДЩ

                                                         Таблица 1.4
                        Значение функции Ф(y).
         ЪДДДДВДДДДВДДДДДВДДДДВДДДДДВДДДДДВДДДДДВДДДДДВДДДДДВДДДДДї
         іy=0 і 0.1і 0.2 і 0.3і 0.4 і 0.5 і 0.6 і 0.7 і 0.8 і 0.9 і
         і    і    і     і    і     і     і     і     і     і     і
         і.0  і.079і.158 і.235і.31  і.38  і.45  і.516 і.576 і0.632і
         ГДДДДЕДДДДЕДДДДДЕДДДДЕДДДДДЕДДДДДЕДДДДДЕДДДДДЕДДДДДЕДДДДДґ
         іy=1 і 1.1і 1.2 і 1.3і 1.4 і 1.5 і 1.6 і 1.7 і 1.8 і 1.9 і
         і    і    і     і    і     і     і     і     і     і     і
         і.68 і.728і.77  і.806і.838 і.866 і.89  і.91  і.93  і0.94 і
         ГДДДДЕДДДДЕДДДДДЕДДДДЕДДДДДЕДДДДДЕДДДДДЕДДДДДЕДДДДДЕДДДДДґ
         іy=2 і 2.1і 2.2 і 2.3і 2.4 і 2.5 і 2.6 і 2.7 і 2.8 і 2.9 і
         і    і    і     і    і     і     і     і     і     і     і
         і.95 і.96 і.97  і.978і.983 і.987 і.99  і.993 і.995 і0.996і
         ГДДДДЕДДДДЕДДДДДЕДДДДЕДДДДДЕДДДДДЕДДДДДЕДДДДДЕДДДДДЕДДДДДґ
         іy=3 і 3.1і 3.2 і 3.3і 3.4 і 3.5 і 3.6 і 3.7 і 3.8 і 3.9 і
         і    і    і     і    і     і     і     і     і     і     і
         і.997і.998і.9986і.999і.9993і.9995і.9997і.9998і.9999і.9999і
         ГДДДДБДДВДБДДДДДБДДДДБДДДДДБДДДДДБДДДДДБДДДДДБДДДДДБДДДДДЩ
         іy >=4.0і
         і       і
         і 0.9999і
         АДДДДДДДЩ

                                                           Таблица 1.5
                     Значения для вероятности p = 0.01
                        и числа степеней свободы l.
         ЙНННННННННННННННННННННННННННННЛНННННННННННННННННННННННННННН»
         єЧисло степ. свободыіРезультатєЧисло степ. свободыіРезульт.є
         є       1           і  6.6    є        8          і  20.1  є
         є       2           і  9.2    є        9          і  21.7  є
         є       3           і 11.3    є       10          і  23.2  є
         є       4           і 13.3    є       11          і  24.7  є
         є       5           і 15.1    є       12          і  26.2  є
         є       6           і 16.8    є       13          і  27.7  є
         є       7           і 18.5    є                   і        є
         ИНННННННННННННННННННННННННННННКННННННННННННННННННННННННННННј

               2. МОЖЕТ ЛИ КОМПЬЮТЕР СТАТЬ ГРАФОЛОГОМ?
    Рукопись в своеобразии начертания букв доносит до нас что-то
личностное. Графологи, продравшись сквозь частокол завитушек, многое
расскажут об их авторе. А что можно узнать с помощью компьютера о
человеке, "долбящему" по клавишам? Попробуем поискать аналогии.
    Д.М.Зуев-Инсаров, автор фундаментальных работ по графологии, не
только убедительно демонстрирует методы определения пола, возраста,
образования, рода занятий писавшего, но и достаточное внимание уделяет
экспериментальным основаниям этого научного направления. Его
классификация содержит такие формальные признаки почерка, как: сила
нажима, динамичность и напряженность движения, вытянутость, наклон и
степень связанности букв, направление строки, расположение и
содержательность текста, способ держания орудия письма, равномерность
и соразмерность букв и слов, ритм и выразительность письма.
     Что же из этого может позаимствовать "клавиатуровед"? Аналогии
есть, это несомненно. Например, временные интервалы между вводом
символов с клавиатуры по информативности ничем не уступают связанности
букв в словах на бумаге. Действительно, если не новичок при хорошем
темпе набора вдруг начал ошибаться, то скорее всего он охвачен
внутренними переживаниями, не относящимися к выполняемой работе. А
ровный темп, взятый в начале и сохраненный до конца, не хуже
графологического признака "равномерность письма" свидетельствует о
пунктуальности и аккуратности тестируемого.
     Конечно, многие особенности рукописного почерка при работе на
компьютере сопоставлять бесполезно, ведь клавиатура и драйверы
стандартизируют написание букв. Зато здесь возможен анализ новых
признаков: зависимость скорости ввода слов от их смысла, относительное
время нажатия клавиш различных полей клавиатуры и другие. Причем они в
некоторых случаях даже более информативны - например, реакция
тестируемого на различные термины укажет сферу его интересов.
Действительно, химик быстрее наберет "водород", "соединение", которыми
он постоянно оперирует, чем "программа", "экскаватор". А модельеру
будут привычнее - "манекен", "выкройка". (Кстати, это свойство
"мышечной" памяти, не контролируемой сознанием, можно использовать для
программы "Детектор лжи".) В данном случае появляется возможность
отдельно анализировать левое и правое полушария мозга (отвечающие за
образное и абстрактное мышление), поскольку они связаны с правой и
левой руками человека, а письмо представляет только "одностороннюю"
информацию.
    Формулы для получения формальных признаков клавиатурного почерка
приведены на рис. 2.1, а их соответствие графологической классификации
- в таблице 2.1. Смысл, вложенный в некоторые термины, отличается от
принятого Зуевым-Инсаровым, потому что похожие особенности в том и
другом случаях выявляются разнымии методами, однако это не
противоречит его работе [1].
    Графологические исследования способствуют также диагностированию
больного, так как почерк меняется при заболевании, возвращаясь к
нормальному виду по мере выздоровления. Кто знает, не подойдет ли
подобный анализ и при постановке предварительного диагноза работающего
на компьютере.
    Можно пойти и дальше - построить Личностный вектор и на его основе
описать внешность, характер и судьбу человека [2]. Заключение хотя и
кажется слишком категоричным, тем не менее основано на известных
теориях и гипотезах из психологии. Впрочем, взаимосвязь внешнего и
внутреннего облика очевидна: закомплексованность из-за физического
изъяна отражается на поведении, которое, в свою очередь, влияет на
способ общения с компьютером. Поэтому решение обратной задачи -
определение по клавиатурному почерку характера и, через него,
внешности - хотя и трудно, но допустимо, пусть пока теретически.
Например, на нештатную ситуацию (якобы "сбой" компьютера, а на самом
деле - предусмотренный автором программы психологический тест)
вспыльчивый холерик и "вечно комплексующий" меланхолик отреагируют по
разному. А кто меньше отвлекается при длительной работе? Флегматик,
сангвиник или холерик? Вероятно, наибольшее возражение вызывает
утверждение о возможности прогнозирования судьбы. Хотя и в его защиту
можно привести немало аргументов. В данном случае даже нет
необходимости опираться на астрологов, которые считают, что жизнь
человека зависит от даты рождения. Возможно и другое объяснение. Выбор
Судьбой для человека поступка/события из альтернативных вариантов -
продиктованы его деятельностью в далеком и недалеком прошлом. То есть,
свобода выбора - всего лишь иллюзия разума. Таким образом, выяснив
главные вехи в биографии и определив основные черты характера, можно с
достаточной степенью вероятности смоделировать линию поведения
человека в той или иной ситуации. В конце концов даже по капле воды
можно судить об океане, а по поступку о жизни. Поэтому возможность
предсказания судьбы становится, пусть спорной, как почти все в этом
мире, но понятной. И в принципе реализуемой - что стоит для хорошего
компьютера учесть несколько тысяч величин? Лишь бы были тщательно
проработаны математические формулы и введены числовые значения всех
факторов, влияющих на человека.

3(

                  ОПРЕДЕЛЕНИЕ ОСОБЕННОСТЕЙ КЛАВИАТУРНОГО ПОЧЕРКА.

           1) Темп набора тестового материала в целом:
                               Tm = T/n
              где T - время набора, n - число символов.

           2) Темп набора каждого слова:
                           Ts[i] = T[i]/k[i]
                  где T[i] - время набора i-того слова,
                      k[i] - число символов в нем.

           3) Средняя пауза между словами:
                         i=L
               Tp = (T -    (T[i]) ) / L
                         i=1
                  где L - число слов в тексте.

           4) Степень связности набора (вычисляется после исключения
         грубых ошибок):
                        ДДДДДДДДДДДДДДДДДї
                  S =   (t[j] - M) /(n-1)
             где  t[j] - время между набором j и j+1 символа в
                         слове (пробелы исключаются),
                      i=L
                  M =    (T[i])/n.
                      i=1

           5) Общий рисунок почерка:
               dX[i] = t[i] - t[i+1] для всех i.

                                   рис. 2.1

                                                          Таблица 2.1

                  СООТВЕТСТВИЕ КЛАВИАТУРНЫХ И РУКОПИСНЫХ
                           ХАРАКТЕРИСТИК ПОЧЕРКА
         ЪДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДї
         і На клавиатуре і    В рукописи      іОсобенность характераі
         ГДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДґ
         іДлительный  по-іОтсутствие    связи іДушевный разлад (еслиі
         іиск клавиши.   імежду буквами слова.іза ПЭВМ не новичок). і
         ГДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДґ
         іОдинаковые пау-іРавномерные интерва-іУверенность  в  себе,і
         ізы между слова-ілы между словами.   іотсутствие    отрица-і
         іми.            і                    ітельных  переживаний.і
         ГДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДґ
         іДлительность   іНеравномерность  ин-іНеустойчивость харак-і
         іпауз между сло-ітервалов  между сло-ітера,   несогласован-і
         івами изменяетсяівами                іность чувств,  актив-і
         ів широких  пре-і                    іность     проявляетсяі
         іделах.         і                    ітолько  в  результатеі
         і               і                    іотдельных вспышек во-і
         і               і                    ілевой энергии.       і
         ГДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДґ
         іРовный темп на-іРавномерность напи- іСпособность к регуля-і
         ібора    каждогоісания как первых такірной  систематическойі
         іслова при  вво-іи последних строк   іработе.   Привычки  кі
         іде всего тесто-ірукописного текста. іпорядку, пунктуально-і
         івого материала.і                    істи и аккуратности.  і
         ГДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДґ
         іПауза     междуіПлотное    написаниеіИстеричность.        і
         ісловами  много-іслов  с  чрезмернымиі                     і
         ікратно превыша-іинтервалами    междуі                     і
         іет паузы  междуіними.               і                     і
         іотдельными бук-і                    і                     і
         івами.          і                    і                     і
         ГДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДґ
         іВысокий    темпіБолее правильное и  іБыстрая утомляемость.і
         ів начале теста,ічеткое написание на-і                     і
         ізаметно снижаю-ічала текста по срав-і                     і
         ішийся к его за-інению с заключением і                     і
         івершению.      і                    і                     і
         ГДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДґ
         іТемп ввода  от-і                    іТестируемый ранее не-і
         ідельных    слові                    іоднократно набирал ихі
         ізначительно вы-і                    іна клавиатуре.       і
         іше среднего.   і                    і                     і
         ГДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДґ
         іОтдельные словаі                    іТестируемый   никогдаі
         івводятся гораз-і                    іне встречался с  дан-і
         ідо    медленнееі                    іными словами, возмож-і
         іостальных.     і                    іно, даже не знает  ихі
         і               і                    іправописания.        і
         АДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДЩ

                  3. КАК ЗАЩИТИТЬСЯ ОТ "РАЗМНОЖЕНИЯ"
                        (идентификация ПЭВМ).
     С развитием отечественного рынка программ возрастает значение их
защиты от несанкционированного копирования (НСК). Разработчики просто
опускают руки перед фатальной неизбежностью пиратского распространения
своего детища, ведь кража этой интеллектуальной собственности проста,
занимает считанные минуты и остается незаметной, хотя доходы приносит
вполне приличные. Правда, корпорации-монстры все же предпочитают не
защищать собственную продукцию, ибо общий оборот их средств намного
превышает убытки от воровства, которые, кстати, частично покрываются
такой "бесплатной рекламой". Однако, для подавляющего большинства фирм
и организаций, занимающихся разработкой ПО, продажа копий (зачастую с
единственной "товарной" программы) - основное средство существования.
"Пираты" же изменяют не только название продукта, но и
фирму-изготовителя, тем самым добавляя к моральным потерям появление
конкурирующего товара с аналогичными потребительскими свойствами.
Поэтому каждый разработчик, несомненно, рано или поздно сталкивается с
проблемой защиты ПО от НСК.
    Первая дилемма, возникающая на этом пути: придумывать ли защиту
самому или же приобрести существующий пакет "контрдействий", которых,
к слову сказать, появилось у нас великое множество. Обычно выбор
определяется важностью и стоимостью защищаемой информации, но,
пожалуй, решающее значение играет квалификация программиста.
Профессионал чаще приступает к созданию оригинальной защиты, ибо
большинство ныне существующих представляют собой так называемый
пристыкованный блок, который, чего греха таить, является чистым
надувательством. Ведь опытные хакеры снимают его за считанные минуты,
даже не удостаивая изучением (например, с помощью утилиты CATCHER,
рекламируемой центром САПР Ассоциации "Наука"). Кроме того,
профессионал никогда не отдаст на откуп другому такую интересную
задачу, как создание защиты. А любитель выберет уже существующие
охранные программы. Бывают еще случаи привлечения программистов "со
стороны", но, поскольку передача исходных текстов сопряжена с утечкой
информации (от которой как раз и стремятся застраховаться), это не
типично для нашего рынка.
     Сейчас, выражаясь на жаргоне программистов, существуют три типа
пресечения НСК: "по дискете", "по машине" и "по пользователю". Первый
- проверяет характеристики и информацию ключевой дискеты, которая
служит, как правило, и носителем защищаемого ПО. Второй - следит за
совпадением некоторых заранее определенных характеристик допущенного
для работы компьютера. О третьем и, пожалуй, самом интересном способе
охраны речь шла в двух предыдущих главах.
     Наиболее эффективен второй путь, так как проверка компьютера
проста и непродолжительна, может часто повторяться по ходу работы, не
снижая общего быстродействия. Если же режим реального времени не
обязателен и возможны многократные обращение к "медленным устройствам"
типа гибких дискет или проверка клавиатурного почерка пользователя
(конечно, когда он участвует в работе программы), то и остальные типы
охраны могут быть встроены в блок защиты.
     Разберем алгоритмы проверки компьютера. Программу удобнее
привязать к следующим характеристиками машины:
    1) быстродействие: процессор, память, контроллеры и т.д.; скорость
вращения двигателей дисководов; скорость реакции на внешние
воздействия;
    2) конфигурация: тип микропроцессора (МП) и разрядность шины
данных; наличие и тип контроллеров для внешних устройств и самих
устройств (жесткие и гибкие диски, сопроцессор);
    3) особенности: контрольная сумма BIOS; содержимое CMOS памяти;
длина конвейера шины данных; аномальные явления в ходе его работы.
    Их разделение на группы обусловлено лишь похожими алгоритмами
определения и применения, а вообщем-то, оно весьма условно.
    Легко заметить, что быстродействие (первая группа) в наибольшей
степени отражает индивидуальные отличия машин - они, пожалуй,
эффективнее других привяжут ПО к компьютеру. Правда, из-за
нестабильности электронных элементов схемы, нестабильны и показатели
его узлов. Незнание способов корректировки таких накладок чаще всего и
отпугивает программистов.
    Один из методов определения быстродействия компьютера представлен
в процедуре "Sample" (рис. 3.1), который фиксирует отсчет таймера за
время выполнения фрагмента 16 - 20. В регистр AX заносится для
дальнейшего использования результат. Напомним, непосредственное его
сравнение с некоторой эталонной величиной может привести к ошибке
из-за нестабильности задающего генератора ПЭВМ. Отметим также, что
реализация аналогичного алгоритма на языке BASIC даст еще больший
разброс значений - это общий недостаток почти всех языков высокого
уровня. Для исключения грубых ошибок и повышения точности необходимо
провести многократные измерения и воспользоваться алгоритмом на рис.
1.1 (глава "Идентификация пользователя: "свой"-"чужой?").
     Время выполнения одного и того же участка программы на разных
компьютерах скорее всего будет отличаться, что и позволит выделить
определенную ПЭВМ из ряда аналогичных.
     Тот же пример (рис. 3.1) годится и для измерения скорости работы
оперативного запоминающего устройства (ОЗУ). Его электрическая схема
набирается из микросхем (МС), объемом по 16, 32 или 64 Кб (килобит). В
зависимости от типа, 8 - 16 таких МС составляют 1 блок (электронщики
называют их "блоком", а программисты "страницей"), емкостью 64 КБ
(килобайт). Значит, в стандартном адресном пространстве IBM PC/XT в
640 КБ - 10 блоков МС, причем каждый имеет собственные характеристики,
чуть-чуть отличающиеся от других. То есть быстродействие страниц ОЗУ у
каждого компьютера различно. На участке 16 - 20 осуществляется простая
перезапись содержимого области памяти (ее регенерация). Время
регенерации всех страниц составит ряд из 10 чисел, значения и
последовательность которых характерны только для данной ПЭВМ.
    Скорость вращения двигателей дисководов определяется аналогично
(например, замер по таймеру операции чтения/записи некоторого сектора
или дорожки дискеты, как это делает COPYLOCK).
    Под скоростью реакции на внешние воздействия понимается время,
необходимое компьютеру на отклик после получения команды внешнего
устройства, или размер паузы между выдачей команды, например, в
контроллер накопителя гибких магнитных дисков (НГМД), и приходом
сигнала готовности (аппаратное прерывание IRQ7 для НГМД). Измерения
проводятся по отсчетам таймера, но можно использовать и свой
программный счетчик, как это делает BIOS при дисковых операциях.
     Если речь идет о компьютерах одной партии, то информация о типе и
конфигурации не уникальна, хотя, как дополнительный элемент привязки к
характеристикам ПЭВМ, не повредит. Ее можно получить через прерывание
BIOS 11h (или по адресу 40h:0010h ОЗУ), а более исчерпывающую - из
CMOS-памяти. Гораздо сложнее определить программным путем тип МП.
    Характеристики третьей группы, очевидно, не всегда индивидуальны у
конкретной машины. Общеизвестно, что в одной партии конрольная сумма
BIOS одинакова (если, конечно, это не так называемая "белая" сборка).
Энергонезависимая память CMOS, содержащая часы реального времени и
информацию о конфигурации, также зачастую одинакова. К сожалению,
формат CMOS различен на разных типах машин, а значит единого способа
привязки нет. Если же расчет строится на определенный тип компьютера,
то доступ к CMOS вполне возможен (с условием, что конфигурация не
будет меняться в процессе эксплуатации программы).
    Алгоритм чтения/записи байтов в ячейки CMOS приведен на рис. 3.2.
Кстати, процедуру подсчета контрольных сумм можно усложнить, если
арифметическую операцию "сложение" заменить на логическую или добавить
к ней еще что-нибудь.
    А на рис. 3.3 более интересный алгоритм, шифрующий и одновременно
привязывающий программу к конкретному компьютеру. На определенные
участки защищаемой программы накладывают некоторую область CMOS
(например, операцией XOR). При запуске программа сама осуществит
обратную процедуру, дешифрируя свой код (удобнее использовать область,
защищенную контрольной суммой, байты 10h - 20h). Естественно, что на
другом компьютере константа "CMOS" будет отличаться и, значит, процесс
дешифровки испортит программу. Кстати, здесь годится и собственная
информация, записанная в резервные ячейки энергонезависимой памяти,
если, конечно, ее формат позволяет это делать, как, например, у
компьютеров фирмы WIPRO Information Technology Limited (допускающих
достаточно вольное обращение с CMOS: в том числе и с ячейками,
защищенными контрольной суммой, с последующей корректировкой по
адресам 2Eh,2Fh). А компьютеры SystemPro фирмы Compaq, хотя и не дают
программисту возможности воспользоваться этим методом защиты, но
обладают (как и некоторые другие на базе МП 80386 и выше) таким
интересным свойством, как пользовательский пароль, который занесен в
байты 38h - 3Fh и защищен от чтения и записи.
    Последние две особенности третьей группы характеристик ПЭВМ, на
наш взгляд, наиболее перспективны для защиты ПО от исследования и
поэтому рассматриваются в следующей главе ("Защита от исследований").
     Независимо от выбранного способа идентификации, больше всего
вопросов вызывает сама передача программ покупателю. Ведь в этот
момент они уже должны содержать в себе эталонные характеристики ПЭВМ
пользователя, чтобы проводить соответствующие проверки. Хорошо, если
автор может прийти и лично настроить свои программы, а как быть с
иногородними покупателями?
     Действия по настройке лучше всего поручить специальной
инстолирующей программе, которая может храниться на одной дискете с
передаваемым пакетом. Инстолятору поручают разархивацию продукции
(расшифровку и приведение в рабочее состояние), перезапись с дискеты
на винчестер, определение используемых характеристик компьютера и
вписывание их в известные одному автору места программ (конкретные
адреса для этих значений должны быть предусмотрены заранее). Попутно
проверяется - не является ли ключевая дискета незаконной копией и
соответствует ли название организации-покупателя упоминаемому в
договоре купли-продажи. По завершению работы инстолятор может стереть
сам себя с дискеты или сделать отметку об успешно проведенной
инстоляции (чтобы самоликвидироваться после исчерпания оговоренного
договором лимита).
     Такую схему передачи можно применять даже при пересылке
программных продуктов по почте - после самоуничтожения инстолятора
владение ключевой дискетой становится бесполезным.

        ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
        і                        Ассемблер:                          і
        і                        ДДДДДДДДДД                          і
        і 1 0000          code    segment para public                і
        і 2                       assume cs:code,ds:code             і
        і 3                                                          і
        і 4 0000          sample  proc                               і
        і 5                                                          і
        і 6 0000  FA          cli                                    і
        і 7 0001  BA 0043     mov dx,43h      ; включить 0-й канал   і
        і 8 0004  B0 34       mov al,34h      ; таймера              і
        і 9 0006  EE          out dx,al                              і
        і10 0007  B2 40       mov dl,40h      ; задать начальное     і
        і11 0009  8A C6       mov al,dh       ; значение счетчика    і
        і12 000B  EE          out dx,al                              і
        і13 000C  EE          out dx,al                              і
        і15                ;=======================================  і
        і16 000D  33 F6         xor si,si        ;                   і
        і17 000F  8B FE         mov di,si        ; Здесь может быть  і
        і18 0011  B9 8000       mov cx,8000h     ; расположен любой  і
        і19 0014  FC            cld              ; ваш текст         і
        і20 0015  F3> A5        rep movsw           ;                і
        і21                ;=======================================  і
        і23 0017  BA 0043   mov dx,43h   ; зафиксировать текущее     і
        і24 001A  B0 04     mov al,4     ; значение счетчика         і
        і25 001C  EE        out dx,al                                і
        і26 001D  B2 40     mov dl,40h   ; считать значение счетчика і
        і27 001F  EC        in  al,dx    ; в AX                      і
        і28 0020  8A E0     mov ah,al                                і
        і29 0022  EC        in  al,dx                                і
        і30 0023  86 E0     xchg ah,al                               і
        і31 0025  FB        sti                                      і
        і32                                                          і
        і33        ; здесь должна быть проверка считанного значения  і
        і34                                                          і
        і35 0026  B8 4C00        mov ax,4c00h                        і
        і36 0029  CD 21          int 21h                             і
        і37                                                          і
        і38 002B         sample  endp                                і
        і39 002B         code    ends                                і
        і40              end     sample                              і
        і                                                            і
        і                        BASIC:                              і
        і                        ДДДДДД                              і
        і100     OUT     &H43, &H34                                  і
        і110     OUT     &H40, 0                                     і
        і120     OUT     &H40, 0                                     і
        і        . . . . . . . . . . . . . . . . . . .               і
        і                                                            і
        і        ' Текст замеряемого участка программы               і
        і                                                            і
        і        . . . . . . . . . . . . . . . . . . .               і
        і300     OUT     &H43, 4                                     і
        і310     X% = INP ( &H40 ) + INP ( &H40 ) * 256              і
        і320     PRINT X%                                            і
        АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
                                  рис. 3.1

        ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
        і1)  чтение:                                                 і
        і    Ассемблер:                         BASIC:               і
        і    ДДДДДДДДДД                         ДДДДДД               і
        і      . . .                           . . .                 і
        іmov al,номер байта CMOS    300  OUT &H70, номер байта CMOS  і
        і  out 70h,al                 310  X% = INP ( &H71 )         і
        і  jmp $+2                                                   і
        і  in al,71h                               . . .             і
        і     . . .                                                  і
        і2   запись:                                                 і
        і        Ассемблер:                     BASIC:               і
        і        ДДДДДДДДДД                     ДДДДДД               і
        і        . . .                          . . .                і
        і  mov al,номер байта CMOS    300  OUT &H70, номер байта CMOSі
        і  out 70h,al                 310  OUT &H71, новое значение  і
        і  jmp $+2                                                   і
        і  mov al,новое значение               . . .                 і
        і  out 71h,al                                                і
        і   . . .                                                    і
        АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
                                  рис. 3.2

        ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
        і    Ассемблер:              BASIC:                          і
        і    ДДДДДДДДДД              ДДДДД                           і
        і  . . .                     . . .                           і
        і  mov ax,0f800h         500  DEF SEG = &Hf800               і
        і  mov es,ax             510  S = 0                          і
        і  xor ax,ax             520  FOR I = 0  TO  32766  STEP 2   і
        і  mov bx,ax             530  S = S + PEEK(I) + PEEK(I+1)*256і
        і  mov cx,4000h          540  NEXT                           і
        іrpt:                    550  PRINT S                        і
        і  add ax,es:[bx]                                            і
        і  inc bx                   . . .                            і
        і  inc bx                                                    і
        і  loop rpt                                                  і
        і   . . .                                                    і
        АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
                              рис. 3.3

                      4. ЗАЩИТА ОТ ИССЛЕДОВАНИЙ.
     Чтобы модернизировать механическое изделие, электронное
устройство или интеллектуальный продукт - программу - надо понять
принцип работы, определить основные и вспомогательные части. Для
программ существуют специальные инструменты, позволяющие разбирать их
"до винтика". Самые универсальные называются дизассемблеры и
отладчики. Первые преобразуют непонятный машинный код в удобочитаемый
текст на языке низкого уровня - ассемблере. Вторые - информируют обо
всех процессах, протекающих в недрах компьютера, после выполнения
отдельного участка или даже каждого шага программ, то есть помогают
понять суть выполняемых операций. Поэтому следущая "линия обороны"
любого блока защиты проходит именно здесь.
    Четкой грани между дизассемблированием и анализом полученного
текста под отладчиком - нет (часто эти функции совмещены в единой
программе), что и позволило объединить методы борьбы с обоими
способами "взлома" в рамках одной статьи. Но приемы против каждого из
них - свои. Ведь противодействовать декодировке записанного на дискете
файла нельзя (допустима лишь пассивная защита - запутывание алгоритма
или шифрация самих кодов), зато при работе защищенных модулей на
компьютере ( пусть даже в пошаговом режиме отладки ) активное
сопротивление вполне возможно.
     Еще одно замечание. Искусственное усложнение исполняемого модуля
затрудняет исследование алгоритмов. Надежность защиты, в данном
случае, зависит от того, насколько программист отождествит себя со
"взломщиком", угадает логику его мышления и представит проблемы, с
которыми тот сталкивается. А для этого ему самому нужно побывать в
роли хакера, почти по системе Станиславского.

             ОБЫЧНЫЕ ПРОБЛЕМЫ ХАКЕРА
    Проще всего разбирать чужую программу, если она уже распечатана на
бумаге на любом языке высокого уровня (Паскаль, Си и т.д.), но в
крайнем случае сгодится и ассемблер (машинные коды заменены их
мнемоническим изображением). Кстати, в качестве универсального
инструмента рекомендуем отладчик Turbo Debugger (TD), имеющий широкий
сервис и удобный интерфейс.
     Естественно, автор программы, предусмотрев это, применил
шифрование или ее разновидность - архивацию. А потому непосредственное
дизассемблирование уже не даст верных результатов, если вообще что-то
даст. Опытный хакер быстро поймет, что вместо текста идет "мусор" и
сразу же начнет поиск средств для снятия шифра. Обычно он достигает
цели, так как рано или поздно программа сама производит нужную
операцию (она ведь не подозревает, что ее запустил хакер). Определив
момент завершения дешифрации, можно "снять" в файл содержимое памяти,
занимаемой уже "нормальной" программой, и, прогнав его дизассеблером,
получить желаемый результат.
    Даже если используется поэтапная дешифровка (то есть она разнесена
по времени), полной гарантии защиты нет - дизассемблирование лишь
несколько затянется. Впрочем, когда дешифрацией занимается несколько
подпрограмм и каждая является результатом работы предыдущей, хакеру
предстоит очень нудная и кропотливая работа по их анализу.
     Отметим, что шифрование, хотя и не гарантирует полной
безопасности программы, но вынуждает хакера запускать ее отдельные
участки (без алгоритмов, разбираясь "на ходу"), таким образом,
разработчику предоставляется возможность активно вмешиваться в процесс
"взлома" (точнее, поручить это своей программе) и, в первую очередь,
отобрать у хакера самый мощный инструмент - пошаговый режим отладки.
     В режиме отладки больше всего забот доставляет стек: его
расположение, размер, варианты применения. Достаточно тонкое его
использование зачастую делает невозможным даже запуск стандартных
отладочных средств. Например, назначение в тело выполняемой задачи:
стековый сегмент совпадает с кодовым, а указатель вершины стека SP
указывает на саму программу. Тогда отработка отладчиком хотя бы одного
прерывания (трассировочного) обязательно сотрет участок размером не
менее 3-х слов. Тем более, что популярные отладчики (TD, CodView и
другие) применяют только пользовательский стек, затирая в нашем случае
коды на большую глубину. Кроме того, старые версии TD имеют
принципиальную ошибку - при начальной загрузке совершенно произвольно
уменьшают стартовое значение указателя стека на 2. Более умеренно
работают со стеком отладчики AFD и PERISCOPE. И наиболее выгодно себя
проявляет обычный DEBUG, поставляемый вместе с DOS.
     Переназначение стека в свободную область памяти как средство
борьбы с назначением его в тело программы не каждому "по плечу", тем
более если через него передаются массивы данных из модуля в модуль, да
и он сам активно участвует в работе (как, например, в пакете CONVOY
фирмы "Элиас", осуществляющем через стек разархивацию защищенного
файла). В этом случае корректный проход программы возможен только без
трассировки (то есть пошаговый режим исключен).
     Не менее важная и такая же сложная проблема, стоящая перед
хакером, - отслеживание прерываний, перехватываемых исследуемой
программой. Суть в следующем. Все стандартные отладчики для нормальной
работы "забирают" первое и третье из них. Первое (трассировочное)
используется для пошагового режима. Третье необходимо для точек
останова программы по заданным адресам. Защитный механизм обязательно
должен их перехватывать, чтобы предотвратить анализ под отладчиком.
Хакер, если он разобрался с замыслом автора, может либо обойти данный
участок (с не малой долей риска, если прерывание выполняет некоторую
"полезную" функцию), либо изменить подпрограмму обработки прерывания
таким образом, чтобы после ее отработки управление передавалось
отладчику (но неумелое ее исправление тоже чревато...).
    Вот далеко не полный перечень того, с чем сталкивается "взломщик"
в своем нелегком труде, только при добывании текста.

                            ОТПОР АНАЛИЗУ:
                                НА УРОВНЕ ТЕКСТОВ ...
     Сформулируем приемы, мешающие анализу: шифрование и архивирование
(как его разновидность); использование самогенерируемых кодов;
изощренный стиль программирования и многое другое, что сможет
придумать автор.
     Шифрование исполняемых файлов - наиболее простое средство для
реализации. Достаточно, например, к каждому байту модуля добавить
некоторую константу, чтобы дизассемблер ничего "не понял".
    Предварительное архивирование также не представляет особых
затруднений для хакера, но является более эффективным по сравнению с
шифрованием, так как решает сразу две задачи: уменьшает размер
защищаемого модуля и скрывает код от дизассемблера. Как это делается?
Возьмем файл рисунка. Он содержит поточечное описание всех строк
экрана (цифры - это точки определенного цвета, ноль - ее отсутствие).
Например, рисунок красной линии на экране, состоящей из 200 точек,
записывается в файл в виде 200 байт, а значение каждого байта равно 4
(код для красного цвета). Архиватор заменяет перечисление одинаковых
цифр (эти 200 четверок) элементарным шифром - двумя байтами (первый -
количество повторов, второй - значение цвета), и размер файла резко
уменьшается (в примере - с 200 до 2 байт). Для других типов записей
существуют свои методы сжатия. Большинство из них описано в
литературе, поэтому не будем останавливаться.
    Метод самогенерируемых кодов наиболее сложен в реализации, но
очень эффективен. Суть его такова. В программу вложен массив данных,
который сам по себе может быть исполняемым кодом (реально получающим
управление) или смысловым текстом, но после некоторых арифметических
или логических операций преобразуемый в участок программы, выполняющий
иные, не менее важные функции.
     Нужно быть виртуозом программирования, чтобы заметить
самомодифицирующуюся ловушку. Ведь при анализе листинга и с явными
алгоритмами разбираться сложно (автор комментарии не оставляет), так
что уж говорить о потайном смысле вроде бы расшифрованного участка.
     Впрочем, и новичок-разработчик создать такие ловушки не сможет.
Но коль скоро он взялся за написание защитных механизмов, то ему
придется осваивать изощренный стиль программирования, который
запутывает дизассемблер нестандартной интерпретацией некоторых команд
и нарушает общепринятые соглашения. Например, использование необычной
структуры программы (совмещение стекового и кодового сегментов ).
Интеллектуальные дизассемблеры, как правило, это плохо воспринимают. А
перекрестные вызовы процедур, многократные переходы из модуля в модуль
и увеличение количества точек входа в них - не позволяют выявить
блочную структуру программы.
     Замена команд переходов, вызовов подпрограмм и прерываний
направляет дизассемблер по ложному следу. Здесь вместо стандартного
оператора вставляется группа других, в конечном счете выполняющих то
же самое. Для неискушенных программистов на рисунке 4.1 (а-д)
приведены такие варианты. Впрочем, для аналогичных эффектов достаточно
в команде перехода изменить значение операнда (примеры е-ж). И еще
проще модифицировать косвенные переходы (з-и).
    Кстати, и саму команду можно модифицировать. Например, на рис. 4.1
(к) дизассемблер по адресу m: покажет PUSH AX (запись регистра AX в
стек), поскольку этот байт имеет код 50h (01010000b), но перед ее
выполнением один бит (4-й) меняется, в результате получается INC AX с
кодом 40h (01000000b, увеличение содержимого регистра AX на 1) - то
есть совсем другая команда, не отраженная в листинге.
     Кропотливая работа преобразует участок до неузнаваемости. А
"умный" дизассемблер (например, Sourcer), отслеживая "явную" передачу
управления (в другое место), не найдет спрятанный блок и,
следовательно, не будет дизассемблировать его.

                          ... И В РЕЖИМЕ ОТЛАДКИ.
     Опытный хакер, если ему не надоест разбираться с защитой, будет
неоднократно прогонять непонятые куски программы отладчиком. Некоторые
приемы борьбы с этим уже рассматривались.
     Очень эффективное средство от пошагового выполнения программы -
назначение стека в ее тело. А если там находятся данные для работы, то
режим отладки усложняется. К тому же частое изменение местоположения
стека, поверьте на слово, измотает хакера окончательно.
    Напомним, что при пошаговом режиме хакеру рекомендовалось обходить
участки, перехватывающие 1-е прерывание. Так вот, чтобы он не смог
воспользоваться этим советом, нужно поручить подпрограмме обработки
прерывания некоторую полезную функцию. Например, генерацию кодов или
дешифрацию.
    Напомним также традиционные методы защиты [1].
    Программа должна подсчитывать и проверять контрольные суммы своих
участков для определения "контрольных точек" или "точек останова",
расставленных хакером. Дело в том, что стандартное применение 3-го
прерывания предусматривает запись кода его вызова вместо байта
программы, а это меняет контрольную сумму. Периодическая же проверка
вовремя проинформирует программу о замене "родных" байт "чужими", то
есть о попытке исследования программы под отладчиком.
    Известно, что выполнение программы в режиме трассировки
значительно уменьшает ее быстродействие. Поэтому по времени "прохода"
отдельных кусков защищаемого ПО можно определить работу под
отладчиком. По таймеру (например, запустив его 2-й канал) заранее
просчитывают скорость выполнения некоторого участка и сравнивают его
со значением, полученным в ходе работы программы. Если есть
существенное расхождение в полученных результатах, то можно сделать
вывод о выполнении данного участка под контролем. Из недостатков
метода отметим лишь разное быстродействие процессоров на разных ПЭВМ,
которое следует учитывать.
    Интересный способ выматывания "исследователя" - применение
достаточно больших процедур, производящих некоторую сложную и, на
первый взгляд, важную работу, но на самом деле, не имеющих никакого
отношения к логике работы программы, так называемых "пустышек". Для
лучшей имитации их важности можно включать в них перехват 13h, 21h,
25h и 26h прерываний (обслуживающих ввод-вывод информации на внешние
устройства), что, безусловно, заинтересует хакера.
    Оригинальный способ защиты ПО от исследования, примененный в
пакете COPYLOCK, использует конвейер шины данных микропроцессора. На
рис. 4.2 изображен его фрагмент. (Надеемся, что не навлечем на себя
гнев цивилизованных пользователей, афишируя некоторые тонкости
программы: все равно она безнадежно устарела, да и не вскрыта лишь
самыми ленивыми. А начинающим специалистам рекомендуем ознакомиться с
ее работой. Полный листинг опубликован в электронном журнале "НСК",
N1, 1992 г.). Фрагмент дан со значением смещений относительно кодового
сегмента, чтобы читатель смог увидеть, как команда REP STOSW в
подпрограмме SUBR затирает значением из регистра AX область ОЗУ, в
которой находится и сама подпрограмма. Тем не менее, SUBR нормально
отрабатывает и возвращает управление в точку вызова (но только не в
пошаговом режиме).
    Трюк очень прост: так как длина конвейера не менее 4-х байт, то,
очевидно, команды, расположенные за REP STOSW, уже находятся в нем до
ее выполнения, что и обеспечивает нормальную работу подпрограммы даже
после затирания ее кода в ОЗУ. Выполнение же по одному шагу (то есть
по трассировочному прерыванию) нарушает очередность засылки кодов в МП
и приводит к непредсказуемому результату.
    Пример на рис. 4.3 демонстрирует более изящное использование
конвейера. Он определяет - идет ли выполнение программы с трассировкой
или нет, и осуществляет ветвление (команда JMP с меткой m:) в
зависимости от этого. Здесь ветвление служит лишь для индикации работы
под отладчиком, но вы можете применить его по своему усмотрению.
     На рис. 4.4 использование конвейера шины данных в иной
интерпретации и в более завуалированном виде. По существу, это
вариация на ту же тему и демонстрирует лишь разнообразие способов
работы с конвейером.
     Аномальные явления, с которыми приходится сталкиваться при
программировании МП Intel 80x86, не менее интересная тема при
рассмотрении построения защитных механизмов. Информацию о них
программист чаще всего получает экспериментальным путем (что
становится его "ноу-хау"). Отступлений от стандарта обычно немного
(исключение составляют машины фирмы Compaq с длинным перечнем
особенностей). Об одном упоминалось в печати [2] - это потеря
трассировочного прерывания после команд, связанных с пересылкой
сегментных регистров типа MOV SEG.REG,R/M и POP SEG.REG. К сожалению,
в статье результаты исследований описаны неполно. Во-первых, для МП
8086/8088 (а точнее, японского аналога V20) существует еще один тип
команд, заставляющий пропускать трассировочное прерывание: MOV
R/M,SEG.REG. Во-вторых, для МП с более высоким номером также идет
потеря трассировки, но только для стекового сегментного регистра. Это
свойство с успехом можно применить для определения трассировки и типа
машин.
    Известно, что отладчики при обработке 1-го прерывания анализируют
текущую команду на PUSHF (код 9Ch) и сбрасывают Т-бит. Поэтому
последовательность команд PUSHF, POP AX под отладчиком не позволит
получить установленный 8-й бит в регистре AX. На рис. 4.5 представлен
текст короткой программы, использующей эту особенность. Команда POP SS
заставляет отладчик пропустить следующую за ней команду PUSHF из-за
потери трассировки, и, благодаря этому, выявляется факт работы под
отладчиком.
     Образцом знания особенностей работы МП и наиболее лаконичным
вариантом распознавания его типа мы считаем подпрограмму, текст
которой приведен в статье "Intel insight on specific instructions"
[3]. Вот два примера из нее:
    1) Для определения типа МП, начиная с 80186 и выше, используется
тот факт, что для них в счетчиках сдвигов (линейных и циклических)
маскируются все биты, кроме 5-и младших, ограничивая тем самым
величину сдвига 31 битом.
    2) Начиная с МП 80286, характерна следующая особенность: команда
PUSH SP заносит в стек значение SP с учетом его декремента, а более
низшие типы МП - без.
    Для пытливого ума выявление особенностей микропроцессоров сослужит
хорошую службу как при составлении защитных алгоритмов, так и для
идентификации ПЭВМ, а именно на таких программистов и рассчитана эта
статья.
   В качестве примера, реализующего некоторые приемы, была разработана
утилита DLOCK. Правила пользования ею приведены в приложении 2.

                 Л и т е р а т у р а
     1. Дмитриевский Н.Н., Расторгуев С.П. " Искусство защиты
и "раздевания" программ", "СОВМАРКЕТ", 1991.
     2. статья "Особенности работы МП 8086/8088 в пошаговом
режиме", "Журнал д-ра Добба", N 2, 1991.
     3. "Intel insight on specific instructions", "Personal
Computer World", April, 1990.

        ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
        і         СОКРЫТИЕ АДРЕСОВ                                   і
        іа) безусловного перехода                                    і
        і    jmp m        mov ax,offset m  ; занести в стек          і
        і    . . .        push ax          ; адрес метки.            і
        і                 ret              ; перейти на метку.       і
        і                 . . .                                      і
        і  m:. . .     m: . . .                                      і
        і    . . .        . . .                                      і
        іб) вызов подпрограммы                                       і
        і    call subr          mov ax,offset m  ; занести в стек    і
        і    . . .              push ax          ; адрес возврата.   і
        і    . . .              jmp subr         ; перейти на под-   і
        і    . . .         m:   . . .            ; программу.        і
        і  subr:        subr:   . . .                                і
        ів) прерывание                                               і
        і    int 21h           pushf         ; занести в стек флаги. і
        і    . . .             xor si,si                             і
        і                      mov es,si                             і
        і                      call dword ptr es:[21h*4]             і
        і                        . . .                               і
        іг) возврат из подпрограммы                                  і
        і    . . .                  . . .          ; взять из стека  і
        і    ret                    pop bx         ; адрес возврата иі
        і                           jmp bx         ; перейти на него.і
        і   . . .                  . . .                             і
        ід) выход из прерывания                                      і
        і   iret                mov bp,sp          ; переход на точкуі
        і                       jmp dword ptr [bp] ; возврата из пре-і
        і   . . .               . . .              ; рывания.        і
        і                       add sp,4           ; точка возврата. і
        і                       popf                                 і
        і                       . . .                                і
        і        МОДИФИКАЦИЯ                                         і
        іе) перехода                                                 і
        і     mov word ptr cs:m+1,1234h  ; адрес 1234h вписать вместоі
        і     . . .                      ; 0000 у оператора безуслов-і
        і  m: jmp 0000h                  ; ного перехода             і
        і     . . .                                                  і
        іж) вызываемой подпрограммы                                  і
        і      mov word ptr cs:m+1,es    ; изменить сегмент п/п      і
        і      mov word ptr cs:m+3,5678h ; и адрес 0000 на 5678h     і
        і      . . .                                                 і
        і  m:  call far 0000h                                        і
        і      . . .                                                 і
        із) косвенного перехода                                      і
        і      mov bx,1234h                                          і
        і      jmp dword ptr cs:[bx]                                 і
        і      . . .                                                 і
        іи) косвенного вызова подпрограммы                           і
        і      les si,dword ptr cs:subr                              і
        і      call word ptr es:[si]                                 і
        і      . . .                                                 і
        ік) команды                                                  і
        і      and  byte ptr cs:m,0EFh ; обнулить 4-й бит по адресу mі
        і      . . .                                                 і
        і  m:  push ax              ; команда преобразуется в INC AX і
        і      . . .                                                 і
        АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
                            рис. 4.1

                        Фрагмент пакета COPYLOCK
            (использование конвейера шины данных микропроцессора)
        ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
        і         . . . . .                                          і
        іcs:07FF          mov     cx,40Eh                            і
        іcs:0802          mov     di,08A6h                           і
        іcs:0805          call    subr                               і
        і        . . . . .                                           і
        і;=====================================                      і
        і; Затирание участка памяти.                                 і
        і        subr     proc    near                               і
        іcs:0D63          pushf                                      і
        іcs:0D64          cld                                        і
        іcs:0D65          mov     ax,ds                              і
        іcs:0D67          mov     es,ax                              і
        іcs:0D69          rep     stosw                              і
        іcs:0D6B          popf                                       і
        іcs:0D6C          retn                                       і
        і        subr     endp                                       і
        АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
                               рис. 4.2

                    ОПРЕДЕЛЕНИЕ РЕЖИМА ТРАССИРОВКИ
                              (1 вариант)
        ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
        і 1 0000         code    segment para public                 і
        і 2              assume cs:code,ds:code                      і
        і 3                                                          і
        і 4 0000         sample1  proc                               і
        і 5                                                          і
        і 6 0000  0E               push cs                           і
        і 7 0001  1F               pop ds                            і
        і 8 0002  C6 06 0008r 00   mov byte ptr m+1,0  ; изменение   і
        і                                 ; смещения в команде JMP   і
        і 9 0007  EB 06        m:  jmp short norm_ex                 і
        і10 0009  BA 001Br         mov dx,offset trace ; выполнение сі
        і                                              ; трассировкойі
        і11 000C  EB 04 90             jmp exit                      і
        і12 000F                       norm_ex:      ; выполнение безі
        і                                            ; трассировки   і
        і13 000F  BA 0026r             mov dx,offset norm            і
        і14 0012               exit:                                 і
        і15 0012  B4 09                    mov ah,9                  і
        і16 0014  CD 21                    int 21h                   і
        і17 0016  B8 4C00              mov ax,4C00h                  і
        і18 0019  CD 21                int 21h                       і
        і19                                                          і
        і20 001B               trace   db 'Tracing!',0Ah,0Dh,'$'     і
        і21                                                          і
        і22 0026               norm    db 'Normal exit.',0Ah,0Dh,'$' і
        і23                                                          і
        і24                                                          і
        і25 0035         sample1  endp                               і
        і26 0035         code     ends                               і
        і27                       end     sample                     і
        АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
                               рис. 4.3

                        ОПРЕДЕЛЕНИЕ РЕЖИМА ТРАССИРОВКИ
                                 (2 вариант)
        ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
        і 1 0000        code    segment para public                  і
        і 2                     assume cs:code,ds:code               і
        і 3                                                          і
        і 4 0000        sample2    proc                              і
        і 5                                                          і
        і 6 0000  0E               push cs                           і
        і 7 0001  0E               push cs                           і
        і 8 0002  07               pop es                            і
        і 9 0003  1F               pop ds                            і
        і10 0004  BF 000Cr         mov di,offset m                   і
        і11 0007  F9                   stc                           і
        і12 0008  FC                   cld                           і
        і13 0009  B0 88                mov al,88h                    і
        і                           ; заменить код операции следующейі
        і                           ; команды на mov byte ptr m, al. і
        і14 000B  AA                   stosb                         і
        і15 000C  3A 06 000Cr  m:  cmp al,byte ptr m                 і
        і16 0010  73 06            jnc norm_ex                       і
        і17 0012  BA 0024r         mov dx,offset trace               і
        і                                ; выполнение с трассировкой,і
        і                                ; если бит CF остался       і
        і18 0015  EB 04 90         jmp exit         ; установленным. і
        і19 0018           norm_ex:                                  і
        і20 0018  BA 002Fr             mov dx,offset norm            і
        і21 001B           exit:                                     і
        і22 001B  B4 09                mov ah,9                      і
        і23 001D  CD 21                int 21h                       і
        і24 001F  B8 4C00              mov ax,4C00h                  і
        і25 0022  CD 21                int 21h                       і
        і26                                                          і
        і27 0024           trace   db 'Tracing!',0Ah,0Dh,'$'         і
        і28 0024                                                     і
        і29 002F           norm    db 'Normal exit.',0Ah,0Dh,'$'     і
        і30                                                          і
        і31                                                          і
        і32 003E        sample2  endp                                і
        і33 003E        code     ends                                і
        і34                      end     sample2                     і
        АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
                               рис. 4.4

                         ОПРЕДЕЛЕНИЕ РЕЖИМА ТРАССИРОВКИ
                                   (3 вариант)
        ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
        і 1 0000        code    segment para public                  і
        і 2                     assume cs:code,ds:code               і
        і 3                                                          і
        і 4 0000        sample3  proc                                і
        і 5                                                          і
        і 6 0000  0E           push cs                               і
        і 7 0001  0E           push cs                               і
        і 8 0002  1F           pop ds                                і
        і 9 0003  17           pop ss                                і
        і10 0004  9C             pushf                               і
        і11 0005  58             pop ax                              і
        і12 0006  F6 C4 01       test ah,1    ; бит TF установлен ?  і
        і13 0009  74 06          jz norm_ex   ; нет - уйти на norm_exі
        і                               ; да  - вып-ие с трассировкойі
        і14 000B  BA 001Dr       mov dx,offset trace                 і
        і15 000E  EB 04 90       jmp exit                            і
        і16 001          norm_ex:                                    і
        і17 0011  BA 0028r          mov dx,offset norm               і
        і18 0014            exit:                                    і
        і19 0014  B4 09             mov ah,9                         і
        і20 0016  CD 21             int 21h                          і
        і21 0018  B8 4C00           mov ax,4C00h                     і
        і22 001B  CD 21             int 21h                          і
        і23                                                          і
        і24 001D            trace   db 'Tracing!',0Ah,0Dh,'$'        і
        і25                                                          і
        і26 0028            norm    db 'Normal exit.',0Ah,0Dh,'$'    і
        і27                                                          і
        і28                                                          і
        і29 0037        sample3 endp                                 і
        і30 0037        code    ends                                 і
        і31                     end     sample3                      і
        АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
                               рис. 4.5

                        DLOCK  ver 2.0
    DLOCK.EXE - программа встраивания в .EXE файлы модуля защиты от
отладчиков и дизассемблеров, которая сама может использоваться как
часть защиты программного обеспечения. Ее достоинством является то,
что пользователь выбирает место расположения встраиваемых защитных
модулей в своей программе.
        Формат запуска программы:
        DLOCK  <имя файла> <смещение>
где:
    <имя файла> - полное имя защищаемого .EXE файла.
    <смещение> - смещение от начала файла, заданное в любой системе
                 счисления до начала буфера , в который будет размещен
                 модуль защиты (не менее 300h байт).
    Для нормальной работы, при программировании необходимо
зарезервировать в своей программе область памяти не менее 300h байт.
Упростить поиск этой области в оттранслированном .EXE файле поможет
какое-нибудь оригинальное ключевое слово. Например:
        Ассемблер:      DB      'figtebe',300h DUP (?)
        C:              char buf[0x300] = "figtebe" ;
    Средствами поиска любой оболочки DOS (XTREE, Norton Commander,
PCTOOLS и др.) находим ключевое слово и определяем по нему смещение,
требуемое в качестве 2-го аргумента формата запуска программы.
Например, если при просмотре командой View (в режиме Hex) в пакете
XTREE .EXE файл выглядел так:
  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
 000240    kstackstackstack
 000250    .3.P..........!.
 000260    ....figtebe.....
 000270    ................
 .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
то смещение равно 264 и формат запуска программы такой:

        DLOCK YOURFILE.EXE 0x264

                         рис. 4.6

           5. САМОМОДИФИКАЦИЯ ПРОГРАММ - ЭФФЕКТНО И ПОЛЕЗНО
     С самомодифицирующейся программой, т.е. такой программой, которая
постоянно меняет свой исполняемый код, разбираться очень трудно.
Представьте, в распечатке с дизассемблированным текстом хакер не понял
какой-то участок. Естественно, что он загрузит отладчик и попробует
"прогнать" непонятный блок в пошаговом режиме. Каково же будет его
удивление, когда он не сможет найти эту часть - по тем же адресам
записано совсем другое. Он удивится еще больше, после того как сравнит
имеющийся листинг с тем, что выводится на экран компьютера. "Ведь это
посторонняя программа! А где же та, на анализ которой я потратил
столько времени?" - воскликнет он. И при последующих попытках
происходит тоже самое - каждый раз предыдущий текст бесследно
исчезает, а на его месте возникает нечто новое, требующее повторного
анализа.
     Впрочем, полностью самомодифицирующиеся модули - большая
редкость. В профессиональных системах защиты чаще применяется
частичная переработка кодов. Легче всего модифицировать EXE и
COM-файлы при загрузке в ОЗУ, выбирая куски для переработки случайным
образом, и при этом можно сразу же вносить изменения в исходный файл
программы на магнитном носителе. Как именно? Познакомьтесь с
несколькими способами.

                ЗАМЕНА НА ЭКВИВАЛЕНТЫ
     Самый простой - периодически заменять одну последовательнось
команд на другую, внешне не похожую, но, в конечном итоге, выполняющую
то же самое действие. Для этого подбираем эквиваленты. Например,
команда MOV AX,BX и последовательность PUSH BX и POP AX - выполняют
одно действие (пересылка содержимого регистра BX в регистр AX),
команда CALL adr заменяется на последовательность PUSH IP+3 и JMP adr.
Примерные варианты взаимозамены для основных команд ассемблера
приведены в таблице 5.1 (естественно, для конкретных программ ее нужно
дополнить и расширить).
     В тексте программы организуется участок, где будут храниться
цепочки команд, с указанием адресов эквивалентных им участков. При
очередной работе программа случайным образом меняет местами отдельные
части из собственного тела и "хранилища". В результате после каждого
прохода исполняемый код будет случайным образом изменен до
неузнаваемости, однако функции программы не нарушаются. Единственный
недостаток этого способа - новый вариант исполняемого кода часто не
может быть адекватен предыдущему по скорости работы.
     Разумеется, конкретная таблица может иметь несколько
альтернативных вариантов для каждой последовательности. А для
выравнивания их длин можно использовать команду NOP или ее аналоги
(пара PUSH - POP или MOV AX,AX).
     Включение в алгоритм элементов случайности делает "внешность"
задачи непредсказуемой. Пример этого способа приведен на прилагаемой
дискете.

                         ИЗМЕНЕНИЕ КОДИРОВКИ
     Более сложный способ - модификация кодов команд с изменением
характера выполняемых операций (рис. 5.1). Делается это так.
Написанный на ассемблере и уже отлаженный модуль транслируется в
объектный код с получением листинга. На листинге, не обращая внимания
на мнемонику, ищем участки с похожими закономерностями изменения
величин кодов команд (вот где пригодится опыт решения математических
задач, типа "найди закономерность", из популярных журналов). Затем
выделяем найденные участки в отдельную подпрограмму и, используя
подмеченную закономерность, составляем алгоритм ее преобразования в
коды первого участка, второго, третьего... Этот алгоритм встраиваем
вместо участков и по завершению преобразования подпрограммы - передаем
ей управление. Как правило, с первой попытки полной аналогии с изъятым
блоком не получается, поэтому нужно поманипулировать командами,
переставить их местами, может быть - добавить лишние (тем не менее не
нарушающими общего алгоритма), что-то заменить эквивалентной
последовательностью.

                    ПРОХОД "СВОИМ ХОДОМ" ПО ДАННЫМ
     Несмотря на кажущуюся простоту, одновременное использование
некоторых байт как операторов и операндов является "высшим пилотажем"
в программировании. Способ пришел от программистов для 8-разрядных
процессоров типа Z80, К580 и др. Дело в том, что у них основные коды
однобайтовых пересылок и букв совпадают, к тому же у компьютеров с МП
Z80 маловато ОЗУ (приходится его экономить). Вот и используют участки
осмысленного текста - как для появляющихся на экране сообщений, так и
для загрузки нужных регистров. Разумеется, некоторые буквы оказываются
лишними при прогоне участка, как кода программы. Но, с другой стороны,
вслед за "сообщением" можно поставить несколько команд, корректирующих
результаты ненужных операций. Пример приведен в распечатке листинга
игры "Jetpac" фирмы "Ultimate" для компьютера "Spectrum-48" на рис.
5.2 (для МП Z80). По ходу космической игры в верхней части экрана
появляются надписи: "1UP" (результат 1 игрока), "HI" (лучший результат
за всю игру) и "2UP" (2 игрок). При анализе текста программы
выяснилось, что эти надписи образуют отдельную подпрограмму,
осуществляющую пересылки некоторого значения из ячейки ОЗУ (адрес
0D055h) в стек и из аккумулятора в эту же ячейку (то есть сложный
обмен значениями между регистром A, стеком и ОЗУ).
     Впрочем, то что легко программируется для 8-разрядных
процессоров, вызывает определенные трудности на 16-разрядных: и
характер операций у "буквенных" кодов другой, и однобайтовых команд
мало (с двух - трехбайтовыми разбираться еще сложнее). Тем не менее,
после некоторой тренировки можно и этот способ взять на вооружение.

                            ЗАМЕНА БЛОКОВ
     Традиционный подход при использовании ветвления заключается в
построении 2-х участков с разным набором команд. При выполнении
запрограммированного условия - выполняется первый, в противном случае
- управление передается на второй. В самомодифицирующихся модулях
лучше отойти от общепринятой схемы, и применить переброску того или
иного блока на один и тот же участок программы. Сработало условие - на
следующие за ним адреса записывается первый набор команд, не сработало
- другой, затирая предыдущие (тем более, что у МП 286 и выше - блочные
пересылки выполняются легко и быстро).
     Определить в распечатке такой "оверлейный" блок - очень сложно,
особенно, если его куски хранятся в других сегментах.

                            БЛОК ДЕКОДИРОВАНИЯ
                (присланный Ерко В.Д., автор неизвестен):
        ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
        і    ; 1 модуль программы                                    і
        іn:  mov HL, nn   ; адрес начала блока                       і
        і    mov BC, ll   ; длина блока                              і
        і    mov AX, kk   ; ввод ключа декодера                      і
        і    xor (HL)     ; декодирование                            і
        і    mov (HL), AX ; замена закодирован. значения на раскодир.і
        і    inc HL       ; переход к очередному байту               і
        і    dec BC       ; уменьшение счетчика                      і
        і    jnz  n       ; повтор декодирования, если BC > 0        і
        і    ..........   ; продолжение модуля                       і
        і    ; 2 модуль программы                                    і
        іnn: db .......................                              і
        і                 ; (Закодированный блок.)                   і
        і    db ........  ; конец блока, адрес = nn + ll             і
        імм: db ........  ; 3 модуль (и так далее)                   і
        і                                                            і
        і      После декодирования 1  блока  и  исполнения  остальныхі
        ікоманд управление передается на декодированный блок, которыйі
        іначинается  с  такой  же  процедуры,  декодирующей следующийі
        іучасток. И таких вложений - 156.                            і
        АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

                                рис. 5.1

                 ИСПОЛЬЗОВАНИЕ ТЕКСТА КАК КОДА ПРОГРАММЫ
                        (для микропроцессора Z80)
        ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
        і6E1E  C3 6C 71    jmp  716Ch      ; завершение предыдущего  і
        і                                  ; участка                 і
        і6E21  47          mov  B,A        ; начало подпрограммы     і
        і6E22  31 55 D0    mov  SP,0D055h  ;1UP - текст первого      і
        і                                  ; сообщения               і
        і6E25  47          mov  B,A        ;                         і
        і6E26  32 55 D0    mov  (0D055h),A ;2UP - текст второго      і
        і                                  ; сообщения               і
        і6E29  45          mov  B,L        ;                         і
        і6E2A  48          mov  C,B        ;H - третье сообщение     і
        і6E2B  C9          ret             ;I   (оно же завершает    і
        і6E2C  21 00 00    mov  HL,0000    ;     подпрограмму)       і
        АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

                            рис. 5.2

                                                      Таблица 5.1
                            ВЗАИМОЗАМЕНЯЕМЫЕ КОМАНДЫ
                 ЪДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДї
                 і Первичный код       і Альтернативный код     і
                 ГДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДґ
                 і               Команды пересылки:             і
                 ГДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДґ
                 і  mov op1,op2        і    push op2            і
                 і                     і    pop op1             і
                 ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДґ
                 і  xchg op1,op2       і    push op1            і
                 і                     і    push op2            і
                 і                     і    pop op1             і
                 і                     і    pop op2             і
                 ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДґ
                 і  lds r,dword ptr op і    mov r,word ptr op   і
                 і                     і    mov ds,word ptr op+2і
                 ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДґ
                 і  les r,dword ptr op і    mov r,word ptr op   і
                 і                     і    mov es,word ptr op+2і
                 ГДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДґ
                 і               Арифметические команды:        і
                 ГДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДґ
                 і  add op1,op2        і    xchg op2,ax         і
                 і                     і    add op1,ax          і
                 і                     і    xchg op2,ax         і
                 ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДґ
                 і  adc,sub,sbb и др.  і    аналогично add      і
                 ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДґ
                 і  inc op             і    add op,1            і
                 ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДґ
                 і  dec op             і    sub op,1            і
                 ГДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДґ
                 і               Логические команды:            і
                 ГДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДґ
                 і and,or,xor и др.    і    аналогично add      і
                 ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДґ
                 і  not op             і    xor op,0ff(ff)h     і
                 ГДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДґ
                 і               Цепочечные команды:            і
                 ГДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДґ
                 і  rep movsb          і     push ax            і
                 і                     і m:  mov al,[si]        і
                 і                     і     mov es:[di],al     і
                 і                     і     inc si             і
                 і                     і     inc di             і
                 і                     і     loop m             і
                 і                     і     pop ax             і
                 ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДґ
                 і  repe(repne) cmpsb  і     push ax            і
                 і                     і m:  mov al,[si]        і
                 і                     і     cmp al,es:[di]     і
                 і                     і     jne(je) m1         і
                 і                     і     inc si             і
                 і                     і     inc di             і
                 і                     і     loop m             і
                 і                     і m1: pop ax             і
                 ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДґ
                 і  lodsb              і    mov al,[si]         і
                 і                     і    inc si              і
                 ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДґ
                 і  stosb              і    mov es:[di],al      і
                 і                     і    inc di              і
                 ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДґ
                 і  shift  op,cnt      і     push cx            і
                 і                     і     mov cx,cnt         і
                 і                     і m:  shift op,1         і
                 і                     і     loop m             і
                 і                     і     pop cx             і
                 ГДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДґ
                 і         Команды передачи управления:         і
                 ГДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДґ
                 і  j(условие) loc     і     jn(условие) loc1   і
                 і                     і     jmp loc            і
                 і                     і loc1:  . . .           і
                 ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДґ
                 і  loop loc           і    dec cx              і
                 і                     і    jne loc             і
                 ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДґ
                 і  jmp addr           і    push addr           і
                 і                     і    ret                 і
                 ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДґ
                 і  jmp dword ptr addr і    push addr+2         і
                 і                     і    push addr           і
                 і                     і    retf                і
                 ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДґ
                 і  call addr          і     push m             і
                 і                     і     jmp addr           і
                 і                     і m:   . . .             і
                 АДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДЩ
     Cокращения: op, op1, op2 - операнды команд; r - операнд-регистр;
shift - код команды сдвига; cnt - счетчик в командах сдвига; loc -
метка в командах перехода и цикла; addr - адрес в командах перехода и
вызова подпрограмм.

              6. ИСПОЛНЯЕМЫЙ МОДУЛЬ - ЧТО МОЖНО СДЕЛАТЬ
                        БЕЗ ИСХОДНЫХ ТЕКСТОВ?
     Одной из самых сложных работ в программировании является
модификация исполняемых модулей при отсутствии исходных текстов. Надо
признать, что программисту не часто приходится заниматься подобными
работами, но, однако, никто не застрахован от потери собственных
исходных текстов программ. В частности, мы обратились к решению
названной задачи для того, чтобы исправить найденную в нашем пакете
ошибку. "Исходники" к тому времени были случайно уничтожены при борьбе
с вирусом. Бесполезно вспоминать и переписывать весь пакет - за тот
срок, в течении которого гарантировалось устранение любых замечаний,
мы в любом случае не успевали этого сделать. Поэтому стали искать
другие пути. В результате разработали соответствующий метод и даже
набор инструментальных средств, который с успехом применяем по сей
день.
     Разумеется, приемы корректировки исполняемых модулей
предназначены профессиональным разработчикам ПО для IBM PC в среде
DOS. Поэтому опустим некоторые детали, которые профессионал должен
знать, а в качестве примера возьмем лишь EXE-файлы - более сложные для
модификации, поскольку все сказанное может быть отнесено и к
COM-файлам.
     Напомним, что EXE-файл состоит из заголовка, таблицы перемещения
и собственно исполняемого кода. Информация заголовка используется
операционной системой для загрузки модуля в оперативную память.
Устанавливаются значения основных регистров, обрабатывается таблица
перемещения, а затем управление передается задаче. В ходе работы все
основные функции ввода/вывода, захвата или освобождения ОЗУ и т.п.
обрабатываются операционной системой через прерывание 21h, а значит,
всегда могут быть изменены с помощью специального драйвера, который
либо резидентно находится в памяти, либо непосредственно включен в
модифицируемый EXE-файл. Второй подход более удобен.
     Для корректировки функций EXE-файла необходимо: внедрить в него
этот драйвер; осуществить передачу управления на драйвер.

               ВКЛЮЧЕНИЕ В ТЕЛО EXE-файла СВОЕГО МОДУЛЯ
      Вариантов включения собственного блока в существующий EXE-файл
несколько: можно добавить его в конец или в начало файла; встроить в
свободное место внутри программы или "склеить" им оба EXE-файла (свой
и модифицируемый).
     Легче всего добавить дополнительные команды в конец EXE-файла и
исправить в заголовке размер загружаемой части (с учетом добавленных
байт). Однако предварительно необходимо проверить, возможна ли их
загрузка в ОЗУ. Дело в том, что задача может быть оверлейной и DOS
загрузит только ее корневой сегмент. Например, в BORLAND C++ размер
BCC.EXE более 800 кб, а объем ОЗУ всего 640 кб. Ясно, что загрузкой и
выгрузкой отдельных частей гиганта занимается специальный блок в
корневом сегменте программы, который ничего не знает о "прилепленном"
в конце модуле, и поэтому тот никогда не попадет в оперативную память.
А в заголовке имеется информация только о корневом блоке, небольшом по
размеру. Так что если к загружаемой части не относится "хвост", значит
данный метод здесь не годится.
     В этом случае можно поискать "пустые" места в загружаемой части
EXE-файла. Например, цепочку любых повторяющихся кодов. Если размер
найденного пространства больше модуля, то все в порядке и следует
вписать туда свои команды.
     Если же и этого нет, то пробуем включить свой модуль в начало
программы, сразу за таблицей перемещения, конечно, при наличии там
свободного места. Впрочем, в отличие от предыдущего способа, здесь его
всегда можно создать. Достаточно "раздвинуть" файл и изменить таблицу
перемещения с учетом сдвига, затем подправить заголовок (адрес первой
исполняемой команды и размер загружаемой в память части файла).
Кстати, пример такой программы с комментариями приводится на дискете.
     В принципе, можно и не раздвигать файл, а создать модуль в виде
такого же COM или EXE-файла. Затем изменить список распределения
кластеров в FAT-таблице каталога, не трогая их самих.
     FAT (File allocation table) - это таблица в начальных секторах
дискеты, которая содержит связный список цепочек кластеров, занимаемых
тем или иным файлом на диске или относящимися к свободному
пространству [2]. Ее дополняет оглавление файлов (называемое также
директорий или каталог). Два байта по смещению 1Ah в элементе
оглавления каждого файла содержат номер начального кластера цепочки, а
каждый элемент цепочки в FAT-таблице указывает на следующее звено или
информирует о конце файла.
     Для включения модуля в EXE-файл необходимо найти в FAT-таблице
цепочку, отмечающую занятые модулем кластеры диска и заменить в ней
метку "конец модуля" ссылкой на начальный кластер встраиваемого
исполняемого файла. Затем в элементе оглавления файла исправить номер
начального кластера (вместо него вписать стартовый номер кластера
нашего модуля), а сам модуль пометить как удаленный.
     В результате при запуске EXE-файла на выполнение операционная
система загрузит в память содержимое всей цепочки кластеров с диска, в
том числе и кластеров нашего файла, который первым получит управление.
Теперь уже его команды должны отвечать за запуск исполняемой части
EXE-файла, в который он был внедрен.
     Основная сложность при "склейке" двух программ заключается в том,
чтобы после первой корректно запустить вторую. Если первая - ваша,
вопрос решается просто: при ее завершении нужно передать управление по
адресам, взятым из заголовка второй задачи. Если же обе из
"склеиваемых" - "чужие", причем завершаются в неизвестном месте и
неизвестным способом, то выход один - необходимо изменить часть DOS,
обрабатывающую функции завершения процессов.
     Это можно сделать двумя способами. Первый. Создается специальный
драйвер перехватывающий все функции завершения работы программ
(назовем его монитор). Затем, "склеиваются" вместе все выбранные EXE
или COM-файлы, причем сначала в полученном конгламерате размещается
монитор. При запуске он принимает на себя обработку прерываний, а
получив управление, анализирует - какая из задач уже отработала,
освобождает ресурсы, выбирает и размещает в ОЗУ следующую задачу, и
передает ей управление. После последней задачи монитор восстанавливает
исходную подпрограмму DOS и завершает свою работу.
    Второй вариант является модификацией первого. Разница заключается
только в том, что монитор не обладает суверенитетом отдельной задачи,
а прикрепляется к первой из них одним из уже описанных способов. После
этого, к "зараженной" монитором задаче можно командой COPY добавлять
любое количество EXE-файлов.

                         ПЕРЕДАЧА УПРАВЛЕНИЯ
     Управление автоматически перейдет на модуль, внедренный в тело
EXE-файла, если изменены начальные значения регистров CS и IP в
заголовке файла (байты 20 - 23 заголовка) или первый оператор, на
который указывают эти регистры (вместо него ставят команду перехода
JMP либо CALL по адресу своего модуля). Но можно перехватить
управление исправив номер прерывания в двухбайтовой команде INT.
Рассмотрим эти методы подробнее.
     Для изменения начальных значений регистров CS и IP в заголовке
EXE-файла после внедрения блока команд в его тело нужно скопировать с
20 по 23-й байт заголовка (CS:IP) в специальный буфер, предусмотренный
в модуле. Затем вписать в заголовок файла адрес первой команды модуля,
а по его завершении передать управление на сохраненный в буфере адрес
начала выполнения EXE-файла.
     Впрочем, можно измененить первую команду (указанную регистрами
CS:IP), не меняя сам заголовок. После внедрения блока команд в тело
файла скопируем первые байты в заранее предусмотренный буфер, а вместо
них впишем JMP или CALL с адресом модуля. По завершении его работы
выполним сохраненные в буфере команды EXE-файла и передадим управление
ему самому (на адрес из заголовка файла с учетом уже выполненных
команд).
     Если же недалеко от начала EXE-файла встретится собственный JMP
или CALL с атрибутом far , то достаточно изменить адрес перехода у
существующей команды (запомнив первоначальное значение) на адрес
встроенного модуля. Удостовериться в том, что обнаруженный вами байт (
EAh или 9Ah ) действительно является первым байтом команды JMP или
CALL с аттрибутом FAR можно используя таблицу перемещения: один из ее
элементов должен указывать на адрес на 3 больший, чем адрес найденного
байта (это сегментная часть адреса в команде).
    Изменение номера прерывания в двухбайтной команде INT является
самым простым из всех перечисленных способов перехвата управления.
Метод не требует внедрения своего модуля в тело "чужого" файла.
Достаточно лишь изготовить резидентный драйвер, отрабатывающий любое
свободное прерывание DOS. А в EXE-файле ищем первое попавшееся
прерывание и заменяем его тем, на котором "висит" наш драйвер.
Естественно, что он должен обрабатывать и функцию исправленной команды
INT в ЕХЕ-файле.

                ДИНАМИЧЕСКАЯ КОРРЕКТИРОВКА ПРОГРАММЫ.
    Допустим, надо отстранить резидентную задачу от обработки
какого-либо прерывания. В этом случае необходимо выяснить, какая из
загруженных в ОЗУ программ получает, словно эстафетную палочку,
обработку данного прерывания.
    Доступ к диску осуществляется, в основном, через 13h и 21h
прерывания. Системы защиты обычно "забирают" их на себя и проверяют,
разрешен ли доступ по ним. Если разрешен, то остальной процесс
возвращается обратно к операционной системе. Порой, чтобы снять
защиту, достаточно восстановить переустановленный вектор прерывания,
направив его на DOS. А найти старый адрес поможет пошаговый режим
(трассировка) отладчика. Но как определить, что "процесс дошел" именно
до защитного механизма? Это можно сделать автоматически. Текст такой
программы (на языке Си) находится на дискете в директории FTRACE.
    Заметим, что трассировкой пользуются не только отладчики, но и
вирусы. Метод их работы демонстрируется программой RV (файлы rv.c,
ftrace.asm, ftrace.h). Кстати, "вирусный" подход можно использовать и
для борьбы с вирусами же. Практика показала его эффективность:
например, приведенная на дискете программа protect.asm мешает "хорошо
себя чувствовать" некоторым вирусам, но и, правда, некоторым
антивирусам тоже.

                7. КАК ОЧИСТИТЬ ПРОГРАММУ ОТ ВИРУСОВ И
                         ПРИСТЫКОВАННЫХ ЗАЩИТ
     В прерыдущей главе описано, как внедрить защитный механизм в тело
программы. В этой, напротив, расскажем о способе его удаления с
помощью программы EXEB, имеющейся на дискете.

                              НАЗНАЧЕНИЕ
     Программа EXEB.EXE предназначена для анализа исполняемых модулей
и удаления из них пристыковочных частей - вирусов, защит и т.п. Она
корректно работает на ПЭВМ типа IBM PC/XT/AT в среде MS DOS версии 3.1
и выше.
                СОДЕРЖИМОЕ ДИСКЕТЫ И ПОРЯДОК УСТАНОВКИ
            Поставляемая дискета содержит следующие файлы:
 README      - описание;
 EXEB.EXE    - основная программа;
 CHSIZE      - утилита для уменьшения размера  результирующей задачи.
   Перед началом работы необходимо скопировать дискету на жесткий диск
в любой директорий.

   Формат команды запуска:
     EXEB [!] <IntNumber> <FuncNumber> <Counter> <TaskName>
               [<CommandLine>]
 где:
       !        -  признак "холостого" срабатывания;
  <IntNumber>  ::= номер перехватываемого прерывания;
  <FuncNumber> ::= номер функции (AH) указанного прерывания;
  <Counter>    ::= счетчик появлений функции FuncNumber;
  <TaskName>   ::= имя исследуемой задачи;
  <CommandLine>::= аргументы  командной   строки  исследуемой
 задачи.
    Примечание:
     В командной строке в качестве аргумента FuncNumber разрешен
символ "*".
     Числовые аргументы задаются в 16-ричной системе счисления.
     Например, "EXEB 21 30 1 a.exe" - означает: перенести код
исследуемой задачи a.exe в результирующий EXE-файл при первом
обращении к 30h функции 21h прерывания после запуска a.exe.
     Аргументы желательно выбирать таким образом, чтобы они
соответствовали первому после пристыкованного блока прерыванию в теле
исследуемой задачи.
     Если программа была создана компиляторами с языков высокого
уровня (С, PASCAL, BASIC и т.п.), то рекомендуются следующие значения
аргументов:
  <IntNumber>   = 21                     <IntNumber>   = 21
  <FuncNumber>  = 30       или           <FuncNumber>  = 35
  <Counter>     = 1                      <Counter>     = 1.
    EXEB позволяет исследовать исполняемый EXE-модуль на команды
вызова прерываний (int). Их номера фиксируются программой EXEB, если в
качестве аргумента FuncNumber использован символ "?". Например: при
строке запуска программы "EXEB 10 ? 1 a.exe" в крайнем правом столбце
экрана будут выcвечиваться текущие номера функций 10-го прерывания.
     Первый аргумент командной строки "!" - признак "холостого"
срабатывания - необязателен. Его функциональное назначение - выдача
звукового сигнала в момент обнаружения указанной вами в командной
строке ситуации (без реальной ее обработки программой EXEB, т.е. без
создания результирующего EXE-файла).
     Итогом работы EXEB является файл с именем TASK.EXE, который можно
запускать на выполнение (в той же среде, в которой он был создан:
версия DOS, конфигурация ПЭВМ).
                           ПРИНЦИПЫ РАБОТЫ
     Будучи запущенной, EXEB захватывает указанное в командной строке
прерывание, запускает исследуемую задачу и начинает отсчитывать
обращения к указанной в командной строке функции захваченного
прерывания. Когда счетчик обращений станет равен 0, EXEB переносит
образ исследуемой задачи из оперативной памяти на диск. При этом
первой исполняемой командой задачи станет вызов указанного в командной
строке EXEB прерывания (int ??). Схематично последовательность работы
EXEB представлена на рис. 7.1 - 7.3.
     После запуска задача EXEB выдает на экран сообщение о готовности
и ожидает нажатия любой клавиши. В этот момент пользователь при
желании может вставить дискету в дисковод (при исследовании задачи,
имеющей защиту по ключевой дискете).
                   ОСОБЕННОСТИ РАБОТЫ И НЕДОСТАТКИ
     Результирующая задача TASK.EXE не всегда способна воспринять
командную строку, указанную в аргументе <CommandLine> при ее создании.
     TASK.EXE должна запускаться примерно в той же среде, где она была
создана (объем свободной оперативной памяти). В случае какого-либо
несоответствия на экран выдается сообщение об этом и TASK.EXE
прекращает работу.
     Так как EXEB "снимает" в файл TASK.EXE практически всю
оперативную память, то его объем может быть очень большим. Для
уменьшения размера TASK.EXE можно использовать утилиту CHSIZE, формат
запуска которой вы можете выяснить запустив ее без аргументов.

                    СХЕМА РАБОТЫ ПРОГРАММЫ EXEB.EXE
        ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
        і                                                             і
        і          ЗАХВАТ ПРЕРЫВАНИЯ И ЗАПУСК ЗАДАЧИ                  і
        і                                                             і
        і                               ЪД<ї                          і
        і                               і  і2                         і
        і ДВДДДДДДДДДДДДДДДДДДДДДДВДДДДДДВДБДДДДДДДДДДДї 1) Захват    і
        і  і     a.exe     int 10 івирус і EXEB        і  обработки поі
        і ДБДДДДДДДДДДДДДДДДДДДДДДБДДДДДДБДДДДДДДДДДДДДЩ  10 вектору. і
        і  ДД>ДДДДДДДДДДД>ДДДДДДДДДДДД>ДДДДДДДДЩ         2) Запуск    і
        і          10 вектор        1                    задачи a.exe.і
        і                                                             і
        і                      рис. 7.1                               і
        і                                                             і
        і                                                             і
        і                 ПЕРЕХВАТ УПРАВЛЕНИЯ                         і
        і                                                             і
        і ДВДДДДДДДДДДДДДДДДДДДДДДВДДДДДДВДДДДДДДДДДДДДї              і
        і  і     a.exe     int 10 івирус і EXEB        і              і
        і ДБДДДДДДДДДДДДДДДДДДВДДДБДДДДДДБДДДДДДДДДДДДДЩ              і
        і                     і                і                      і
        і                     АД>ДДДДД>ДДДДД>ДДЩ                      і
        і                                                             і
        і                      рис. 7.2                               і
        і                                                             і
        і                                                             і
        і          ЗАПИСЬ СОДЕРЖИМОГО ПАМЯТИ В ФАЙЛ                   і
        і                                                             і
        і  ДВДДДДДДДДДДДДДДДДДДДДДДВДДДДДДВДДДДДДДДДДДДДї             і
        і   і     a.exe     int 10 івирус і EXEB        і             і
        і  ДЕДДДДДДДДДДДДДДДДДВДДДДБДДДДДДБДДДДДДДДДДДДДЩ             і
        і   є                 є                                       і
        і   є                 є                                       і
        і   ИНННННННННННННННННКННННД> TASK.EXE (дискета)              і
        і                                                             і
        і                       рис. 7.3                              і
        АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

                        8. ПРОВЕРКА УСВОЕННОГО
     Если вы внимательно прочитали весь предшествующий материал, то
справиться с двумя головоломками будет несложно. Если же задания
оказались вам не под силу, вновь проштудируйте статьи.

                            ГОЛОВОЛОМКА 1
      На рис. 8.1 приведена программа, которая не работает под
отладчиком в пошаговом режиме. Проверьте это, оттранслировав и
запустив ее, например, под Turbo Debugger. Нажимая клавишу F8 (без
захода в п/п), благополучно доберетесь до ее конца. Если же попробуете
пройти программу в потактовом режиме (клавиша F7), с заходом в
подпрограмму "DEL", то после выполнения оператора STOSW продолжение
будет невозможно. Почему?

                            ГОЛОВОЛОМКА 2
     Программа на рис. 8.2 также не работает в пошаговом режиме, но
причина здесь иная. В чем тут дело?

                            ГОЛОВОЛОМКА 1
        ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
        і cseg        segment para public 'code'                     і
        і         assume cs:cseg                                     і
        і exam        proc                                           і
        і start:                                                     і
        і         jmp        frwd                                    і
        і del:                                                       і
        і                 pushf                                      і
        і                 cld                                        і
        і                 mov        ax,cs                           і
        і                 mov        es,ax                           і
        і                 rep        stosw                           і
        і                 popf                                       і
        і                 ret                                        і
        і frwd:                                                      і
        і         push        cs                                     і
        і         pop        ds                                      і
        і         mov        cx,12                                   і
        і         mov        di,offset start                         і
        і         call        del                                    і
        і         mov        dx,offset msg                           і
        і         mov        ah,9                                    і
        і         int        21h                                     і
        і         mov        ax,4c00h                                і
        і         int        21h                                     і
        і msg        db 'Hellow, boys!',0ah,0dh,'$'                  і
        і exam        endp                                           і
        і cseg        ends                                           і
        і         end        start                                   і
        АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

                               рис. 8.1

                            ГОЛОВОЛОМКА  2
        ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
        і TEXT:       segment byte public 'CODE'                     і
        і         assume cs:TEXT                                     і
        і         org 100h                                           і
        і                                                            і
        і start:        mov        dx,offset prv                     і
        і         mov        ah,9                                    і
        і         int        21h                                     і
        і         db        2eh                                      і
        і         pushf                                              і
        і         pop        ax                                      і
        і         sahf                                               і
        і         mov        ah,9                                    і
        і         jb        Glk                                      і
        і         mov        dx,offset mes1                          і
        і         int        21h                                     і
        і         mov        ax,4c00h                                і
        і         int        21h                                     і
        і Glk:                                                       і
        і         mov        dx,offset mes2                          і
        і         int        21h                                     і
        і         mov        ax,4c01h                                і
        і         int        21h                                     і
        і                                                            і
        і prv        label byte                                      і
        і         db 'dbtest',0ah,0dh,024h                           і
        і                                                            і
        і mes1        label byte                                     і
        і         db 'Ok',0ah,0dh,24h                                і
        і                                                            і
        і mes2        label byte                                     і
        і         db 'Trace',0ah,0dh,24h                             і
        і                                                            і
        і TEXT        ends                                           і
        і         end start                                          і
        АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

                               рис. 8.2

                      9. АНОНС ВМЕСТО ЗАКЛЮЧЕНИЯ

     Второй номер компьютерного приложения к журналу
"Техника-молодежи" продолжит тему защиты информации. В нем будут даны
ответы на некоторые вопросы по вирусологии, возникающие у неискушенных
пользователей, состоится знакомство с программами-отладчиками и
детально описаны способы защиты исполняемых модулей от исследования:
  - вирусы и их функции;
  - отладчики: состояние, перспективы; как "доработать" имеющийся
отладчик;
  - библиотека подпрограмм для защиты исполняемого кода от
исследования;
  - распределенные программные модули; генерация исполняемого
кода;
  - программный замок с псевдослучайным ключом;
  - DLOCK ver 3.0;
  - рекомендации по защите программ для ПЭВМ типа "Enterprisse" и
"Spectrum" ("Синклер");
  - квалификационная тест-программа.
  Дискета, как всегда, содержит исполняемые модули и исходные тексты
программ на Ассемблере, Си, Бейсике.

     Подписаться на оптовую поставку компьютерного приложения можно в
редакции журнала "Техника-молодежи" (125015, Москва, Новодмитровская
ул., д. 5а, тел. 285-16-87, 285-89-80), приобрести единичные
экземпляры - там же или у наших диллеров (у которых Вы купили первый
выпуск).

                                        Приложение 1

               СЛОВАРЬ ТЕРМИНОВ

Аномалии МП - специфические особенности выполнения некоторых команд
            микропроцессора.

Байт - единица информации, в системе MS DOS байт может принимать
            значения кодов от 0 до 255, 2 байта составляют машинное
            слово (значение от 0 до 65536).

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

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

Дисперсия - мера рассеяния значений случайной величины около ее
            математического ожидания.

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

Заголовок
EXE-файла - начальная часть файла, в которой, в частности, содержится
            информация о стартовом значении регистров МП, размере
            всего файла, таблица перемещения и т.д.

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

Идентификация - сопоставление предъявленных характеристик с
            эталонными.

Исполняемый
модуль - программа или ее законченная часть (хранящаяся на диске
            отдельно), имеющая набор команд и данных, имя и
            предназначенная для загрузки в оперативную память ПЭВМ с
            последующуй передачей ему управления.

Исходный
текст (исходник) - текст программы на одном из языков программирования
            и введенный в ПЭВМ непосредственно программистом (до
            какой-либо обработки его компьютером).

Кластер - минимальная единица дисковой памяти, выделяемая DOS-ом для
            хранения файла.

Ключевая
фраза - (она же - парольная) последовательность символов, вводимая
            пользователем с клавиатуры для его идентификации.

Конвейер шины
данных - аппаратно реализованная память ПЭВМ (обычно 4 - 6 байт),
            предназначенная для хранения очереди процессорных команд,
            ожидающих выполнения.

Контроллер - аппаратное устройство, реализующее обмен информации между
            ПЭВМ и периферийным оборудованием.

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

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

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

МП         - микропроцессор.

НСК        - несанкционированное копирование.

НСД        - несанкционированный доступ.

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

ПО         - программное обеспечение.

Пошаговый
режим - процесс выполнения программы по одной команде. После
            выполнения каждого шага управление возвращается программе,
            осуществляющей пошаговый режим (для возможности просмотра
            состояния ОЗУ и содержимого регистров МП).

Прерывание - программно или аппаратно инициированная передача
            управления по адресу, который находится в таблице векторов
            прерываний:
- аппаратное - инициируется контроллерами периферийного оборудования;
- программное - инициируется программой;
- трассировочное - аппаратное прерывание по вектору 1, выполняемое
            после каждой команды процессора, если флаг трассировки TF
            слова состояния процессора установлен;
- 21h - программное прерывание по вектору 21h, реализующее все
            основные функции DOS (файловые операции, управление
            памятью, справочная информация и т.д.);
- 13h - программное прерывание по вектору 13h, реализующее все
            основные операции по работе с диском;
- функции - выполняемые тем или иным прерыванием в зависимости от
            значений входных аргументов.

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

Псевдослучайная
последовательность - последовательность чисел, подчиняющаяся
            заданному закону распределения.

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

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

Сегмент - страница оперативной памяти (блок ОЗУ), отведенная либо для
            кодов программы (кодовый сегмент), либо под стек
            (стековый), либо под данные (сегмент данных).

Сегментные:
регистры - аппаратные регистры микропроцессора, предназначенные для
            хранения адресов соответствующих сегментов: CS - кодового,
            DS - данных, SS - стека;
пересылки  - пересылки данных из сегмента в сегмент, в которых
            участвуют сегментные регистры.

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

Таблица
перемещения - часть заголовка EXE-файла, содержащая адреса команд и
            данных в его теле, относительно начала файла на диске.
            После выделения DOS-ом свободных сегментов для загрузки в
            ОЗУ, операционная система, пользуясь таблицей перемещений,
            пересчитает относительные адреса на абсолютные (те, на
            которых программа реально будет располагаться в
            оперативной памяти).

Точка останова - адрес команды, перед выполнением которой управление
            передается отладчику.

Трассировка - процесс пошагового выполнения программы под отладчиком.

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

Элемент
оглавления - структура, описывающая дисковый файл.

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

BIOS - Base Input Output System (базовая система ввода/вывода).

CMOS - энергонезависимая память ПЭВМ, имеет встроенные часы реального
            времени с календарем, содержит информацию о конфигурации
            машины.

COM-файл - исполняемый модуль, содержащий только бинарный образ задачи
            без какой-либо управляющей информации; этот тип программ
            всегда загружается в ОЗУ по одним и тем же адресам
            (указанным при написании программы), величина COM-файла не
            может превышать размер одного сегмента (64 КБ).

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

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

SP (указатель
вершины стека) - аппаратный регистр МП, содержащий смещение текущего
            адреса стека относительно начала стекового сегмента (адрес
            в регистре SS).

                       ДОРОГИЕ ДРУЗЬЯ !

   Предлагаем вашему вниманию набор информационных материалов:

   2BART1  - КАК СОЗДАТЬ TSR БЕЗ PSP;
   2BART2  - НЕСКОЛЬКО СЛОВ О ВИДЕОАДАПТЕРАХ;
   2BCOPY1 - КАК СКОПИРОВАТЬ ЗАЩИЩЕННУЮ ОТ КОПИРОВАНИЯ ДИСКЕТУ;

   Материалы подготовлены в формате для непосредственной печати
на любом устройстве.

   Статьи  2BART1,   2BART2  предназначены  для  программистов.
Статья 2BCOPY1 возможно будет  интересна как для программистов,
так и для пользователей ПЭВМ.

                    НЕСКОЛЬКО СЛОВ ОБ АВТОРАХ.

   Материалы подготовлены группой авторов, которые назвали себя
2B  PROGRAMMERS   GROUP.  Мы   все  в   прошлом   работали   на
госпредприятии, а  теперь в  совместном предприятии  "ДИАЛОГ" в
отделе экспертизы  и сертификации  программного обеспечения.  В
состав   группы    входят   высококвалифицированные   системные
программисты,    занимавшиеся    разработкой    и    доработкой
операционных  систем   для  ЕС   ЭВМ.  В   настоящее  время  мы
специализируемся в  области систем  компьютерной  безопасности,
систем  защиты   от  копирования   и  разработки   программного
обеспечения для различного оборудования ПЭВМ.

                        КАК HАЙТИ АВТОРОВ

   Телефон:   095-329-4611
   Телефакс:  095-329-4711
   E-mail:    Vlad_Seregin, 2:5020/6 @FidoNet (JVD1BBS, 095-329-2192)

   Адpес:     г. Москва, ул. Ягодная, 17
              Отдел Экспеpтизы и Сеpтификации.

                                                            1

                                    ГРУППА ПРОГРАММИСТОВ 2B.

           СПОСОБ СОЗДАНИЯ TSR ПРОГРАММ БЕЗ PSP.

     В  данной   статье  рассматривается  способ  построения
резидентных программ  - TSR  (Terminate and  Stay Resident),
позволяющий  использовать   область  PSP   (Program  Segment
Prefix) для размещения резидентного кода программы.

                   НЕСКОЛЬКО СЛОВ О TSR.

     При разработке  TSR -  программ стандартными средствами
DOS  в   памяти  после  завершения  программы  остается  PSP
размером 256  байт или  по  крайней  мере  его  часть,  если
программа использует  область FCB  (File  Control  Block)  и
параметров для собственных нужд. Мы расскажем Вам о способе,
позволяющем полностью  использовать область  PSP в интересах
резидентной программы  и приведем  пример  такой  программы.
Данный способ  был разработан  авторами в  начале 1989 года,
когда  потребовалось   загрузить  много   крохотных  TSR   -
программ, размер которых не превышал PSP.

        КОЕ ЧТО О НЕДОКУМЕНТИРОВАННЫХ ФУНКЦИЯХ DOS.

     Для  понимания   механизма  разработки   TSR  без   PSP
необходимо ознакомиться  с  некоторыми  недокументированными
функциями DOS  и с  форматами PSP  и MCB  -  Memory  Control
Block.

               PSP - PROGRAM SEGMENT PREFIX.

     PSP всегда  строится DOS  при запуске любой программы и
непосредственно предшествует  началу  программы.  Рассмотрим
формат PSP.

СМЕЩЕНИЕ   РАЗМЕР    ОПИСАНИЕ

00h        2 БАЙТА   содержит команду INT 20h, которая
                      используется для завершения программы
02h        СЛОВО     сегментный адрес свободной памяти,
                     следующей, за памятью, выделенной
                     программе. Это может быть либо адрес за
                     памятью DOS (например, A000h), либо
                     адрес следующего доступного MCB.
04h        БАЙТ      резерв.
05h        5 БАЙТ    длинный вызов диспетчера функций DOS.
                     Содержит команду длинного перехода к
                     диспетчеру функций DOS. Используется в
                     программах, ориентированных на CP/M.
                     Смещение в команде длинного перехода
                     содержит количество байтов, доступных в
                     сегменте кода программы.

                                                            2

0Ah        ДВ.СЛОВО  копия вектора прерывания 22h, по
                     которому управление передается для
                     завершения программы.
0Eh        ДВ.СЛОВО  копия вектора прерывания 23h, по
                     которому управление передается при
                     нажатии CONTROL-BREAK или CONTROL-C.
12h        ДВ.СЛОВО  копия вектора прерывания 24h, по
                     которому управление передается при
                     обнаружении критической ошибки.
16h        СЛОВО     сегментный адрес PSP родительского
                     процесса (адрес текущего PSP для
                     процесса, у которого нет родителя).
18h        20 БАЙТ   FILE HANDLE TABLE. Содержит 20
                     однобайтовых индексов для системной
                     таблицы файлов. Первые пять входов
                     предназначены для STDIN, STDOUT,STDERR,
                     AUXIO и LSTOUT.
2Ch        СЛОВО     сегментный адрес блока среды для
                     процесса.
2Eh        ДВ.СЛОВО  область сохранения указателя стека
                     процесса, когда процесс использует стек
                     DOS (т.е. содержимое SS:SP перед
                     последним подключением функции DOS с
                     помощью INT 21h).
32h        СЛОВО     максимальное количество входов в FILE
                     HANDLE TABLE (по умолчанию 20).
34h        ДВ.СЛОВО  адрес FILE HANDLE TABLE (стандартно
                     указывает на таблицу в текущем PSP).
38h        24 БАЙТА  резерв.
50h        3 БАЙТА   команда INT 21h, за которой следует
                     команда far RET. Используется для
                     вызова диспетчера функций DOS.
53h        2 БАЙТА   резерв.
55h        7 БАЙТ    расширение первого FCB.
5Ch        16 БАЙТ   начальные байты первого неоткрытого
                     FCB. Открытие данного FCB приведет к
                     разрушению второго FCB и байта с длиной
                     командной строки.
6Ch        16 БАЙТ   начальные байты второго неоткрытого
                     FCB. Открытие данного FCB приведет к
                     разрушению командной строки.
7ch        ДВ.СЛОВО  резерв.
80h        128 БАЙТ  область DTA (Data Transfer Area) по
                     умолчанию. Перекрывает байт с длиной
                     командной строки и буфер командной
                     строки (127 байтов).

     Размер блока - 256 байт.

                                                            3

                MCB - MEMORY CONTROL BLOCK.

     MCB   является    блоком   DOS    описывающим    каждый
распределенный  участок   памяти.  Как  правило  MCB  всегда
строится перед  PSP исполняемой программы. Рассмотрим формат
MCB.

СМЕЩЕНИЕ   РАЗМЕР    ОПИСАНИЕ

00h        БАЙТ      тип блока:
                     'M' (4Dh) - промежуточный блок;
                     'Z' (5Ah) - последний блок.
01h        СЛОВО     сегмент владельца блока, 0 - свободный
                     блок.
03h        СЛОВО     количество параграфов в блоке.
05h        11 БАЙТ   резерв.

     Размер блока - 16 байт.

              НЕДОКУМЕНТИРОВАННЫЕ ФУНКЦИИ DOS.

     Рассмотрим  теперь   недокументированные  функции  DOS,
которые используются для построения TSR без PSP.

                  УСТАНОВИТЬ ТЕКУЩИЙ PSP.

     Данная функция  указывает DOS,  что в качестве текущего
следует использовать указанный PSP.

     ВХОДНЫЕ ПАРАМЕТРЫ:

     AH = 50h
     BX = сегментный адрес нового PSP.

                  СОЗДАТЬ ПОДЧИНЕННЫЙ PSP.

     Данная функция  требует от DOS создать подчиненный PSP.
В отличии  от функции  26h данные  не копируются из текущего
PSP, а строятся заново.

     ВХОДНЫЕ ПАРАМЕТРЫ:

     AH = 55h
     BX = сегментный адрес для построения нового PSP.
     SI = значение, которое требуется установить в поле со
          смещением 2 в новом PSP.

                                                            4

         ПРОЦЕСС ЗАВЕРШЕНИЯ РЕЗИДЕНТНОЙ ПРОГРАММЫ.

     Сущность  завершения   резидентной  программы  без  PSP
состоит в  создании нового  PSP и  указании DOS использовать
этот  PSP   в  качестве   активного.  При   этом  сам  текст
резидентной части перемещается на начало старого PSP.

     Рассмотрим последовательность  действий при  завершении
программы.

     1. Освободить  ENVIRONMENT, адрес  которого находится в
PSP по  смещению 2Ch. Вообще говоря, это действие не связано
с собственно  процессом завершения резидентной программы без
PSP  и   рекомендуется   для   любого   способа   завершения
резидентных программ.
     2. Изменить  размер  памяти,  используемый  программой,
указав в  качестве нового  размера длину  резидентной  части
программы в  параграфах, а  в качестве адреса модифицируемой
памяти -  сегментный адрес  PSP. Для выполнения используется
функция DOS  4Ah. Если резидентная часть начинается с начала
программы,  то   ее  следует  сначала  сохранить,  т.к.  при
освобождении памяти  в теле  программы будет  построен новый
MCB. Также  целесообразно зарезервировать  после резидентной
части участок  длиной 16  байт для  MCB,  чтобы  последующие
действия не уничтожили дальнейший код программы.
     3. Вычисляется  сегментный адрес  для построения нового
PSP    по     формуле    <длина    резидентной    части    в
параграфах>+<сегментный адрес  старого PSP>+1  (размер MCB в
параграфах).
     4.  Строится  новый  PSP  по  вычисленному  сегментному
адресу с  использованием функции 55h. В качестве значения SI
берется поле со смещением 2 в старом PSP.
     5. Корректируется  адрес родительского  PSP в новом PSP
по смещению  16h. Значение  выбирается из  поля с  таким  же
смещением из старого PSP.
     6. Новый  PSP указывается  DOS в  качестве  текущего  с
использованием функции 50h.
     7. Корректируется  указатель на  собственника памяти  в
новом MCB  по смещению  01h. MCB  расположен по  сегментному
адресу  равному   сегменту  нового  PSP  минус  1.  Значение
указателя устанавливается  равным сегментному  адресу нового
PSP.
     8. Резидентная  часть программы  пересылается по адресу
сегмента старого PSP со смещением 0.
     9.  Выполняются   необходимые  действия  для  настройки
резидентной части. Их можно также выполнить заранее.
     10. Программа  завершается обычным  образом по  функции
DOS 04Ch.

                                                            5

     Схематически этот метод изображен на 3-х рисунках.

     Рисунок 1  показывает изменение в расположении блоков в
памяти при выполнении функции DOS 4Ah.

ЪДДВДДДДДДДДДДДДДДДї                    ЪДДВДДДДДДДДДДДДДДДї
і  і               і                    і  і               і
і  і      MCB      і  Ъ>    На PSP   <ї і  і      MCB      і
і  і               і  і    родителя   і і  і               і
і  ГДДДДДДДДДДДДДДДґ  і               і і  ГДДДДДДДДДДДДДДДґ
АД>і    текущий    ГДДЩ               і АД>і    текущий    і
   і      PSP      і                  АДДДДґ      PSP      і
   ГДДДДДДДДДДДДДДДґ                       ГДДДДДДДДДДДДДДДі
   і               і       Выполнение      і  ПРОГРАММА    і
   і               і        функции        ГДДДДДДДДДДДДДДДґ
   і               і          DOS          і     новый     і
   і               і          4Ah          і      MCB      і
   і               і                       і   свободный   і
   і   ПРОГРАММА   і                       ГДДДДДДДДДДДДДДДґ
   і               і                       і               і
   і               і                       і   ПРОГРАММА   і
   АДДДДДДДДДДДДДДДЩ                       АДДДДДДДДДДДДДДДЩ

                          Рис. 1.

     Рисунок 2  показывает изменение в расположении блоков в
памяти после  выполнения функции  DOS 55h  и  при  коррекции
указателей.

                Выполнение функции DOS 55h.

ЪДДВДДДДДДДДДДДДДДДї                    ЪДДВДДДДДДДДДДДДДДДї
і  і               і Ъ>    На PSP       і  і               і
і  і      MCB      і і    родителя      і  і      MCB      і
і  і               і і                  і  і               і
і  ГДДДДДДДДДДДДДДДґ і                  і  ГДДДДДДДДДДДДДДДґ
АД>і    текущий    ГДЩ                  АД>і    текущий    і
   і      PSP      і<ДДї                   і      PSP      і
   і               і   і                   і               і
   ГДДДДДДДДДДДДДДДі   і                   ГДДДДДДДДДДДДДДДі
   і  ПРОГРАММА    і   і                   і  ПРОГРАММА    і
   ГДДДДДДДДДДДДДДДґ   і                ЪДДЕДДДДДДДДДДДДДДДґ
   і     новый     і   і   Коррекция    і  і     новый     і
   і      MCB      і   і   указателей   і  і      MCB      і
   і   свободный   і   і                і  і   распределен і
   ГДДДДДДДДДДДДДДДґ   і                і  ГДДДДДДДДДДДДДДДґ
   і     новый     ГДДДЩ                АД>і     новый     і
   і      PSP      і          На PSP  <ДДДДґ      PSP      і
   ГДДДДДДДДДДДДДДДґ          родителя     ГДДДДДДДДДДДДДДДґ
   і   ПРОГРАММА   і                       і   ПРОГРАММА   і
   АДДДДДДДДДДДДДДДЩ                       АДДДДДДДДДДДДДДДЩ

                          Рис. 2.

                                                            6

     Рисунок 3  показывает изменение в расположении блоков в
памяти после выполнения функции DOS 50h.

                Выполнение функции DOS 50h.

ЪДДВДДДДДДДДДДДДДДДї
і  і               і
і  і      MCB      і
і  і               і
і  ГДДДДДДДДДДДДДДДґДДДДї
АД>і    старый     і    і
   і      PSP      і    ГДДДД> Вся эта область доступна TSR.
   ГДДДДДДДДДДДДДДДґ    і
   і  ПРОГРАММА    і    і
ЪДДЕДДДДДДДДДДДДДДДґДДДДЩ
і  і     новый     і
і  і      MCB      і
і  і  распределен  і
і  ГДДДДДДДДДДДДДДДґ
АД>і    текущий    ГДДДДДДДД> На PSP родителя.
   і      PSP      і
   ГДДДДДДДДДДДДДДДґ
   і   ПРОГРАММА   і
   АДДДДДДДДДДДДДДДЩ

                          Рис. 3.

                       СОВМЕСТИМОСТЬ.

     Данный  метод   опробован   в   различных   совместимых
операционных средах:

     - MS/PC DOS 3.30;
     - MS/PC DOS 4;
     - MS DOS 5 beta release;
     - DR DOS 3.41;
     - DR DOS 5;
     - с  использованием загрузчика  LOADHI от  системы QEMM
5.0;
     - с  использованием загрузки в старшую память HILOAD DR
DOS 5.

                                                            7

           ПРИМЕР РЕЗИДЕНТНОЙ ПРОГРАММЫ БЕЗ PSP.

     Для лучшего  понимания порядка  завершения  резидентной
программы без PSP приведем пример.

        page    60,132
        title   NONPSP - Резидентная программа без PSP
;==========================================================
;
;    Пример построения резидентной программы без PSP
;
;    Авторские права ГРУППЫ ПРОГРАММИСТОВ 2B
;
;    Язык программирования: Ассемблер
;    Транслятор           : MASM
;
;===========================================================
;
; сообщить транслятору адресацию
;
        assume  cs:code,ds:code,es:nothing
;
;  определить сегмент кода
;
code    segment para
;
        subttl  Резидентная часть программы
;
ResStart label  byte            ;определим начало программы

                  Текст резидентной части.

ResEnd  label   byte            ;конец резидентной части
ResLen  equ     ResEnd-ResStart ;размер резидентной части в
                                ; байтах
ResSize equ     (ResEnd-ResStart+15)/16 ;размер резидентной
                                        ; части в параграфах
        org     ResStart+ResSize*16     ;для выравнивания на
                                        ; границу параграфа
;
        page
        subttl  Инициализация резидентной программы без PSP
;
MCBLen  equ     10h                     ;размер MCB
;
PSPMCB  db      MCBlen dup (0)  ;резервная область для MCB
SavRes  db      ResLen dup (0)  ;область сохранения
                                ; резидентной части
;
PspOld  dw      0               ;для адреса старого PSP
PspNew  dw      0               ;для адреса нового  PSP

                                                            8

;
;  сообщения
;
MsgInst label   byte
        db      0ah,0dh
        db      'Программа установлена'
        db      0ah,0dh
        db      '$'
MsgNoInst label   byte
        db      0ah,0dh
        db      'Ошибка. Программа не установлена'
        db      0ah,0dh
        db      '$'
;=========================================================
;
;  процедура инициализации резидентной программы без PSP
;
;=========================================================
ini     proc    far
;
        cld                             ;для операций
                                        пересылки
        mov     cs:PspOld,ds            ;сохраним старый PSP
;
;       Освобождение environment
;
        mov     ax,ds:[2ch]             ;адрес сегмента
        mov     es,ax                   ;       environment
        cmp     ax,0                    ;есть environment ?
        je      Go1                     ; нет
        mov     ah,49h                  ;код функции
        int     21h                     ;   освободить
                                        ; память
        jnc     Go1                     ;успешно
        jmp     ErrorRet                ;неуспешно
Go1:
        mov     word ptr ds:[2ch],0     ;укажем, что нет
                                        ; environment
        push    cs                      ;установим
        pop     es                      ;    ES
        push    cs                      ;установим
        pop     ds                      ;    DS
;
; запомним резидентную часть
; т.к. она будет разрушена при построении новых PSP и MCB
;
        mov     si,Offset ResStart      ;откуда
        mov     di,Offset SavRes        ;куда
        mov     cx,ResLen               ;сколько
    rep movsb                           ;перешлем

                                                            9

;
; модифицируем размер памяти текущей программы от сегмента
; PSP на длину резидентной части
; это приведет к построению нового MCB в теле программы
;
        mov     ah,4ah                  ;модифицируем память
        mov     bx,ResSize              ;размер резидентной
                                        ; части
        mov     es,PspOld               ;сегмент старого PSP
        int     21h                     ;выполним
        jnc     Go2                     ;успешно
        jmp     ErrorRet                ;неуспешно
Go2:
;
; подсчитаем сегмент памяти для нового PSP
;
        mov     ax,ResSize              ;длина резидентной
                                        ; части в параграфах
        add     ax,PspOld               ; плюс сегмент
                                        ; старого PSP
        add     ax,MCBLen/16            ; плюс длина MCB
        mov     PspNew,ax               ;запомним сегмент
                                        ; для нового PSP
;
; создадим новый PSP
;
        mov     es,PspOld               ;адрес старого PSP
        mov     si,word ptr es:[02h]    ; конец памяти
        mov     ah,55h                  ;построим
                                        ; подчиненный PSP
        mov     dx,PspNew               ;сегмент нового PSP
        int     21h                     ;выполним
;
; скорректируем указатель на родительский PSP в новом PSP
;
        mov     es,PspOld               ;сегмент старого PSP
        mov     ax,word ptr es:[16h]    ;адрес родительского
                                        ; PSP
        mov     es,PspNew               ;сегмент нового PSP
        mov     word ptr es:[16h],ax    ;скорректируем
;
; сообщим DOS о новом активном PSP
;
        mov     bx,PspNew               ;сегмент нового PSP
        mov     ah,50h                  ;функция указания
                                        ; нового PSP
        int     21h                     ; выполним

                                                            10

;
; укажем принадлежность полученной памяти для нового PSP
;
        mov     ax,bx                   ;сегмент нового PSP
        sub     ax,1                    ;сегмент
                                        ; построенного MCB
        mov     es,ax                   ;==================
        mov     word ptr es:[01h],bx    ;скорректируем адрес
                                        ; владельца памяти
;
; переместим резидентную часть на старый PSP
;
        mov     es,PspOld               ;адрес старого PSP
        mov     cx,ResLen               ;размер резидентной
                                        ; части
        mov     di,0                    ;куда
        mov     si,Offset SavRes        ;откуда
    rep movsb                           ;переместим
        push    cs                      ;восстановим
        pop     es                      ;    ES
;
;       Успешный выход из программы
;
PrgEnd:
        mov     ah,09h                  ; выведем сообщение
        mov     dx,offset MsgInst       ;       об успешной
                                        ; установке
        int     21h                     ;
        mov     ax,4c00h                ;завершим программу
        int     21h                     ;       обычным
                                        ; образом с кодом 0
;
; Выход из программы по ошибке
;
ErrorRet:
        push    cs                      ;установим адресацию
        pop     ds                      ;       данных
        mov     ah,09h                  ; выведем сообщение
        mov     dx,offset MsgNoInst     ;       о неуспешной
                                        ; установке
        int     21h                     ;
        mov     ax,4c04h                ;завершим программу
        int     21h                     ;       обычным
                                        ; образом с кодом 4
ini     endp
;
code    ends
;
; СТЕК
;
stack   segment stack
        dw      512 dup(0)
stack   ends
        end     ini

                                                           1

                                    ГРУППА ПРОГРАММИСТОВ 2B.

              НЕСКОЛЬКО СЛОВ О ВИДЕОАДАПТЕРАХ.

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

     ЧТО ТАКОЕ ОСНОВНОЙ И АЛЬТЕРНАТИВНЫЙ ВИДЕОАДАПТЕР.

     Обычно на  ПЭВМ мы  работаем только с одним дисплеем и,
соответственно, с  одним видеоадаптером.  Однако  аппаратура
ПЭВМ  допускает   стандартное  подключение   дополнительного
видеоадаптера и  дисплея. Такой  дополнительный видеоадаптер
называется  альтернативным.   При  этом  не  следует  путать
альтернативные      видеоадаптеры      с      нестандартными
видеоадаптерами.    Первые    поддерживаются    стандартными
средствами   BIOS,    а   вторые   используются   различными
программами  (САПР   или  издательские  системы)  с  помощью
нестандартных  программных   средств.   Иначе   говоря,   на
стандартно подключенный  видеоадаптер всегда можно перевести
вывод всех  сообщений DOS  и программ,  которые  для  вывода
используют средства BIOS.
     Не всякие  виды видеоадаптеров  могут  быть  подключены
одновременно к  ПЭВМ. В таблице 1 рассматриваются допустимые
сочетания видеоадаптеров.

                                                           2

                 СОЧЕТАНИЯ ВИДЕОАДАПТЕРОВ.

                                                  Таблица 1.

ЪДДДДДДДДДДДДДДВДДДВДДДВДДДВДДДДВДДДВДДДВДДДДВДДДДДДДДДДДДДї
і Видеоадаптер іMDAіCGAіEGAіMCGAіVGAіHGCіHGC+іHGC In Color і
ГДДДДДДДДДДДДДДЕДДДЕДДДЕДДДЕДДДДЕДДДЕДДДЕДДДДЕДДДДДДДДДДДДДґ
іMDA           і - і + і + і +  і + і - і  - і      -      і
ГДДДДДДДДДДДДДДЕДДДЕДДДЕДДДЕДДДДЕДДДЕДДДЕДДДДЕДДДДДДДДДДДДДґ
іCGA           і + і - і + і  - і + і + і  + і      +      і
ГДДДДДДДДДДДДДДЕДДДЕДДДЕДДДЕДДДДЕДДДЕДДДЕДДДДЕДДДДДДДДДДДДДґ
іEGA           і + і + і - і  - і - і + і  + і      +      і
ГДДДДДДДДДДДДДДЕДДДЕДДДЕДДДЕДДДДЕДДДЕДДДЕДДДДЕДДДДДДДДДДДДДґ
іMCGA          і + і - і - і  - і + і + і  + і      +      і
ГДДДДДДДДДДДДДДЕДДДЕДДДЕДДДЕДДДДЕДДДЕДДДЕДДДДЕДДДДДДДДДДДДДґ
іVGA           і + і + і - і  + і - і + і  + і      +      і
ГДДДДДДДДДДДДДДЕДДДЕДДДЕДДДЕДДДДЕДДДЕДДДЕДДДДЕДДДДДДДДДДДДДґ
іHGC           і - і + і + і  + і + і - і  - і      -      і
ГДДДДДДДДДДДДДДЕДДДЕДДДЕДДДЕДДДДЕДДДЕДДДЕДДДДЕДДДДДДДДДДДДДґ
іHGC+          і - і + і + і  + і + і - і  - і      -      і
ГДДДДДДДДДДДДДДЕДДДЕДДДЕДДДЕДДДДЕДДДЕДДДЕДДДДЕДДДДДДДДДДДДДґ
іHGC In Color  і - і + і + і  + і + і - і  - і      -      і
АДДДДДДДДДДДДДДБДДДБДДДБДДДБДДДДБДДДБДДДБДДДДБДДДДДДДДДДДДДЩ

     Следует отметить,  что к  ПЭВМ не может быть подключено
два видеоадаптера,  работающие одновременно  в  цветном  или
монохромном  режиме.   Если  один  видеоадаптер  работает  в
цветном режиме,  то другой  должен  работать  в  монохромном
режиме.
     Рассмотрим  теперь   особенности  определения  текущего
видеоадаптера при работе резидентной программы.

                     ВИДЕОАДАПТЕР EGA.

     Для определения активности видеоадаптера EGA достаточно
проверить бит активности EGA адаптера в области данных BIOS.
     Признак активности  видеоадаптера расположен  в поле по
адресу 40h:87h.  Если установлен  флажок 08h, то это значит,
что в  текущий момент  видеоадаптер EGA  не активен, поэтому
следует  организовывать   работу  с  учетом  альтернативного
видеоадаптера.  Приведем   фрагмент  кода   для  определения
активности видеоадаптера EGA.

        mov     ax,40h                  ;адресация данных
        mov     es,ax                   ;    BIOS
        test    byte ptr es:[87h],08h   ;EGA активен ?
        jz      EgaAct                  ;EGA активен
        jmp     NonEga                  ;EGA не активен

     Следует отметить,  что среди  обилия видеоадаптеров EGA
существуют     видеоадаптеры,     позволяющие     программно
переключаться в  режим совместимости MDA и HGC. При этом они
зачастую корректируют  адрес обработчика  INT 10h.  Поэтому,
перед проверкой активности видеоадаптера EGA, мы рекомендуем

                                                           3

убедиться, что  EGA до сих пор существует на вашей ПЭВМ. Это
можно сделать путем считывания переключателей EGA по функции
INT  10h,   AH=12h,  BL=10h.  Приведем  фрагмент  кода,  для
выполнения этой функции.

        mov     ah,12h                  ;запрос
        mov     bl,10h                  ; переключателей
        int     10h                     ; вызвать INT 10h
        cmp     bl,10h                  ;функция выполнена ?
        je      NonEga                  ; EGA не активен
        jmp     EgaAct                  ; EGA активен

                  ВИДЕОАДАПТЕРЫ VGA/MCGA.

     Видеоадаптеры   VGA    и   MCGA   являются   поколением
видеоадаптеров, анонсированных  в ПЭВМ  PS/2  фирмы  IBM.  В
настоящее время существует большое количество видеоадаптеров
VGA.   Среди    них   есть   видеоадаптеры,   поддерживающие
расширенные графические и текстовые режимы.
     Чтобы  определить   активность  видеоадаптера  VGA/MCGA
достаточно выполнить функцию INT 10h, AX=1A00h. Если функция
обеспечена, то  в регистре  AL будет  значение 1Ah.  В  этом
случае в регистре BL Вы получите код основного, а в регистре
BH -  код альтернативного  дисплея в текущий момент времени.
Возможны следующие коды:

00h - отсутствует;
01h - монохром;
02h - CGA;
03h - резерв;
04h - EGA с цветным дисплеем;
05h - EGA с монохромным дисплеем;
06h - PGC с цветным дисплеем;
07h - VGA с монохромным дисплеем;
08h - VGA с цветным дисплеем;
09h - 0Ah - резерв;
0Bh - MCGA с монохромным дисплеем;
0Ch - MCGA с цветным дисплеем;
0Dh - FEh - резерв;
-1  - неизвестен.

     Таким    образом    процесс    определения    активного
видеоадаптера для  ПЭВМ, оборудованных  видеоадаптерами VGA,
не представляет особых проблем.

                                                           4

     Приведем   фрагмент   кода,   определяющий   активность
видеоадаптера VGA/MCGA.

        mov     ax,1a00h        ;спросим код дисплея
        int     10h             ;выполним
        cmp     al,1ah          ;подсистема активна ?
        jne     NonSubst        ;нет, возможно переключение
                                ; в режим другого
                                ; видеоадаптера или
                                ; подсистема остутствует
        cmp     bl,07h          ;VGA ?
        je      VgaAct          ; да
        cmp     bl,08h          ;VGA ?
        je      VgaAct          ; да
        cmp     bl,0bh          ;MCGA ?
        je      MCGAct          ; да
        cmp     bl,0ch          ;MCGA ?
        je      MCGAct          ; да
        jmp     NonSubst        ; не найден VGA/MCGA

     Следует отметить,  что все  регистры видеоадаптера  VGA
можно прочитать.  Таким образом  резидентная программа может
определить режим  работы  видеоадаптера  -  графический  или
текстовый. Это  может быть  полезно  для  программ,  которым
требуется  сохранить   текущее  состояние  экрана,  или  для
драйверов русского  языка, чтобы  определить режим  загрузки
знакогенератора.  Знание   режима  видеоадаптера   позволяет
драйверам русского  языка поддерживать старшие режимы работы
нестандартных видеоадаптеров  VGA, не  привязываясь к номеру
видеорежима. Определение текущего режима основано на анализе
содержимого регистра  06h GRAFICS  CONTROLLER (Miscellaneous
Register). Размер  буквы можно  узнать в области данных BIOS
по адресу 40h:85h.
     Приведем фрагмент  кода для  определения режима  работы
видеоадаптера VGA.

; прочитаем GC регистр 06h
        mov     dx,03ceh        ;адресный порт
        mov     al,06h          ;номер регистра
        out     dx,al           ;затребуем регистр
        jmp     short $+2
        inc     dx              ;порт данных
        in      al,dx           ;прочитаем регистр
; анализ типа знакогенератора
        test    al,01           ;графический режим ?
        jz      VgaTxt          ;текстовый режим
        jmp     VgaGraf         ;графический режим

                                                           5

    СПОСОБ ОПРЕДЕЛЕНИЯ ТИПА ОСНОВНОГО И АЛЬТЕРНАТИВНОГО
                       ВИДЕОАДАПТЕРА.

     В данном  разделе мы  расскажем  Вам,  как  определить,
какие видеоадаптеры  установлены на ПЭВМ. Предлагаемый метод
позволяет  идентифицировать  видеоадаптеры  MDA,  CGA,  EGA,
MCGA, VGA,  HGC,  HGC+  и  HGC  In  Color  и  совместимые  с
HERCULES, которые мы будем называть MGA.

           ПОРЯДОК ИДЕНТИФИКАЦИИ ВИДЕОАДАПТЕРОВ.

     Приведем  порядок,  в  котором  Вам  следует  выполнять
идентификацию видеоадаптеров.

     1.  Проверить   наличие  видеоподсистемы   VGA/MCGA  по
функции INT  10h, AX=1A00h.  Если подсистема активна, то код
основного и  альтернативного видеоадаптера  будет передан  в
регистрах BL и BH.
     2. Если  в шаге  1 обнаружен  монохромный  дисплей,  то
следует удостовериться,  не является  ли он  адаптером  типа
HERCULES. Метод  определения  видеоадаптеров  типа  HERCULES
рассмотрим ниже.
     3.  Если  функция  шага  1  не  выполнена,  то  следует
проверить наличие  видеоадаптера EGA  по  функции  INT  10h,
AH=12h, BL=10h.
     4.  Если   видеоадаптер  EGA   обнаружен,  то   следует
определить, работает  EGA в  цветном или монохромном режиме.
Метод определения основан на анализе переключателей на плате
EGA, полученных по функции INT 10h, AH=12h, BL=10h в младших
четырех  битах   регистра  CL.   Комбинация   переключателей
следующая:

000X - обычный цветной дисплей;
001X - цветной дисплей с расширенными возможностями;
010X - монохромный терминал;
011X - обычный цветной дисплей;
100X - цветной дисплей с расширенными возможностями;
101X - монохромный терминал.

     5. Если  видеоадаптер EGA работает в цветном режиме, то
следует   проверить,    не   подключен    ли    видеоадаптер
MDA/HERCULES.
     6. Если видеоадаптер EGA работает в монохромном режиме,
то следует проверить, не подключен ли видеоадаптер CGA.
     8. Если  видеоадаптер  EGA  не  обнаружен,  то  следует
проверить наличие видеоадаптеров MDA/HERCULES или CGA. Выбор
текущего  видеоадаптера  при  одновременном  наличии  CGA  и
MDA/HERCULES производится  на основе  анализа видеорежима  в
области  данных  BIOS  по  адресу  40h:49h.  Видеорежим  07h
указывает на активность видеоадаптера MDA/HERCULES.

                                                           6

            МЕТОД ОПРЕДЕЛЕНИЯ ВИДЕОАДАПТЕРА CGA.

     Видеоадаптер CGA  определяется путем  проверки  наличия
6845 CHIP (CRT CONTROLLER) с индексным регистром 3D4h. Метод
проверки наличия 6845 описан ниже.

       МЕТОД ОПРЕДЕЛЕНИЯ ВИДЕОАДАПТЕРА MDA/HERCULES.

     Проверка наличия  видеоадаптера  MDA  или  HERCULES,  а
также подобных им адаптеров выполняется на основе следующего
алгоритма.
     1. Проверяется  наличие 6845  CHIP (CRT  CONTROLLER)  с
индексным регистром 3B4h.
     2. Считывается  содержимое порта 3BAh  (состояние CRTC)
и проверяется,  изменяется ли  бит 7 этого порта (индицирует
VERTICAL SYNC).  Если нет,  то видеоадаптер классифицируется
как MDA.
     3. Адаптеры  фирмы HERCULES идентифицируются битами 4-6
состояния CRTC:

000 - HGC;
001 - HGC+;
101 - InColor Card).
остальное - совместимый с HERCULES монохромный графичесий
адаптер - MGA.

     Следует отметить,  что идентификация типа видеоадаптера
фирмы HERCULES на базе бит 4-6 может быть недостоверна, т.к.
многие   фирмы   разработчики   совместимых   видеоадаптеров
неправильно устанавливают эти биты.
     Приведем фрагмент  кода, идентифицирующий видеоадаптеры
MDA/HERCULES/MGA.

        mov     dx,3B4h         ; проверить наличие 6845
                                ; CHIP.
        call    Test_6845       ; процедура проверки наличия
                                ; 6845
                                ; CF=1 - 6845 не найден
                                ; CF=0 - 6845 найден
        jc      NonMdaHgc       ;6845 CHIP отсутствует.
                                ;нет MDA/HERCULES/MGA.
        mov     dx,3BAh         ; считать регистр состояния
        in      al,dx           ; CRTC.
        and     al,80h          ; изолировать бит 7
                                ; (VERTICAL SYNC).
        mov     ah,al           ; проверим, изменяется ли
                                ; бит 7.
        mov     cx,8000h        ; количество повторов.
TBIT7:  in      al,dx           ; регистр состояния CRTC
        and     al,80h          ; изолировать бит 7
                                ; (VERTICAL SYNC).
        cmp     ah,al           ; сравним значения
        loope   TBIT7           ; повторим

                                                           7

        je      MDAFOUND        ; переход, если бит 7 не
                                ; изменился. Только MDA
; определим тип адаптера HERCULES.
        in      al,dx           ; считать состояние CRTC.
        and     al,70h          ; изолировать биты 4-6.
        jz      HGCFOUND        ; переход, если это HGC.
        cmp     al,10h          ; это HGC+?
        je      HGCPFOUND       ; да, переход.
        cmp     al,50h          ; это InColor Card?
        je      HGCICFOUND      ; да, переход.
        jmp     MGAFOUND        ; адаптер, совместимый с
                                ; HERCULES - MGA.

            МЕТОД ОПРЕДЕЛЕНИЯ НАЛИЧИЯ 6845 CHIP

     6845 CHIP  используется в  видеоадаптерах  MDA,  CGA  и
HERCULES в  качестве CRT  CONTROLLER. Техника    определения
наличия этой микросхемы заключается в том,  что в регистр 15
CRT  CONTROLLER   (младший  байт   местоположения   курсора)
записывается значение,  которое затем  считывается  обратно.
Если возвращено  записанное значение,  то 6845  CHIP есть  в
компьютере.
     Приведем  фрагмент  кода  для  определения  6845  CHIP.
Считается, что  при входе  в программу  регистр DX  содержит
адрес индексного регистра 6845 CHIP ( 3D4h/3B4h ).

        cli                     ; запретить прерывания.
        mov     al,15           ; подготовиться к работе с
                                ; регистром 15 CRTC.
        out     dx,al           ; передать номер регистра
        jmp     short $+2
        inc     dx              ; регистр данных
        in      al,dx           ; считать текущее значение
                                ; регистра 15.
        mov     ah,al           ; запомнить считанное
                                ; значение
        mov     al,66h          ; записать в регистр 15
                                ; тестовое значение.
        out     dx,al           ; передадим
        jmp     short $+2
        mov     cx,400h         ; дождаться, пока 6845 все
                                ; это воспримет.
W1:     loop    W1              ; ждем
        in      al,dx           ; считать тестовое значение.
        xchg    ah,al           ; восстановить
                                ; первоначальное значение
                                ; регистра 15.
        out     dx,al           ; передадим
        jmp     short $+2
        sti                     ; разрешить прерывания.
        cmp     ah,66h          ; считано тестовое значение?
        je      F6845           ; да, 6845 найден.
        jmp     NF6845          ; 6845 не найден

                                                           8

                      ОПЫТ ПРИМЕНЕНИЯ.

     Описанный  механизм  был,  в  частности,  применен  при
разаработке универсального  драйвера русского  языка. Авторы
стокнулись с  тем фактом,  что ни  один из  существоваших на
этот момент драйверов не поддерживал работу с альтернативным
видеоадаптером и  не обеспесчивал  расширенных  режимов  VGA
видеоадаптера.  Любая   попытка  перейти  на  альтернативный
видеоадаптер  приводила   к  срыву   синхронизации.   Авторы
использовали комбинации  видеоадаптеров EGA/HGC  и  VGA/MGA.
Разработанный авторами  драйвер поддерживает  все  описанные
выше комбинации  видеоадаптеров. Он  может  запускаться  как
драйвер  из   CONFIG.SYS  или   использоваться  как  обычная
программа и запускаться, например, из AUTOEXEC.BAT.

                                                                      1

                                               ГРУППА ПРОГРАММИСТОВ 2B.

          КАК СКОПИРОВАТЬ ЗАЩИЩЕННУЮ ОТ КОПИРОВАНИЯ ДИСКЕТУ.

     Статья посвящена анализу форматов защищенных от копирования дискет
и возможным методам их копирования.

                НЕСКОЛЬКО СЛОВ О ЗАЩИТЕ ОТ КОПИРОВАНИЯ.

     Системы  защиты   от   копирования   предотвращают   использование
"ворованных" копий  программного обеспечения. Разработка таких систем в
условиях нашей  страны, когда  огромные толпы  программистов  стремятся
всячески  вскрыть   защищенные  программы,  является  делом  достаточно
сложным и  требует определенной квалификации и опыта. В настоящее время
на  рынке  программного  обеспечения  средств  защиты  появилось  много
программ, обеспечивающих  защиту от  копирования. Зачастую реклама этих
программ не  соответствует действительным  возможностям. Авторы  решили
приобщиться к  когорте программистов,  вскрывающих  системы  защиты  от
копирования. При  этом мы не хотим дискредитировать сами системы защиты
от копирования,  а просто  хотим предостеречь  возможных покупателей от
использования несовершенных  систем с  одной стороны,  а также привлечь
новые отряды  высококвалифицированных программистов к разработке систем
защиты, которые действительно всем нам очень нужны.
     В основном все программисты, занимающиеся вскрытием защит, идут по
пути  преодоления   систем  защиты   от  отладчиков,   чтобы  выполнить
модификацию  тех   частей  программы,   которые  отвечают  за  проверку
легальности копии.  Эта работа  требует высокой  квалификации. Мы пошли
несколько другим  путем. Система  защиты предполагает  наличие дискеты,
называемой ключевой,  и не  копируемой стандартными средствами, а также
специальными  программами   или   аппаратурой   для   копирования.   Мы
исследовали  дискеты   систем  защиты   и  можем   предложить   способы
копирования защищенных  дискет с  использованием подручных  программных
средств. Вам  потребуется широко  распространенные  программы  COPYWRIT
издания март 1987 и EXPLORER издания апрель 1987.

     Мы подвергли анализу несколько системы.

     JAWS версия 4.0 1989 год. Автор Малькович А.П.

     НОТА  версия   1.1  февраль   1990.  Автор   Стас  Ляшев.  Система
распространяется СП НОВИНТЕХ.

     SHIELD (известна  также под  названиями ARMOUR,  БРОНЯ и ЩИТ). Под
названием SHIELD распространяется кооперативом ЭЛИАС.

     Система защиты  ПП от  несанкционированного копирования (программа
INST_FD) версия  2.1, май 1990. Производитель не известен. Известна под
названием PROTECT.

                                                                      2

                                 JAWS.

     Система защиты  от копирования  JAWS утверждает,  что созданные ей
дискеты  не   копируются  программой   COPYWRIT.  Это   утверждение  не
соответствует действительности.  Автор программы  записывает  некоторую
информацию на  0 поверхность  42 цилиндра.  Мы не  будем  рассказывать,
какой именно  формат и как записывается на этот цилиндр, т.к. Вы можете
запустить программу  COPYWRIT и, указав максимальный копируемый цилиндр
42, получить  работоспособную копию  защищенной  дискеты.  Естественно,
дискета легко копируется с помощью платы COPY II PC OPTION BOARD DELUXE
(в дальнейшем  изложении будем  называть для  краткости  просто  OPTION
BOARD), если вы укажете копирование до 42 цилиндра. При работе с платой
достаточно сначала  скопировать дискету  обычной программой DISKCOPY, а
затем с помощью платы скопировать 42 цилиндр.

                                 НОТА.

     Авторы этой  системы также  решили расположить информацию о защите
на  инженерном   цилиндре.  В   отличие  от  системы  JAWS  они  решили
использовать  41  цилиндр.  Однако  программа  COPYWRIT  также  успешно
копирует эту  дискету.  Дискета  естественно  легко  копируется  платой
OPTION BOARD.

                                SHIELD.

     Авторы система  SHIELD не  пошли проторенным  путем  использования
инженерного цилиндра. Они использовали свободное пространство на 0, 1 и
2 цилиндрах  для размещения  ключевой информации. Дискета не копируется
напрямую  программой  COPIWRYT.  Однако  после  копирования  программой
COPYWRIT достаточно  немножко помочь  программой EXPLORER  и Вы  имеете
работоспособную копию. Дискета не устойчива к копированию платой OPTION
BOARD. Мы  рекомендуем Вам  при использовании платы скопировать сначала
дискету программой DISKCOPY, а затем скопировать платой цилиндры 0-2.
     Для получения  работоспособной  копии  дискеты  после  копирования
программой COPYWRIT Вам следует воспользоваться программой EXPLORER. Мы
приведем пошаговую  инструкцию по  работе  с  программой  EXPLORER  при
копировании дискеты системы SHIELD.
     Установите оригинальную дискету в НГМД.
     Вызовите программу EXPLORER.

     Перед Вами появится первый экран.

       Recover file   a:
     Read directory   a:
        Read layout   a: <-выберите номер НГМД клавишами +/-
              Sides   2
      Diskette type   low density
           Position   0.0.0
      Analyze track  brief <-выберите режим brief и нажмите
                               ввод.

                                                                      3

Перед вами появиться второй экран.

pos arc     C   H   R   N SC cluster flags
  9 37.8    0   0   1   2  2
 47 37.8    0   0   2   2  2
 85 37.7    0   0   3   2  2
122 37.7    0   0   4   2  2
160 37.7    0   0   5   2  2
198 37.8    0   0   6   2  2
236 37.7    0   0   7   2  2
273 37.8    0   0   8   2  2
311 37.8    0   0   9   2  2
349 20.2   0   0  11   6  1         Sh <-установите сюда
                                         курсор и нажмите
                                            ввод.

     Перед вами появиться содержимое сектора. Сохраните его в буфере по
команде Ctrl-F1.  Затем вернитесь  на предыдущий  экран  клавишей  Esc.
Установите  дискету,   скопированную  программой   COPYWRIT.  Повторите
действия для  экрана 2.  Восстановите данные из буфера по команде Ctrl-
F2. Перед вами появиться картинка, похожая на следующую, хотя некоторое
значения на ней могут быть другими.

ЫЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЫ
Ы цццццццццццццццццццццццццццццццццццццццццццццццццццццццццццццццц Ы
Ы цццццццццццццццццццццццццццццццццццццццццццццццццццццццццццццццц Ы
Ы цццццццццццццццццццццццццццццццццццццццццццццццццццццццццццццццц Ы
Ы цццццццццццццццццццццццццццццццццццццццццццццццццццццццццццццццц Ы
Ы К·N99999999999999999999999999999998           ЖЖЗш  2)Ѕ9999999 Ы
Ы 999999999999998            44?}fТ      (IдeЖ`@@ N           Ы
                       ^
                       АДДДД установите курсор в эту позицию

     Вы должны  установить курсор примерно на 4-5 позиций дальше второй
повторяющейся группы символов.
     Нажмите клавишу  F8 -  короткая запись  и  подтвердите  запрос  на
короткую запись  нажатием клавиш  Ctrl-S. На  этом копирование  дискеты
закончено и Вы можете выходить из программы EXPLORER.

                        СИСТЕМА ЗАЩИТЫ INST_FD.

     Авторы этой защиты записывают нестандартную информацию на цилиндры
0 и  41. Дискета  легко копируется платой OPTION BOARD. Для копирования
этой дискеты  Вам потребуется  побольше времени,  чем  для  копирования
предыдущих защит.  При этом  Вы будете  пользоваться только  программой
EXPLORER.
     Выполните форматирование  дискеты, на  которую будет  копироваться
исходная дискета.  Запустите программу  EXPLORER и  выберете данные  на
первом экране, как делалось при копировании системы SHIELD.
     После  нажатия  ввода  и  считывания  формата  дискеты  Вы  должны
установить приемную  дискету  и  нажать  клавишу  F7  -  редактирование
формата. Отредактируйте  параметры  форматирования  (перемещение  между
параметрами производиться  стрелками  "ВЛЕВО"  и  "ВПРАВО".  Вы  должны
установить в левой части экрана под символом N значение 1, под символом

                                                                      4

GPL -  255, а  под символом  D -  88, как показано на примере. Значения
изменяются клавишами +/-.

Edit Format               Ы    C   H   R   N  SC  flag
                          Ы    0   0   1   2   1
drive:track.head  a:0.0   Ы    0   0   2   2   1
                          Ы    0   0   3   2   1
  N  SC GPL   D kind      Ы    0   0   4   2   1
  1  11 255  88           Ы    0   0   5   2   1
                          Ы    0   0   6   2   1
timing consistency +.09 % Ы    0   0   7   2   1
track estimate     6243   Ы    0   0   8   2   1
                          Ы    0   0   9   2   1
   key   purpose          Ы    0   0  11   6   1  Sh
         select field     Ы  123  17 249   7   1  Sh
  PgUp   edit command     Ы
  PgDn   edit id's        Ы
   Esc   return           Ы
  +  -   change field     Ы
    F5   format track     Ы
 enter   read sector      Ы

     Теперь нажмите клавишу F5 - форматирование и на запрос подтвердите
операцию  форматирования  лавишами  CTRL-F.  Аналогичную  операцию  Вам
необходимо проделать  для цилиндра  41. Номер  цилиндра  выбирается  на
первом экране.
     Для цилиндра  41 Вам  следует  переписать  сектор,  у  которого  в
столбце R  (см. предыдущий  экран) установлено  значение 1.  Это  можно
сделать с  помощью программы  EXPLORER. Прочитайте  сектор  с  исходной
дискеты.  Для   этого  установите  исходную  дискету  и  нажмите  ввод,
установим курсор  напротив этого  сектора. Запомните данные в буфере по
команде Ctrl-F1.  Теперь установите  приемную дискету и прочитайте этот
же сектор. Восстановите данные из буфера по команде Ctrl-F2 и выполните
запись сектора по команде F5, при этом подтвердите разрешение записи по
команде Ctrl-W.
     Для цилиндра  0 Вам  следует переписать  все сектора, у которого в
столбце R  (см. предыдущий экран) установлено значение 1 - 9. Вы можете
это сделать  аналогичным образом  или воспользоваться  любой программой
посекторного копирования.

                        ДОПОЛНИТЕЛЬНЫЕ ДАННЫЕ.

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

     CONVOY - распространяется фирмой ЭЛИАС.

     SOFT LOCK - производитель не известен.

     SUPER GUARD - производительне известен (возможно KAMI).

     GUARD -  производительне известен (возможно KAMI).

                                                                      5

                                 JAWS

     Ключевая  информация   в  системе   располагается  на   дорожке  0
инженерного цилиндра  с номером 42. Автор системы защиты от копирования
JAWS  утверждает,   что  созданные  дискеты  не  копируются  программой
COPYWRIT. Это  утверждение не  соответствует действительности.  Дискета
копируется  программой   COPYWRIT,  если   указать  максимальный  номер
копируемого цилиндра,  равным 42. Естественно, дискета легко копируется
с помощью  платы COPY  II PC  OPTION BOARD  DELUXE (в дальнейшем OPTION
BOARD), если указать копирование до 42 цилиндра включительно.
     Формат ключевой информации следующий.
     Дорожка 0  цилиндра 42  форматируется на  9  секторов  с  обычными
параметрами  (GAP=80,   N=2).  При   форматировании  применяется  метод
нарушения последовательности  секторов. Первый  сектор на дорожке имеет
номер 11, остальные сектора имеют последовательные номера от 2 до 9.
     Следует отметить, что программа проверяет только наличие сектора с
номером 11  путем считывания сектора с этим номером. Поэтому достаточно
иметь на  ключевой дорожке  обычный сектор  с номером  11, а  остальные
сектора не нужны.

                                 НОТА

     Авторы этой системы также решили расположить информацию о защите в
области инженерных  цилиндров. В  отличие от  системы JAWS  они  решили
использовать дорожку  0 цилиндра  41. Однако программа COPYWRIT и плата
OPTION BOARD также успешно копируют эту дискету.
     В системе  применен более  любопытный формат  ключевой дорожки, по
сравнению с системой JAWS.
     На дорожке применяется один из вариантов метода нарушения значений
CHRN. Метод  состоит в  следующем. Ключевая дорожка форматируется на 10
секторов с параметрами GAP=16, N=2. В поле N всех секторов записываются
значения 3.  Перезаписывается  сектор  с  номером  1.  Это  приводит  к
затиранию  маркера   идентификатора  следующего   сектора.  На  дорожке
остается  9  секторов.  Значения  CHRN  затираемого  сектора  не  имеют
принципиального значения. Номера оставшихся секторов нумеруются обычным
образом от  1  до  9.  В  сектор  с  номером  1  записывается  ключевая
информация.
     Как и  в  предыдущей  системе  JAWS,  проверяется  только  наличие
сектора с  номером 1  (R=1) и  N=3 и  считывается из  него  информация.
Поэтому на  ключевой дорожке  достаточно иметь  только  этот  сектор  и
записанную  в   него  информацию.  Остальные  сектора  не  проверяются.
Копирование  проще   всего  сделать   отформатировав  ключевую  дорожку
дискеты-копии на  1 сектор с параметром N=3 и записав в него информацию
из первого сектора ключевой дорожки оригинальной дискеты.
     Следует  отметить,   что  авторы   не   использовали   возможность
дополнительного  контроля   примененного  формата.  Чтение  секторов  с
номерами  2, 3, ... , 8   и   анализ   информации   в   них   позволяет
контролировать размер  GAP3, заданный  при  форматировании.  Информация
сектора  с  номером  9  позволяет  определять  и  контролировать  длину
дорожки. При  этом авторы  получили бы защиту от копирования программой
COPYWRIT.

                                                                      6

                                SHIELD

     Авторы системы  SHIELD не  пошли проторенным  путем  использования
инженерного цилиндра  и  нарушения  CHRN.  Они  использовали  свободное
пространство на  дорожке 0  цилиндров 0,  1 и 2 для размещения ключевой
информации. Дискета  не копируется напрямую программой COPYWRIT. Однако
после  копирования   программой  COPYWRIT  достаточно  немножко  помочь
программой DISK EXPLORER и Вы имеете работоспособную копию. Естественно
дискета легко копируется платой OPTION BOARD.
     На дискете  применяется метод  форматирования  с  кодом  длины  1.
Рассмотрим формат ключевых дорожек.
     Все ключевые  дорожки форматируются  на 19  секторов с  N=1 и GAP3
между 3  и 7. В данном случае длина GAP3 не имеет значения, так как она
не проверяется. В нечетных секторах в CHRN устанавливается N=2 и номера
секторов R  принимают последовательные  значения от  1 до 9. Перезапись
этих секторов  затирает адресные  маркеры  идентификаторов  примыкающих
секторов и получается стандартный формат с N=2 и номерами секторов R от
1 до 9. Последний сектор используется для контроля ключевой информации.
     На цилиндре  0 последний  сектор имеет  параметры  N=6  и  R=11  и
используется для контроля длины дорожки. При чтении этого сектора можно
получить длину GAP4B и увидеть начало дорожки.
     На цилиндрах  1 и 2 последний сектор имеет параметры N=1 и R=10. В
эти сектора записывается ключевая информация.
     Для получения  работоспособной  копии  дискеты  после  копирования
программой  COPYWRIT   Вам  следует   воспользоваться  программой  DISK
EXPLORER. При этом необходимо скорректировать последний сектор цилиндра
0, чтобы  программа  проверки  ключевой  дискеты  получала  необходимые
данные  при  чтении  этого  сектора.  Для  этого  необходимо  прочитать
ключевой сектор  с оригинальной  дискеты и  выполнить  короткую  запись
этого сектора  на дискету-копию.  Длина записываемых данных должна быть
достаточной для  перезаписи GAP4B  и всех  данных начала дорожки. Чтобы
при короткой  записи не  затереть маркер идентификатора первого сектора
на дорожке, рекомендуем при форматировании ключевой дорожки на цилиндре
0 использовать  маленький  GAP  порядка  3.  Это  обеспечит  достаточно
большую  длину   GAP4B  и   необходимое  место   для   записи   данных,
контролируемых программой.  Не забудьте  переписать  содержимое  других
секторов на  этих дорожках,  так как  в них  содержится информация  для
работы DOS.

                           PROTECT - INST_FD

     Авторы  этой   системы  не   удержались  от   примечательной  идеи
использования  области   инженерных  цилиндров.   Нестандартный  формат
применяется на  дорожке 0  цилиндров 0  и  41.  Дискета  не  копируется
программами COPYWRIT  и COPYIIPC,  но успешно  копируется платой OPTION
BOARD.
     На дискете  применяется метод  форматирования с  длиной  1.  Также
применяется метод  увеличения длины последнего сектора, для запутывания
программ  COPYIIPC  и  COPYWRIT.  Применяемый  формат  имеет  следующие
характеристики.
     Формат одинаков  для цилиндров  0 и 41. Выполняется форматирование
на 11  секторов с  N=1, GAP=255  и символом  заполнителем формата  "X".
Первые 9  секторов имеют  стандартные R  от 1 до 9 и N=2. Предпоследний
CHRN имеет  R=11 и  N=6. У  последнего сектора поля CHRN соответственно

                                                                      7

равны 123,  17, 249  и 7. Полученный формат при работе с секторами от 1
до 9  имеет "отрицательный"  GAP3, так как форматирование выполняется с
кодом длины  1, а операции с секторами выполняются с кодом длины 2. При
этом CRC  сектора залезает  на SYNC  адресного  маркера  идентификатора
следующего сектора.  В первом секторе цилиндра 41 записывается ключевая
информация, а  сектора 2, 3, ... , 9  заполняются  символами  F6h,  что
должно маскировать их под обычный формат.
     Вместе с тем, авторы проверяют из всего объема ключевой информации
только информацию  из первого  сектора  на  цилиндре  41.  Поэтому  при
копировании достаточно  завести  обычный  сектор  с  номером  1  на  41
цилиндре и переписать туда ключевую информацию.
     Авторы  не   использовали  дополнительных   возможностей  контроля
ключевой информации. Анализ данных при чтении предпоследнего сектора на
ключевых  дорожках   позволяет  контролировать  размер  GAP3  и  символ
заполнитель, использованные при форматировании, а также CHRN последнего
сектора на дорожке и длину дорожки.

                                CONVOY

     Анализ проводился  на основе  ключевой дискеты.  Самой  системы  в
распоряжении не было.
     Дискета не  копируется программами COPYWRIT и COPYIIPC, но успешно
копируется платой OPTION BOARD.
     Все дорожки форматируются стандартным образом. Ключевая информация
в системе располагается в поле GAP 3 сразу за полем CRC первого сектора
на цилиндре 0 дорожке 0.
     Рассмотрим способ  построения ключевой  дискеты. Для  изготовления
дискеты может  быть применен  метод прекращения  операции  контроллера.
Выполняется "короткое" форматирование на один сектор дорожки 0 цилиндра
0 с  прекращением операции  в GAP 2. Параметры CHRN сектора - C=0, H=0,
R=1 и кодом длины сектора N=3. Такое форматирование полностью сохраняет
данные на  дискете, но позволяет перезаписывать данные сектора, включая
данные GAP  3. Затем  выполняется "короткая"  запись  данных  ключевого
сектора, причем записывается поле данных сектора, поле CRC и данные GAP
3. Прекращение  операции выполняется в поле GAP 3 после записи ключевой
информации. Затем  выполняется "короткое" форматирование на один сектор
дорожки 0  цилиндра 0  с прекращением  операции в GAP 2. Параметры CHRN
сектора - C=0, H=0, R=1 и кодом длины сектора N=2. Такое форматирование
восстанавливает исходный формат дорожки.

                               SOFT LOCK

     Формат дискеты системы SOFT LOCK строго аналогичен формату системы
CONVOY.

                              SUPER GUARD

     Cистема SUPER  GUARD использует  схему защиты, сходную с системами
CONVOY и  SOFT LOCK,  но для  хранения ключевой информации используется
поле GAP 3 первого сектора дорожки 0 цилиндра 1.
     Помимо этого,  авторы системы  для усиления  защиты на дисководах,
обеспечивающих 80  цилиндров (дисководы  1.2 Мб),  записывают данные на
цилиндр, не  используемый при форматировании дискеты на 360 Кб. Дорожка
0 цилиндра  с абсолютным номером 31 (для накопителя, обеспечивающего 80

                                                                      8

цилиндров) форматируется с параметрами GPL=84, N=1, H=0 на 9 секторов с
номерами секторов  R соответственно  равными 1, 2, 3, 244, 5, 6, 7, 10,
9. Ключевые  данные записываются в сектор с номером R равным 244. Такой
метод позволяет защитить дискету от копирования платой OPTION BOARD при
использовании на  дисководах 1.2 Мб (на дисководах 360 Кб копия дискеты
естественно работает).  Это объясняется  тем, что плата OPTION BOARD не
копирует промежуточные цилиндры для дискет емкостью 360 Кб.

                                 GUARD

     Анализ проводился  на основе  ключевой дискеты.  Самой  системы  в
распоряжении не было.
     Дискета не  копируется программами COPYWRIT и COPYIIPC, но успешно
копируется платой OPTION BOARD.
     Авторы  системы  не  отказали  себе  в  удовольствии  использовать
инженерные цилиндры.  Вместе  с  тем  ключевая  информация  расположена
практически на всей дискете.
     Дорожки 0  цилиндров 0,  1 и  2 форматируются обычным образом на 9
секторов. Все  остальные дорожки  всех цилиндров,  включая  цилиндр  41
форматируются на  5 секторов с параметрами GPL=192, кодом длины сектора
N=3,  символом   заполнителем  формата   42  и   номерами  секторов   R
соответственно равными  1, 2,  3, 4, 5. При этом данные записываются во
все  сектора   дорожки  0  на  всех  цилиндрах.  На  дорожке  1  данные
записываются в  сектора только  на цилиндрах  0, 1  и 2. Также ключевые
данные записываются  в сектор с номером 5 на дорожке 1 цилиндра 41. Все
остальные сектора  после  форматирования  не  перезаписываются.  Вполне
возможно, что  информация в  эти сектора  не записывалась,  т. к. объем
защищаемых данных был меньше.

                                ВЫВОДЫ

     Анализ    вышеперечисленных    систем    позволяет    предположить
(специальных  исследований   не  проводилось),  что  проверка  ключевой
информации на  дискете в  ряде систем осуществляется с помощью INT 13h.
Также следует  отметить, что  авторы не  всех систем  достаточно  полно
использовали возможности контроля ключевой информации.
     Результаты    анализа    вышеперечисленных    систем    показывают
однотипность используемых методов размещения ключевой информации в поле
GAP 3  (CONVOY,  SOFTLOCK,  SUPER  GUARD).  Это  позволяет  говорить  о
возможном заимствовании  схемы  построения  ключевой  дискеты.  Впервые
такая схема была применена в системе защиты кооператива "Эклипс".
     Исследованию  подвергался   еще  ряд   систем,  не   включенных  в
изложение. Приведем их краткое описание.
     Система, с  помощью  которой  выполнялась  защита  русской  версии
пакета GEM фирмы DIGITAL RESEARCH, копируется достаточно легко.
     Система защиты  русификатора  WINDOWS  3.0  (CYRWIN).  Система  не
только легко  копируется, но  в ней очень просто изменить счетчик числа
установок.
     Авторы анализировали  еще ряд  различных систем названий которых и
параметров форматировыния  уже  не  помнят,  т. к.  не  обнаружили  там
принципиально новых идей.

                                                                      9

        ЧТО НАДО ЗНАТЬ ПРИ ВЫБОРЕ СИСТЕМЫ ЗАЩИТЫ ОТ КОПИРОВАНИЯ

     Выбор системы  защиты от  копировании является  достаточно сложной
проблемой. При необходимости выбора лучше всего получить консультацию у
независимых экспертов  или по крайней мере у специалистов. Однако можно
выделить следующие  основные вопросы, на которые следует получить ответ
у разработчиков или распространителей системы.
     Вопрос:
     Используются ли  функции BIOS  для проверки ключевой информации на
дискете?
     Если используются функции BIOS, то такая система легко вскрывается
и формат дискеты вряд ли достаточно сложный.
     Вопрос:
     Копируется ли дискета платой OPTION BOARD?
     В СССР  платы OPTION  BOARD  получили  широкое  распространение  и
скорее всего защищенная дискета будет копироваться и распространяться.
     Вопрос:
     Имеются ли в системе функции снятия установленной программы с НЖМД
с восстановлением счетчика установок на ключевой дискете?
     Если  такие  функции  присутствуют,  то  при  использовании  такой
система легко получить нелегальную копию.
     Вопрос:
     Применяются ли в системе специальные меры для защиты от отладчиков
в процессорах INTEL 80386 и INTEL 80486?
     Если такие  меры не  применяются, то  легко выполнить  трассировку
программы  на   специализированных   отладчиках,   использующих   режим
виртуального процессора 8086 для процессоров INTEL 80386 и INTEL 80486.

                              ЗАКЛЮЧЕНИЕ.

     Мы приглашаем  всех специалистов в увлекательную гонку по созданию
систем защиты.  При этом рекомендуем программистам, не умеющим работать
напрямую  с   контроллером  НГМД   без  применения  BIOS,  не  пытаться
участвовать в этом увлекательном мероприятии.

                                                                    1

                                               ГРУППА ПРОГРАММИСТОВ 2B

          АНАЛИЗ ОТЕЧЕСТВЕННЫХ СИСТЕМ ЗАЩИТЫ ОТ КОПИРОВАНИЯ
                              (выпуск 2)

     Мы продолжаем обзор форматов ключевых дискет отечественных систем
защиты от  копирования (предыдущий  обзор  Вы  можете  найти  в  файле
2BINFO.ZIP в  статье 2BCOPY).  Несмотря на  заявления, содержащиеся  в
рекламных  материалах   ряда  нижеперечисленных   систем   защиты,   о
некопируемости ключевых  дискет с  помощью платы  OPTION BOARD (так мы
для краткости  будем называть плату COPYIIPC DELUXE OPTION BOARD фирмы
Central Point  Software), эти  заявления сильно  преувеличены.  Видимо
авторы  этих   систем  выдают  желаемое  за  действительное.  Чтобы  в
дальнейшем специально  не повторяться,  сразу отметим  - дискеты  всех
нижеперечисленных систем  защиты легко  копируются этой платой. Авторы
настоящего обзора  обычно используют  плату OPTION  BOARD для создания
архивных копий  ключевых дискет  систем защиты  от  копирования.  Ниже
помимо формата  ключевых  дискет  систем  защиты  приводится  один  из
возможных способов получения соответствующего формата.

                                STAS-3

     Анализ проводился  на основе  ключевой дискеты.  Самой системы  в
распоряжении не было.
     Автор системы  Стас Ляшев  (см. систему НОТА в предыдущем обзоре)
не отказался  от идеи  использования  инженерных  цилиндров.  Ключевая
информация  располагается   на  0  поверхности  41  цилиндра.  Дорожка
форматировалась на  3 сектора  с кодом  длины сектора  2  (стандартный
сектор 512  байт), GAP=84  и символ  заполнитель  246.  Значения  CHRN
секторов  следующие   -  (41,0,11,2),  (41,0,12,2)  и  (41,0,99,3).  В
последний сектор  (с кодом  длины 3) записана ключевая информация. Для
получения  работоспособной  копии  информацию  из  последнего  сектора
ключевой  дискеты   необходимо  переписать  в  соответствующий  сектор
дискеты-копии.
     Дискету крайне  легко копировать  с помощью программы EXPLORER, а
те, кто  умеет работать  с дискетами  через BIOS,  с легкостью напишут
программу копирования этой дискеты.

                         ALFA - 2.05 (RAIZOR)
                      (производитель МП "АНКАД")

     Система ALFA  тоже  использует  крайне  простой  формат  ключевой
дискеты. Поверхность  0 цилиндра  39 отформатирована  на 19 секторов с
кодом  длины   сектора  1   (сектор  256   байт),  GAP=10   (точно  не
анализировали за  ненадобностью) и символом заполнителем 246. Значения
CHRN первых  9 секторов: C=39, H=0, R=1-9 и N=1. Остальные 10 секторов
имеют  нулевые  значения  во  всех  полях  CHRN.  Ключевая  информация
записана в  первом секторе.  Вообще говоря,  для  копирования  дискеты
достаточно отформатировать  соответствующую дорожку дискеты-копии на 1
сектор с  кодом длины 1 и CHRN (39,0,1,1) и перезаписать в этот сектор
информацию из ключевой дискеты.
     Дискету крайне  легко копировать  с помощью  программы  EXPLORER.
Если Вы  умеете работать  с  дискетами  с  помощью  средств  BIOS,  то
написать программу копирования ключевой дискеты с помощью этих средств
для Вас не составит труда.

                                                                    2

                             PROTECT 5.0.

     Дискета строго аналогична по формату дискете системе ALFA.

                                 ECP
                      распространяется ЦЭИ МФТИ.

     Авторы этой  системы утверждают,  что они  гораздо  круче  систем
COP's  COPYLOCK   и  CERBERUS.  Делать  такие  заявления  надо  весьма
осмотрительно.  Мы,   как  разработчики   системы   CERBERUS,   весьма
положительно относимся  к неизвестным  нам разработчикам системы COP's
COPYLOCK,  т. к.   в  ней   применены  простые,  но  весьма  и  весьма
эффективные средства создания ключевой дискеты. Спор может идти только
вокруг стойкости  защиты от  отладчика и возможности выпуска ключей на
различных ПЭВМ.  Защиту от  отладчика  COP's  COPYLOCK  делает  весьма
слабо. Для  того чтобы  выпустить ключевую  дискету  с  помощью  COP's
COPYLOCK, нужно  долго искать  подходящую ПЭВМ.  Также COP's  COPYLOCK
страдает тем,  что ключевая  дискета  может  неустойчиво  опознаваться
(даже в НГМД, в котором она была создана).
     Авторы же  ECP, похоже не пошли дальше использования средств BIOS
при создании  ключевой дискеты.  Ключевая информация  располагается на
инженерных цилиндрах.  Поверхность 0 цилиндра 40 форматировалась на 30
секторов с  кодом длины  сектора 0,  GAP порядка 10 (это достаточно) и
символом  заполнителем  11.  В  первом,  четвертом,  седьмом  и  т. д.
секторах в  CHRN устанавливается  N=2 и  номера секторов  R  принимают
последовательные значения от 1 до 9. Перезапись этих секторов затирает
адресные  маркеры   идентификаторов  двух   примыкающих   секторов   и
получается стандартный  формат с  N=2 и номерами секторов R от 1 до 9.
Сектор  28  не  затирается  и  для  него  в  CHRN  при  форматировании
устанавливается  (40,0,10,1).  В  этот  сектор  записывается  ключевая
информация. После  записи затирается  адресный  маркер  идентификатора
одного примыкающего  сектора. В  результате на  дорожке остается  один
последний сектор,  используемый для  контроля GAP4B. Сектор имеет CHRN
(40,0,11,2). Все это легко повторить с помощью программы EXPLORER. Для
сохранения  длины   GAP  4B  необходимо  выполнить  "короткую"  запись
информации из  этого сектора  с ключевой  дискеты. О методе "короткой"
записи рассказывалось при анализе системы SHIELD в предыдущем обзоре.
     Также ключевая информация располагается на поверхности 1 цилиндра
40.  Там   наворочена  всякая   ерунда  со   стандартными  параметрами
форматирования (количество секторов = 9, N=2 и символ заполнитель 11).
Вся игра  происходит на  длине GAP  и CHRN  секторов. Анализ структуры
дорожки и  форматирование легко  сделать с помощью программы EXPLORER.
Никакая дополнительная информация на эту дорожку не записывается.

                         СИСТЕМА БЕЗ НАЗВАНИЯ

     Система защиты,  название которой нам неизвестно, анализировалась
на основе дискеты, на которой была записана ИПС "ТРАНЗИСТОР".
     Очень приятно было увидеть использование новых принципов создания
ключевой дискеты  (новых, с точки зрения рассмотренных в наших обзорах
систем),  явно   требующих  знания   контроллера   НГМД.   Поздравляем
разработчиков!!!
     Поверхности 0 и 1 форматировались, как описано для системы SHIELD
в  предыдущем   обзоре.   Однако   последние   сектора   на   дорожках
использовались не  для контроля  GAP 4B.  Они имеют R=11 и N=6 и в них
производилась "короткая" запись ключевой информации (использование N=6
препятствует копированию  этих секторов  с помощью программы COPYIIPC,
которая не  умеет перезаписывать  "короткие"  сектора  с  таким  кодом

                                                                    3

длины).  Помимо   этого  используется   хранение  информации   в  GAP3
(аналогично системам  CONVOY, SOFT  LOCK  и  т. д.  -  см.  предыдущий
обзор).
     На наш  взгляд, это  одна из лучших защищенных дискет, которые мы
анализировали.

                           File_PROTECTION
                             Version 3.10
                   (C) 1991 NOVEX Technology, Ltd.

     Ключевая  информация  располагается  на  инженерном  цилиндре  40
поверхности 0.  Дорожка форматировалась  на 11  секторов с кодом длины
сектора  1  и  GAP=232.  В  каждом  случае  используется  свой  символ
заполнитель. Способ  его определения  мы опишем  ниже.  При  первичном
форматировании CH секторов устанавливаются 40,0. R и N устанавливаются
следующим образом:
(1,2),(16,0),(17,0),(9,2),(5,3),(6,3),(7,3),(8,3),(9,3),(10,3),(11,3).
     Затем производится  запись в  сектор с  RN (11,3), что приводит к
затиранию первого сектора дорожки, потом запись в сектор с RN (10,3) и
т.д., включая  запись в  сектор с  RN (9,2).  В результате  получается
формат дорожки  с 3-мя  секторами с RN - (16,0),(17,0),(9,2). Теперь в
сектор  с  RN  (9,2)  переписывается  информация  из  соответствующего
сектора ключевой дискеты.
     На  ключевой   дискете  с   самим   File_PROTECTION   также   был
отформатирован инженерный  цилиндр 40  поверхность 1  с  CH  (40,1)  и
остальным аналогичным форматом.
     Разработчики системы  не проверяют  многое из  того,  что  у  них
получается в  формате дорожки.  Поэтому для получения ключевой дискеты
достаточно выполнить форматирование на 3 сектора с кодом длины сектора
2, RN  (16,0),(17,0),(9,2),  GAP=80  и  перезаписать  сектор  (9,2)  с
ключевой дискеты.
     Для определения символа заполнителя достаточно прочитать сектор с
RN (17,0) с ключевой дискеты и посмотреть код первого символа, который
в нем записан. Это и есть символ заполнитель формата.
     Все  вышеперечисленные  процедуры  легко  выполняются  с  помощью
программы EXPLORER.

                             ЗАКЛЮЧЕНИЕ.

     Подводя итог  двум выпускам  этого  обзора  можно  отметить,  что
данные, приведенные  в сборнике  фирмы "ЭЛИАС",  по  стойкости  систем
защиты от копирования, не совсем верные.
     Во-первых, все  вышеперечисленные (в  этом и  предыдущем  обзоре)
системы легко копируются платой OPTION BOARD (мы также анализировали и
другие отечественные  системы, о  которых уже  не помним,  но все  они
легко копируются  платой OPTION  BOARD). Вообще  защита от копирования
платой OPTION  BOARD является  делом весьма сложным и по внешнему виду
формата ключевой дискеты всегда можно сказать, есть ли на дискете что-
то, что  не позволяет скопировать ее с помощью платы. Также для защиты
от платы  необходимо в совершенстве владеть знаниями о формате дискеты
и о работе с контроллером НГМД (включая специальные "трюки").
     Во-вторых, ряд  систем легко  копируется подручными  программными
средствами (например с помощью программы EXPLORER).
     В-третьих, для  некопируемых с  помощью программы EXPLORER систем
(типа CONVOY, SUPER GUARD и т.д.) можно разработать достаточно простые
программы копирования, т.к. на ключевых дискетах слишком мало ключевых
признаков и они достаточно однообразны.

                                                                    4

     На этом  мы пока  прекратим обзоры  систем защиты от копирования.
Эти материалы  готовились для  того, чтобы  ввести  читателей  в  курс
проблемы и  помочь сделать  правильный выбор.  В ближайшем  будущем мы
готовим  к   выпуску   книгу,   посвященную   проблемам   компьютерной
безопасности и  защите от  копирования. Также  планируется подготовить
серию книг,  описывающих методы  программирования аппаратуры  ПЭВМ без
использования BIOS на уровне адресов ввода/вывода. Если Вас интересует
такая проблематика,  то  мы  готовы  выслушать  предложения,  о  какой
аппаратуре следует  написать в  первую очередь  и  за  какую  цену  Вы
согласны купить  такие  книги.  Серия,  помимо  книг,  будет  включать
дискеты с примерами.
     Авторы не  только "ковыряют" чужие системы. Прямо скажем, что это
вообще не  их профиль  (на анализ  всех вышеперечисленных систем у нас
ушло очень  мало времени).  Мы такие  же разработчики  программ, как и
все. В  качестве образца  наших программ  Вы  можете  познакомиться  с
системой защиты от копирования CERBERUS.
     CERBERUS не  использует BIOS,  а работает напрямую с контроллером
НГМД.
     На  дискете   системы  CERBERUS   версии  1.8   содержится  много
контролируемых ключевых  признаков. На  отечественном  рынке  CERBERUS
единственная система,  дискеты  которой  ДЕЙСТВИТЕЛЬНО  НЕ  КОПИРУЮТСЯ
платой OPTION BOARD.
     Первые версии  CERBERUS (1.0 и 1.1) обладали недостаточно стойким
алгоритмом защиты от отладчика. Разработчики имели ряд бесед со своими
знакомыми специалистами по взлому, которые указали им на недостатки. В
CERBERUS версии  1.8 алгоритм защиты от отладчика значительно улучшен.
Также значительно  улучшена надежность  работы программы  на различных
типах ПЭВМ.
     Сейчас  готовится   новая  версия  системы  -  CERBERUS  2.0.  (В
настоящее время  готов бета-релиз  системы). Она  умеет  защищать  все
классы DOS  программ -  COM, EXE,  внутренние оверлеи,  драйверы DOS и
даже независимые  системные программы (Вы можете защитить саму DOS или
программы, загружаемые  непосредственно с  дискеты; для  отладки  этой
части мы  защищали операционную систему DR DOS). В алгоритме защиты от
отладчика использованы  все мыслимые  (и немыслимые) приемы. По совету
наших друзей  мы включили те приемы, о которых знали, но не считали их
достаточно серьезными.  На дискете  значительно  увеличено  количество
ключевых признаков.
     Помимо этого,  в настоящее  время также идет создание специальных
инструментальных средств,  позволяющих разработчику программы включать
средства защиты  в свой  модуль. Это позволит решить проблему "снятия"
программы из оперативной памяти.
     Также  значительно   повышена  надежность   работы  программы  на
различных типах ПЭВМ.

Как связаться с авторами:
телефон:  (095)329-4611
телефакс: (095)329-4711
адрес:    115598, г. Москва, ул. Ягодная, д.17 СП "ДИАЛОГ"
          Отдел экспертизы и сертификации ПО
E-MAIL Vlad_Seregin 2:5020/6 @Fidonet (JVD1BBS,095-329-2192)
RELCOM: qa-dep@jvd.msk.su


Яндекс цитирования