Эмуляция физического ключа 1с в локальной сети. Механизм системы защиты. Установка эмулятора Sable

ВведениеТехнология защиты программного обеспечения с помощью аппаратных ключей широко распространена по всему миру. Каждая компания сама решает, стоит ли защищать свой продукт с помощью привязки к аппаратному ключу или следует остановиться на другом механизме обеспечения лицензионной безопасности. Время от времени аппаратные ключи крупнейших мировых производителей взламываются, в сети Интернет появляются в свободном доступе программные эмуляторы аппаратных ключей... В ответ на это разработчики создают новые версии своих ключей, которые в течение какого-то времени сдерживают пиратов и т.д. Борьба "снаряда и брони" бесконечна... Данная статья расскажет о новой версии ключей HASP от компании Aladdin Software Security R. D.

Мы уже писали о технологии HASP и даже проводили некоторое сравнение с технологией Sentinel от компании Rainbow Technologies. Если вас, уважаемый читатель, интересует подробное описание технологии HASP, состав самого аппаратного ключа, базовые возможности утилит для его настройки и т.д., то советуем обратиться к нашей предыдущей статье, ссылка на которую дана выше. Далее мы постараемся сконцентрировать внимание именно на отличиях нового пятого поколения технологии HASP (пятое поколение называется HASP HL, и именно о нем далее пойдет речь) от HASP4.

Интервью с экспертом

О новой версии технологии защиты программного обеспечения на основе ключей HASP HL нам согласился рассказать Александр Гурин, менеджер отдела защиты ПО компании Aladdin Software Security R. D.


Александр Гурин, менеджер отдела защиты ПО компании Aladdin Software Security R. D.



Алексей Доля: Вы не могли бы кратко описать, чем HASP HL отличается от других версий электронных ключей HASP?

Александр Гурин: Компания Aladdin уже много лет выпускает ключи защиты программного обеспечения. Естественно, как и любой продукт, они совершенствовались, становясь более эффективными и максимально отвечающими требованиям заказчика. До настоящего момента HASP4 - был, пожалуй, самым удачным ключом. В нем были хорошо сбалансированы и стойкость защиты, и простота её реализации.

Но будем объективны: во всех аладдиновских ключах, включая HASP4, был один недостаток, вернее даже не недостаток, а уязвимость. Я говорю о так называемом "секретном" алгоритме шифрования данных.

Основная опасность использования "секретных" алгоритмов, равно как и заказных, сделанных для конкретного разработчика - это вероятность того, что алгоритм станет известен, а, следовательно, сможет быть реализован программно. В этом случае появляется программный эмулятор ключа защиты, полностью реализующий все его функции. Кроме того, разработчик никогда не знает, насколько надежную защиту он использует. Стойкость алгоритма оценивается постфактум: этот ключ сломали за 3 года - хорошая была защита!

В новых ключах HASP HL мы полностью отказались от использования секретных алгоритмов. Для шифрования данных используется публичный, аппаратно реализованный алгоритм AES с ключом шифрования 128 бит. Алгоритм опубликован, и с 2000 года является стандартом криптографии США (пришел на смену легендарного DES).

Использование публичного алгоритма делает бесполезными все прежние атаки на ключи. Суть взлома каждой конкретной защиты сводится к нахождению ключей шифрования. Эти ключи хранятся в служебной памяти HASP HL и никогда не выходят наружу. На физическом уровне - попросту отсутствуют команды по их извлечению. Таким образом, взлом каждой защиты сводится к задаче криптоанализа, что во много раз сложнее простой эмуляции ключа.

В прошлом нашем интервью , я сравнил защиту с помощью ключей HASP4 с обычным кухонным стулом. Можно сделать такой стул, который рассыплется при первом же использовании, а можно такой, который будет служить долгие годы. Если провести аналогию с HASP HL, то для того чтобы сломать хорошо построенный (с помощью HASP HL) стул - его надо, по меньшей мере, разобрать на атомы:).


Алексей Доля: Есть ли какие-нибудь разновидности ключей HASP HL?

Александр Гурин: Модельный ряд HASP HL состоит из:

HASP HL Basic - самый простой ключ, не имеет внутренней памяти и уникального ID-номера;
HASP HL Pro - пришел на смену наиболее популярной модели HASP4 M1. Ключ содержит 112 байт защищенной памяти и уникальный ID-номер;
HASP HL Max - необходим в случае защиты нескольких программ при помощи одного ключа (до 112 программ). Содержит 4096 байт защищенной памяти и ID-номер;
HASP HL Time - содержит встроенные часы реального времени, 4096 байт защищенной памяти и ID-номер;
HASP HL Net - сетевой ключ, позволяющий ограничивать число одновременно работающих с защищенной программой пользователей. Выпускаются модификации на 10, 50 и 250 пользователей.


Кроме того, хотелось бы отметить, что все сетевые ключи работают как локальные, а локальные - как сетевые. За счет универсального HASP HL API теперь нет необходимости разрабатывать отдельно сетевую и локальную защиту.


Алексей Доля: Расскажите, пожалуйста, о возможностях, реализуемых с помощью технологии HASP HL.

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

Самым, пожалуй, важным нововведением в ключах HASP HL является наличие так называемой, системы автоматического лицензирования. Эта система позволяет полностью разделить процесс защиты и лицензирования продукта. Как это работает, поясню на примере. Ваше приложение состоит из трех модулей - А, В и С. Перед вами стоит задача выпуска нескольких версий, в которые будут входить упомянутые модули в различных комбинациях. При выпуске продукта вы можете еще и не знать, какие версии вам понадобятся в будущем. На первом этапе разработчики встраивают защиту для каждого модуля. На втором - менеджеры, несколькими кликами мыши в графическом интерфейсе определяют, что будет представлять собой та или иная версия продукта, какие модули будут в нее входить. Кроме того, менеджеры могут быстро сформировать обновление продукта. И все это совершенно независимо от разработчиков. Как я уже говорил, API в ключах HASP HL - универсально. Нет нужды в создании отдельной локальной и отдельной сетевой защиты. Таким образом, вы экономите время разработчиков по внедрению защиты, этому также способствует встроенный генератор исходных кодов HASP HL API.


Алексей Доля: Каков форм-фактор нового электронного ключа?

Александр Гурин: Все ключи HASP HL выпускаются только в USB форм-факторе. Наряду с поддержкой Windows Update - это обеспечивает автоматическую установку драйверов HASP HL, что на наш взгляд, должно существенно снизить нагрузку на техническую поддержку.


Алексей Доля: Каковы системные и аппаратные требования ключа HASP HL? Реализована ли поддержка платформ Unix и Macintosh?

Александр Гурин: Как и прежде, ключи HASP HL являются межплатформенным решением. HASP HL работает под Windows 98SE/ME/2000/XP/Server 2003, Mac OS 10.2.x и выше, а так же под основными дистрибутивами Linux (SuSЕ, RedHat, Alt и др.).


Алексей Доля: Какую техническую поддержку вы оказываете пользователям HASP HL?

Александр Гурин: Политика Aladdin в области технической поддержки HASP остается прежней: "Неважно, разработчик вы или просто пользователь программного обеспечения защищенного с помощью HASP, Aladdin всегда и бесплатно окажет вам техническую поддержку своего продукта".


Алексей Доля: Хорошая позиция. Сколько стоит ключ HASP HL и где его можно купить?

Александр Гурин: Ценовая политика для ключей HASP HL такова: локальные ключи на 10% дороже соответствующих моделей HASP4, а сетевые ключи - на 15% дешевле. Полная информация по ценам на ключи HASP HL представлена на нашем сайте . Приобрести наши ключи можно, оформив заявку на сайте, либо через обширную сеть наших партнеров по России, а так же в странах Ближнего Зарубежья.


Алексей Доля: Хотите сказать что-нибудь нашим читателям напоследок?

Александр Гурин: Хотелось бы поздравить всех с новогодними праздниками и пожелать удачи в 2005 году. Огромное спасибо за внимание. Если возникли какие-либо вопросы - буду рад ответить.

Алексей Доля: Вам тоже спасибо, что уделили нам время. Мы и дальше будем следить за развитием технологий компании Aladdin. Удачи вам и вашей компании!

Некоторые комментарии

Как отметил Александр Гурин, все ключи HASP HL теперь поставляются в форм-факторе USB. К этому следует добавить, что инженеры компании Aladdin смогли уменьшить сам аппаратный ключ в полтора раза, теперь максимальный размер ключа составляет 38 мм. Как утверждают менеджеры Aladdin Software Security R. D., это "самый компактный ключ на рынке". Взглянем несколько подробнее на то, какие виды ключей HASP HL бывают.


Ключ HASP HL Basic. Это недорогое решение. Ключи не имеют памяти и уникального ID-номера.




Ключ HASP HL Pro. Самый популярный и универсальный ключ, содержит 112 байт защищенной перезаписываемой памяти и уникальный ID-номер. С помощью одного ключа HASP HL Pro можно защитить до 16 различных приложений.




Ключ HASP HL Max. Оптимален для случаев, когда необходимо обеспечить защиту нескольких приложений одним ключом. Данная модель содержит 4096 байт защищенной перезаписываемой памяти и уникальный ID-номер и может использоваться для защиты до 112 приложений.




Ключ HASP HL Time. Содержит встроенные часы реального времени, показывающие текущую дату и время. HASP HL Time позволяет передавать защищенное приложение во временное использование (на ознакомление или тестирование), организовать сдачу в аренду, лизинг, а также использовать какие-либо ресурсы приложения в течение заданного промежутка времени. HASP HL Time содержит 4096 байт защищенной перезаписываемой памяти и уникальный ID-номер.




Ключ HASP HL Net. Сетевые ключи позволяют защищать приложения в сети и ограничивать количество пользователей (лицензий). С помощью одного ключа HASP HL Net можно защитить до 112 различных приложений или модулей программы и ограничить число одновременных пользователей. Данная модель содержит 4096 байт защищенной перезаписываемой памяти и уникальный ID-номер.




Ключ HASP HL Master Key. Ключ содержит уникальные коды и идентификаторы, используемые системой HASP HL, которые присваиваются разработчику компанией Аладдин. Пароли для каждой серии HASP HL хранятся в защищенной памяти HASP HL Master Key. Этот ключ нужен разработчику для построения защиты приложения как с помощью HASP API, так и с помощью утилиты автоматической защиты HASP Envelope.



Если вы внимательно читали описание ключей, то, скорее всего, заметили увеличившийся размер защищенной памяти ключей: с 512 байт до 4096 байт.

Александр Гурин отметил, что менеджеры теперь могут работать отдельно от разработчиков в плане определения лицензионной политики продукта. К этому следует добавить, что с помощью автоматической системы лицензирования HASP HL менеджеры могут устанавливать ограничения для каждого модуля или функции защищенной программы по количеству запусков, по времени использования и по количеству одновременно работающих пользователей в сети.

Следует также отметить, что ключи HASP HL полностью совместимы с HASP4 и HASP3. Таким образом, ключи HASP HL могут работать с программами, защищенными с помощью ключей HASP4 и HASP3, без внесения каких-либо изменений в исходный код. Но ключи HASP HL выпускаются только в USB форм-факторе. В случае отсутствия USB порта, необходимо использовать LPT ключи HASP4.

Итоговая таблица

Напоследок приводим итоговую таблицу, в которой отражены основные функциональные возможности HASP HL и HASP4, а также дано сравнение этих двух поколений аппаратных ключей.

Возможности ключей HASP

Возможности HASP HL HASP4
Автоматическая защита (Envelope) + +
Автоматическая система лицензирования + -
Аппаратно реализованный в ключе алгоритм кодирования данных AES секретный
Генератор исходных кодов модулей защиты + -
Дистанционное перепрограммирование + +
Кросс-платформенность + +
Размер памяти до 4096 байт до 512 байт
USB интерфейс + +
LPT интерфейс - +
Автоматическая установка драйверов (Windows Update) + только USB

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

Общеизвестно, что для работы в 1С требуется лицензия. Фирмой 1С поставляются различные ключи защиты: локальные и сетевые. Локальный ключ может быть использован только на одном компьютере, имея вид привычной нам флешки.

Сетевые ключи могут предоставлять лицензии для нескольких пользователей в зависимости от своей серии. На крупных предприятиях чаще всего используются ключи на 300 и 500 соединений, но при необходимости можно приобрести и меньше. Обратите внимание, что на одном компьютере не может находиться более одного ключа одной и той же серии.

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

Настройка HASP менеджера лицензий

Начнем с того, что на тот компьютер, который станет раздавать лицензии, установим менеджер лицензий. В дальнейшем мы будем называть данный компьютер сервером лицензий. Все требуемое ПО включено в поставку 1С:Предприятие.

Скачать Alladin HASP License Manager для Windows x64 и x32 можно по ссылке .

Для правильной работоспособности менеджера нужно произвести некоторые предварительные настройки. Файл, где вы будете их производить называется nhsrv.ini. Чаще всего его можно найти по адресу «C:\Program Files\Aladdin\HASP LM», если менеджер лицензий установлен в качестве приложения. В противном случае (установлен как сервис) он будет в системном каталоге операционной системы.

Откройте найденный вами файл в любом текстовом редакторе, например, в блокноте и добавьте туда строку:

NHS_IP_LIMIT = 192.168.*.*

Вместо звездочек вы можете проставить любое число от 0 до 254. Так же, если оставить знаки «*», это будет означать, что лицензии будут «видеть» все компьютеры в сети, адрес которых начинается с 192.168.

Например, если в файле nhsrv.ini у вас указана надстройка NHS_IP_LIMIT = 192.168.1.*, то лицензии будут доступны только компьютерам с ip в диапазоне от 192.168.1.0 до 192.168.1.254.

Настройки на клиентских ПК

После того, как вы произведи все необходимые настройки на сервере лицензий 1C, нужно настроить и сами клиентские компьютеры.

При запуске 1С на пользовательском ПК, программа обращается с запросом на предоставление лицензии по адресу, указанному в файле nethasp.ini. Найти его можно в папке «conf» каталога, куда установлена платформа 1С. В нашем случае адрес следующий: «d:\Program Files (x86)\1cv8\conf\».

Без каких-либо дополнительных настроек, программа 1С будет искать лицензии по всей локальной сети. Для ускорения данного процесса мы можем самостоятельно указать ip адрес сервера лицензий в этом файле, добавив в него выделенный на рисунке ниже текст.


В статье речь пойдет о реализации аппаратно-программной защиты на основе любой флешки. Но следует учитывать, что предложенная методика не является серъезным конкурентом существующих аппаратных ключей таких как HASP HL (с обновляемой прошивкой) от Alladin , Sentinel, Rockey и др…

Вы никогда не задумывались, для чего может сгодиться обычная флешка? Многие сразу ответят: "… что за вопрос? Конечно для хранения информации…". Но, это если рассматривать с точки зрения обывателя. А если взлянуть на нее "глазами компьютера"? Очевидно, что этот процесс достаточно непрост, это и протокол обмена по USB, переходные процессы, идентификаторы и GUID (Globally Unique IDentifier)…

Немного теории...
HASP (Hardware Against Software Piracy) - это система защиты программы (ПО) и аппаратуры от нелегального использования. Основой большинства ключей HASP - обычно является заказной чип c уникальным ПО, как например в получивших сейчас широкое распространение в дверной автоматике таблетках iBUTTON от Dallas Semiconductor.

Принцип защиты состоит в том, что в процессе запуска программа опрашивает ключ, подключённый к компьютеру по I2C, LPT, PCMCIA или USB. Если ключ отвечает "правильно", то программа выполняется нормально. Иначе, она блокирует доступ к определенным функциям или просто не запускается. Таким образом, любая защищаемая программа состоит непосредственно из самой программы и механизмов проверки ключа. Задача этих механизмов - проверить наличие ключа, получить его уникальный идентификатор, прочитать или изменить содержимое встроенной памяти.

Предпосылки защиты ПО. Существующие решения
Основными критериями для использования аппаратных ключей являются:

  • цена используемых ключей должна быть неизмеримо меньше цены софта
  • длительный срок жизни программного продукта
  • индивидуальный алгоритм взаимодействия
Первый критерий обеспечивается довольно легко: с интенсивной разработкой новых видов памяти, таких как PRAM*, цены на SSD (Solid State Disk) носители уже составляют от 5 долларов. Таким образом разработчик без ущерба для бюджета может распространять продукт на самом ключе.

* PRAM (Phasechange Random Access Memory) - память с произвольным доступом, основанная на фазовых переходах вещества - халькогенида, обладающую скоростью доступа порядка 10 нс, что сравнимо с современными ОЗУ.


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

Существует множество вариаций ключей: без собственной памяти, с защищенной памятью, со встроенными REAL TIME часами, со встроенными сетевыми протоколами.

В то же время, кроме предлагаемого в статье встраиваемого решения в виде компонента, существуют такие продукты как StarForce и HASP Envelope от компании Alladin, позволяющие уже на этапе продажи добавлять защитные модули обмена с ключом в готовые программы, интегрируя их в код продукта. Но у них есть издержки, связанные с затратами на покупку самих HASP ключей, стоимость которых составляет от 25 до 50 долларов за штуку (в зависимости от модели ключа) и ПО для встраивания (от 200 долларов), при стоимости защищаемой программы от 20 долларов.

Разработка ПО и средства отладки
Как известно, метод защиты HASP основан на привязке программы к некоему или совокупности уникальных параметров ключа и даже оборудования. Так как мы будем использовать устройство USB, то априори достаточно считать серийник и ID флешки**, поскольку они не меняются при их форматировании.

** не все флеш-накопители имеют данный номер, к примеру некоторые чипы от LG


Для работы необходимо следующее:

  • среда Borland Delphi 5-7
  • утилита Dependency Walker из комплекта Visual C++ 6.0
В средах NT/XP информацию о устройствах предоставляет стандартная системная библиотека SetupApi.dll . Чем и воспользуемся... Рассмотрим экспортируемые ею функции с помощью Dependency Walker, и для удобства разработчика встроим в компонент (в дальнейшем он будет использоваться как базис механизма защиты)
... CM_Get_Device_IDA:function(dnDevInst: DWORD; Buffer: PChar; BufferLen: DWORD; ulFlags: DWORD): DWORD; stdcall; SetupDiGetClassDevsA:function(ClassGuid: PGUID; Enumerator: PChar; hwndParent: HWND; Flags: DWORD): HDEVINFO; stdcall; SetupDiEnumDeviceInfo:function(DeviceInfoSet: HDEVINFO; MemberIndex: DWORD; DeviceInfoData: PSP_DEVINFO_DATA): boolean; stdcall; SetupDiDestroyDeviceInfoList:function(DeviceInfoSet: HDEVINFO): boolean; stdcall; CM_Get_Device_ID_Size:function(pulLen: PDWORD; dnDevInst: DWORD; ulFlags: DWORD): DWORD; stdcall; SetupDiCallClassInstaller:function(InstallFunction: DWORD; DeviceInfoSet: DWORD; DeviceInfoData: PSP_DEVINFO_DATA): BOOL; stdcall; SetupDiGetDeviceRegistryPropertyA:function(DeviceInfoSet: DWORD; DeviceInfoData: PSP_DEVINFO_DATA; Propertys: DWORD; PropertyRegDataType: PWORD; PropertyBuffer: PByte; PropertyBufferSize: DWORD; RequiredSize: PWORD): BOOL; stdcall; SetupDiSetClassInstallParamsA:function(DeviceInfoSet: DWORD; DeviceInfoData: PSP_DEVINFO_DATA; ClassInstallParams: PSP_CLASSINSTALL_HEADER; ClassInstallParamsSize: DWORD): BOOL; stdcall; FLib: THandle; ...

для их использования - осуществим динамическое их подключение в компоненте

Function LinkProc(ProcName: string):Pointer; begin try result:= GetProcAddress(FLib,PChar(ProcName)); Win32Check(Assigned(Result)) except end end; ... CM_Get_Device_IDA:= LinkProc("CM_Get_Device_IDA"); SetupDiGetClassDevsA:= LinkProc("SetupDiGetClassDevsA"); SetupDiEnumDeviceInfo:= LinkProc("SetupDiEnumDeviceInfo"); SetupDiDestroyDeviceInfoList:= LinkProc("SetupDiDestroyDeviceInfoList"); CM_Get_Device_ID_Size:= LinkProc("CM_Get_Device_ID_Size"); SetupDiCallClassInstaller:= LinkProc("SetupDiCallClassInstaller"); SetupDiGetDeviceRegistryPropertyA:= LinkProc("SetupDiGetDeviceRegistryPropertyA"); SetupDiSetClassInstallParamsA:= LinkProc("SetupDiSetClassInstallParamsA"); ...

при создании компонента инициализируем опрос USB:

Var Info: TDevBroadcastDeviceInterface; //интерфейс- ... Info.dbcc_size:= SizeOf(DEV_BROADCAST_DEVICEINTERFACE); Info.dbcc_devicetype:= DBT_DEVTYP_DEVICEINTERFACE; Info.dbcc_classguid:= FClassGUID; FNotifyHandle:= RegisterDeviceNotification(FWnd,@Info,DEVICE_NOTIFY_WINDOW_HANDLE); // таймер на CountDiskEnum ftimer:= ttimer.Create(self); ftimer.Enabled:= false; ftimer.interval:= FPoolingInterval; ftimer.ontimer:= tmr; ftimer.Enabled:= true ...

Покажем на практике как это работает. Встроим компонент в уже готовую программу и в меню осуществим активацию режима "мини HASP" (см. рис.)


после того как флешка будет вставлена, наступает событие DBT_DEVICEARRIVAL

... //--- читаем очередь сообщений и отлавливаем момент подключения-съема USB procedure TDUSB.WndProc(var Msg:TMessage); begin with Msg do if (Msg=WM_DEVICECHANGE)and ((wParam=DBT_DEVICEARRIVAL)or(wParam=DBT_DEVICEREMOVECOMPLETE)) then try DoDeviceChange(wParam,PDevBroadcastDeviceInterface(lParam)); except end else Result:= DefWindowProc(FWnd,Msg,wParam,lParam) end; ...

производим считывание серийного номера, ID и GUID

Var VID,PID: Word; Serial,GUID: string; const USBNameMask="\\?\USB#Vid_%x&Pid_%x#%s#%s"; begin if (Device.dbcc_devicetype=DBT_DEVTYP_DEVICEINTERFACE)and Assigned(FOnChange) and ParseDeviceName(USBNameMask,PChar(@Device.dbcc_name), [@VID,@PID,@Serial,@GUID]) then case Event of DBT_DEVICEARRIVAL: FOnChange(Self,VID,PID,Serial,GUID,doInsert); DBT_DEVICEREMOVECOMPLETE: FOnChange(Self,VID,PID,Serial,GUID,doRemove) end end; ...


для того, чтобы программа знала о наличии нужного нам "девайса" в любой момент времени, а не только в момент съема, воспользуемся функцией SetupDiGetClassDevsA все той же библиотеки - setapi.dll

Procedure TDUSB.CountDiskEnum; // вызов по таймеру ftimer- const GUID_DEVCLASS_DISKDRIVE: TGUID = (D1: $4D36E967; D2: $E325; D3: $11CE; D4: ($BF, $C1, $08, $00, $2B, $E1, $03, $18)); var hDevInfoSet: HDEVINFO; DevInfo: SP_DEVINFO_DATA; i: Integer; s: string; pp: boolean; begin DevInfo.cbSize:= sizeof(SP_DEVINFO_DATA); hDevInfoSet:= SetupDiGetClassDevsA(@GUID_DEVCLASS_DISKDRIVE, nil, 0, 2); i:= 0; list.Clear; // обнуляем stringlist // if hDevInfoSet INVALID_HANDLE_VALUE then begin while (SetupDiEnumDeviceInfo(hDevInfoSet, i, @DevInfo)) do begin s:= GetDevName(DevInfo.DevInst); //фильтрация строки вида- //USBSTOR\DISK&VEN_KINGSTON&PROD_DATATRAVELER_2.0&REV_PMAP\5B661B004102&0 //USBSTOR\DISK&VEN_SAMSUNG&PROD_MIGHTY_DRIVE&REV_PMAP\07521094081F&0 if pos("USB",s)=1 then // наполняем список подключенных- list.Add(sel_ser(s)); Inc(i) end; SetupDiDestroyDeviceInfoList(hDevInfoSet) end; ...

введем алгоритм простейшей защиты на основе функции BlockInput из библиотеки - user32.dll

Procedure BlockInput; external "user32.dll"; ... //проверка на блокировку ПК- pp:= false; if (FActive)and(fblock"") then begin for i:= 0 to list.Count-1 do if list[i]= fblock then begin pp:= true; break end; if pp then UnBlock else block end; // FSerChange(Self,list) // возврат события компонента- ...

Полные исходные тексты компонента и тестовый монитор доступны по .


Рис. - Тестовый монитор USB
Рис. - Компонент мини HASP

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

Итоги
Обратите внимание, что рассмотренный метод защиты USB флешкой, так и самими ключами HASP имеет уязвимое место - это аппаратный перехват вызова устройства. Имея отладчик с пошаговой трассировкой, можно выделить процедуру во время которой идет обращение к устройству и "работать" дальше с ней. Тем не менее, учитывая дешевизну, скорость разработки, а главное простоту - данный метод с успехом можно использовать для минимальной защиты как ПК, так и привязки программ.

  • Cайт Alladin http://www.alladin.ru
  • Dependency Walker из комплекта Visual C++ 6.0 http://ra-xp.narod.ru/zip/dll.zip
  • Модификация системы управления ПК http://ra-xp.narod.ru/zip/ram.zip
  • Компонент miniHASP for DELPHI и компиляция тестового проекта http://ra-xp.narod.ru/zip/hsp.zip

Контактная информация:

[email protected]

Эмулятор – это программа, которая имитирует работу различных физических устройств или других программ.

Например, виртуальные диски, эмуляторы игровых приставок, игр и т.д. В статье рассматривается эмулятор ключа защиты HASP.

HASP – аппаратно программный комплекс защиты ПО от незаконного (несанкционированного) использования и распространения.

Ключи выпускаются для различных ОС – Windows, Linux, Android и 32- и 64-разрядных компьютеров.

Система разработана компанией Aladdin KS, в защиту которой входит:

– электронный ключ (брелок USB);
– специальное ПО для привязки к ключу, защиты программ и данных.

Существуют различные исполнения ключа HASP:

– брелок USB;
– ключ LPT;
– карта PCMCIA, внутренняя карта PCI.

Наибольшее распространение имеет брелок USB. В настоящее время применяются несколько вариантов ключей:

1) HASP 4 (первая версия защиты), HASP HL (HardLock – современный вариант) – это аппаратные ключи.

2) HASP SL (Soft Lock) – программный ключ. Этот ключ более удобен для распространения приложений, но имеет меньший уровень защиты, чем у HL.

3) HASP SRM комбинированное решение, в нем есть выбор – что использовать: аппаратный HL или программный SL ключ.

Защитой HASP пользуются такие пакеты программ как 1С, Консультант Плюс. Порядок защиты примерно такой. Ключ присоединен к определенному порту компьютера. Устанавливается специальный драйвер защиты.

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

Эмуляция ключей используется в следующих случаях:

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

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

Это значит, что для установки любого эмулятора, у вас должна быть лицензионная версия ПО.

Если по какой-то причине необходим эмулятор ключа, нужно иметь в виду следующее – вариантов эмуляторов, это зависит от:

– числа пользователей программы;
– версии программы – сетевая или для локальных пользователей;
– для какого сервера нужен эмулятор – Server 2003, 2008 и др.

Создано много программ эмуляции, среди них комплекс Sable. Далее два конкретных примера.

Установка эмулятора Hasp HL

Дополнительная информация:

www.xaker.name/forvb/showthread.php?t=20555&page=11
exctcryptor.ucoz.ru/haspharddong2007.zip

Распаковать и запустить HASPHL2007.exe

Должны быть установлены драйвера и оригинальный ключ подключения.

В программе DRIVER нажать INSTALL – установка драйвера.

Запустиь программу edgehasp.exe – генерация ключа. Полученный ключ ввести в закладку “EMULATOR”. Нажать “StartService”.

Запустить защищенную программу, проверить ее работу, далее, если все работает, открыть окно «DUMPER». В окне отображаются пароли. Для создания копии нажать «DUMP». Результат – файл типа.dmp.

Запустить программу EDGEHASP.EXE для преобразования файла.

Открыть файл «DONGLES» в окне «HASP/Hardlock Emulator» и указать имя файла.

Очистить дамп – кнопка CLEAN.

Можно пользоваться. 🙂

Установка эмулятора Sable

Информацию можно найти по адресу:

www.emus2.narod.ru/emulyator-sable.html
www.gigatorrent.net/programms/office

Запустить Sable и дождаться перезагрузки.

Удалить ярлык эмулятора – C:\Documents Settings\All users\StartМenu\Programs\Startup

Запустить C:\ProgramFiles\SABLE\ . Запустить delnt.bat – удаление Hasp из реестра.

Установить эмулятор Hasp — C:\ProgramFiles\SABLE – запустить instnt.bat .

Запустить startnt.bat . ПУ – система – Оборудование -ДУ

Меню View-ShowHiddenDevice – Нажать NonPlag… -Scan for hardware …

Cвойства (Propetries – hasp Automatic.) Ok.

Копировать patch77. exe из C:\ProgramFiles\sable в папку 1С.

Запустить patch77.exe /F1cv7.exe.

Замечание . Приведенные инструкции – это примеры, на которые нужно ориентироваться в реальной обстановке.

Здесь вы можете Скачать HASP эмулятор совершенно бесплатно.

На сегодня у меня все, следите за блогом по электронной почте. Жду ваших отзывов в комментариях. Пока!

В этой статье описаны способы обхода аппаратных систем защиты. В качестве примера рассмотрена технология HASP (Hardware Against Software Piracy), разработанная компанией Aladdin Knowledge Systems Ltd. В прошлом данная технология являлась одной из самых популярных аппаратных систем защиты ПО.

Мощью аппаратной защиты HASP пользуются многие серьезные разработчики софта, которые не хотят, чтобы их продукт несанкционированно распространялся. Хаспом, например, защищаются пакеты «1С.Бухгалтерия» или «1С.Предприятие», без которых не может прожить ни одно более или менее организованное дело. Популярный юридический справочник «КонсультантПлюс» также защищает доступ к данным с помощью электронных ключиков. Чтобы воспользоваться вышеупомянутым или другим не менее дорогостоящим софтом, не платя никому ни копейки, недостаточно просто полазить по Сети в поисках txt’шника с ключиками. Однако хакер всегда разберется, что делать с защитой, пусть и аппаратной. И паяльник ему для этого не понадобится.

Взглянем

Утрируя, можно сказать, что HASP состоит из двух частей: аппаратной и программной. Аппаратная часть - это электронный ключик в виде USB-брелка, PCMCIA-карты, LTP-девайса или вообще внутренней PCI-карты. Установленный софт будет работать только на той машине, в которую воткнут электронный ключ. Собственно, неплохо было бы отучить софт от такой неприятной для кошелька привычки.

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

Механизм системы защиты

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

Главным недостатком такой системы защиты является возможность перехвата вызовов диспетчера ввода-вывода и эмулирования аппаратного ключа. Существует также вариант разработки драйвера виртуального ключа, но это гораздо более сложная техническая задача, нежели перехват вызовов.
Как тебе известно, модель драйвера описывается в структуре DRIVER_OBJECT при загрузке модуля. Она хранит массив обработчиков сообщений. Причем никто не мешает переписать эти адреса и получить управление, выполнив наш код. Таким образом, можно перехватывать и подменять IRP-пакеты, подставляя лицензионные данные. Другими словами, имея дамп ключа защиты, можно передать его программе, проверяющей верность лицензионных данных!

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

Перехват и эмуляция

Как уже отмечалось, идея перехвата состоит в перезаписи обработчиков IRP-пакетов. Для этого необходимо иметь возможность изменять поля структуры DRIVER_OBJECT. К счастью, существует функция IoGetDevicePointer, которая возвращает указатель на объект вершины стека именованных устройств и указатель на соответствующий файловый объект. Вот фрагмент кода функции, устанавливающей ловушку:

UNICODE_STRING DeviceName;
PDEVICE_OBJECT DeviceObject;
PFILE_OBJECT FileObject;

RtlInitUnicodeString(&DeviceName, lpDevice);
IoGetDeviceObjectPointer(&DeviceName, 1u, &FileObject, &DeviceObject);

Получив указатель на структуру DEVICE_OBJECT, имеем указатель на DRIVER_OBJECT. Теперь заменим адреса обработчиков и функций выгрузки драйвера на свои:

NTSTATUS HookDevice(LPWSTR lpDevice)

gDriverObject = DeviceObject-> DriverObject;

gDeviceControl = gDriverObject-> MajorFunction;
gDriverObject-> MajorFunction = HookDispatch;

gInternalDeviceControl = gDriverObject-> MajorFunction;
gDriverObject-> MajorFunction = HookDispatch;

gDriverUnload = gDriverObject->DriverUnload;
gDriverObject->DriverUnload = HookUnload;

ObfDereferenceObject(FileObject);

В последней строчке вызывается функция ObfDereferenceObject, которая уменьшает количество ссылок на файловый объект. Это необходимо делать для корректной выгрузки драйвера, чтобы не было утечки ресурсов и аналогичных ошибок.

Так как указатель на объект драйвера защиты сохранeн, то чтобы снять ловушку, нужно просто восстановить прежние обработчики IRP-пакетов:

void UnhookDevice(void)

gDriverObject-> MajorFunction = gDeviceControl;
gDriverObject-> MajorFunction = gInternalDeviceControl;
gDriverObject->DriverUnload = gDriverUnload;

Конечно, надо добавить соответствующие проверки на валидность указателей и прочее.

Теперь необходимо реализовать правильную выгрузку драйверов. Так как система защиты по каким-либо причинам может закончить свою работу раньше нашего драйвера, то чтобы избежать краха системы из-за неверных указателей, обработаем это событие в функции HookUnload:

void HookUnload(PDRIVER_OBJECT DrvObj)

UnhookDevice();
gDriverUnload(DrvObj);

Здесь происходит восстановление полей структуры DRIVER_OBJECT, и передаeтся управление на оригинальный код выгрузки драйвера перехваченного устройства.

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

Принцип работы эмулятора

Перехватчик

Зная основные принципы простейшего перехвата IRP-пакетов, приступим к реализации пока только самого перехватчика для дальнейшего анализа. Для этого создадим объект драйвера, который содержит символьное имя (например DosDevicesHook) и точки входа CREATE, CLOSE, READ.

IoCreateDevice(DriverObject, 0, &usDeviceName, FILE_DEVICE_NULL, 0, 0, &pDeviceObject);
IoCreateSymbolicLink(&usSymbolicDeviceName, &usDeviceName);

DriverObject->MajorFunction = DriverDispatch;
DriverObject->MajorFunction = DriverDispatch;
DriverObject->MajorFunction = DriverDispatch;
DriverObject->DriverUnload = DriverUnload;

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

Код HookDispatch

if (idlTail->IrpData.InputLength)
{
idlTail->InputBuffer = ExAllocatePool(NonPagedPool, idlTail->IrpData.InputLength);
RtlCopyMemory(idlTail->InputBuffer, Irp->AssociatedIrp.SystemBuffer, idlTail->IrpData.InputLength);
}

if (IoSL->MajorFunction == IRP_MJ_DEVICE_CONTROL)
Status = pHookedDriverDispatch(DeviceObject, Irp);

if (idlTail->IrpData.OutputLength)
{
idlTail->OutputBuffer = ExAllocatePool(NonPagedPool, idlTail-> IrpData.OutputLength);
RtlCopyMemory(idlTail->OutputBuffer, lpBuffer, idlTail->IrpData.OutputLength);
}

Осталось реализовать чтение из драйвера. Так как пакет содержит буферы, чье содержимое представляет интерес, то размер сообщений заранее не известен. Поэтому поступим следующим образом: при первом чтении получаем общую информацию о пакете и размере буферов; при повторном читаем содержимое, удаляем звено из списка пакетов и не забываем про спиновые блокировки для последовательной работы с данными:

Код DriverDispatch

Length = IoSL->Parameters.Read.Length;
if (Length == sizeof(IRP_DATA) && idlHead)
RtlCopyMemory(Irp->UserBuffer, &idlHead->IrpData, Length);
else if (idlHead && Length == (idlHead-> IrpData.InputLength + idlHead-> IrpData.OutputLength))
{
RtlCopyMemory(Irp->UserBuffer, idlHead-> InputBuffer, idlHead->IrpData.InputLength);
RtlCopyMemory((PVOID)((ULONG)Irp->UserBuffer + idlHead->IrpData.InputLength), idlHead-> OutputBuffer, idlHead->IrpData.OutputLength);
}
else if (Length == 1 && idlHead)
{
if (idlHead->InputBuffer)
ExFreePool(idlHead->InputBuffer);
if (idlHead->OutputBuffer)
ExFreePool(idlHead->OutputBuffer);

idlTemp = idlHead->ldlNext;
ExFreePool(idlHead);
idlHead = idlTemp;
if (!idlTemp)
idlTail = NULL;
}

Когда перехватчик готов, запускаем сначала его, а затем - защищенное приложение с ключами и без. Из полученных логов становится видно, какие управляющие коды посылаются и их результаты. Также можно видеть, что запросы и ответы на два различных кода (9c402450, 9c4024a0) не изменяются. Казалось бы, можно построить табличный эмулятор, но после серии запусков убеждаемся, что это невозможно, так как содержимое буферов различно, и неизвестно, как оно образуется.

Перехваченные пакеты без ключа

Перехваченные пакеты с ключом

Затем возможны несколько вариантов дальнейших действий:

  • изучать дебри драйвера защиты;
  • воспользоваться информацией самих разработчиков системы.

Оба варианта дают необходимую информацию. Итак, оказывается, содержимое пакетов шифруется публичным симметричным алгоритмом AES (Advanced Encryption Standard). Логичной целью является получение ключа шифрования.

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

Пример дампа ключа

Поэтому первое, что нужно сделать, это получить ключ. Поставленную задачу может решить обычный брутфорс:

unsigned short Key;
unsigned char RefKey, VerKey;

for (Key = 0; Key <= 0x7fff, Key++)
{
if (!HL_LOGIN(Key, 1, RefKey, VerKey))
{
HL_LOGOUT();
Break;
}
}

Функции HL_LOGIN, HL_LOGOUT доступны из HASP SDK для разработчиков приложений, защищенных на этой платформе, и имеют следующие прототипы:

WORD HL_LOGIN(WORD ModAd, Word Access, Byte *RefKey, Byt *VerKey);
WORD HL_LOGOUT(void);

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

Новый API мало отличается от старого, и это никак не сказывается на принципе работы брутфорса. Подробную документацию Hasp API, готовые реализации брутфорса и дампера ключей можно найти на .

Обработчик

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

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

NTSTATUS HookDispatch():

PIO_STACK_LOCATION Stack = Irp-> Tail.Overlay.CurrentStackLocation;
ULONG IoControlCode;
if (Stack->MajorFunction == 14)
{
IoControlCode = Stack.DeviceIoControl.IoControlCode;
If (IoControlCode != 0x9c402458)
{
Return gDeviceControl(DeviceObject, Irp);
}
else
{
Encrypt(Irp->AssociatedIrp.SystemBuffer);
Crypt(Irp->AssociatedIrp.SystemBuffer, Key, DumpMemory);
}
}

Return STATUS_FAILED;

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

Код Encrypt()

void Encrypt(BYTE * Buffer)
{
WORD Seed = ((WORD )Buffer + 0x5e);
WORD Ver = ((WORD )Buffer + 0xba);

if (Ver)
{
for (int i = 0; i < 0xB9; i++) {
(WORD )(Buffer + i) += Seed;
Seed = (Seed >> 15) | (Seed << 1);
Seed -= (WORD )(Buffer + i) ^ i;
}

for (int i = 0xBE; i < 0xFF; i++) {
(WORD )(Buffer + i) -= Seed;
Seed = (Seed >> 15) | (Seed << 1);
Seed += (WORD )(Buffer + i) ^ i;
}

((WORD )Buffer + 0xba) = Seed;
}
}

Видно, что алгоритм гораздо сложнее, чем обычный сдвиг и исключающее «или». А вот алгоритм дешифрования:

Код Decrypt()

void Decrypt(BYTE* Buffer)
{
WORD Seed = ((WORD )Buffer + 0x5e);
WORD Ver = ((WORD )Buffer + 0xba);

if (Ver) {
for (int i = 0xFE; i > 0xBD; i—) {
Seed -= (WORD )(Buffer + i) ^ i;
Seed = (Seed << 15) | (Seed >> 1);
(WORD )(Buffer + i) += Seed;
}

for (int i = 0xB8; i >= 0; i—) {
Seed += (WORD )(Buffer + i) ^ i;
Seed = (Seed << 15) | (Seed >> 1);
(WORD )(Buffer + i) -= Seed;
}

((WORD )Buffer + 0xba) = Seed;
}
}

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

В заключение отмечу, что построение табличного эмулятора, основанного на перехвате DeviceIoControl, - достаточно трудная задача. Но такой принцип эмулятора можно использовать и на другом уровне взаимодействия: создать виртуальную USB-шину.

Заключение

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