Тайна золотого ключика или Особенности системы лицензионных ключей, используемой компанией Software AG

Дата публикации 6 мар 2006

Тайна золотого ключика или Особенности системы лицензионных ключей, используемой компанией Software AG — Архив WASM.RU

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

  1. Посмотреть, как реализована система лицензирования на примере довольно дорогих коммерческих продуктов от компании Software AG
  2. А также показать на реальном примере, что иногда вовсе не обязательно проводить все ночи напролет, закопавшись в отладчике или дизассемблере, чтобы корректно "поправить" лицензионный ключ (цели "правки" могут быть любыми), что иногда достаточно просто пошире открыть глаза…

Чтобы придать статье некую логическую последовательность, попробую дать ответы на вполне закономерные вопросы:

  1. Что же это за компания такая - "Software AG"?
  2. В чем суть пресловутой системы лицензионных ключей?
  3. И в чем, собственно, особенности этой системы?

Software AG

В те стародавние времена, когда компьютеры были большими, а программисту при поступлении на работу выдавался не навороченный комп в персональное пользование, а линейка, карандаши, ручка и график работы на "машине" (именно так любовно назывался монстр, стучащий копытом по фальшполу в машзале в окружении ленточных стоек и ЦПУ), эта немецкая компания была более известна, чем сейчас, благодаря своим довольно известным в СССР продуктам ADABAS (СУБД) и NATURAL (язык программирования). Сегодня же редкий специалист по ИТ сможет вспомнить, "что это за зверь, и с чем его едят".

Немного информации о компании (информация взята с ее официального сайта).

  • Название - Software AG (принятое сокращение SAG)
  • Официальный сайт - http://www.softwareag.com, http://www.softwareag.com/ru - на русском языке
  • Год основания - 1969
  • Головной офис - г. Дармштадт (Германия)
  • Количество сотрудников - более 2 600 чел
  • Валовой доход - 411 млн. евро (по 2004 г)
  • Направление деятельности - "разработка, продажа, последующее обслуживание и сопровождение высокоэффективных программных продуктов, служащих основой для интеграции информационных систем предприятия".
  • Дополнительно - более 3000 заказчиков (в более чем 60 странах мира)

Линейка основных программных продуктов:

  • ADABAS - быстродействующая СУБД, предназначенная для использования в больших системах, работоспособность которых жизненно важна для предприятия
  • NATURAL - мощный сервер приложений компании Software AG, позволяющий разработчикам быстро создавать критически важные приложения1
  • ENTIREX - надежное, высокопроизводительное интеграционное программное обеспечение, позволяющее организациям использовать функциональность унаследованных систем при разработке новых приложений
  • TAMINO XML Server - высокопроизводительный сервер для хранения, управления, публикации и обмена XML - документами

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

Что ж, если верить тому что написано, перед нами вполне солидная компания… Похоже, есть что продавать (увы, не в России!), и значит, есть, что лицензировать… Так что там с системой лицензионных ключей?

Система лицензионных ключей

Прежде чем говорить про лицензионные ключи, хотелось бы отметить одну особенность - в продуктах SAG система лицензирования - это не система защиты от взлома. По мнению представителей компании, от взлома их защищают сам договор лицензии и закон. А система лицензирования - скорее средство оградить заказчика от установки продуктов "куда попало" - например, Natural for Windows 2000/XP не будет нормально работать под Windows98/ME (нечто подобное и с unix'ами).

Условности соблюдены, теперь за дело!

Продукты SAG в последнее время используют так называемый "файл лицензии", являющийся по сути xml-файлом, и содержащим информацию о продукте и об условиях его поставки. Именно здесь находится информация о сроке действия лицензии, об операционной системе, о доступных компонентах продукта и проч. Вполне логично, что он используется как при установке продукта (отсюда берется информация о том, какие компоненты устанавливать, а какие нет; проверяется "среда обитания" продукта ), так и при эксплуатации (проверяется "среда обитания" продукта). Проверка "Среды обитания" - проверяется заявленная и фактическая ОС, и проверяется срок действия лицензии.

Пример файла лицензии (взят из форума http://tamino.forums.softwareag.com2):

Код (Text):
  1.  
  2. <SoftwareAG_License>
  3.     <Component Id="SalesInfo">
  4.         <SerialNumber>0000004680</SerialNumber>
  5.         <LicenseKey>A7B77D8CC2B46E9C5821DEC41B9B9CE0</LicenseKey>
  6.         <CustomerID>SAG</CustomerID>
  7.         <CustomerName>Software AG</CustomerName>
  8.     </Component>
  9.     <Component Id="ProductInfo">
  10.         <ExpirationDate>30days</ExpirationDate>
  11.         <OS>w2000p, w2000s, winxp_pro, winxp_per</OS>
  12.         <ProductCode>INS</ProductCode>
  13.         <ProductID>INS414FSETWIN</ProductID>
  14.         <ProductName>Tamino XML Server</ProductName>
  15.         <ProductVersion>4.1.4</ProductVersion>
  16.         <Usage>XML Starter Kit 4</Usage>
  17.         <RegistryDate>2005/06/30</RegistryDate>
  18.     </Component>
  19.     <Component Id="TaminoServer">
  20.         <XTension>yes</XTension>
  21.         <ConcurrentSessions>3</ConcurrentSessions>
  22.         <DatabaseSize>20</DatabaseSize>
  23.         <CPU>1</CPU>
  24.         <XML>yes</XML>
  25.         <Logging>yes</Logging>
  26.         <AdditionalTokenizedLanguages>chinese, japanese, korean</AdditionalTokenizedLanguages>
  27.         <Readonly>no</Readonly>
  28.     </Component>
  29.     <Component Id="TaminoEnterprise">
  30.         <ExternalBackup>no</ExternalBackup>
  31.         <Replication>yes</Replication>
  32.         <SNMP>no</SNMP>
  33.     </Component>
  34.     <Component Id="TaminoXNode">
  35.         <DBMS>SQL Server, Microsoft SQL Server, ACCESS, Informix, DB2, Oracle, ADABAS, ADABAS D </DBMS>
  36.     </Component>
  37. </SoftwareAG_License>

Любая попытка модифицировать этот файл (например, продлить срок лицензии, изменить ОС и т.д.) заканчивается сообщением об "инвалидности файла лицензии" при запуске продукта.

Небольшое расследование показывает, что все функции, необходимые для работы с лицензионным файлом, собраны в одной библиотеке (очень удобно - и вашим и нашим!) с незатейливым именем saglic.dll, устанавливаемой в папку %CommonProgramFiles%\Software AG. Имена экспортируемых этой библиотекой функций весьма красноречивы. Пройдемся по ключевым функциям:

Код (Text):
  1.  
  2.     LIC_read_Parameter
  3.     LIC_checkExpiration
  4.     LIC_checkOS
  5.     LIC_checkSignature
  6.     LIC_genSignature
  7.     LIC_set_trace_level

LIC_read_Parameter

Прототип функции:

Код (Text):
  1.  
  2. int LIC_read_Parameter (
  3.     char *,     //  (in)        указатель на имя файла лицензии
  4.     char *,     //  (in)        укзатель на название компонента
  5.     char *,     //  (in)        указатель на название поля в компоненте
  6.     char **,    //  (out)   адрес указателя на значение поля)  
  7. )

Назначение: Получить значение заданного поля.
Примечание: Необходимо иметь в виду, что LIC_read_Parameter() вызывает LIC_checkExpiration(), т.е. вначале проверяется валидность ключа.

LIC_checkExpiration

Прототип функции:

Код (Text):
  1.  
  2. int LIC_ checkExpiration(
  3.     char *,     //  (in)        указатель на имя файла лицензии
  4.     char *      //  (in)        указатель на название компонента ("ProductInfo")
  5. )

Назначение: Проверка срока действия лицензии.
Примечание: В этой функции "рабочей лошадкой" является поле файла лицензии. Функция считает поле "валидным", если его значение задано одним из трех способов:

  1. <ExpirationDate>Unlimited</ExpirationDate>
  2. <ExpirationDate>YYYY/MM/DD</ExpirationDate> (YYYY-год, ММ - месяц, DD - день, т.е. дата завершения лицензии)
  3. <ExpirationDate>Ndays</ExpirationDate> (N - количество дней действия лицензии)

При способе "Ndays" делается попытка найти значение (задается в формате YYYY/MM/DD). Если поле отсутствует - берется текущая дата. Подсчитывается дата завершения действия лицензии и заносится в в формате YYYY/MM/DD. Производится пересчет . Т.е. такой способ задания значения "живет" до первого вызова LIC_checkExpiration, после которого превращается в способ "YYYY/MM/DD"

LIC_checkOS

Прототип функции:

Код (Text):
  1.  
  2. int LIC_checkOS (
  3.     char *,     //  (in)        указатель на имя файла лицензии
  4.     char *      //  (in)        указатель на название компонента ("ProductInfo")
  5. )

Назначение: Проверка соответствия фактической операционной системы и заданной в лицензии.
Примечание: В этой функции "подопытным" является поле . Как можно увидеть из примера, в этом поле допустимо перечисление "лицензированных" операционных систем. Помимо явного задания допустимых ОС (например, w2000p - Windows 2000 Professional), возможно задать группу ОС (например, w2000).

Чуть ниже я покажу простой способ определения ОС в идентификации SAG, отмечу лишь, что возможно использование ключевых слов "any" или "win" в этом поле (т.е., становится возможным эксплуатировать продукт SAG под любой - в первом случае - ОС, либо под ОС семейства Windows - во втором случае), но злоупотреблять, конечно же, этим не стоит

LIC_checkSignature

Прототип функции:

Код (Text):
  1.  
  2. int LIC_checkSignature (
  3.     char *,     //  (in)        указатель на имя файла лицензии
  4. )

Назначение: Проверка соответствия фактического хэш-значения файла лицензии и операционной системы и "эталонного" (хранящегося непосредственно в файле лицензии).
Примечание: В этой функции "козырным" является поле . Проверка осуществляется следующим образом. Лицензионный файл "хэшируется" (поле LicenseKey в этой процедуре не участвует) и происходит его сравнение (увы, операция сравнения производится в явном виде) со значением LicenseKey. По словам разработчиков и по отладочной информации можно предположить, что сей хэш рассчитывается по MD5-алгоритму. Может быть и так, не проверял.

LIC_genSignature

Прототип функции:

Код (Text):
  1.  
  2. int LIC_genSignature (
  3.     char *,     //  (in)        указатель на имя файла лицензии
  4. )

Назначение: ???
Примечание: Исходя из названия, можно предположить, что это - функция генерации . Но нам остается только предполагать, т.к. в Public - версии библиотеки saglic.dll реализации функции отсутствует (вывод отладочной информации - не в счет! Об отладочной информации я расскажу чуть ниже)

LIC_set_trace_level

Прототипы функции:

Код (Text):
  1.  
  2. int LIC_set_trace_level (
  3.     int ,       // (in)     уровень трассировки
  4.     char *      // (in)     указатель на имя трассируемой функции
  5. //      (не используется)
  6.     int         // (in)     номер строки
  7. //      (не используется)
  8. )
  9.  
  10. int LIC_set_trace_level (
  11.     int         // (in)     уровень трассировки
  12. )

Назначение: Установка уровня трассировки
Примечание: Этой функцией устанавливается "глобальный уровень трассировки" (название условно). Вся отладочная информация выводится функциями библиотеки не напрямую, а через специальную подпрограмму, одним из параметров которой является "локальный уровень трассировки". Эта подпрограмма сравнивает "глобальный уровень" и "локальный уровень", если "локальный уровень" не меньше "глобального", то информация выводится, иначе - нет.

Коды возврата

  • 0 LICENSE OK
  • 1 ERROR - LICENSE KEY NOT FOUND
  • 2 ERROR - INVALID (TAMPERED) LICENSE KEY
  • 3 ERROR - INVALID (TAMPERED) LICENSE KEY (действительно повтор!)
  • 4 ERROR - PARAMETER NOT FOUND IN LICENSE KEY
  • 5 ERROR - COMPONENT NOT FOUND IN LICENSE KEY
  • 6 ERROR - MISSING PARAMETER(S) - SEE FUNCTION USAGE
  • 7 ERROR - MISSING WINSOCK DLL ON WIN32
  • 8 ERROR - WRONG WINSOCK DLL (BELOW 1.0 ] ON WIN32
  • 9 ERROR - SOCKET CANNOT BE OPENED
  • 10 ERROR - HOST CANNOT BE FOUND IN HTTP ADDRESS
  • 11 ERROR - HOST CANNOT BE OPENED IN HTTP ADDRESS
  • 12 ERROR - HOST CANNOT BE OPENED IN HTTP ADDRESS
  • 13 ERROR - CANNOT CREATE LICENSE USING EXTERNAL LIC VERSION
  • 14 ERROR - CANNOT ALLOCATE MEMORY
  • 15 ERROR - LICENSE EXPIRED
  • 16 ERROR - INVALID LICENSE OS
  • 17 ERROR - CANNOT CREATE FIRST WINDOWS REGISTRY KEY
  • 18 ERROR - CANNOT ACCESS WINDOWS REGISTRY
  • 19 ERROR - READING LICENSE KEY FILE
  • 20 ERROR - TRIAL LICENSE KEY FILES must NOT be WRITE-PROTECTED and MUST be passed as a PATHNAME (not CONTEN TS).
  • 21 ERROR - CONVERTING ASCII-TO-EBCDIC (OR VICE-VERSA)
  • 22 ERROR - SYSTEM COMMAND (I.E., UNAME)
  • 23 ERROR - CANNOT READ LOCAL SAG SECURITY PROFILE
  • 24 ERROR - WRITING to LICENSE KEY FILE

Думаю, разбор потрохов пора завершать.

Если по-крупному, действительно защита отсутствует напрочь ("крутой" алгоритм хэширования не в счет!). Логика системы лицензирования понятна, и очень сильно облегчают понимание этой логики красноречивые имена экспортируемых функций не менее красноречивой saglic.dll, а также обилие отладочной информации.

"Тоже мне, диковина!" - воскликнет проницательный читатель. - "Да такие чудеса на каждом углу по 10 копеек кулек!"

Ну что ж, настало время десерта…

Особенности системы лицензионных ключей

Пикантность ситуации заключается в том, что вместе с установкой основного продукта, на ваш компьютер устанавливается и своеобразный бонус от Software AG в виде двух утилит, уютно разместившимся в папке %Common Files%Software AG (Вообще-то подарков больше, но нужно же знать меру!). Речь пойдет о sagver.exe и saglicExeWrapper.exe.

sagver.exe

Попробуем выполнить ее для начала без параметров (лучше из консольного файл-менеджера, и лучше перенаправить вывод потока в файл).

Что это? А это, дорогие читатели, ни что иное, как описание свойств файлов, содержащихся в текущей (%Common Files%Software AG) папке. Конечно, эту же информацию можно получить и из Проводника (правая кнопка мыши -> Свойства ->Вкладка "Версия"), но это долго и не очень удобно, если нужно просмотреть описание многих файлов.

Судя по всему, описания файлов довольно полные, а не попробовать ли нам поискать что-нибудь на лицензионную тему, по подстроке поиска, скажем, "lic"? Сказано - сделано! А вот и старый знакомый

Описание свойств saglic.dll:

Код (Text):
  1.  
  2. Software AG Version Information for .\saglic.dll
  3.     Company            - Software AG
  4.     Description        - Software AG Licensing Services API
  5.     Product Version    - 1.4.0
  6.     Internal Name      - SAGLIC DLL
  7.     Copyright          - (C) Copyright Software AG 1995-2003. All rights reserved.
  8.     Product Name       - saglic
  9.     Patch Level        - 10
  10.     Build Number       - 1
  11.     Release            - Release
  12.     File OS            - Windows 32-Bit
  13.     File Type          - Dynamic Link Library
  14. Windows Numeric Version Info for .\saglic.dll
  15.     File Version       - 1.4.0.10
  16.     Product Version    - 1.4.0.10
  17. Windows String Version Info for .\saglic.dll
  18.     Comments           - Public-use DLL  
  19.     Company Name       - Software AG
  20.     File Description   - Software AG Licensing Services API
  21.     File Version       - 1.4.0.10
  22.     Internal Name      - SAGLIC DLL
  23.     Legal Copyright    - (C) Copyright Software AG 1995-2003. All rights reserved.
  24.     Original Filename  - saglic.dll
  25.     Product Name       - License System
  26.     Product Version    - 1.4.0
  27.     Special Build      - PUBLIC

(То же самое можно получить, набрав в командной строке sagver saglic.dll)

Итак, с sagver.exe более-менее понятно - эта утилита вытаскивает описание свойств заданного файла, а если файл не задан - сканирует библиотеку и выдает описание всех содержащихся в ней файлов. Правда, нужно отметить, что "подсунув" этой утилите "чужой" файл, мы разочаруемся - утилита не выдаст никакой информации. Фокус в том, что она (утилита) проверяет содержимое "подопытного" файла на присутствие определенной сигнатуры (или по образному выражению разработчиков SAG "EyeCatch"), которая является началом структуры, содержащей служебную информацию о файле (т.е. описание его свойств). Маленькая подсказка для любознательных - утилита sagver.exe тоже может вывести отладочную информацию, если ее хорошо попросить - например, создать переменную окружения SVRLOG со значением 0xFFFF.

Однако, помимо уже знакомой нам saglic.dll, мы наткнемся и на saglicExeWrapper.exe, тоже относящуюся к License System. А это что за чудо-утилита?

saglicExeWrapper.exe

Еще раз отдадим должное разработчикам SAG - название говорит само за себя! Эта утилита - обертка вокруг saglic.dll, в которой собраны все функции, связанные с системой лицензирования.

Попробуем ее выполнить без параметров.

Синтаксис вызова saglicExeWrapper.exe:

Код (Text):
  1.  
  2. PRODUCT NAME: saglicExeWrapper (SAGLIC EXE)
  3.               (C) Copyright Software AG 1995-2003. All rights reserved.
  4. DESCRIPTION:  Software AG Licensing Services API
  5. VERSION:      1.4.0
  6. PATCH LEVEL:  10
  7. BUILD TYPE:   PUBLIC
  8.  
  9. USAGE:
  10.  
  11.     saglicExeWrapper.exe 0
  12.            List LICLOG &lt;trace_level&gt; options
  13.  
  14.     saglicExeWrapper.exe 1 &lt;xmlfile_in&gt; &lt;component&gt; &lt;parameter&gt; [&lt;trace_level&gt;]
  15.            LIC_read_parameter() called with the middle 3 parameters
  16.  
  17.     saglicExeWrapper.exe 2 &lt;xmlfile_in&gt; &lt;xmlfile_out&gt; [&lt;trace_level&gt;]
  18.            LIC_genSignature() called with the middle 2 parameters
  19.  
  20.     saglicExeWrapper.exe 3 &lt;xmlfile_in&gt; [&lt;trace_level&gt;]
  21.            LIC_checkSignature() called with the middle parameter
  22.  
  23.     saglicExeWrapper.exe 4 &lt;xmlfile_in&gt; &lt;component&gt; [&lt;trace_level&gt;]
  24.            LIC_checkExpiration() called with the middle 2 parameters
  25.  
  26.     saglicExeWrapper.exe 5 &lt;xmlfile_in&gt; &lt;component&gt; [&lt;trace_level&gt;]
  27.            LIC_checkOS() called with the middle 2 parameters
  28.  
  29.     saglicExeWrapper.exe 6 [&lt;trace_level&gt;]
  30.            LIC_checkExpiration() called with DIRECT INPUT of an internal
  31.            Trial ('90 Days') License Certificate.  (THIS SHOULD FAIL!)
  32.  
  33.     saglicExeWrapper.exe 7
  34.            LIC_validOS() called with no parameters
  35.  
  36. For example:
  37.  
  38.     saglicExeWrapper.exe 5 ino223.xml TaminoProduct CHECK_OS

Взгляните, перед нами действительно практически все экспортируемые saglic.dll функции!

Думаю, не стоит повторяться с описанием параметров вызова saglicExeWrapper.exe - посмотрите описание экспортируемых функций saglic.dll, все то же самое. Единственное, на что хотелось бы обратить ваше внимание, на необязательный параметр trace_level.

Понятно, что он как-то связан с уровнем трассировки, используемым функциями saglic.dll, но как? Может быть, утилита нам сама подскажет?

Выполняем saglicExeWrapper.exe 0 /?.

Код (Text):
  1.  
  2. LICLOG  &lt;trace_level&gt; DESCRIPTION
  3. ---------------------------------------------------------
  4. 0x0001  ERR           Trace error conditions
  5. 0x0002  EXT           Trace external LIC API functions
  6. 0x0004  INT           Trace internal LIC functions
  7. 0x0008  DBG           Trace debugging info
  8. 0x0010  CHECK_OS      LIC_checkOS function only
  9. 0x0020  CHECK_EXP     LIC_checkExpiration function only
  10. 0x0040  READ_PARM     LIC_read_parameter function only
  11. 0x0080  CHECK_SIG     LIC_checkSignature function only
  12. 0x0100  GEN_SIG       LIC_genSignature function only
  13. 0x0200  FREE_PARM     LIC_freeParameter function only
  14. 0x0400  SOCKETS       Socket-related operations only
  15. 0x0800  UTILS         Utility functions only
  16. 0x1000  MD5           MD5 (Message Digest) functions only
  17. 0x2000  UNUSED        UNUSED
  18. 0x4000  LOG           Trace LOG functions only
  19. 0x8000  LOG_FILE      LOG to a local file in TMP directory
  20. 0x03f0  HIGH_LEVEL    High Level (LIC) functions only
  21. 0x1c00  LOW_LEVEL     Low Level operations only
  22. 0xffff  LOG_ALL       Log ALL Trace Levels
  23.  
  24. Trace Level(s) may be set using TWO different methods:
  25.  
  26. 1. Via the LICLOG environment variable when set to the SUM of
  27.    the appropriate HEX value(s) shown above.  For example, to
  28.    trace the LIC_checkOS() and LIC_read_parameter() functions,
  29.    set LICLOG = (0x0008 + 0x0010 + 0x0040) = 0x0058
  30.    (Set LICLOG directly to trace LIC functions called directly
  31.    from applications such as Tamino.)
  32.  
  33. 2. Via the optional <trace_level> argument in this executable
  34.  
  35.    Example 1:  saglicExeWrapper 5 ino223.xml TaminoProduct
  36.                                 CHECK_OS READ_PARM
  37.  
  38.    traces the LIC_checkOS() and LIC_read_parameter() functions.
  39.  
  40.    Example 2:  saglicExeWrapper 5 ino223.xml TaminoProduct
  41.                                 CHECK_OS LOG_FILE
  42.  
  43.    will send LIC_checkOS() Trace output to a temporary file.

Хорошо, и что со всем этим "добром" делать?

Первое, что идет на ум, все же попробовать saglicExeWrapper.exe с параметром 2 ( LIC_genSignature() ). Понятно, что в saglic.dll эта функция "недореализована", но вдруг эта реализация есть в saglicExeWrapper.exe?

Итак: saglicExeWrapper.exe 2 ino414.xml test.xml

Похоже, чудо не случилось.

Код (Text):
  1.  
  2. LIC_genSignature()...
  3.  
  4. License File (IN)  = ino414.xml
  5. License File (OUT) = test.xml
  6.  
  7. 13:  ERROR - CANNOT CREATE LICENSE USING EXTERNAL LIC VERSION

Так, а что если попробовать saglicExeWrapper.exe с параметром 3 ( LIC_checkSignature() )? Да не просто так, а с полной трассировкой, авось что-нибудь выудим!

saglicExeWrapper.exe 3 ino414.xml LOG_ALL
(LOG_ALL - именно в верхнем регистре)

После долгого мелькания отладочной информации должны получить нечто вроде такого

Код (Text):
  1.  
  2. MD5_memcpy():
  3. {
  4. Encode():
  5. {
  6. MD5_memset():
  7. {
  8. SAG_certification():
  9.    aSig[0] = A7
  10. SAG_certification():
  11.    aSig[1] = B7
  12. SAG_certification():
  13.    aSig[2] = 7D
  14. SAG_certification():
  15.    aSig[3] = 8C
  16. SAG_certification():
  17.    aSig[4] = C2
  18. SAG_certification():
  19.    aSig[5] = B4
  20. SAG_certification():
  21.    aSig[6] = 6E
  22. SAG_certification():
  23.    aSig[7] = 9C
  24. SAG_certification():
  25.    aSig[8] = 58
  26. SAG_certification():
  27.    aSig[9] = 21
  28. SAG_certification():
  29.    aSig[10] = DE
  30. SAG_certification():
  31.    aSig[11] = C4
  32. SAG_certification():
  33.    aSig[12] = 1B
  34. SAG_certification():
  35.    aSig[13] = 9B
  36. SAG_certification():
  37.    aSig[14] = 9C
  38. SAG_certification():
  39.    aSig[15] = E0
  40. SAG_certification():
  41. returned 0
  42. SAG_certification():
  43. }
  44. LIC_checkSignature():
  45. returned 0
  46. LIC_checkSignature():
  47. }
  48.  
  49.    0:  LICENSE OK

Смотрите, а ведь последовательность A7B77D8CC2B46E9C5821DEC41B9B9CE0 не что иное, как нашего файла лицензии! Как минимум, любопытно…

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

Почему бы не попробовать модифицировать файл лицензии и посмотреть, изменится ли эта последовательность! Что ж, попробуем… Подкорректируем дату регистрации (2006/01/01), сохраним его с именем _ino414.xml и "натравим" на него saglicExeWrapper.exe

saglicExeWrapper.exe 3 _ino414.xml LOG_ALL

Код (Text):
  1.  
  2. MD5_memcpy():
  3. {
  4. Encode():
  5. {
  6. MD5_memset():
  7. {
  8. SAG_certification():
  9.    aSig[0] = 9E
  10. SAG_certification():
  11.    aSig[1] = 1F
  12. SAG_certification():
  13.    aSig[2] = 58
  14. SAG_certification():
  15.    aSig[3] = B4
  16. SAG_certification():
  17.    aSig[4] = FB
  18. SAG_certification():
  19.    aSig[5] = 3B
  20. SAG_certification():
  21.    aSig[6] = D7
  22. SAG_certification():
  23.    aSig[7] = 1D
  24. SAG_certification():
  25.    aSig[8] = D6
  26. SAG_certification():
  27.    aSig[9] = 73
  28. SAG_certification():
  29.    aSig[10] = 14
  30. SAG_certification():
  31.    aSig[11] = 3B
  32. SAG_certification():
  33.    aSig[12] = 91
  34. SAG_certification():
  35.    aSig[13] = D
  36. SAG_certification():
  37.    aSig[14] = 99
  38. SAG_certification():
  39.    aSig[15] = 18
  40. SAG_certification():
  41. returned 0
  42. SAG_certification():
  43. }
  44. LIC_checkSignature():
  45. returned 3
  46. LIC_checkSignature():
  47. }
  48.  
  49.    3:  ERROR - INVALID (TAMPERED) LICENSE KEY

Однако, последовательность совсем другая! Может быть, это как раз то хэш-значение, с которым и сравнивается LicenseKey из файла лицензии? Если наши рассуждения верны, и это и есть "правильный" LicenseKey , то поставив заветную последовательность (не забывая про ведущий нолик для значений aSig[], меньших 0x10) в поле LicenseKey файла _ino414.xml, мы должны бы получить "0: LICENSE OK"

Пробуем!

Результат выполнения saglicExeWrapper.exe с параметром 3 (LIC_checkSignature):

Код (Text):
  1.  
  2. MD5_memcpy():
  3. {
  4. Encode():
  5. {
  6. MD5_memset():
  7. {
  8. SAG_certification():
  9.    aSig[0] = 9E
  10. SAG_certification():
  11.    aSig[1] = 1F
  12. SAG_certification():
  13.    aSig[2] = 58
  14. SAG_certification():
  15.    aSig[3] = B4
  16. SAG_certification():
  17.    aSig[4] = FB
  18. SAG_certification():
  19.    aSig[5] = 3B
  20. SAG_certification():
  21.    aSig[6] = D7
  22. SAG_certification():
  23.    aSig[7] = 1D
  24. SAG_certification():
  25.    aSig[8] = D6
  26. SAG_certification():
  27.    aSig[9] = 73
  28. SAG_certification():
  29.    aSig[10] = 14
  30. SAG_certification():
  31.    aSig[11] = 3B
  32. SAG_certification():
  33.    aSig[12] = 91
  34. SAG_certification():
  35.    aSig[13] = D
  36. SAG_certification():
  37.    aSig[14] = 99
  38. SAG_certification():
  39.    aSig[15] = 18
  40. SAG_certification():
  41. returned 0
  42. SAG_certification():
  43. }
  44. LIC_checkSignature():
  45. returned 0
  46. LIC_checkSignature():
  47. }
  48.  
  49.    0:  LICENSE OK

Ого! Работает!!!

Что ж, осталось собрать полученную информацию об "особенностях системы лицензирования" воедино.

Чтобы получить корректный файл лицензии после его модификации необходимо:

  1. Убедиться, что наша ОС соответствует тому, что задано в файле лицензии. Для этого используем утилиту saglicExeWrapper.exe

    saglicExeWrapper.exe 7

    Если в файле лицензии нет ни одного из предложенных значений ОС - правим значение поля "OS" файла лицензии в соответствии с "рекомендациями" saglicExeWrapper.exe . Напомню, что самым общим является значение "any", менее общим для семейства Windows - "win". Это менее корректный вариант, но в этом случае необходимости использовать утилиту saglicExeWrapper.exe нет.

  2. Убедиться, что срок действия лицензии не истек. Если есть необходимость, правим значение поля "ExpirationDate". Напомню, здесь допустимо значение "Unlimited"
  3. Рассчитать новое значение LicenseKey, используя saglicExeWrapper.exe в режиме трассировки (достаточно уровня GEN_SIG)
saglicExeWrapper.exe 3 lic_file.xml GEN_SIG 4. Полученную последовательность занести в поле "LicenseKey" файла лицензии (не забывая про ведущий ноль!) и проверить на отсутствие ошибок. saglicExeWrapper.exe 3 lic_file.xml

В принципе, должно работать. Если получаете ошибку "3: ERROR - INVALID (TAMPERED) LICENSE KEY", проверьте еще разок, правильно ли переписали значение LicenseKey.

На эту процедуру у вас едва ли уйдет более 2 минут. Причем, заметьте, результат получается исключительно благодаря своей голове и замечательному подарку от компании Software AG в виде утилиты saglicExeWrapper.exe

Хорошо, а что делать, если вы устанавливаете самый первый продукт SAG (т.е. у вас нет ни папки %CommonProgramFiles%\Software AG, ни saglicExeWrapper.exe), а вам очень нужно "поправить" файл лицензии до инсталляции (например, вам нужно установить компонент, не входящий в демо-лицензию)? Проще всего найти на установочном диске папку Windows\BTY, а в ней - файл data1.cab. Нужно извлечь из этого архива 2 файла saglic.dll и saglicExeWrapper.exe (в архиве они находятся в весьма неприглядном виде, например, saglic.dll.44FFEB35_100E_11D6_A6C8_00300501EF6A, поэтому после извлечения переименуйте их так, как положено). Извлечь можно WinRar'ом, либо любым другим упаковщиком, понимающим формат .cab. В эту же папку скопируйте свой лицензионный файл и дальше действуйте по общей схеме.

Заключение

Вот некоторые замечания, которые пришли мне на ум, когда я разбирался с пресловутой "системой лицензирования":

  1. Как отмечалось выше, отсутствие защитных механизмов в системе лицензирования продуктов компании Software AG не делает им чести. И использование MD5- алгоритма сильно ситуацию не исправляет - как вы видите, вполне можно обойтись и без знания тонкостей хэширования, чтобы делать с лицензионным файлом все, что душа пожелает. Но если разработчики считают, что закон их оберегает надежнее, чем они сами себя - что ж, это их право.
  2. Возможность трассировки - штука несомненно полезная, но только не в системе защиты/лицензирования! По крайней мере, это просто не очень разумно.
  3. Наличие утилит для внутреннего служебного пользования (к которым без всякого сомнения относятся sagver.exe и saglicExeWrapper.exe) в дистрибутиве вообще не поддается разумному объяснению! Причем эти утилиты помещаются в дистрибутивы большинства продуктов SAGа из версии к версии…

Выявленные изъяны не стали неожиданностью для разработчиков Software AG. Остается только понадеется, что следующие версии продуктов Software AG станут более защищенными.

1 В настоящее время готовится к публикации описание p-кода, используемого в NATURAL (будем надеяться, что автор выполнит это обещание - прим.ред.).

2 Полный адрес http://tamino.forums.softwareag.com/download.php?id=774&sid=96bcb784da946a6dec504a291d84801d (для зарегистрированных пользователей). © Konstantin


0 1.077
archive

archive
New Member

Регистрация:
27 фев 2017
Публикаций:
532