...
...

Armadillo: защити свою программу от взлома. Часть 2

В прошлый раз я начал рассказ о специализированной системе защиты ПО: armadillo. Armadillo выступает в роли "бронированного сейфа", скрывая и защищая внутри себя от взлома некоторую программу, для доступа к которой мы создавали ключи и сертификаты. Сегодня я продолжу рассказ об особенностях создания сертификатов, о привязке созданных ключей к конкретному железному обеспечению, а также покажу, как можно создать приложение, взаимодействующее с armadillo с помощью специального программного интерфейса (api).

В прошлой статье я остановился на том, что рассказал о методике создания сертфикатов: в терминологии armadillo это правило, по которому мы можем использовать защищенную программу. Я рассказал обо всех основных приемах: ограничение по времени работы, ограничение по количеству запусков, ограничение на время установки/первого запуска. Осталось рассмотреть еще немного хитростей. Прежде всего, это правило обновления сертификатов. Итак, если вы выпускаете и продаете как shareware некоторый программный продукт, то очевидно, что несколько последующих версий (исправлений/дополнений) пользователь должен получать бесплатно. Когда вы создаете сертификат, и этот сертификат не является сертификатом по умолчанию (напоминаю, что этот сертификат устанавливается автоматически, и традиционно именно в нем закладываются ограничения на использование нашей shareware-программы). Так вот, при создании обычного сертификата вы можете указать на закладке Upgrade Keys перечисление тех сертификатов, с которых возможно выполнить обновление версии. Например, сертификат версии basic может быть обновлен на сертификат версии professional и т.д. Как именно разделить функционал программы по уровню сертификата, я расскажу немного позже. Если пользователь имеет ключ к сертификату basic, то он может купить ключ для сертификата professional (разумеется, обмануть armadillo и установить новый сертификат без предыдущего невозможно). Настоятельно рекомендую заранее предусмотреть все возможные способы использования вашей программы (например, разделение по функционалу, срокам работы) и создать сертификаты для всех этих действий. Так, при выполнении операции "защитить программу" все сведения о сертификатах шифруются и вкладываются внутрь вашей программы. Соответственно, если вы выпустите ключ для сертификата, неизвестного на момент защиты программы, или же этот сертификат был отключен (закладка other options), то такой ключ будет нераспознан. Если после создания защищенной программы вы даже просто поменяли некоторые параметры сертификата (например, увеличили время работы), то он также не будет распознан при вводе ключа. Для защиты созданных ключей от многократного дублирования, когда один и тот же (пусть даже честно купленный) ключ используется на множестве разных компьютеров, можно применять две базовые методики: привязку к аппаратному обеспечению и сетевое лицензирование.

Сначала о более простом (и более удобном, если быть честными) методе сетевого лицензирования. Есть две базовые методики: peer-to-peer и client- server. В первом случае при запуске программы выполняется поиск по локальной сети запущенных версий этой программы и проверяется, под каким ключом они работают. Если некоторое число одновременно работающих копий было превышено (это число, которое можно указать на закладке Network Licensing, не должно быть более 255), то запуск программы блокируется. В зависимости от загрузки сети время запуска программы может увеличиваться, но основную сложность составляет все же работа с firewall, который может блокировать служебный трафик armadillo. Как вывод: режим peer-to-peer говорит, что ключи должны быть установлены на каждой из клиентских машин, просто в одно время невозможно запустить более X экземпляров, использующих одинаковый ключ. Второй режим сетевой защиты — client-server — предполагает, что в сети предприятия существует специальный сервер лицензирования, который и хранит сведения о ключах. При запуске программа соединяется с этим сервером, который и принимает решение о возможном или нет запуске защищенного приложения. Для каждого из этих двух режимов можно управлять признаком "копия", а именно что в данном случае считается копией программы: каждый ее запущенный экземпляр (даже если пять штук запущены на одной машине) или же количество собственно компьютеров. Также сведения об этом предельном количестве копий могут быть сохранены не внутри сертификата, а внутри ключа. Это избавляет вас от необходимости создавать двадцать сертификатов-клонов, отличающихся только одной цифрой — 1, 2… 10, 11 — одновременно запущенных экземпляров. Для режима client-server интересна и опция don't fall back to standalone mode — проще говоря, что делать, если сервер не запущен или не может быть найден в сети. Если это случилось, то при включенной опции запуск программы будет невозможен, иначе будет использован установленный на локальной машине ключ. Теперь вопрос: а откуда возьмется этот самый сервер лицензирования? Сервер лицензирования будет встроен в саму программу. Например, я решил защитить стандартный калькулятор windows, после чего получил новый файл размером в 750 Кб (и это выросло из исходных 150 Кб). Для того, чтобы запустить сервер, я выполнил из командной строки команду calc.exe SERVER, после чего появилось окно со статистикой, где отображено, сколько копий программы было уже запущено — запуск лишних блокируется, как это показано на рис. 1. Через 60 секунд окно сервера будет автоматически скрыто, если же вы хотите его полностью завершить, используйте строку команды: calc.exe SERVERDOWN. Поиск сервера выполняется автоматически по всей сети, но если вы хотите переопределить этот параметр, то в файле настроек (это текстовый файл в формате ini, который должен размещаться в той же папке, что и собственно защищаемая программа) возможно указать конкретный IP-адрес сервера. На этом про сетевую защиту все — переходим к методам привязки к аппаратному обеспечению.

Комплектующие, из которых состоит ваш компьютер, имеют свои уникальные цифровые отпечатки. Еще до создания сертификата в свойствах проекта armadillo вы на закладке Std Hardware locking включаете отметку unlock, затем решаете, какие именно "железки" компьютера будут считаться уникальными. Возможно выбрать CPU, BIOS, сетевое имя компьютера, информацию о геометрии жесткого диска, его параметры SMART, также уникальный номер MAC сетевого адаптера, объем физической памяти. Главное — относиться к пользователю уважительно и дать ему возможность менять неключевые компоненты компьютера без лишних сложностей. Например, привязка к сетевому имени или объему памяти слишком жесткая. В любом случае на этой же закладке Std Hardware locking вы можете указать некоторое число — предельное количество сменившегося оборудования. После этого необходимо создать новый сертификат, для которого на закладке hardware Locking отметить, какой режим аппаратной hardware-основанными ключами можно делать две интересные привязки будет использован: стандартный или расширенный. Если вы все сделаете правильно, то диалоговое окно ввода ключа при регистрации изменится: появится строка со значением вашей аппаратной подписи (см. рис. 2). Этот же номер следует указать при генерации ключа. При работе с hardware-основанными ключами можно делать две интересные операции: перенос ключа и отказ от ключа. В первом случае вы хотите ключ, привязанный к машине "A", перенести на машину "B" (естественно, при этом первоначальный ключ станет недействительным, и запустить с его помощью программу на первой машине будет уже невозможно). Ранее мы опускали вопрос того, какой именно алгоритм используется armadillo для генерации ключа. На самом деле это очень важно. Так, если вы зайдете на первую же закладку при создании сертификата name/template/sig.level, то увидите набор радиопереключателей, управляющих тем, как будет формироваться и защищаться сам ключ. Общее правило таково: чем выше уровень signature, тем надежнее. Однако если вы хотите создать аппаратный ключ и разрешить для него операцию переноса, то необходимо использовать режим unsigned (без специальной защиты). После этого вы можете на закладке сертификата включить отметку пункта allow TRANSFER command, и теперь можно запустить программу из командной строки с параметром TRANSFER. После того, как вы согласитесь с тем, что ключ перестанет после переноса работать на вашем компьютере, необходимо в еще одном диалоговом окне указать значение "цифрового снимка" для того компьютера, на который вы хотите выполнить перенос ключа. После чего в корне диска c:\ появится файл с именем transfer.txt, в котором и будет находиться новый сгенерированный ключ, действительный для другого компьютера.

При запуске программы вы можете указать некоторый набор параметров командной строки — мы уже познакомились с опциями SERVER и SERVERDOWN, когда разбирали методы лицензирования по сети. Также можно использовать параметр INFO — он приводит к появлению на экране окна сообщения с регистрационным номером (довольно опасная вещь, скажу прямо). Затем REGISTER приводит к появлению окна ввода ключа — даже если программа уже зарегистрирована, это полезно в случае, если вы хотите сменить сертификат — например, перейти с basic-версии на professional. Аналогично опция UNREGISTER приводит к отмене регистрации. При этом появляется специальное диалоговое окно, в котором находится специальный код — подтверждение отмены регистрации. Клиент может отправить его разработчику программы, мол, так и так, не понравилась мне ваша программа, и я возвращаю вам этот ключ, а также прошу вернуть мне мои денежки. Естественно, что, если вы после этого решите схитрить и попробуете ввести старый ключ повторно, то получите сообщение об ошибке "ключ был израсходован, давайте новый". В свою очередь, разработчик, получив от клиента код подтверждения об отказе, не обязан верить ему на слово и, используя меню: keys -> check key, в специальном диалоговом окне вводит имя пользователя, его ключ, цифровой отпечаток компьютера (fingerprint), а также код отзыва. И в результате получает подтверждение или, наоборот, узнает, что его хотели обмануть и подсунуть фальшивый код отзыва. При генерации аппаратнозависимого ключа можно использовать режим привязки к ключу, расположенному на USB-флэшке. К сожалению, я так этот режим и не попробовал, поскольку мало того, что мне нужна какая-то особая флэшка (чем именно она так "особенна", можно узнать на сайте www.u3.com), так еще и ключи невозможно сгенерировать без помощи какой-то организации digital river. А идея, вообще-то, очень хороша: информация о регистрации программы хранится не в реестре компьютера, а на USB-носителе, так что, придя и сев за любой компьютер, вам достаточно вставить флэшку с ключом — и программа заработает.

Чем больше я разбираюсь с возможностями armadillo,тем более удостоверяюсь, что забота об удобстве конечных пользователей у них на первом месте. Вот, например, такая простая ситуация: для того, чтобы защитить программу от timeback (методика взлома, основанная на откате в прошлое значения системных часов), armadillo блокирует запуск программы, если timeback был обнаружен до тех пор, пока вы не вернете часы назад. Однако возможен и "несчастный случай", когда у вас по какой-то причине часы были установлены в будущем времени, а затем вы вернули их в настоящее (правильное). Armadillo, естественно, не может отличить этот случай от злонамеренного timeback. Но предлагает сгенерировать вам специальный fixclock-ключ, который может быть отправлен незадачливому клиенту. Он, в свою очередь, запускает вашу программу с параметром командной строки FIXCLOCK и вводит присланный ему ключ, после чего armadillo исправляет отсчет времени. Естественно, fixclock-ключ не вечен, и через пару дней он станет недействительным. Если запустить вашу программу с параметром командной строки SHOWNETUSERS, то вы увидите перечисление имен тех компьютеров, на которых запущены в режиме сетевого лицензирования peer-to-peer-копии вашей программы. Почти все описные мною выше опции командной строки можно предварить ключевым словом SERVER — например, SERVER FIXCLOCK. В этом случае опция будет действовать на сервер лицензирования в модели client- server.

Теперь пора рассказать о методиках создания программ, взаимодействующих с armadillo напрямую, о том, как, используя вызовы специальных функций api, можно получить информацию о регистрации, вносить/удалять/изменять ключи самому. Простейшее применение — это разделение возможностей программы на несколько уровней: basic, professional. Мы научились создавать сертификаты различных уровней, но как спросить: а какая версия сертификата используется? Или спросить: а сколько дней осталось до завершения trial-периода этой программы? Самый простой способ организации подобного взаимодействия — использовать переменные окружения или, возможно, вызывать специальные функции, находящиеся в файле ArmAccess.dll. Стоит упомянуть, что на самом деле эта библиотека играет роль заглушки и просто перенаправляет все вызовы внутрь встроенного в сам защищаемый файл кода — одним словом, библиотека получается виртуальной, что не совсем мешает вызывать из нее методы традиционным методом LoadLibrray, GetProcAddress или через декларацию external. Далее я создал приложение на Delphi в виде одной формы, на которой разместил два текстовых поля: одно для ввода имени пользователя, второе — для ввода кода регистрации. Также потребовалась кнопка, по нажатию которой и происходит проверка введенного ключа и его последующее сохранение. Кроме того, моя программа будет защищена сертификатом по умолчанию с лимитом в 100 запусков, поэтому я создал текстовое поле, в которое при запуске формы заносится число, равное количеству оставшихся запусков. Для того, чтобы форсировать увеличение числа запусков, я создал еще одну кнопку. И, наконец, я покажу вам прием работы со слотами пользовательской информации. В защищенной armadillo программе можно создать девять ячеек, которые будут защищены, зашифрованы и помещены в секретное хранилище, так что эта информация сохраняется между несколькими запусками программы. Результат работы программы виден на рис. 3.

Function SetUserString (which:LongInt;str:PChar) : Boolean; stdcall; external 'armaccess.dll';
Function GetUserString (which:LongInt;buffer:PChar;bufferlength:LongInt) : LongInt; stdcall; external 'armaccess.dll';
Function InstallKey (name,code:PChar) : Boolean; stdcall; external 'armaccess.dll';
Function IncrementCounter : Boolean; stdcall; external 'armaccess.dll';

procedure TForm1.Button1Click(Sender: TObject);
begin
if InstallKey (PChar( txtUser.Text), PChar (txtKey.Text)) then
ShowMessage ('Порядок, под подошел')
else ShowMessage ('Ошибка'); end;
procedure TForm1.btnIncCounterClick(Sender: TObject);
begin IncrementCounter;end;
procedure TForm1.FormCreate(Sender: TObject);
begin labCounterValue.Caption := GetEnvironmentVariable('USESLEFT');end;
procedure TForm1.Button2Click(Sender: TObject);
begin SetUserString(0, PChar(txtSecret.Text));end;
procedure TForm1.btnGetSecretClick(Sender: TObject);
var s: array[0..255] of char;
begin GetUserString(0, s, 255); txtSecret.Text := s;end;

Завершу я данную статью, пожалуй, на следующем неприятном моменте: многие системы защиты (и armadillo не исключение) используют для хранения информации об установленном ключе реестр windows, создавая для этого всяческие "мусорные" ключи, имитирующие "правильные" записи реестра. Соответственно, если пользователь выполняет чистку реестра от мусора с помощью некоторых программ-чистильщиков, то с некоторой долей вероятности возможна ситуация, когда эти ключи будут потеряны, и необходимо будет выполнять повторную регистрацию. Приятный побочный эффект в том, что записи о регистрации некоторой триальной программы также могут быть утеряны, и отсчет времени будет начат заново — на этом эффекте построены специальные хакерские утилиты-чистильщики. Названий я специально не привожу — их легко найти в Интернете. Как ведут себя разработчики чистящих утилит в плане, сохранять или удалять ключи регистрации — вопрос открытый, и прямых ответов они стараются избегать. Но даже если бы подобные ключи сохранялись, то вопрос осложняется тем, что рынок armadillo-подобных систем защиты достаточно велик, существует множество экзотичных продуктов, некоторые из которых уже покинули наш мир. Так что есть вероятность после переустановки windows или прогонки подобной утилитой- чистильщиком потерять информацию о регистрации программы. Максимум, что я могу вам посоветовать — изучить api для armadillo и комбинировать стандартные методики защиты со своими собственными.

black zorro, black-zorro@tut.by

© Компьютерная газета

полезные ссылки
Аренда ноутбуков