mirror of
https://github.com/Obfuscator-Collections/VMProtect.git
synced 2025-08-03 07:50:10 +03:00
first commit
Version 3.x.x
This commit is contained in:
312
help/ru/manager/usage/api.htm
Normal file
312
help/ru/manager/usage/api.htm
Normal file
@@ -0,0 +1,312 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<link rel="Stylesheet" type="text/css" href=
|
||||
"../../default.css" />
|
||||
<meta http-equiv="Content-Type" content=
|
||||
"text/html; charset=utf-8" />
|
||||
|
||||
<title>Описание функций API лицензирования</title>
|
||||
<style type="text/css">
|
||||
/*<![CDATA[*/
|
||||
th {text-align:left;}
|
||||
table {border-collapse:collapse; margin-top: 4px;}
|
||||
td,th {border: 1px solid #B0B0B0; padding-left:10;padding-right:10;}
|
||||
/*]]>*/
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Описание функций API лицензирования</h1>
|
||||
|
||||
<p>API системы лицензирования является продолжением API VMProtect
|
||||
и входит в его SDK. API позволяет задать серийный номер и
|
||||
получить информацию о нем: подходит он к программе или нет, истек
|
||||
ли срок действия, на кого зарегистрирован продукт и т.п. Также API
|
||||
позволяет получить идентификатор оборудования, на котором
|
||||
выполняется программа.</p><strong id=
|
||||
"VMProtectSetSerialNumber">VMProtectSetSerialNumber</strong>
|
||||
|
||||
<p>Функция предназначена для загрузки серийного номера в систему
|
||||
лицензирования. Полный формат вызова представлен ниже:</p>
|
||||
<pre class="code">int VMProtectSetSerialNumber(const char *SerialNumber);
|
||||
</pre>
|
||||
|
||||
<p>Входной параметр <strong>SerialNumber</strong> должен
|
||||
содержать указатель на текстовую строку с серийным номером в
|
||||
кодировке base-64 и завершаемую нулем ('\0'). Функция возвращает
|
||||
битовую маску флагов состояния серийного номера, аналогичную той,
|
||||
что возвращает <strong>VMProtectGetSerialNumberState()</strong>,
|
||||
подробнее о флагах будет написано ниже. Серийный номер считается
|
||||
"хорошим", если функция вернула значение 0.</p><br />
|
||||
<strong id=
|
||||
"VMProtectGetSerialNumberState">VMProtectGetSerialNumberState</strong>
|
||||
|
||||
<p>Функция возвращает флаги состояния серийного номера,
|
||||
предварительно установленного вызовом
|
||||
<strong>VMProtectSetSerialNumber()</strong>.</p>
|
||||
<pre class="code">int VMProtectGetSerialNumberState();
|
||||
</pre>
|
||||
|
||||
<p>Наличие хотя бы одного установленного флага говорит о
|
||||
проблемах с серийным номером: программа не должна работать, если
|
||||
установлен хотя бы один бит. Подробные значениях флагов описаны в
|
||||
таблице:</p>
|
||||
|
||||
<table border="1" cellspacing="0" cellpadding="2">
|
||||
<tr>
|
||||
<th>Флаг</th>
|
||||
|
||||
<th>Значение</th>
|
||||
|
||||
<th>Описание</th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>SERIAL_STATE_FLAG_CORRUPTED</td>
|
||||
|
||||
<td>0x00000001</td>
|
||||
|
||||
<td>Система лицензирования повреждена. Возможные причины:
|
||||
некорректная настройка проекта защиты, попытка взлома
|
||||
программы.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>SERIAL_STATE_FLAG_INVALID</td>
|
||||
|
||||
<td>0x00000002</td>
|
||||
|
||||
<td>Серийный номер некорректен. Флаг выставляется, если
|
||||
система лицензирования не может расшифровать серийный
|
||||
номер.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>SERIAL_STATE_FLAG_BLACKLISTED</td>
|
||||
|
||||
<td>0x00000004</td>
|
||||
|
||||
<td>Серийный номер подходит к продукту, однако занесен в
|
||||
черный список в VMProtect.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>SERIAL_STATE_FLAG_DATE_EXPIRED</td>
|
||||
|
||||
<td>0x00000008</td>
|
||||
|
||||
<td>Срок действия серийного номера истек. Подробную
|
||||
информацию о сроке действия можно получить вызовом
|
||||
<strong>VMProtectGetSerialNumberData()</strong></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>SERIAL_STATE_FLAG_RUNNING_TIME_OVER</td>
|
||||
|
||||
<td>0x00000010</td>
|
||||
|
||||
<td>Время работы программы истекло. Подробную информацию о
|
||||
времени работы программы можно получить вызовом
|
||||
<strong>VMProtectGetSerialNumberData()</strong></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>SERIAL_STATE_FLAG_BAD_HWID</td>
|
||||
|
||||
<td>0x00000020</td>
|
||||
|
||||
<td>Идентификатор оборудования не совпадает с тем, что
|
||||
записан в серийном номере.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>SERIAL_STATE_FLAG_MAX_BUILD_EXPIRED</td>
|
||||
|
||||
<td>0x00000040</td>
|
||||
|
||||
<td>Серийный номер не предназначен для работы с этой версией
|
||||
защищаемой программы. Максимальную дату сборки программы, к
|
||||
которой подходит этот серийный номер, можно узнать вызовом
|
||||
<strong>VMProtectGetSerialNumberData()</strong>.</td>
|
||||
</tr>
|
||||
</table><br /><br />
|
||||
<strong id=
|
||||
"VMProtectGetSerialNumberData">VMProtectGetSerialNumberData</strong>
|
||||
|
||||
<p>Функция предназначена для получения информации о содержимом
|
||||
серийного номера, установленного вызовом
|
||||
<strong>VMProtectSetSerialNumber()</strong>. Формат вызова
|
||||
представлен ниже:</p>
|
||||
<pre class="code">bool VMProtectGetSerialNumberData(VMProtectSerialNumberData *Data, int Size);
|
||||
</pre>
|
||||
|
||||
<p>Первый параметр - указатель на структуру
|
||||
<strong>VMProtectSerialNumberData</strong>, в которую будет
|
||||
записана вся необходимая информация. Второй параметр - размер
|
||||
структуры, передаваемой в первом параметре - служит для контроля
|
||||
формата структуры. Функция возвращает FALSE в случаях, если система
|
||||
лицензирования повреждена (см. флаг состояния
|
||||
SERIAL_STATE_FLAG_CORRUPTED), если на вход подан нулевой адрес
|
||||
структуры или если переданный размер структуры некорректен. Во
|
||||
всех остальных случаях функция возвращает TRUE и записывает всю
|
||||
информацию о серийном номере по указанном адресу. Ниже
|
||||
описываются все элементы структуры:</p>
|
||||
|
||||
<table border="1" cellspacing="0" cellpadding="2">
|
||||
<tr>
|
||||
<th>Элемент</th>
|
||||
|
||||
<th>Тип</th>
|
||||
|
||||
<th>Описание</th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>nState</td>
|
||||
|
||||
<td>int</td>
|
||||
|
||||
<td>Битовая маска флагов проверки ключа. Аналогична той, что
|
||||
возвращает
|
||||
<strong>VMProtectGetSerialNumberState()</strong>.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>wUserName</td>
|
||||
|
||||
<td>wchar_t[256]</td>
|
||||
|
||||
<td>Имя покупателя в кодировке UNICODE, завершаемое
|
||||
нулем.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>wEMail</td>
|
||||
|
||||
<td>wchar_t[256]</td>
|
||||
|
||||
<td>E-Mail покупателя в кодировке UNICODE, завершаемый
|
||||
нулем.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>dtExpire</td>
|
||||
|
||||
<td>VMProtectDate</td>
|
||||
|
||||
<td>Дата окончания срока действия ключа. Формат структуры
|
||||
VMProtectDate описан ниже.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>dtMaxBuild</td>
|
||||
|
||||
<td>VMProtectDate</td>
|
||||
|
||||
<td>Максимальная дата сборки продукта, с которой будет
|
||||
работать этот ключ. Формат структуры VMProtectDate описан
|
||||
ниже.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>bRunningTime</td>
|
||||
|
||||
<td>int</td>
|
||||
|
||||
<td>Количество минут, которое программа будет работать
|
||||
(максимальная длина сессии). Измеряется в минутах,
|
||||
отсчитывается с момента запуска программы.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>nUserDataLength</td>
|
||||
|
||||
<td>unsigned char</td>
|
||||
|
||||
<td>Длина пользовательских данных, размещенных в поле
|
||||
<strong>bUserData</strong>.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>bUserData</td>
|
||||
|
||||
<td>unsigned char[255]</td>
|
||||
|
||||
<td>Пользовательские данные, записанные в ключ. Количество
|
||||
актуальных байт указано в поле
|
||||
<strong>nUserDataLength</strong>.</td>
|
||||
</tr>
|
||||
</table><br />
|
||||
|
||||
<p>Структура <strong>VMProtectDate</strong> предназначена для
|
||||
компактного хранения даты. Ее поля описаны в таблице:</p>
|
||||
|
||||
<table border="1" cellspacing="0" cellpadding="2">
|
||||
<tr>
|
||||
<th>Элемент</th>
|
||||
|
||||
<th>Тип</th>
|
||||
|
||||
<th>Описание</th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>wYear</td>
|
||||
|
||||
<td>unsigned short</td>
|
||||
|
||||
<td>Год.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>bMonth</td>
|
||||
|
||||
<td>unsigned char</td>
|
||||
|
||||
<td>Месяц, нумерация начинается с единицы.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>bDay</td>
|
||||
|
||||
<td>unsigned char</td>
|
||||
|
||||
<td>День, нумерация начинается с единицы.</td>
|
||||
</tr>
|
||||
</table><br />
|
||||
<br />
|
||||
<strong id=
|
||||
"VMProtectGetCurrentHWID">VMProtectGetCurrentHWID</strong>
|
||||
|
||||
<p>Функция предназначена для получения идентификатора
|
||||
оборудования, на котором работает программа. Формат вызова
|
||||
следующий:</p>
|
||||
<pre class="code">int VMProtectGetCurrentHWID(char * HWID, int Size);
|
||||
</pre>
|
||||
|
||||
<p>Первый параметр - указатель на область памяти, куда будет
|
||||
записан идентификатор. Второй параметр - размер области данных.
|
||||
Функция возвращает количество записанных байт с учетом
|
||||
завершающего нуля ('\0'). Если вместо первого параметра подать
|
||||
NULL, то функция вернет необходимое количество байт для записи
|
||||
номера. Наиболее правильный способ вызова функции следующий:</p>
|
||||
<pre class="code"><strong>int</strong> nSize = <strong>VMProtectGetCurrentHWID</strong>(NULL, 0); // получим необходимый размер буфера
|
||||
<strong>char *</strong>pBuf = <strong>new char</strong>[nSize]; // выделим буфер
|
||||
<strong>VMProtectGetCurrentHWID</strong>(pBuf, nSize); // получим идентификатор
|
||||
// используем его
|
||||
<strong>delete</strong> [] pBuf; // освободим память
|
||||
</pre><br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<hr noshade="noshade" size="1" />
|
||||
|
||||
<div align="center">
|
||||
© 2006-2015 Copyright VMProtect Software
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
127
help/ru/manager/usage/index.htm
Normal file
127
help/ru/manager/usage/index.htm
Normal file
@@ -0,0 +1,127 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<link rel="Stylesheet" type="text/css" href=
|
||||
"../../default.css" />
|
||||
<meta http-equiv="Content-Type" content=
|
||||
"text/html; charset=utf-8" />
|
||||
|
||||
<title>Интеграция в приложение</title>
|
||||
<style type="text/css">
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Интеграция в приложение</h1>
|
||||
|
||||
<p>В нескольких шагах, описанных ниже, мы создадим тестовое
|
||||
приложение, которое будет обращаться к системе лицензирования:
|
||||
подавать ей серийные номера и получать статус номера и его
|
||||
содержимое. На первом этапе система лицензирования будет
|
||||
использоваться в тестовом режиме, а на втором этапе - в
|
||||
реальном.</p><strong>Режимы работы системы
|
||||
лицензирования</strong>
|
||||
|
||||
<p>В создании защиты всегда есть два этапа: разработка и
|
||||
использование. В случае с лицензированием, вы сначала создаете
|
||||
приложение, потом интегрируете механизмы защиты, добавляете
|
||||
проверки и блокируете функции. И только потом, после
|
||||
всестороннего тестирования, продукт передается пользователям и
|
||||
начинается второй этап. Тестирование защищаемого приложения -
|
||||
процесс сложный, необходимо убедиться в работоспособности всех
|
||||
проверок и условных переходов. Создание "настоящих" серийных
|
||||
номеров на все случаи жизни на этапе тестирования может оказаться
|
||||
неудобным, поэтому у системы лицензирования есть т.н. "режим
|
||||
разработки" или "тестовый" режим, при котором никакой защиты не
|
||||
осуществляется, а реакция системы на серийные номера описывается
|
||||
в конфигурационном файле. Когда приложение отлажено и корректно
|
||||
работает с системой лицензирования, VMProtect заменяет "тестовый"
|
||||
модуль лицензирования на реальный, проверяющий реальные серийные
|
||||
номера. Это происходит в момент защиты приложения, поэтому
|
||||
пропустить этот этап по ошибке не получится.</p><strong id="TestMode">Этап 1:
|
||||
Тестовый режим работы</strong>
|
||||
|
||||
<p>В тестовом режиме реакция системы лицензирования на серийные
|
||||
номера, все возвращаемые статусы и данные описываются в
|
||||
конфигурационном файле. Файл называется VMPLicense.ini и должен
|
||||
располагаться в рабочем каталоге приложения. В 10 шагах,
|
||||
представленных ниже, мы пройдем от создания простейшего
|
||||
приложения до полноценного использования системы лицензирования в
|
||||
тестовом режиме с привязкой к оборудованию и ограничением срока
|
||||
бесплатных обновлений.</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="step11_app.htm">Шаг 1.1: Создаем защищаемое
|
||||
приложение</a></li>
|
||||
|
||||
<li><a href="step12_code.htm">Шаг 1.2: Добавляем код проверки
|
||||
лицензии</a></li>
|
||||
|
||||
<li><a href="step13_flags.htm">Шаг 1.3: Получаем флаги состояния
|
||||
номера</a></li>
|
||||
|
||||
<li><a href="step14_name.htm">Шаг 1.4: Получаем имя и e-mail
|
||||
пользователя</a></li>
|
||||
|
||||
<li><a href="step15_exp.htm">Шаг 1.5: Проверяем срок действия
|
||||
номера</a></li>
|
||||
|
||||
<li><a href="step16_time.htm">Шаг 1.6: Ограничиваем время работы
|
||||
программы</a></li>
|
||||
|
||||
<li><a href="step17_maxbuild.htm">Шаг 1.7: Ограничиваем
|
||||
бесплатные обновления</a></li>
|
||||
|
||||
<li><a href="step18_blacklist.htm">Шаг 1.8: Номера из "черного
|
||||
списка"</a></li>
|
||||
|
||||
<li><a href="step19_hwid.htm">Шаг 1.9: Привязка к
|
||||
оборудованию</a></li>
|
||||
|
||||
<li><a href="step1A_userdata.htm">Шаг 1.10: Пользовательские
|
||||
данные</a></li>
|
||||
</ul><strong id="RealMode">Этап 2: Реальный режим работы</strong>
|
||||
|
||||
<p>В реальном режиме работы системы лицензирования VMProtect
|
||||
помещает в защищаемое приложение специальный модуль
|
||||
лицензирования. Модуль выполняет все те же функции, что и
|
||||
тестовый код в SDK, но работает не с ini-файлом, а с содержимым
|
||||
серийного номера. В следующих пяти шагах мы защитим простое
|
||||
приложение полноценной защитой на основе VMProtect и системы
|
||||
лицензирования.</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="step21_src.htm">Шаг 2.1: Создаем новое защищаемое
|
||||
приложение</a></li>
|
||||
|
||||
<li><a href="step22_vmp.htm">Шаг 2.2: Создаем проект защиты в
|
||||
VMProtect</a></li>
|
||||
|
||||
<li><a href="step23_product.htm">Шаг 2.3: Первый запуск
|
||||
защищенного продукта</a></li>
|
||||
|
||||
<li><a href="step24_test.htm">Шаг 2.4: Тестируем
|
||||
результат</a></li>
|
||||
|
||||
<li><a href="step25_codelock.htm">Шаг 2.5: Привязываем код к
|
||||
серийному номеру</a></li>
|
||||
</ul><strong>Дополнительная информация</strong>
|
||||
|
||||
<p>Значения всех битовых флагов, форматы структур и параметры
|
||||
вызова функций можно посмотреть в разделе <a href="api.htm">API
|
||||
системы лицензирования</a>. Этот раздел удобно использовать как
|
||||
справочник, тогда как шаги, описанные выше, позволяют легко
|
||||
реализовать готовые типовые схемы защиты.</p><br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<hr noshade="noshade" size="1" />
|
||||
|
||||
<div align="center">
|
||||
© 2006-2015 Copyright VMProtect Software
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
62
help/ru/manager/usage/step11_app.htm
Normal file
62
help/ru/manager/usage/step11_app.htm
Normal file
@@ -0,0 +1,62 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<link rel="Stylesheet" type="text/css" href=
|
||||
"../../default.css" />
|
||||
<meta http-equiv="Content-Type" content=
|
||||
"text/html; charset=utf-8" />
|
||||
|
||||
<title>Шаг 1.1: Создаем защищаемое приложение</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Шаг 1.1: Создаем защищаемое приложение</h1>
|
||||
|
||||
<p>Первым шагом будет создание приложения. Это будет простое
|
||||
приложение, без интерфейса пользователя и каких-либо серьезных
|
||||
возможностей. Нашей задачей будет передать системе лицензирования
|
||||
серийный номер и получить от нее ответ.</p>
|
||||
<pre class="code">#include <windows.h>
|
||||
#include <stdio.h>
|
||||
|
||||
bool is_registered(const char *serial)
|
||||
{
|
||||
return serial && serial[0] == 'X';
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *serial = "Xserialnumber"; // зададим номер непосредственно в коде для простоты
|
||||
if (!is_registered(serial))
|
||||
{
|
||||
printf("please register!\n");
|
||||
return 0;
|
||||
}
|
||||
printf("We are registered.\n");
|
||||
return 0;
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>Программа реализует очень простую схему проверки серийного
|
||||
номера. Функция <strong>is_registered()</strong> сравнивает
|
||||
первую букву номера с 'Х' и считает номер корректным в случае
|
||||
совпадения. Для некорректного номера выдается просьба о
|
||||
регистрации, а в случае правильного номера выводится сообщение
|
||||
"We are registered."</p>
|
||||
|
||||
<p><a href="step12_code.htm">Следующим шагом</a> будет добавление
|
||||
кода проверки серийного номера на основе системы лицензирования
|
||||
VMProtect.</p><br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<hr noshade="noshade" size="1" />
|
||||
|
||||
<div align="center">
|
||||
© 2006-2015 Copyright VMProtect Software
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
105
help/ru/manager/usage/step12_code.htm
Normal file
105
help/ru/manager/usage/step12_code.htm
Normal file
@@ -0,0 +1,105 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<link rel="Stylesheet" type="text/css" href=
|
||||
"../../default.css" />
|
||||
<meta http-equiv="Content-Type" content=
|
||||
"text/html; charset=utf-8" />
|
||||
|
||||
<title>Шаг 1.2: Добавляем код проверки лицензии</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Шаг 1.2: Добавляем код проверки лицензии</h1><strong>Подключаем
|
||||
VMProtect SDK</strong>
|
||||
|
||||
<p>Если вы этого еще не сделали, то сейчас самое время подключить
|
||||
к проекту VMProtect SDK. SDK это три файла: заголовочный файл
|
||||
(VMProtectSDK.h), файл библиотеки (VMProtectSDK32.lib) и dll-файл
|
||||
с реализацией (VMProtectSDK32.dll). Для 64-битной платформы есть
|
||||
отдельные реализации библиотеки и dll-файла.</p>
|
||||
|
||||
<p>Помещаем dll-файл в рабочий каталог нашего приложения,
|
||||
файл заголовков и библиотечный файл - рядом с исходниками, включаем
|
||||
файл заголовков в основной файл:</p>
|
||||
<pre class="code">#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include "VMProtectSDK.h"
|
||||
</pre>
|
||||
|
||||
<p>Собираем проект и убеждаемся, что он компилируется, запускается
|
||||
и работает, как и раньше. Система лицензирования пока еще не
|
||||
активна.</p><strong>Подаем серийный номер в систему
|
||||
лицензирования</strong>
|
||||
|
||||
<p>Теперь непосредственно после строки с серийным номером добавим
|
||||
вызов функции SDK системы лицензирования:</p>
|
||||
<pre class="code">char *serial = "Xserialnumber"; // зададим номер непосредственно в коде для простоты
|
||||
int res = VMProtectSetSerialNumber(serial);
|
||||
printf("res = 0x%08X\n", res);
|
||||
</pre>
|
||||
|
||||
<p>Если после этого программа будет завершаться с ошибкой об
|
||||
отсутствии dll-файла, убедитесь, что вы положили соответствующий
|
||||
DLL-файл в рабочий каталог нашего приложения. В случае успешного
|
||||
запуска, вы должны увидеть сообщение:</p>
|
||||
<pre class="code">res = 0x00000002
|
||||
</pre>
|
||||
|
||||
<p>Число 2 соответствует флагу SERIAL_STATE_FLAG_INVALID,
|
||||
<a href="api.htm">описанному в API</a>. Т.е. система
|
||||
лицензирования посчитала наш ключ некорректным, что вполне
|
||||
логично, т.к. мы до сих пор не "объяснили" системе лицензирования,
|
||||
какие ключи считать правильными, а какие - нет.</p><strong>Задаем
|
||||
"правильный" серийный номер</strong>
|
||||
|
||||
<p>В тестовом режиме система лицензирования анализирует файл
|
||||
VMProtectLicense.ini, и реагирует на вызовы функций согласно
|
||||
указанным там настройкам. Подробно файл разбирается в следующих
|
||||
шагах, а здесь мы просто создадим такой файл и поместим туда
|
||||
следующий текст:</p>
|
||||
<pre class="code">[TestLicense]
|
||||
AcceptedSerialNumber=Xserialnumber
|
||||
</pre>
|
||||
|
||||
<p>Запустим нашу программу еще раз. Если вы снова получили код
|
||||
ошибки "2", то убедитесь, что ini-файл находится в рабочем
|
||||
каталоге приложения. В этот раз вы должны получить результат "0".
|
||||
Признак того, что система лицензирования приняла и одобрила
|
||||
серийный номер. Теперь мы можем убрать функцию
|
||||
<strong>is_registered()</strong> - проверкой серийного номера
|
||||
займется система лицензирования:</p>
|
||||
<pre class="code">#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include "VMProtectSDK.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *serial = "Xserialnumber"; // зададим номер непосредственно в коде для простоты
|
||||
|
||||
int res = VMProtectSetSerialNumber(serial);
|
||||
printf("res = 0x%08X\n", res);
|
||||
|
||||
if (res)
|
||||
{
|
||||
printf("please register!\n");
|
||||
return 0;
|
||||
}
|
||||
printf("We are registered.\n");
|
||||
return 0;
|
||||
}
|
||||
</pre><br />
|
||||
<a href="step13_flags.htm">Следующий шаг</a>
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<hr noshade="noshade" size="1" />
|
||||
|
||||
<div align="center">
|
||||
© 2006-2015 Copyright VMProtect Software
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
96
help/ru/manager/usage/step13_flags.htm
Normal file
96
help/ru/manager/usage/step13_flags.htm
Normal file
@@ -0,0 +1,96 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<link rel="Stylesheet" type="text/css" href=
|
||||
"../../default.css" />
|
||||
<meta http-equiv="Content-Type" content=
|
||||
"text/html; charset=utf-8" />
|
||||
|
||||
<title>Шаг 1.3: Получаем флаги состояния серийного номера</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Шаг 1.3: Получаем флаги состояния серийного
|
||||
номера</h1><strong>Удобная функция для печати флагов</strong>
|
||||
|
||||
<p>Первым делом добавим в наш файл одну удобную функцию, которая
|
||||
будет печатать в человеческом виде значения флагов состояния
|
||||
серийного номера. Код функции приведен ниже:</p>
|
||||
<pre class="code">#define PRINT_HELPER(state, flag) if (state & flag) printf("%s ", #flag)
|
||||
void print_state(INT state)
|
||||
{
|
||||
if (state == 0)
|
||||
{
|
||||
printf("state = 0\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("state = ");
|
||||
PRINT_HELPER(state, SERIAL_STATE_FLAG_CORRUPTED);
|
||||
PRINT_HELPER(state, SERIAL_STATE_FLAG_INVALID);
|
||||
PRINT_HELPER(state, SERIAL_STATE_FLAG_BLACKLISTED);
|
||||
PRINT_HELPER(state, SERIAL_STATE_FLAG_DATE_EXPIRED);
|
||||
PRINT_HELPER(state, SERIAL_STATE_FLAG_RUNNING_TIME_OVER);
|
||||
PRINT_HELPER(state, SERIAL_STATE_FLAG_BAD_HWID);
|
||||
PRINT_HELPER(state, SERIAL_STATE_FLAG_MAX_BUILD_EXPIRED);
|
||||
printf("\n");
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>Несмотря на свой размер, функция очень простая - она
|
||||
последовательно проверяет все битовые флаги и печатает те, что
|
||||
присутствуют в переменной состояния. Заменим
|
||||
<strong>printf</strong> после проверки номера на вызов
|
||||
<strong>print_state</strong>, заодно временно поправим серийный
|
||||
номер, который подается в систему лицензирования:</p>
|
||||
<pre class="code">char *serial = "Xserialnumber1"; // зададим номер непосредственно в коде для простоты
|
||||
int res = VMProtectSetSerialNumber(serial);
|
||||
print_state(res);
|
||||
</pre>
|
||||
|
||||
<p>Если запустить эту программу, то на консоль выведется
|
||||
следующее:</p>
|
||||
<pre class="code">state = SERIAL_STATE_FLAG_INVALID
|
||||
please register!
|
||||
</pre>
|
||||
|
||||
<p>Вернем теперь старый серийный номер, убрав "1", и запустим
|
||||
программу еще раз:</p>
|
||||
<pre class="code">state = 0
|
||||
We are registered.
|
||||
</pre>
|
||||
|
||||
<p>Теперь, когда мы можем видеть флаги состояние серийного
|
||||
номера, перейдем к получению флагов и данных из серийного
|
||||
номера.</p><strong>Получение состояния номера</strong>
|
||||
|
||||
<p>Состояние номера можно получить тремя способами: вызвав
|
||||
<strong>VMProtectSetSerialNumber()</strong>, вызвав
|
||||
<strong>VMProtectGetSerialNumberState()</strong> и вызвав
|
||||
<strong>VMProtectGetSerialNumberData()</strong> - флаги состояния
|
||||
будут помещены в одно из полей структуры. Каждый из методов
|
||||
предназначен для использования в разное время. Первая проверка
|
||||
серийного номера происходит непосредственно при его установке. В
|
||||
этот момент нужно отсекать некорректные номера, номера с истекшим
|
||||
сроком действия, номера из черного списка и т.п. Некоторые
|
||||
ограничения - скажем, максимальное время работы продукта или срок
|
||||
действия номера, имеет смысл проверять и в процессе работы
|
||||
программы. Тут оптимально воспользоваться простым и быстрым
|
||||
методом <strong>VMProtectGetSerialNumberState()</strong>, а в
|
||||
случае, если нужно получить подробную информацию о данных в
|
||||
серийном номере, можно использовать более мощную функцию
|
||||
<strong>VMProtectGetSerialNumberData()</strong>.</p><br />
|
||||
<a href="step14_name.htm">Следующий шаг</a>
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<hr noshade="noshade" size="1" />
|
||||
|
||||
<div align="center">
|
||||
© 2006-2015 Copyright VMProtect Software
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
53
help/ru/manager/usage/step14_name.htm
Normal file
53
help/ru/manager/usage/step14_name.htm
Normal file
@@ -0,0 +1,53 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<link rel="Stylesheet" type="text/css" href=
|
||||
"../../default.css" />
|
||||
<meta http-equiv="Content-Type" content=
|
||||
"text/html; charset=utf-8" />
|
||||
|
||||
<title>Шаг 1.4: Получаем имя и e-mail пользователя</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Шаг 1.4: Получаем имя и e-mail пользователя</h1>
|
||||
|
||||
<p>Начнем с простого: получим из серийного номера имя и e-mail
|
||||
пользователя (часто показываются в окне About). Для этого нам
|
||||
придется прописать их в ini-файл. Добавим еще две строчки к нашим
|
||||
двум:</p>
|
||||
<pre class="code">[TestLicense]
|
||||
AcceptedSerialNumber=Xserialnumber
|
||||
UserName=John Doe
|
||||
EMail=john@doe.com
|
||||
</pre>
|
||||
|
||||
<p>А в самой программе, в случае успешной регистрации, добавим
|
||||
получение этих данных и вывод их на экран:</p>
|
||||
<pre class="code">VMProtectSerialNumberData sd = {0};
|
||||
VMProtectGetSerialNumberData(&sd, sizeof(sd));
|
||||
printf("name = %ls,\ne-mail = %ls\n", sd.wUserName, sd.wEMail);
|
||||
</pre>
|
||||
|
||||
<p>Структура содержит данные в UNICODE, поэтому в
|
||||
<strong>printf()</strong> использованы спецификаторы %ls вместо %s.
|
||||
Программа должна вывести на экран текст:</p>
|
||||
<pre class="code">state = 0
|
||||
We are registered.
|
||||
name = John Doe,
|
||||
e-mail = john@doe.com
|
||||
</pre><br />
|
||||
<a href="step15_exp.htm">Следующий шаг</a>
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<hr noshade="noshade" size="1" />
|
||||
|
||||
<div align="center">
|
||||
© 2006-2015 Copyright VMProtect Software
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
59
help/ru/manager/usage/step15_exp.htm
Normal file
59
help/ru/manager/usage/step15_exp.htm
Normal file
@@ -0,0 +1,59 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<link rel="Stylesheet" type="text/css" href=
|
||||
"../../default.css" />
|
||||
<meta http-equiv="Content-Type" content=
|
||||
"text/html; charset=utf-8" />
|
||||
|
||||
<title>Шаг 1.5: Проверяем срок действия серийного номера</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Шаг 1.5: Проверяем срок действия серийного номера</h1>
|
||||
|
||||
<p>Поместите в ini-файл строчку вида ExpDate=YYYYMMDD - например,
|
||||
такую:</p>
|
||||
<pre class="code">ExpDate=20000101
|
||||
</pre>
|
||||
|
||||
<p>Важно, чтобы дата, указанная в строке, уже прошла. Т.е.
|
||||
максимум - вчера. Запустив программу, вы увидите следующее:</p>
|
||||
<pre class="code">state = SERIAL_STATE_FLAG_DATE_EXPIRED
|
||||
please register!
|
||||
</pre>
|
||||
|
||||
<p>Добавим получение дополнительной информации перед выходом с
|
||||
сообщением "please register":</p>
|
||||
<pre class="code">if (res)
|
||||
{
|
||||
VMProtectSerialNumberData sd = {0};
|
||||
VMProtectGetSerialNumberData(&sd, sizeof(sd));
|
||||
printf("exp. date: y = %d, m = %d, d = %d\n", sd.dtExpire.wYear, sd.dtExpire.bMonth, sd.dtExpire.bDay);
|
||||
printf("please register!\n");
|
||||
return 0;
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>Повторный запуск приложения даст нам больше подробностей:</p>
|
||||
<pre class="code">state = SERIAL_STATE_FLAG_DATE_EXPIRED
|
||||
exp. date: y = 2000, m = 1, d = 1
|
||||
please register!
|
||||
</pre>
|
||||
|
||||
<p>Удалите из ini-файла строку ExpDate=..., чтобы она не мешала
|
||||
нам в дальнейшем.</p><br />
|
||||
<a href="step16_time.htm">Следующий шаг</a>
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<hr noshade="noshade" size="1" />
|
||||
|
||||
<div align="center">
|
||||
© 2006-2015 Copyright VMProtect Software
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
79
help/ru/manager/usage/step16_time.htm
Normal file
79
help/ru/manager/usage/step16_time.htm
Normal file
@@ -0,0 +1,79 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<link rel="Stylesheet" type="text/css" href=
|
||||
"../../default.css" />
|
||||
<meta http-equiv="Content-Type" content=
|
||||
"text/html; charset=utf-8" />
|
||||
|
||||
<title>Шаг 1.6: Ограничиваем время работы программы</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Шаг 1.6: Ограничиваем время работы программы</h1>
|
||||
|
||||
<p>Вы можете ограничить время работы программы с момента запуска.
|
||||
Это может быть полезно для демонстрационных целей: выдается
|
||||
полноценный серийный номер, однако программа работает не более
|
||||
пяти минут. Система лицензирования не закрывает такую программу
|
||||
принудительно по истечении указанного времени, а лишь уведомляет
|
||||
об окончании времени выставлением флага состояния. Зададим
|
||||
ограничение времени работы в одну минуту, добавив в ini-файл
|
||||
строчку:</p>
|
||||
<pre class="code">TimeLimit=1
|
||||
</pre>
|
||||
|
||||
<p>Модифицируем программу следующим образом:</p>
|
||||
<pre class="code">int main(int argc, char **argv)
|
||||
{
|
||||
char *serial = "Xserialnumber"; // зададим номер непосредственно в коде для простоты
|
||||
|
||||
int res = VMProtectSetSerialNumber(serial);
|
||||
print_state(res);
|
||||
if (res) return 0;
|
||||
|
||||
VMProtectSerialNumberData sd = {0};
|
||||
VMProtectGetSerialNumberData(&sd, sizeof(sd));
|
||||
printf("I will run for %d minute(s)\n", sd.bRunningTime);
|
||||
print_state(VMProtectGetSerialNumberState());
|
||||
Sleep(60 * 1000 * sd.bRunningTime);
|
||||
printf("After %d minute(s):\n", sd.bRunningTime);
|
||||
print_state(VMProtectGetSerialNumberState());
|
||||
|
||||
return 0;
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>Программа выводит состояние серийного номера в момент старта,
|
||||
потом считывает максимальное время работы, ждет, пока оно пройдет
|
||||
и выводит состояние номера еще раз. Для одной минуты мы получим
|
||||
следующий результат:</p>
|
||||
<pre class="code">state = 0
|
||||
I will run for 1 minute(s)
|
||||
state = 0
|
||||
After 1 minute(s):
|
||||
state = SERIAL_STATE_FLAG_RUNNING_TIME_OVER
|
||||
</pre>
|
||||
|
||||
<p>Защищаемая программа должна анализировать состояние серийного
|
||||
номера с определенной периодичностью и завершить свою работу в
|
||||
случае появления такого флага. Система лицензирования не делает
|
||||
этого автоматически, т.к. программе может требоваться освободить
|
||||
какие-то ресурсы, записать данные в файл и т.д. Также программа
|
||||
может не завершаться по истечении данного времени, а переходить в
|
||||
более ограниченный режим работы. Система лицензирования оставляет
|
||||
эти вопросы на усмотрение разработчика.</p><br />
|
||||
<a href="step17_maxbuild.htm">Следующий шаг</a>
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<hr noshade="noshade" size="1" />
|
||||
|
||||
<div align="center">
|
||||
© 2006-2015 Copyright VMProtect Software
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
85
help/ru/manager/usage/step17_maxbuild.htm
Normal file
85
help/ru/manager/usage/step17_maxbuild.htm
Normal file
@@ -0,0 +1,85 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<link rel="Stylesheet" type="text/css" href=
|
||||
"../../default.css" />
|
||||
<meta http-equiv="Content-Type" content=
|
||||
"text/html; charset=utf-8" />
|
||||
|
||||
<title>Шаг 1.7: Ограничиваем бесплатные обновления</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Шаг 1.7: Ограничиваем бесплатные обновления</h1><strong>Схема
|
||||
работы</strong>
|
||||
|
||||
<p>В момент защиты приложения VMProtect запоминает дату, когда это
|
||||
происходило. Эта дата является для системы лицензирования датой
|
||||
сборки приложения. В серийном номере можно прописать максимальную
|
||||
дату сборки, для которой подойдет этот номер. Таким образом, если
|
||||
при создании ключа Вы пропишете в него текущую дату + 1 год, то
|
||||
ключ подойдет ко всем релизам Вашей программы, которые вы
|
||||
выпустите в течение года. К релизу, выпущенному через год и 1
|
||||
день ключ уже не подойдет и у пользователя будет выбор:
|
||||
пользоваться более старой версией или купить новый ключ, который
|
||||
будет работать еще год.</p><strong>Пробуем на деле</strong>
|
||||
|
||||
<p>Поместите в ini-файл строчку вида MaxBuildDate=YYYYMMDD -
|
||||
например, такую:</p>
|
||||
<pre class="code">MaxBuildDate=20000101
|
||||
</pre>
|
||||
|
||||
<p>В тестовом режиме система лицензирования считает датой сборки
|
||||
сегодняшнее число, поэтому важно, чтобы дата, указанная в строке,
|
||||
уже прошла. Т.е. максимум - вчера. Модифицируйте исходный код
|
||||
функции <strong>main()</strong>, чтобы он выглядел так:</p>
|
||||
<pre class="code">int main(int argc, char **argv)
|
||||
{
|
||||
char *serial = "Xserialnumber"; // зададим номер непосредственно в коде для простоты
|
||||
|
||||
int res = VMProtectSetSerialNumber(serial);
|
||||
print_state(res);
|
||||
|
||||
if (res)
|
||||
{
|
||||
VMProtectSerialNumberData sd = {0};
|
||||
VMProtectGetSerialNumberData(&sd, sizeof(sd));
|
||||
printf("max. build date: y = %d, m = %d, d = %d\n", sd.dtMaxBuild.wYear, sd.dtMaxBuild.bMonth, sd.dtMaxBuild.bDay);
|
||||
printf("please register!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf("I'm registered\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>Тогда при запуске программы вы увидите следующее:</p>
|
||||
<pre class="code">state = SERIAL_STATE_FLAG_MAX_BUILD_EXPIRED
|
||||
max. build date: y = 2000, m = 1, d = 1
|
||||
please register!
|
||||
</pre>
|
||||
|
||||
<p>Заменив в ini-файле дату на сегодняшнюю или завтрашнюю, мы
|
||||
получим "рабочую" программу:</p>
|
||||
<pre class="code">state = 0
|
||||
I'm registered
|
||||
</pre>
|
||||
|
||||
<p>Удалите из ini-файла строку MaxBuildDate=..., чтобы она не
|
||||
мешала нам в дальнейшем.</p><br />
|
||||
<a href="step18_blacklist.htm">Следующий шаг</a>
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<hr noshade="noshade" size="1" />
|
||||
|
||||
<div align="center">
|
||||
© 2006-2015 Copyright VMProtect Software
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
64
help/ru/manager/usage/step18_blacklist.htm
Normal file
64
help/ru/manager/usage/step18_blacklist.htm
Normal file
@@ -0,0 +1,64 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<link rel="Stylesheet" type="text/css" href=
|
||||
"../../default.css" />
|
||||
<meta http-equiv="Content-Type" content=
|
||||
"text/html; charset=utf-8" />
|
||||
|
||||
<title>Шаг 1.8: Номера из "черного списка"</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Шаг 1.8: Номера из "черного списка"</h1>
|
||||
|
||||
<p>Номер, помеченный в VMProtect как "заблокированный", больше не
|
||||
должен приниматься системой лицензирования. При очередной защите
|
||||
приложения VMProtect запишет в защищаемый файл хеш от номеров
|
||||
черного списка, вследствие чего система лицензирования в этом приложении откажет при попытке
|
||||
установить такой номер.</p>
|
||||
|
||||
<p>Сократим до минимума код функции <strong>main()</strong>:</p>
|
||||
<pre class="code">int main(int argc, char **argv)
|
||||
{
|
||||
char *serial = "Xserialnumber"; // зададим номер непосредственно в коде для простоты
|
||||
|
||||
int res = VMProtectSetSerialNumber(serial);
|
||||
print_state(res);
|
||||
|
||||
return 0;
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>Запустим программу и убедимся, что система лицензирования
|
||||
принимает наш серийный номер:</p>
|
||||
<pre class="code">state = 0
|
||||
</pre>
|
||||
|
||||
<p>Теперь занесем наш номер в черный список с точки зрения
|
||||
системы лицензирования. Для этого в ini-файл добавим строку:</p>
|
||||
<pre class="code">BlackListedSerialNumber=Xserialnumber
|
||||
</pre>
|
||||
|
||||
<p>И снова запускаем программу:</p>
|
||||
<pre class="code">state = SERIAL_STATE_FLAG_BLACKLISTED
|
||||
</pre>
|
||||
|
||||
<p>Сообщать ли пользователю о занесении его номера в черный список,
|
||||
или просто сообщить, что номер неверный - оставлено на усмотрение
|
||||
разработчика. Система лицензирования лишь сообщает программе о
|
||||
факте использования заблокированного номера.</p><br />
|
||||
<a href="step19_hwid.htm">Следующий шаг</a>
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<hr noshade="noshade" size="1" />
|
||||
|
||||
<div align="center">
|
||||
© 2006-2015 Copyright VMProtect Software
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
123
help/ru/manager/usage/step19_hwid.htm
Normal file
123
help/ru/manager/usage/step19_hwid.htm
Normal file
@@ -0,0 +1,123 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<link rel="Stylesheet" type="text/css" href=
|
||||
"../../default.css" />
|
||||
<meta http-equiv="Content-Type" content=
|
||||
"text/html; charset=utf-8" />
|
||||
|
||||
<title>Шаг 1.9: Привязка к оборудованию</title>
|
||||
<style type="text/css">
|
||||
/*<![CDATA[*/
|
||||
div.c2 {text-align: center}
|
||||
p.c1 {color:red;}
|
||||
/*]]>*/
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Шаг 1.9: Привязка к оборудованию</h1><strong>Получение
|
||||
идентификатора оборудования</strong>
|
||||
|
||||
<p>Прежде чем привязываться к оборудованию, необходимо получить
|
||||
идентификатор оборудования. Идентификатор помещается в серийный
|
||||
номер и при передаче этого номера системе лицензирования
|
||||
происходит проверка соответствия идентификаторов. Поэтому для
|
||||
начала получим идентификатор нашего оборудования. Сократим
|
||||
<strong>main()</strong> до самого короткого варианта:</p>
|
||||
<pre class="code">int main(int argc, char **argv)
|
||||
{
|
||||
int nSize = VMProtectGetCurrentHWID(NULL, 0);
|
||||
char *buf = new char[nSize];
|
||||
VMProtectGetCurrentHWID(buf, nSize);
|
||||
printf("HWID: %s\n", buf);
|
||||
delete [] buf;
|
||||
return 0;
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>Запустив эту программу, мы получим тестовый идентификатор
|
||||
оборудования, используемый по умолчанию:</p>
|
||||
<pre class="code">HWID: myhwid
|
||||
</pre>
|
||||
|
||||
<p>Чтобы изменить идентификатор, используемый по умолчанию,
|
||||
добавьте в ini-файл строку:</p>
|
||||
<pre class="code">MyHWID=test
|
||||
</pre>
|
||||
|
||||
<p>Запустив программу после этого, мы увидим, что система
|
||||
лицензирования теперь считает "test" идентификатором
|
||||
оборудования:</p>
|
||||
<pre class="code">HWID: test
|
||||
</pre>
|
||||
|
||||
<p class="c1"><strong>Внимание!</strong> реальный идентификатор
|
||||
оборудования программа будет выдавать только после ее обработки в
|
||||
VMProtect.</p><br />
|
||||
<strong>Серийный номер с привязкой к оборудованию</strong>
|
||||
|
||||
<p>Чтобы наш тестовый серийный номер был привязан к оборудованию,
|
||||
добавим в ini-файл еще одну строчку, на этот раз с
|
||||
идентификатором, "записанным" в номер:</p>
|
||||
<pre class="code">KeyHWID=test
|
||||
</pre>
|
||||
|
||||
<p>А функцию <strong>main()</strong> слегка усложним, она снова
|
||||
будет подавать серийный номер и анализировать получаемый
|
||||
результат:</p>
|
||||
<pre>
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int nSize = VMProtectGetCurrentHWID(NULL, 0);
|
||||
char *buf = new char[nSize];
|
||||
VMProtectGetCurrentHWID(buf, nSize);
|
||||
printf("HWID: %s\n", buf);
|
||||
delete [] buf;
|
||||
|
||||
char *serial = "Xserialnumber";
|
||||
int res = VMProtectSetSerialNumber(serial);
|
||||
print_state(res);
|
||||
return 0;
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>Запустив код, получим следующий результат:</p>
|
||||
<pre class="code">HWID: test
|
||||
state = 0
|
||||
</pre>
|
||||
|
||||
<p>Система лицензирования сравнила текущий идентификатор
|
||||
оборудования и тот, который был запиан в серийном номере.
|
||||
Идентификаторы совпали и функция
|
||||
<strong>VMProtectSetSerialNumber()</strong> вернула 0 - серийный
|
||||
номер подходит.</p>
|
||||
|
||||
<p>Попробуем теперь "запустить" нашу программу на другом
|
||||
оборудовании. Для этого поменяем значение "test" параметра MyHWID
|
||||
в ini-файле на "new test". И снова запустим программу:</p>
|
||||
<pre class="code">HWID: new test
|
||||
state = SERIAL_STATE_FLAG_BAD_HWID
|
||||
</pre>
|
||||
|
||||
<p>На этот раз система лицензирования вернула флаг
|
||||
SERIAL_STATE_FLAG_BAD_HWID, означающий несовпадение реально
|
||||
идентификатора оборудования с тем, что хранится в серийном
|
||||
номере. Текущий идентификатор оборудования, выведенный на экран -
|
||||
"new test", а в серийном номере хранится "test". Поменяв в
|
||||
ini-файле значение параметра KeyHWID на "new test" можно добиться
|
||||
работы серийного номера и на этом "оборудовании".</p><br />
|
||||
<a href="step1A_userdata.htm">Следующий шаг</a>
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<hr noshade="noshade" size="1" />
|
||||
|
||||
<div align="center">
|
||||
© 2006-2015 Copyright VMProtect Software
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
76
help/ru/manager/usage/step1A_userdata.htm
Normal file
76
help/ru/manager/usage/step1A_userdata.htm
Normal file
@@ -0,0 +1,76 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<link rel="Stylesheet" type="text/css" href=
|
||||
"../../default.css" />
|
||||
<meta http-equiv="Content-Type" content=
|
||||
"text/html; charset=utf-8" />
|
||||
|
||||
<title>Шаг 1.10: Пользовательские данные</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Шаг 1.10: Пользовательские данные</h1>
|
||||
|
||||
<p>Серийный номер может содержать до 255 байт произвольных
|
||||
данных, которые система лицензирования без изменений передает
|
||||
вызывающей программе. Это может быть какая-то дополнительная
|
||||
информация о продаже, данные, без которых не будет работать
|
||||
полная версия, или еще что-нибудь. Изменим функцию
|
||||
<strong>main()</strong>, чтобы она считывала данные из серийного
|
||||
номера и показывала их на экране:</p>
|
||||
<pre class="code">int main(int argc, char **argv)
|
||||
{
|
||||
char *serial = "Xserialnumber";
|
||||
int res = VMProtectSetSerialNumber(serial);
|
||||
print_state(res);
|
||||
if (res) return 0;
|
||||
|
||||
VMProtectSerialNumberData sd = {0};
|
||||
VMProtectGetSerialNumberData(&sd, sizeof(sd));
|
||||
printf("Serial number has %d byte(s) of data\n", sd.nUserDataLength);
|
||||
for (int i = 0; i < sd.nUserDataLength; i++)
|
||||
printf("%02X ", sd.bUserData[i]);
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>Ini-файл при этом сократим до такого вида:</p>
|
||||
<pre class="code">[TestLicense]
|
||||
AcceptedSerialNumber=Xserialnumber
|
||||
</pre>
|
||||
|
||||
<p>Теперь запустим программу и убедимся, что наш серийный номер
|
||||
подходит, но не содержит никаких данных:</p>
|
||||
<pre class="code">state = 0
|
||||
Serial number has 0 byte(s) of data
|
||||
</pre>
|
||||
|
||||
<p>Чтобы добавить пользовательские данные в серийный номер,
|
||||
необходимо создать в ini-файле переменную UserData и присвоить ей
|
||||
строчку из HEX-символов. Символы должны идти парами, т.е. длина
|
||||
строки должна быть кратна 2. Строка может быть, например,
|
||||
такой:</p>
|
||||
<pre class="code">UserData=010203A0B0C0D0E0
|
||||
</pre>
|
||||
|
||||
<p>В этом случае при запуске программы мы получим следующий
|
||||
результат:</p>
|
||||
<pre class="code">state = 0
|
||||
Serial number has 8 byte(s) of data
|
||||
01 02 03 A0 B0 C0 D0 E0
|
||||
</pre><br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<hr noshade="noshade" size="1" />
|
||||
|
||||
<div align="center">
|
||||
© 2006-2015 Copyright VMProtect Software
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
109
help/ru/manager/usage/step21_src.htm
Normal file
109
help/ru/manager/usage/step21_src.htm
Normal file
@@ -0,0 +1,109 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<link rel="Stylesheet" type="text/css" href=
|
||||
"../../default.css" />
|
||||
<meta http-equiv="Content-Type" content=
|
||||
"text/html; charset=utf-8" />
|
||||
|
||||
<title>Шаг 2.1: Создаем новое защищенное приложение</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Шаг 2.1: Создаем новое защищенное приложение</h1>
|
||||
|
||||
<p>Если на первом этапе мы создавали несколько разных тестовых
|
||||
приложений для изучения API системы лицензирования, то на втором этапе
|
||||
приложение будет одно. Оно также будет консольным и в нем будет
|
||||
функция <strong>foo()</strong>, которая может работать только в
|
||||
зарегистрированной версии. Вот код нашего тестового
|
||||
приложения:</p>
|
||||
<pre class="code">#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include "VMProtectSDK.h"
|
||||
|
||||
#define PRINT_HELPER(state, flag) if (state & flag) printf("%s ", #flag)
|
||||
void print_state(INT state)
|
||||
{
|
||||
if (state == 0)
|
||||
{
|
||||
printf("state = 0\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("state = ");
|
||||
PRINT_HELPER(state, SERIAL_STATE_FLAG_CORRUPTED);
|
||||
PRINT_HELPER(state, SERIAL_STATE_FLAG_INVALID);
|
||||
PRINT_HELPER(state, SERIAL_STATE_FLAG_BLACKLISTED);
|
||||
PRINT_HELPER(state, SERIAL_STATE_FLAG_DATE_EXPIRED);
|
||||
PRINT_HELPER(state, SERIAL_STATE_FLAG_RUNNING_TIME_OVER);
|
||||
PRINT_HELPER(state, SERIAL_STATE_FLAG_BAD_HWID);
|
||||
PRINT_HELPER(state, SERIAL_STATE_FLAG_MAX_BUILD_EXPIRED);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
char *read_serial(const char *fname)
|
||||
{
|
||||
FILE *f;
|
||||
if (0 != fopen_s(&f, fname, "rb")) return NULL;
|
||||
fseek(f, 0, SEEK_END);
|
||||
int s = ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
char *buf = new char[s + 1];
|
||||
fread(buf, s, 1, f);
|
||||
buf[s] = 0;
|
||||
fclose(f);
|
||||
return buf;
|
||||
}
|
||||
|
||||
// метод foo() очень короткий, но он нам нужен в виде отдельной функции
|
||||
// поэтому мы попросим компилятор не делать его inline
|
||||
__declspec(noinline) void foo()
|
||||
{
|
||||
printf("I'm foo!\n");
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *serial = read_serial("serial.txt");
|
||||
int res = VMProtectSetSerialNumber(serial);
|
||||
delete [] serial;
|
||||
if (res)
|
||||
{
|
||||
printf("serial number is bad\n");
|
||||
print_state(res);
|
||||
return 0;
|
||||
}
|
||||
printf("serial number is correct, calling foo()\n");
|
||||
foo();
|
||||
printf("done\n");
|
||||
return 0;
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>Скомпилируем программу без отладочной информации, но в
|
||||
настройках линкера попросим создать MAP-файл, который потребуется
|
||||
для работы VMProtect. При запуске программы мы должны увидеть
|
||||
следующий текст:</p>
|
||||
<pre class="code">serial number is bad
|
||||
state = SERIAL_STATE_FLAG_INVALID
|
||||
</pre>
|
||||
|
||||
<p>В настоящий момент система лицензирования все еще работает в
|
||||
тестовом режиме, т.к. файл еще не был обработан VMProtect'ом и в
|
||||
него не был внедрен модуль лицензирования. На <a href=
|
||||
"step22_vmp.htm">следующем шаге</a> мы создадим проект VMProtect
|
||||
и попробуем защитить нашу программу.</p><br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<hr noshade="noshade" size="1" />
|
||||
|
||||
<div align="center">
|
||||
© 2006-2015 Copyright VMProtect Software
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
42
help/ru/manager/usage/step22_vmp.htm
Normal file
42
help/ru/manager/usage/step22_vmp.htm
Normal file
@@ -0,0 +1,42 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<link rel="Stylesheet" type="text/css" href=
|
||||
"../../default.css" />
|
||||
<meta http-equiv="Content-Type" content=
|
||||
"text/html; charset=utf-8" />
|
||||
|
||||
<title>Шаг 2.2: Создаем проект защиты в VMProtect</title>
|
||||
<style type="text/css">
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Шаг 2.2: Создаем проект защиты в VMProtect</h1>
|
||||
|
||||
<p>Теперь, когда тестовая программа готова, скомпилирована и
|
||||
рядом с ней находится ее MAP-файл, мы можем запустить VMProtect
|
||||
Ultimate и открыть исполняемый файл. Нам нужно будет добавить в
|
||||
проект две функции: _main (так Visual Studio переименовала нашу
|
||||
функцию main()) и foo(). Обе функции видны в списке функций в
|
||||
VMProtect в разделе "Функции".</p>
|
||||
|
||||
<!-- <p class="c1"><br /><img src="../../images/real_project_functions.png" alt="Дерево проекта" /></p> -->
|
||||
|
||||
<p>Далее необходимо инициализировать систему лицензирования.
|
||||
Перейдите на вкладку "Лицензии" и создайте пару кючей длиной 2048
|
||||
бит.</p><br />
|
||||
<a href="step23_product.htm">Следующий шаг</a>
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<hr noshade="noshade" size="1" />
|
||||
|
||||
<div align="center">
|
||||
© 2006-2015 Copyright VMProtect Software
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
70
help/ru/manager/usage/step23_product.htm
Normal file
70
help/ru/manager/usage/step23_product.htm
Normal file
@@ -0,0 +1,70 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<link rel="Stylesheet" type="text/css" href=
|
||||
"../../default.css" />
|
||||
<meta http-equiv="Content-Type" content=
|
||||
"text/html; charset=utf-8" />
|
||||
|
||||
<title>Шаг 2.3: Первый запуск защищенного продукта</title>
|
||||
<style type="text/css">
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Шаг 2.3: Первый запуск защищенного продукта</h1>
|
||||
|
||||
<p>Система лицензирования инициализирована, так что мы можем
|
||||
попробовать скомпилировать проект VMPrtoect и запустить
|
||||
защищенный файл. Запустив его из командной строки мы получим
|
||||
следующее сообщение:</p>
|
||||
<pre class="code">C:\test>dummy_app.vmp.exe
|
||||
serial number is bad
|
||||
state = SERIAL_STATE_FLAG_INVALID
|
||||
</pre>
|
||||
|
||||
<p>Запустив программу depends.exe, мы можем убедиться, что наш
|
||||
защищенный файл более не связан с библиотекой VMProtectSDK.dll, а
|
||||
значит модуль лицензирования встроен в приложение. Список
|
||||
используемых DLL можно посмотреть и в VMProtect, открыв
|
||||
защищенный файл и выбрав из раздела "Свойства" секцию "Импорты".</p>
|
||||
|
||||
<p><img src="../../images/depends.png" /></p>
|
||||
|
||||
<p>Наша защищаемая программа читает серийный номер из файла
|
||||
serial.txt. Поскольку этого файла сейчас нет, то модулю лицензирования
|
||||
подается пустой номер, который также не считается корректным.
|
||||
Перейдем на закладку "лицензии" и сгенерируем серийный номер.
|
||||
Подробно эта процедура описана <a href=
|
||||
"../licenses.htm">здесь</a>, мы создадим самый простой серийный
|
||||
номер без каких-либо ограничений.</p>
|
||||
|
||||
<p><img src="../../images/project_add_license.png" /></p>
|
||||
|
||||
<p>Затем скопируем серийный номер (в свойствах лицензии выделим поле
|
||||
"Серийный номер" и нажмем Ctrl+C), создадим рядом с
|
||||
защищенным приложением файл serial.txt и вставим туда серийный
|
||||
номер. После запуска программы мы увидим следующее:</p>
|
||||
<pre class="code">C:\test>dummy_app.vmp.exe
|
||||
serial number is correct, calling foo()
|
||||
I'm foo
|
||||
done
|
||||
</pre>
|
||||
|
||||
<p>Система лицензирования проверила серийный номер и посчитала
|
||||
его корректным. На <a href="step24_test.htm">следующем шаге</a> мы
|
||||
попробуем применить некоторые ограничения и посмотрим что из
|
||||
этого выйдет.</p><br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<hr noshade="noshade" size="1" />
|
||||
|
||||
<div align="center">
|
||||
© 2006-2015 Copyright VMProtect Software
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
90
help/ru/manager/usage/step24_test.htm
Normal file
90
help/ru/manager/usage/step24_test.htm
Normal file
@@ -0,0 +1,90 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<link rel="Stylesheet" type="text/css" href=
|
||||
"../../default.css" />
|
||||
<meta http-equiv="Content-Type" content=
|
||||
"text/html; charset=utf-8" />
|
||||
|
||||
<title>Шаг 2.4: Тестируем результат</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Шаг 2.4: Тестируем результат</h1><strong>Срок действия
|
||||
серийного номера</strong>
|
||||
|
||||
<p>Создадим еще один серийный номер с ограничением срока
|
||||
действия - скажем, 2005-м годом. Эта дата уже прошла и наш номер
|
||||
должен быть недействительным. Перейдите на закладку "Лицензии" и
|
||||
нажмите кнопку "Добавить лицензию". В появившемся окне поставьте
|
||||
галочку "Срок годности" и введите "30 сентября 2005 года".
|
||||
Создайте номер, скопируйте его и поместите в файл seral.txt,
|
||||
после чего запустите программу:</p>
|
||||
<pre class="code">C:\test>dummy_app.vmp.exe
|
||||
serial number is bad
|
||||
state = SERIAL_STATE_FLAG_DATE_EXPIRED
|
||||
</pre>
|
||||
|
||||
<p>Модуль лицензирования вернул флаг "срок действия номера
|
||||
закончен". Вернем рабочий номер обратно в файл serial.txt и
|
||||
убедимся, что его модуль лицензирования примет без проблем.</p>
|
||||
<pre class="code">C:\test>dummy_app.vmp.exe
|
||||
serial number is correct, calling foo()
|
||||
I'm foo
|
||||
done
|
||||
</pre><strong>Занесение номера в черный список</strong>
|
||||
|
||||
<p>Предположим, что наш "хороший" серийный номер выложен в
|
||||
Интернет. Нам необходимо его заблокировать, чтобы в следующих
|
||||
версиях программы он уже не работал. Для этого мы выбираем его в
|
||||
списке номеров и нажимаем кнопку "Заблокировать". Сам факт
|
||||
нажатия кнопки не блокирует серийный номер в защищенном
|
||||
приложении, однако после повторной защиты файла, он откажется
|
||||
принимать этот серийный номер. Проверим. Если сейчас запустить
|
||||
нашу программу, то она примет заблокированный номер без проблем,
|
||||
т.к. это старая версия программы и она еще не знает о
|
||||
блокировке:</p>
|
||||
<pre class="code">C:\test>dummy_app.vmp.exe
|
||||
serial number is correct, calling foo()
|
||||
I'm foo
|
||||
done
|
||||
</pre>
|
||||
|
||||
<p>Сделаем копию нашей программы и назовем ее
|
||||
"dummy_app1.vmp.exe", а после этого перейдем в VMProtect и
|
||||
повторно защитим наше приложение, после чего запустим новую
|
||||
версию программы:</p>
|
||||
<pre class="code">C:\test>dummy_app.vmp.exe
|
||||
serial number is bad
|
||||
state = SERIAL_STATE_FLAG_BLACKLISTED
|
||||
</pre>
|
||||
|
||||
<p>Теперь для сравнения еще раз запустим старую версию
|
||||
программы:</p>
|
||||
<pre class="code">C:\test>dummy_app1.vmp.exe
|
||||
serial number is correct, calling foo()
|
||||
I'm foo
|
||||
done
|
||||
</pre>
|
||||
|
||||
<p>Старая версия ничего не знает о блокировании номера и
|
||||
продолжает работать как и раньше. </p><br />
|
||||
<br /><p>На <a href=
|
||||
"step25_codelock.htm">последнем шаге</a> мы попробуем привязать
|
||||
выполняемый код к серийному номеру. Перед этим разблокируйте
|
||||
серийный номер и перезащитите приложение в VMProtect, чтобы оно
|
||||
снова принимало наш серийный номер. Или создайте новую
|
||||
лицензию.</p><br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<hr noshade="noshade" size="1" />
|
||||
|
||||
<div align="center">
|
||||
© 2006-2015 Copyright VMProtect Software
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
144
help/ru/manager/usage/step25_codelock.htm
Normal file
144
help/ru/manager/usage/step25_codelock.htm
Normal file
@@ -0,0 +1,144 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<link rel="Stylesheet" type="text/css" href=
|
||||
"../../default.css" />
|
||||
<meta http-equiv="Content-Type" content=
|
||||
"text/html; charset=utf-8" />
|
||||
|
||||
<title>Шаг 2.5. Привязка кода к серийному номеру</title>
|
||||
<style type="text/css">
|
||||
/*<![CDATA[*/
|
||||
p.c2 {color:red;}
|
||||
span.c1 {background-color:yellow;}
|
||||
/*]]>*/
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Шаг 2.5. Привязка кода к серийному номеру</h1>
|
||||
|
||||
<p>Одним из наиболее популярных способов взлома программ является
|
||||
поиск проверки серийного номера и последующего условного
|
||||
перехода. Если номер корректен, то ход выполнения программы идет
|
||||
по одной ветке, если некорректен, то по другой. Хакер находит
|
||||
этот переход и заменяет его на безусловный переход на
|
||||
"правильную" ветку. Давайте "взломаем" таким образом нашу
|
||||
тестовую программу. На уровне исходников, конечно же. "Отключим"
|
||||
условный переход:</p>
|
||||
<pre class="code">char *serial = read_serial("serial.txt");
|
||||
int res = VMProtectSetSerialNumber(serial);
|
||||
delete [] serial;
|
||||
if (<span class="c1">false &&</span> res)
|
||||
{
|
||||
</pre>
|
||||
|
||||
<p>Теперь наша программа примет любой серийный номер и будет
|
||||
работать как ни в чем не бывало. Безусловно, если файл защищен
|
||||
VMProtect, то даже опытному хакеру потребуется не один месяц,
|
||||
чтобы найти и исправить этот переход так, как сделали это мы. А с
|
||||
учетом того, что правильно защищенная программа проверяет
|
||||
серийный номер не в одном месте и не всегда, то даже такая
|
||||
простая проверка уже достаточно надежна. Однако мы пойдем
|
||||
дальше.</p><strong>Привяжем код к серийному номеру</strong>
|
||||
|
||||
<p class="c2"><strong>Внимание!</strong> демо-версия VMProtect
|
||||
имеет ограничение на количество обрабатываемых функций:
|
||||
обрабатывается только одна функция. Поэтому в случае
|
||||
использования демо-версии, необходимо включать в проект только
|
||||
функцию foo(), т.к. в противном случае демо-версия VMProtect
|
||||
может выбрать для защиты функцию main() и привязка кода к
|
||||
серийному номеру не сработает.</p>
|
||||
|
||||
<p>Система лицензирования VMProtect позволяет привязать код одной
|
||||
или нескольких функций к серийному номеру так, что они не будут
|
||||
работать без корректного номера. Тело функции виртуализируется,
|
||||
потом шифруется и может быть расшифровано только при наличии
|
||||
корректного серийного номера. То есть даже если хакер найдет и
|
||||
исправит условный переход в коде проверки номера, функции,
|
||||
привязанные к номеру, все равно не будут работать. Давайте
|
||||
попробуем. В VMProtect в разделе "Функции" выберем функцию <strong>foo()</strong> и в
|
||||
правой панели изменим значение опции "Привязать к серийному номеру" на "Да".</p>
|
||||
|
||||
<p><img src="../../images/lock_to_serial.png" /></p>
|
||||
|
||||
<p>После этого защитим наше приложение. С учетом
|
||||
того, что оно "взломано", поместим в файл serial.txt произвольный
|
||||
текст и запустим приложение. В консоли появится текст:</p>
|
||||
<pre class="code">C:\test>dummy_app.vmp.exe
|
||||
serial number is correct, calling foo()
|
||||
</pre>
|
||||
|
||||
<p>То есть хакер "исправил" нужный условный переход и программа
|
||||
пошла по "правильной" ветке. Однако в момент вызова
|
||||
<strong>foo()</strong> программа выводит сообщение:</p>
|
||||
|
||||
<p><img src="../../images/codelock_error.png" /></p>
|
||||
|
||||
<p>Так как мы привязали функцию <strong>foo()</strong> к
|
||||
серийному номеру, а у хакера его нет, то при попытке расшифровать
|
||||
код функции модуль лицензирования выдал сообщение о невозможности
|
||||
продолжить выполнение программы. После нажатия кнопки "ОК"
|
||||
программа завершится и в консоли мы не увидим строчки
|
||||
"done".</p><strong>Что привязывать к серийному номеру?</strong>
|
||||
|
||||
<p>Привязывать к серийному номеру имеет смысл те функции, которые
|
||||
вызываются только в зарегистрированной версии программы. Так как
|
||||
привязка возможна только при использовании виртуализации, то
|
||||
необходимо принимать во внимание возможное падение
|
||||
производительности. Скажем, если текстовый редактор не позволяет
|
||||
сохранять результаты своей работы в демо-версии, то к серийному
|
||||
номеру можно привязать функцию сохранения документа. Если эта
|
||||
функция вызывает ряд других в процессе работы, то их привязывать
|
||||
уже не обязательно, так как без основной функции от них будет
|
||||
немного толку.</p>
|
||||
|
||||
<p>Также необходимо помнить, что вызов привязанной функции без
|
||||
серийного номера приведет к завершению работы программы без
|
||||
возможности сохранения результатов работы, поэтому тщательно
|
||||
тестируйте защищаемую программу, чтобы она не позволяла вызвать
|
||||
такие функции в демо-режиме. В примере с текстовым редактором
|
||||
убедитесь, что в демо-режиме пункт меню "Сохранить" всегда
|
||||
неактивен, что комбинация Ctrl+S не срабатывает и что при
|
||||
закрытии программы также не предлагается сохранить изменения. В
|
||||
противном случае пользователь может составить негативное мнение о
|
||||
вашей программе.</p><strong>Привязка к серийному номеру и
|
||||
нерабочие номера</strong>
|
||||
|
||||
<p>При вызове функции <strong>VMProtectSetSerialNumber()</strong>
|
||||
модуль лицензирования проверяет переданный серийный номер и
|
||||
зашифрованные участки кода будут выполняться только в том случае,
|
||||
если на момент проверки серийный номер был полностью корректным -
|
||||
не занесенным в черный список, с правильным идентификатором
|
||||
оборудования, с неистекшим сроком годности и т.п. В этом случае все
|
||||
зашифрованные процедуры будут выполняться до завершения работы
|
||||
приложения или до нового вызова
|
||||
<strong>VMProtectSetSerialNumber()</strong>.</p>
|
||||
|
||||
<p>Некоторые ограничения могут "сработать" в процессе выполнения
|
||||
программы: например, может истечь время работы программы или
|
||||
окончится срок действия серийного номера. В этом случае модуль
|
||||
лицензирования продолжит расшифровывать и выполнять функции,
|
||||
привязанные к серийному номеру. Это делается потому, что
|
||||
защищенному приложению будет сложно отследить момент срабатывания
|
||||
ограничений и соответствующим образом изменить модель своего
|
||||
поведения (заблокировать пункты меню и т.п). Если модуль
|
||||
лицензирования неожиданно для приложения перестанет выполнять
|
||||
привязанные к серийному номеру участки кода, это с большой
|
||||
вероятностью приведет к неработоспособности приложения. Поэтому
|
||||
все решается в момент установки серийного номера и именно в этот
|
||||
момент определяется режим, в котором будет работать
|
||||
приложение.</p><br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<hr noshade="noshade" size="1" />
|
||||
|
||||
<div align="center">
|
||||
© 2006-2015 Copyright VMProtect Software
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
Reference in New Issue
Block a user