Sentinel API

Sentinel LDK позволяет построить защиту как с помощью автоматической утилиты Sentinel Envelope, так и на уровне исходного кода используя Sentinel Licensing API. Максимальный эффективность в гибкости и надежности лицензирования достигается при одновременном использовании обоих инструментов. Гибкое лицензирование и шифрование критичных данных лучше реализовывать с помощью API, а уже скомпилированное приложение защищать с помощью Sentinel Envelope для обеспечения максимального уровня безопасности.

Sentinel Licensing API - это набор библиотек под различные операционные системы и языки программирования, которые позволяет обращаться к лицензии(как аппаратной, так и программной), на уровне исходного кода. API крайне прост и с содержит всего 13 функций. Для быстрого изучения API в составе SDK присутствует утилита ToolBox, которая позволяет в интерактивном режиме познакомиться с работой API, а также сгенерировать исходный код для вставки в код вашего приложения.
Sentinel ToolBox


Sentinel Licensing API позволяет выполнить следующие действия:
  • проверить наличие нужной лицензии и открыть с ней сессию если ее лицензионные ограничения еще не истекли;
  • зашифровать/расшифровать любой массив данных используя крипто-процессор ключа;
  • прочитать или записать любые данные в безопасное хранилище ключа;
  • узнать время используя аппаратный или программный таймер;
  • применить обновления к ключу, получить информацию об имеющихся лицензиях, их ограничениях и открытых сессиях.
С помощью Sentinel Licensing API вы на уровне исходного кода можете определить должен ли быть доступен для пользователя тот или иной элемент интерфейса приложения, который требует наличия лицензии. Проверить наличие лицензии и ее лицензионных ограничения непосредственно перед выполнением кода функции.

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

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

API это не только гибкое лицензирование и безопасность, но и удобство для пользователя. API позволяет автоматизировать применение обновлений к лицензии, ее перенос на другой компьютер, управление доступом, контроль использования и многое другое. Подробная документация и примеры работы с API для разных языков программирования вы можете найти в составе SDK Sentinel LDK.


Стоит также отметить, что кроме Sentinel Licensing API в составе SDK есть и ряд других API:
  • EMS Webservice API - RESTful API предоставляющий доступ ко всем возможностям Sentinel EMS через API.
  • License Generation API - позволяет создавать лицензии для аппаратных или программных лицензий не используя сервис Sentinel EMS.
  • Admin API - позволяет управлять Admin Control Center или встроить его в свое приложение.
  • RuntimeInstall - автоматизация процесса установке драйвера.
  • Envelope API - позволяет определять с какими параметрами Envelope будет защищать приложение или его часть на уровне исходного кода.


Пример построения надежной защиты на базе Licensing API

Для достижения максимального уровня безопасности рекомендуется применять одновременно и защиту на уровне Licensing API и утилиты Envelope. Но если по каким-либо причинам использовать Envelope не представляется возможным, то можно реализовать надежную защиту и только на уровне API. Это требует времени и экспертизы в области защиты программного обеспечения, поэтому мы рекомендуем идти таким путем только в крайнем случае.

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

Скачать все примеры с исходным кодом и вспомогательными утилитами можно по ссылке: скачать

Sample.00
Незащищенное тестовое приложение. Функция WinMain инициализирует и выводит главное окно приложения, а если приложение уже запущено, то "поднимает" окно на передний план. Две функции Function1 и Function2 запускаются из меню главного окна как отдельные потоки (Threads). Они выполняют генерацию случайных чисел в диапазонах [0;128] и [128;255], выводя "правильные" (укладывающиеся в диапазон) значения зеленым цветом, "неправильные" - красным цветом. Кроме того, реализована проверка на возникновение неких "редких" событий, которые выводятся синим цветом.

Sample.01
Простейшая защита, в функции WinMain выполняется Login/Logout на демонстрационный ключ Sentinel HL с использованием Feature ID 0. Проверка результатов работы функции Login выполняется здесь же. В случае отсутствия ключа выводится MessageBox с сообщением об ошибке и выполнение приложения завершается.

Sample.02
Небольшая модернизация защиты из предыдущего примера - проверка результата работы функции Login сделана отложенной, а не сразу же после возврата из функции, и, кроме того, она убрана на другой уровень вложенности, в процедуры InitInstance и RegisterWindowClass. Введен дополнительный уровень защиты - запуск низкоприоритетного потока, выполняющего фоновую проверку ключа. Результат этой проверки учитывается в работе функции Function1, прекращая ее выполнение в случае отсутствия ключа. Так же, проверяющим потоком выдается MessageBox с сообщением об ошибке.

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

Sample.04
В дополнение к предыдущим защитным механизмам, добавлено простейшее лицензирование работы функций Function1 и Function2 при помощи Feature ID. В каждой функции выполняется Login/Logout на демонстрационный ключ Sentinel HL с использованием различных Feature ID, отличных от 0. В случае отсутствия в ключе соответствующей лицензии выводится MessageBox с сообщением об ошибке и выполнение функции прерывается. Кроме того, Function2 теперь так же, как и Function1, зависит от результатов работы потока, выполняющего фоновый опрос ключа.

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

Sample.06
В дополнение к ранее реализованным защитным механизмам, добавлен контроль целостности зашифрованных данных в процедуре Function1 и контроль целостности критичных участков кода, содержащих защитные механизмы, в процедуре Function2. При этом, возможно обнаружение трассировки контролируемого кода с использованием программных точек останова. Запуск процедур контроля CRC осуществляется по возникновению "редких" событий. Для расчета эталонных CRC после сборки приложения используется утилита CrcProtect.

Sample.07
Один из возможных вариантов реализации эшелонированной защиты с использованием кодов Рида-Соломона, позволяющих восстановить разрушенные защитные механизмы. Также, уничтожаются все установленные в контролируемом коде программные точки останова, что позволяет активно противодействовать трассировке кода с их использованием. Запуск процедур коррекции кода и данных производится, когда количество неудачных проверок CRC в процедурах Function1 и Function2 превысит заданные пороговые значения. Для расчета кодов коррекции ошибок после сборки приложения используется утилита EccProtect.

Sample.08
Пример реализации высокоэшелонированной защиты с применением кодирования Рида-Соломона. Демонстрируется совместное использование всех ранее рассмотренных защитных механизмов. Первый эшелон защиты – обычная работа с ключом по необходимости, фоновый опрос ключа из защищенного потока. Второй эшелон защиты – редкие, проводимые по случайным событиям, проверки CRC критичных участков кода/данных. Задача – сбор статистики о состоянии защиты первого эшелона и триггерная активация третьего эшелона защиты в случае необходимости. В качестве триггера используется наличие/отсутствие файла «alarm» в одном каталоге с защищенным приложением. Третий эшелон защиты – восстановление разрушенных защитных механизмов первого эшелона и зашифрованных данных с использованием кодов Рида-Соломона. В исходном состоянии эшелон не активен и начинает работать на постоянной основе только после изменения состояния триггера, в результате работы механизмов второго эшелона. После этого, запуск механизмов третьего эшелона производится при каждом старте взломанного приложения через механизм TLS_Callback, что позволяет восстановить код защиты первого эшелона в памяти, причем, еще до передачи управления на точку входа (Entry Point) приложения. Утилита EccProtect инициализирует механизм TLS_Callback и рассчитывает коды коррекции ошибок (ECC) для указанных регионов после сборки приложения. Для демонстрационных целей в каталоге «TEST» данного примера находятся два приложения, служащих для взлома защиты первого эшелона. Приложение Patch.exe убирает защиту путем внесения изменений в файл защищенного приложения. Приложение Loader.exe оставляет файл без изменений, убирая защиту в процессе загрузки образа защищенного приложения в память, т.е. является runtime patcher'ом.

Sample.09
Защита сделана на основе примера Sample.04, с добавлением динамического расшифровывания/зашифровывания критичных участков кода примера. Перед выполнением защищенного таким образом региона кода, выполняется его расшифровывание с последующей передачей управления на него. При завершении выполнения кода защищенного региона, выполняется обратное зашифрование, что делает бессмысленным статическое изучение кода приложения, выполняемое как обычным образом, так и со снятием дампа. Используется как зашифрование через ключ (AES), так и при помощи алгоритма, ранее использованного для маскировки характерных сигнатур. Для начального зашифрования кода функций после сборки приложения используется утилита CodeEncrypt.

Sample.10
Защита аналогична предыдущему примеру, однако расшифрование/зашифровывание кода реализовано неявно, через обработчики исключительных ситуаций (SEH/VEH). Дополнительно реализовано противодействие трассировке кода с использованием аппаратных точек останова. Для начального зашифрования кода функций после сборки приложения используется утилита CodeEncrypt.

Sample.11
В дополнение к предыдущему примеру реализовано противодействие табличной эмуляции ключа, путем внесения "шума" в подлежащие криптографическому преобразованию участки кода. На тот случай, если эмулятор все же внедрен в тело приложения, добавлен контроль целостности точек входа HASP API при помощи алгоритма CRC32. В случае подмены кода API выполняется его восстановление при помощи декодера Рида-Соломона.

Sample.Fixup
Реализация алгоритмов, использующих механизмы контрольных сумм, кодов Рида-Соломона и динамическое шифрование исполняемого кода, предназначенных для использования в приложениях и библиотеках, содержащих перемещаемые элементы. Контрольными суммами и кодами коррекции ошибок защищены точки входа LDK API, зашифрованный массив с коэффициентами для функции Function1 и код Function1. Код функции Function2 зашифрован.

Sample.NET
Пример автоматизированного использования Envelope для защиты .NET-кода. Доступны следующие возможности: обфускация символьной информации, зашифрование строковых данных, control_flow - обфускация CIL-кода, зашифрование CIL-кода. Управление параметрами защиты осуществляется из исходного кода защищенного приложения через механизм аттрибутов.