Защита от несанкционированного копирования
Защита от несанкционированного копирования
Прежде чем перейду к изложению материала, хотелось бы немного рассказать о тех причинах, которые заставили взяться за перо. Дело в том, что я считаю себя окончательно сформировавшимся идеологическим противником подобных систем и убежден, что защитой авторских прав должны заниматься люди, для которых это является работой, то есть профессионалы, и, соответственно, другими методами.
Требовать от покупателя пакета ПО наличия некой ключевой дискеты и т.п. считаю дурным тоном. Однако при всем этом я признаю необходимость постоянно улучшать такие системы для отраслей бизнеса, где критически важна надежность, например парольной защиты. И все же непосредственным поводом, заставившим меня писать эти строки, послужил недавно попавший мне в руки компакт-диск фирмы BIT Software с так называемой TRY & BUY (попробуй-и-купи) версией популярного пакета Fine Reader Pro 3.0 В документации было сказано, что, оплатив стоимость полной версии пакета, владелец CD с помощью сообщаемого по телефону пароля сможет превратить его в полноценный дистрибутив.
На поверку "защита" оказалась пустым звуком и была "сломана" за 3-4 минуты. Слова "защита" и "сломана" употреблены мной в кавычках, так как я еще никогда прежде не обходил защиту при помощи только Windows Explorer(!).
Оставалось лишь диву даваться, как в столь уважаемой мной фирме рядом с безусловно талантливейшими людьми, создавшими замечательные технологии, находится место откровенному дилетантству. Библиотеки DLL переполнены отладочной информацией, а при работе программы установки возникает несколько исключений, которые никто не удосужился перехватить, в результате Microsoft Foundation Classes (тоже отладочная версия) выводит сообщение с указанием исходного файла и строки, содержащей ошибку. Забавно. Уж если BIT Software так хотелось обеспечить защиту своему продукту, почему этого не сделать цивилизованно?
Вероятно, чтобы ответить на этот вопрос, необходимо сначала вспомнить недалекое прошлое.
Вчера
Еще в недалеком прошлом коммерческие программные продукты могли быть защищены ценой относительно невысоких затрат и усилий благодаря широкому спектру специализированных пакетов защитного ПО. В основном принцип их действия сводился к следующему: непременным атрибутом дистрибутивного комплекта являлась так называемая ключевая дискета. Ключевой она называлась из-за нанесенной на нее программным или аппаратным способом метки-ключа. Стоит заметить, что аппаратные методы нанесения меток столь же дороги, сколь и точны, и, как следствие, применялись лишь крупными зарубежными фирмами-разработчиками ПО. Гораздо более широкое применение нашли программные методы защиты, т.е. методы, не требующие дополнительного оборудования.
Основывались эти технологии на низкоуровневом форматировании треков ключевой дискеты, не использующем сервис прерывания ВН, а управляющем контроллером гибких дисков напрямую. В результате становилось возможным не только создание примитивных ловушек наподобие секторов с неправильным идентификатором, но и довольно изощренные приемы, такие как многократное форматирование дорожки с прерыванием форматирования, сохранение данных в межсекторных промежутках, имитация физических повреждений сектора, запись со сбоем синхронизации. Затем используемый модуль программы компоновался с объектным кодом, предоставляемым разработчиком защитного ПО. При запуске осуществлялась проверка соответствия ключевой дискеты необходимым условиям, по результатам которой либо запускалась программа инсталляции, либо выдавалось сообщение об ошибке. Следующей задачей было установить программу так, чтобы она работала только на определенном компьютере. Такая привязка осуществлялась чаще всего к определенному сектору жесткого диска, хотя встречались и другие варианты, например, к микросхеме BIOS.
Здесь и было слабое место подобных систем. Обладая некоторыми навыками в области низкодревнего программирования, любой юный хакер мог дизассемблировать EXE-файл и заменить инструкцию JZ на JNZ или сделать что-либо подобное. И все же, такие системы обеспечивали определенный уровень защиты и были выполнены вполне профессионально.
Сегодня
А потом наступили другие времена. Платформа Win32 завоевала сердца миллионов тех самых юзеров, которые, голосуя своим кошельком, определяют лучшего разработчика. Сейчас можно услышать много критики в ее адрес, программисты ругают бестолковых пользователей, падких на красивые бестолковые примочки. С этими мнениями можно соглашаться или не соглашаться, однако факты остаются фактами. Новое время принесло новые подходы. В результате, идеи объектно-ориентированного программирования, призванные когда-то сделать программы мощнее и гибче, попав на вооружение людям, лишенным чувства меры, стали причиной появления невообразимых по размеру, прожорливости и тугодумию программных монстров. Скорость разработки ставится во главу угла. Приносятся в жертву производительность, экономичность, даже функциональность. Разработчики компиляторов лепят огромные библиотеки классов и соревнуются друг с другом в том, чьи окошки красивее, однако никто еще не дал возможности породить класс во время выполнения. Да и зачем это? Пользователи наверняка не оценят. Но самое страшное в том, что новые компиляторы, обширные библиотеки классов, средства визуальной разработки развращают самих программистов. Красота (или псевдокрасота - как угодно) программирования становится для них важнее конечного продукта. Тысячи людей работают над тем, чтобы программист делал как можно меньше работы, а компилятор - как можно больше. Если кто-то думает, что это способствует повышению квалификации, я возьму на себя смелость утверждать, что он ошибается.
Все вышеизложенное представляет собой хорошую тему для огромной философской статьи, но я описал тенденции последних лет лишь для того, чтобы выделить причины отсутствия достаточно надежных и универсальных систем защиты от несанкционированного копирования.
Программа, работающая в Win32 на уровне приложения никогда не получит доступа к регистрам контроллера гибких дисков, так как в защищенном режиме процессор Intel пресечет попытку доступа к порту, не указанном в таблице IOPM, выдав ошибочное состояние. Доступ туда может иметь лишь ядро Windows да еще VxD (если речь идет о Windows'95).
Ограничения, накладываемые процессором на доступ к портам и памяти представляют собой серьезное, но не основное препятствие на пути к достижению цели. Вряд ли сегодня кто-либо всерьез станет говорить о дистрибутивном комплекте дискет. Объемы информации вынуждают переходить на другие типы носителей, такие как CD-ROM.
И, наконец, еще одна объективная сложность состоит в устойчивости программы к попыткам взлома. Таким образом, защитное ПО, разрабатываемое для Win32, должно как-то справляться с перечисленными сложностями. Перед тем, как я начну излагать принцип предлагаемой идеи, мне бы хотелось заметить, что круг ее применения шире, чем показано в этой статье.
Итак, суть метода заключается в создании специального варианта STARTUP-кода для 32-битовых программ и программы-кодировщика EXE-файла, шифрующей определенный сегмент кода. Я хочу сразу внести ясность в употребление термина "сегмент". Дело в том, что даже в модели flat сегмент, помеченный как выгружаемый, остается таковым в виде объекта в едином плоском сегменте. Именно о таком объекте я и говорю, употребляя термин "сегмент". Startup-код, кроме обычных операций по замене смещений логическими адресами, передаваемыми Windows во время загрузки, выполняет еще довольно приличный кусок работы. Во-первых, он должен создать элемент таблицы сегментных дескрипторов, указывающий на сегмент кода программы, но со значением в поле типа сегмента, означающем, что сегмент, на который указывает этот дескриптор, является сегментом данных, и что в него допускается запись. После этого, используя этот дескриптор для доступа, Startup-код дешифрует требуемый сегмент, который, в свою очередь, содержит функцию, вызовы которой обрамляют в основной программе критический участок кода, например, парольную защиту, т.е. этот участок будет расшифрован непосредственно перед использованием и сразу после использования снова зашифрован. Созданную подобным образом программу невозможно будет дизассемблировать ни одним из имеющихся на сегодняшний день инструментов. Остается продумать процедуру получения пользователем пароля, но в каждом конкретном случае она может быть разной - это работа продавца ПО. Однако, скорее всего, программа инсталляции должна будет подобным образом шифровать запускной файл, используя индивидуальный ключ, например, номер сектора жесткого диска, благо его несложно получить при помощи функции CreateFile, предоставляемой модулем Kernel32.dll. Шифрованные сегменты в программе должны быть помечены как невыгружаемые, во избежание подгрузки из EXE-файла на исходной версии. Также мне хотелось бы отметить, что использование функции CreateFile для доступа к секторам физического или логического диска под Windows NT требует полномочий администратора.
Завтра
Сказать, что будут представлять собой системы защиты от несанкционированного копирования даже в ближайшем будущем, наверное, еще тяжелее, чем прогнозировать перспективы развития ПО более традиционных направлений. Однако от себя мне хотелось бы пожелать комплексам защитного ПО скорейшего и бесследного исчезновения. Хочется верить, что когда-нибудь авторские права будут достаточно охраняться, и, что гораздо важнее, станут глубоко уважаемой и почитаемой сущностью. До тех пор, пока это не произойдет, все, даже самые лучшие системы, не смогут исправить положения дел. Единственная польза от них в том, что они заставляют людей думать и искать пути обхода, прибавляя опыт и позволяя совершенствовать мастерство программирования.
В заключение мне хотелось бы вернуться к тому, с чего начал. Несмотря на то, что я противник разного рода защит, мне было бы очень приятно, если изложенный подход будет кем-то реализован и позволит избежать таких проявлений дилетантства, одному из которых эта статья обязана своим появлением. Отдельно хочу подчеркнуть, что приведенные соображения относительно механизма защиты были изложены мной для свободного обсуждения и использования всеми желающими, не требуют соблюдения авторских, имущественных и любых других прав, и уж точно - наличия ключевой дискеты.
Сергей Зеленков компьютерная газета
Прежде чем перейду к изложению материала, хотелось бы немного рассказать о тех причинах, которые заставили взяться за перо. Дело в том, что я считаю себя окончательно сформировавшимся идеологическим противником подобных систем и убежден, что защитой авторских прав должны заниматься люди, для которых это является работой, то есть профессионалы, и, соответственно, другими методами.
Требовать от покупателя пакета ПО наличия некой ключевой дискеты и т.п. считаю дурным тоном. Однако при всем этом я признаю необходимость постоянно улучшать такие системы для отраслей бизнеса, где критически важна надежность, например парольной защиты. И все же непосредственным поводом, заставившим меня писать эти строки, послужил недавно попавший мне в руки компакт-диск фирмы BIT Software с так называемой TRY & BUY (попробуй-и-купи) версией популярного пакета Fine Reader Pro 3.0 В документации было сказано, что, оплатив стоимость полной версии пакета, владелец CD с помощью сообщаемого по телефону пароля сможет превратить его в полноценный дистрибутив.
На поверку "защита" оказалась пустым звуком и была "сломана" за 3-4 минуты. Слова "защита" и "сломана" употреблены мной в кавычках, так как я еще никогда прежде не обходил защиту при помощи только Windows Explorer(!).
Оставалось лишь диву даваться, как в столь уважаемой мной фирме рядом с безусловно талантливейшими людьми, создавшими замечательные технологии, находится место откровенному дилетантству. Библиотеки DLL переполнены отладочной информацией, а при работе программы установки возникает несколько исключений, которые никто не удосужился перехватить, в результате Microsoft Foundation Classes (тоже отладочная версия) выводит сообщение с указанием исходного файла и строки, содержащей ошибку. Забавно. Уж если BIT Software так хотелось обеспечить защиту своему продукту, почему этого не сделать цивилизованно?
Вероятно, чтобы ответить на этот вопрос, необходимо сначала вспомнить недалекое прошлое.
Вчера
Еще в недалеком прошлом коммерческие программные продукты могли быть защищены ценой относительно невысоких затрат и усилий благодаря широкому спектру специализированных пакетов защитного ПО. В основном принцип их действия сводился к следующему: непременным атрибутом дистрибутивного комплекта являлась так называемая ключевая дискета. Ключевой она называлась из-за нанесенной на нее программным или аппаратным способом метки-ключа. Стоит заметить, что аппаратные методы нанесения меток столь же дороги, сколь и точны, и, как следствие, применялись лишь крупными зарубежными фирмами-разработчиками ПО. Гораздо более широкое применение нашли программные методы защиты, т.е. методы, не требующие дополнительного оборудования.
Основывались эти технологии на низкоуровневом форматировании треков ключевой дискеты, не использующем сервис прерывания ВН, а управляющем контроллером гибких дисков напрямую. В результате становилось возможным не только создание примитивных ловушек наподобие секторов с неправильным идентификатором, но и довольно изощренные приемы, такие как многократное форматирование дорожки с прерыванием форматирования, сохранение данных в межсекторных промежутках, имитация физических повреждений сектора, запись со сбоем синхронизации. Затем используемый модуль программы компоновался с объектным кодом, предоставляемым разработчиком защитного ПО. При запуске осуществлялась проверка соответствия ключевой дискеты необходимым условиям, по результатам которой либо запускалась программа инсталляции, либо выдавалось сообщение об ошибке. Следующей задачей было установить программу так, чтобы она работала только на определенном компьютере. Такая привязка осуществлялась чаще всего к определенному сектору жесткого диска, хотя встречались и другие варианты, например, к микросхеме BIOS.
Здесь и было слабое место подобных систем. Обладая некоторыми навыками в области низкодревнего программирования, любой юный хакер мог дизассемблировать EXE-файл и заменить инструкцию JZ на JNZ или сделать что-либо подобное. И все же, такие системы обеспечивали определенный уровень защиты и были выполнены вполне профессионально.
Сегодня
А потом наступили другие времена. Платформа Win32 завоевала сердца миллионов тех самых юзеров, которые, голосуя своим кошельком, определяют лучшего разработчика. Сейчас можно услышать много критики в ее адрес, программисты ругают бестолковых пользователей, падких на красивые бестолковые примочки. С этими мнениями можно соглашаться или не соглашаться, однако факты остаются фактами. Новое время принесло новые подходы. В результате, идеи объектно-ориентированного программирования, призванные когда-то сделать программы мощнее и гибче, попав на вооружение людям, лишенным чувства меры, стали причиной появления невообразимых по размеру, прожорливости и тугодумию программных монстров. Скорость разработки ставится во главу угла. Приносятся в жертву производительность, экономичность, даже функциональность. Разработчики компиляторов лепят огромные библиотеки классов и соревнуются друг с другом в том, чьи окошки красивее, однако никто еще не дал возможности породить класс во время выполнения. Да и зачем это? Пользователи наверняка не оценят. Но самое страшное в том, что новые компиляторы, обширные библиотеки классов, средства визуальной разработки развращают самих программистов. Красота (или псевдокрасота - как угодно) программирования становится для них важнее конечного продукта. Тысячи людей работают над тем, чтобы программист делал как можно меньше работы, а компилятор - как можно больше. Если кто-то думает, что это способствует повышению квалификации, я возьму на себя смелость утверждать, что он ошибается.
Все вышеизложенное представляет собой хорошую тему для огромной философской статьи, но я описал тенденции последних лет лишь для того, чтобы выделить причины отсутствия достаточно надежных и универсальных систем защиты от несанкционированного копирования.
Программа, работающая в Win32 на уровне приложения никогда не получит доступа к регистрам контроллера гибких дисков, так как в защищенном режиме процессор Intel пресечет попытку доступа к порту, не указанном в таблице IOPM, выдав ошибочное состояние. Доступ туда может иметь лишь ядро Windows да еще VxD (если речь идет о Windows'95).
Ограничения, накладываемые процессором на доступ к портам и памяти представляют собой серьезное, но не основное препятствие на пути к достижению цели. Вряд ли сегодня кто-либо всерьез станет говорить о дистрибутивном комплекте дискет. Объемы информации вынуждают переходить на другие типы носителей, такие как CD-ROM.
И, наконец, еще одна объективная сложность состоит в устойчивости программы к попыткам взлома. Таким образом, защитное ПО, разрабатываемое для Win32, должно как-то справляться с перечисленными сложностями. Перед тем, как я начну излагать принцип предлагаемой идеи, мне бы хотелось заметить, что круг ее применения шире, чем показано в этой статье.
Итак, суть метода заключается в создании специального варианта STARTUP-кода для 32-битовых программ и программы-кодировщика EXE-файла, шифрующей определенный сегмент кода. Я хочу сразу внести ясность в употребление термина "сегмент". Дело в том, что даже в модели flat сегмент, помеченный как выгружаемый, остается таковым в виде объекта в едином плоском сегменте. Именно о таком объекте я и говорю, употребляя термин "сегмент". Startup-код, кроме обычных операций по замене смещений логическими адресами, передаваемыми Windows во время загрузки, выполняет еще довольно приличный кусок работы. Во-первых, он должен создать элемент таблицы сегментных дескрипторов, указывающий на сегмент кода программы, но со значением в поле типа сегмента, означающем, что сегмент, на который указывает этот дескриптор, является сегментом данных, и что в него допускается запись. После этого, используя этот дескриптор для доступа, Startup-код дешифрует требуемый сегмент, который, в свою очередь, содержит функцию, вызовы которой обрамляют в основной программе критический участок кода, например, парольную защиту, т.е. этот участок будет расшифрован непосредственно перед использованием и сразу после использования снова зашифрован. Созданную подобным образом программу невозможно будет дизассемблировать ни одним из имеющихся на сегодняшний день инструментов. Остается продумать процедуру получения пользователем пароля, но в каждом конкретном случае она может быть разной - это работа продавца ПО. Однако, скорее всего, программа инсталляции должна будет подобным образом шифровать запускной файл, используя индивидуальный ключ, например, номер сектора жесткого диска, благо его несложно получить при помощи функции CreateFile, предоставляемой модулем Kernel32.dll. Шифрованные сегменты в программе должны быть помечены как невыгружаемые, во избежание подгрузки из EXE-файла на исходной версии. Также мне хотелось бы отметить, что использование функции CreateFile для доступа к секторам физического или логического диска под Windows NT требует полномочий администратора.
Завтра
Сказать, что будут представлять собой системы защиты от несанкционированного копирования даже в ближайшем будущем, наверное, еще тяжелее, чем прогнозировать перспективы развития ПО более традиционных направлений. Однако от себя мне хотелось бы пожелать комплексам защитного ПО скорейшего и бесследного исчезновения. Хочется верить, что когда-нибудь авторские права будут достаточно охраняться, и, что гораздо важнее, станут глубоко уважаемой и почитаемой сущностью. До тех пор, пока это не произойдет, все, даже самые лучшие системы, не смогут исправить положения дел. Единственная польза от них в том, что они заставляют людей думать и искать пути обхода, прибавляя опыт и позволяя совершенствовать мастерство программирования.
В заключение мне хотелось бы вернуться к тому, с чего начал. Несмотря на то, что я противник разного рода защит, мне было бы очень приятно, если изложенный подход будет кем-то реализован и позволит избежать таких проявлений дилетантства, одному из которых эта статья обязана своим появлением. Отдельно хочу подчеркнуть, что приведенные соображения относительно механизма защиты были изложены мной для свободного обсуждения и использования всеми желающими, не требуют соблюдения авторских, имущественных и любых других прав, и уж точно - наличия ключевой дискеты.
Сергей Зеленков компьютерная газета
Компьютерная газета. Статья была опубликована в номере 02 за 1998 год в рубрике безопасность :: разное