Реставрируя достаточно большое количество программ зачастую приходится сталкиваться с защитными механизмами, установленными для предотвращения нелегального распространения, реализованными через привязку к оборудованию.
Со временем и прогрессом оборудование меняется и подобные системы защиты перестают работать и, как следствие, возможность запустить защищённую ими программу пропадает. Виртуальные машины не являются решением, так как там основной упор делается на программную составляющую, нежели на различные тонкости эмуляции оборудования.
Чтобы иметь общее представление о чём идёт речь, ниже приведены несколько примеров таких защит, с которыми приходилось сталкиваться.
1) Достаточно старая (примерно 1990 года) программа для MS-DOS.
На современных компьютерах зависает сразу после запуска, под виртуальными машинами или эмуляторами чуть позже - через 5-10 секунд. Защита, установленная на программу, оказалась настолько же простой и гениальной, насколько и нежизнеспособной в долгосрочной перспективе. Итак, после запуска программа ждёт около 10 секунд, показав при этом экран с логотипом (не пропускается), затем читает один из своих файлов и тут же проверяет некоторое значение в памяти отвечающее за состояние мотора дисковода. Если оно равно определённому значению, значит, мотор работает, и, следовательно, последняя операция чтения была выполнена с дисковода и проверка проходит, так как работа мотора позволяет предположить, что и программу запустили с дискеты (та пауза в 10 секунд нужна была чтобы закончилась операция чтения, сделанная во время запуска исполняемого файла самой программы, и мотор дисковода остановился). Если же значение не равно необходимому, то программа пытается считать его снова и снова, в результате чего попадает в бесконечный цикл - "зависает" (проверка не прошла).
У этой программы, на самом деле, проблемы начинаются ещё раньше того времени, как НГМД и дисководы уйдут в историю и их заменят USB-Flash накопители. Всё дело в том, что пользователь может запустить программу для DOS под названием SmartDrive (SMARTDRV.EXE), которая кеширует последние открытые файлы, увеличивая тем самым скорость работы. В результате при повторном запуске программы не исключена ситуация, когда её файлы будут отданы из кеша SmartDrive, а не считаны с диска и, как результат, обращений к диску не будет, мотор дисковода не запустится - программа "зависнет". На современных же системах, даже если программа без проблем запускается под NTVDM (виртуальная машина DOS x16/x32 и Windows x16 приложений для линейки систем Windows NT x32), то не факт, что на компьютере, где была запущена программа, физически есть дисковод, не говоря уже о том, что сами дискеты весьма недолговечны. С виртуальными машинами ситуация не лучше, т.к. эмулируя дисковод, они не эмулируют или не полностью эмулируют то самое значение в памяти отвечающее за состояние дисковода.
Для "корректировки" данной защиты пришлось изменить код программы так, чтобы тот самый участок с бесконечным циклом и проверкой никогда не выполнялся.
2) Следующая программа (примерно 1995 года) тоже для MS-DOS.
Здесь разработчики для реализации защиты решили использовать самоизменяющийся код. При запуске программы стартует крохотных кусочек кода - загрузчик - который делает несколько проверок, а также расшифровывает тело основной программы в памяти. Казалось бы, никаких привязок к оборудованию. Но разработчики забывают про такую важную вещь как ЦП (центральный процессор). Всё дело в том, что очень скоро рынок будет заполнен процессорами имеющими конвейер. Инструкции загруженные в конвейер можно сбросить выполнив, например, операции "call" или "jmp", которые приводят к очистке конвейера и загрузке в него инструкций с нового адреса. Однако, тот загрузчик этого не делает, а лишь меняет следующий байт-инструкцию с "ret" (возврат из подпрограммы) на "nop" (пустой оператор), если все проверки прошли успешно. Так как байт который поменялся уже давно находится в конвейере ЦП, то все его изменения в памяти ничего не дадут без сброса кеша самого конвейера. Таким образом, проверка всегда будет проваливаться, а программа не запускаться.
Некоторые виртуальные машины решают проблему с конвейером (так как он у них отсутствует), но там уже проваливаются другие проверки связанные с неполной эмуляцией аппаратной составляющей. Для корректной работы программы пришлось менять изначальную инструкцию "ret" на "nop", чтобы то что было в конвейере не отличалось от того что есть в программе.
3) Уже упомянутая в предыдущей статье программа "АстроЛогос" (примерно 1996 года) 16-разрядная для Windows.
Защита сделана через привязку к LPT-ключу. Как мы все знаем LPT-портов на современных компьютерах нет. Программа есть, ключ есть, а порта для него нет.
Однако, программа была возвращена к жизни, о чём можно более подробно прочитать в соответствующей статье "Не выбрасывайте старые программы".
4) Ещё одна программа уже более современная (примерно 2000 года) 32-разрядная для Windows.
С ней всё было отлично пока 64-разрядные системы не стали обыденностью. На Windows 7 x64 программа не могла запуститься и падала. Оказалось, что защита была привязана к архитектуре x32 и на x64 работала неверно, отчего программа, в буквальном смысле, просто разваливалась после запуска.
Для устранения этого дефекта пришлось писать и внедрять в неё код эмулирующий работу системы x32, чтобы защита отработала корректно и программа могла продолжить выполнение.
И так далее и тому подобное - примеров можно привести множество.
Из изложенного выше хорошо видно, что любая защита, алгоритм работы которой опирается на аппаратную реализацию, рано или поздно выходит из строя не оставляя тем самым пользователям никаких легальных способов (соблюдая все условия лицензионного соглашения) на возможность работы с официально приобретённой программой.
Возможно, что такой способ защиты оправдывает себя, когда разработчики выпускают исправления или новые версии программы на которые пользователи могут перейти со старых. Но, зачастую, после некоторого момента даже очень хорошее ПО начинает обрастать множеством ненужных вещей, а нужные могут быть убраны или перемещены в труднодоступные части программы, сводя таким образом всё удобство работы с ней на нет. В результате пользователь стоит перед выбором: либо пытаться как-то запустить удобную версию программы, либо работать с неудобной. Или, вообще, выбора нет, если в новой версии необходимый функционал полностью отсутствует, а программа является уникальной и аналогов не имеет.
Впрочем, для этих и многих других проблем (при условии персонального использования) решение есть.
Если же говорить о защитах вообще, то любую защиту можно снять. Всё зависит от популярности ПО на котором она установлена и степени сложности самой защиты. Так что, дабы не создавать никому неудобств, при разработке и/или использовании защиты стоит руководствоваться несколькими простыми правилами:
1) Время и средства потраченные на разработку защиты не должны превышать времени и средств потраченных на написание защищаемой программы.
Потому что это увеличит срок разработки и стоимость программы, а ведь это время и средства можно было потратить на доработку или улучшение, так как конечный пользователь платит именно за функционал, а не за защиту, которую он даже не видит (если она не мешает ему работать).
2) Защита не должна создавать проблем с эксплуатацией легально приобретённой программы.
Здесь можно вспомнить печально известные защиты, при использовании которых зачастую лицензионные пользователи получали фатальные ошибки и крах системы вместо нормально работающей программы. Сюда же можно отнести защиты, которые в силу специфики своей работы замедляют и утяжеляют защищаемые программы, вынуждая официальных клиентов пользоваться модифицированными версиями, для повышения быстродействия, а зачастую и общей стабильности работы программы.
3) Защита не должна использовать недокументированные возможности системы.
Это чревато тем, что на новой системе или после установки какого-либо системного обновления защита может перестать работать, что сделает защищаемую программу неработоспособной.
4) Защита не должна провоцировать ложные срабатывания антивирусов.
Многие защиты используют достаточно грязные методы для шифрования и затруднения отладки программы или отдельных её частей, чем и напоминают вредоносное программное обеспечение заставляя эвристический анализатор антивирусов бить ложную тревогу. Проблема, по идее, решается цифровой подписью программы сертификатом как минимум третьего уровня, но не всегда есть возможность такое сделать.
5) Ну и, наконец, последнее - защита не должна привязываться к физическому устройству оборудования, а пользоваться только документированными функциями для работы с ним, предоставляемыми операционной системой.
2015.04.08