VMProtect/help/ru/manager/keygen/keygen_dll.htm
VNGhostMans 5ec92ee05e first commit
Version 3.x.x
2023-05-14 20:21:09 +07:00

285 lines
16 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!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>Генератор ключей: Windows-версия</title>
</head>
<body>
<h1>Генераторы ключей: Windows-версия</h1>
<h3>Описание</h3>
<p>Генератор для Windows представляет собой DLL-файлы для
платформ x86 и x64, заголовочный файл языка C и lib-файл,
совместимый с MSVC. Таким образом, библиотека может быть как слинкована статически, так
и загружаться динамически.</p>
<p>Все файлы генератора находятся в каталоге
<strong>Keygen\DLL</strong>, там же находится тестовое
приложение, которое генерирует серийные номера.</p>
<h3>API генератора</h3>
<p>Генератор экспортирует всего две функции: одна непосредственно
генерирует серийный номер, вторая - освобождает память,
выделенную первой. Начнем с первой и основной функции:</p>
<pre class="code"><strong>VMProtectErrors</strong> __stdcall <strong>VMProtectGenerateSerialNumber</strong>(
<strong>VMProtectProductInfo *</strong> pProductInfo,
<strong>VMProtectSerialNumberInfo *</strong> pSerialInfo,
<strong>char **</strong> pSerialNumber
);
</pre>
<p>Первый параметр - указатель на структуру
<strong>VMProtectProductInfo</strong>, содержимое которой
выгружается в VMProtect (см. <a href=
"../licenses.htm#export">Экспорт параметров продукта</a>).
Структура содержит приватный ключ продукта, используемый алгоритм
и количество бит, а также идентификатор продукта. Подробнее о
заполнении этой структуры написано ниже.</p>
<p>Второй параметр - указатель на структуру
<strong>VMProtectSerialNumberInfo</strong>, содержимое которой
переносится в генерируемый серийный номер. Структура содержит все
поля серийного номера, а также битовую маску, определяющую какие
именно поля должны быть записаны в серийный номер.</p>
<pre class="code">struct <strong>VMProtectSerialNumberInfo</strong>
{
<strong>INT</strong> flags;
<strong>wchar_t *</strong> pUserName;
<strong>wchar_t *</strong> pEMail;
<strong>DWORD</strong> dwExpDate;
<strong>DWORD</strong> dwMaxBuildDate;
<strong>BYTE</strong> nRunningTimeLimit;
<strong>char *</strong> pHardwareID;
<strong>size_t</strong> nUserDataLength;
<strong>BYTE *</strong> pUserData;
};
</pre>
<p>Поле <strong>flags</strong> содержит битовые флаги из набора
<strong>VMProtectSerialNumberFlags</strong>, описанного перед
структурой:</p>
<ul>
<li><strong>HAS_USER_NAME</strong> - поместить в серийный номер
имя пользователя, находящееся в переменной
<strong>pUserName</strong>.</li>
<li><strong>HAS_EMAIL</strong> - поместить в серийный номер
e-mail пользователя, находящийся в переменной
<strong>pEMail</strong>.</li>
<li><strong>HAS_EXP_DATE</strong> - серийный номер перестанет
действовать поле окончания дня, указанного в переменной
<strong>dwExpDate</strong>.</li>
<li><strong>HAS_MAX_BUILD_DATE</strong> - серийный номер будет
подходить только к версиям продукта, созданным до даты,
указанной в переменной <strong>dwMaxBuildDate</strong>.</li>
<li><strong>HAS_TIME_LIMIT</strong> - программа перестанет
работать по истечении времени, указанного в переменной
<strong>nRunningTimeLimit</strong> (время указывается в минутах
и не может превышать 255).</li>
<li><strong>HAS_HARDWARE_ID</strong> - программа будет работать
только на оборудовании с идентификатором, указанным в
переменной <strong>pHardwareID</strong>.</li>
<li><strong>HAS_USER_DATA</strong> - поместить в серийный номер
пользовательские данные длинной
<strong>nUserDataLength</strong>, расположенные по адресу,
указанному в переменной <strong>pUserData</strong>.</li>
</ul>
<p>Третий параметр - указатель на указатель. Туда будет записан
адрес сгенерированного серийного номера. После генерации номер
необходимо скопировать, а адрес передать во вторую функцию API
генератора, которая освободит занимаемую серийным номером
память.</p>
<pre class="code"><strong>void</strong> __stdcall <strong>VMProtectFreeSerialNumberMemory</strong>(<strong>char *</strong> pSerialNumber);
</pre>
<p>Функция <strong>VMProtectGenerateSerialNumber</strong>
возвращает значение типа <strong>VMProtectErrors</strong>,
содержащее 0 в случае успешной генерации номера или код ошибки в
противном случае. Возможны следующие коды ошибок:</p>
<ul>
<li><strong>ALL_RIGHT</strong> - ошибок нет, номер сгенерирован
успешно.</li>
<li><strong>UNSUPPORTED_ALGORITHM</strong> - в первом параметре
функции передан некорректный алгоритм шифрования ключа.</li>
<li><strong>UNSUPPORTED_NUMBER_OF_BITS</strong> - в первом
параметре функции передано некорректное количество бит в
ключе.</li>
<li><strong>USER_NAME_IS_TOO_LONG</strong> - длина имени
пользователя в кодировке UTF-8 превысила 255 байт.</li>
<li><strong>EMAIL_IS_TOO_LONG</strong> - длина e-mail
пользователя в кодировке UTF-8 превысила 255 байт.</li>
<li><strong>USER_DATA_IS_TOO_LONG</strong> - длина
пользовательских данных превышает 255 байт.</li>
<li><strong>HWID_HAS_BAD_SIZE</strong> - идентификатор
оборудования имеет некорректный размер.</li>
<li><strong>PRODUCT_CODE_HAS_BAD_SIZE</strong> - идентификатор
продукта, переданный в первом параметре функции, имеет неверный
размер.</li>
<li><strong>SERIAL_NUMBER_TOO_LONG</strong> - серийный номер
слишком длинный и не помещается в указанное в алгоритме количество
бит.</li>
<li><strong>BAD_PRODUCT_INFO</strong> - первый параметр функции
некорректен или NULL.</li>
<li><strong>BAD_SERIAL_NUMBER_INFO</strong> - второй параметр
функции некорректен или NULL.</li>
<li><strong>BAD_SERIAL_NUMBER_CONTAINER</strong> - третий
параметр функции не указывает на ячейку памяти для записи
адреса серийного номера.</li>
<li><strong>NOT_EMPTY_SERIAL_NUMBER_CONTAINER</strong> - третий
параметр функции не указывает на пустую ячейку, в ячейке должно
быть значение NULL.</li>
<li><strong>BAD_PRIVATE_EXPONENT</strong> - значение приватной
экспоненты в первом параметре функции некорректно.</li>
<li><strong>BAD_MODULUS</strong> - значение модуля в первом
параметре функции некорректно.</li>
</ul>
<p>Ошибки делятся на две категории: те, что связаны с
некорректными параметрами или с содержимым первого параметра
функции, и все остальные. Ошибки первой категории редки и
являются признаком некорректной настройки структуры. Имеет смысл
выгрузить информацию о продукте повторно и убедиться, что
структура заполняется правильно. Пример правильного заполнения
приведен ниже.</p>
<p>Ошибки второй категории связаны с попыткой вместить в ключ
больше данных, чем это возможно ввиду его размера. В таком случае
разумно будет отправить регистратору вместо ключа текст "Ключ
будет выслан в течение суток", а всю необходимую информацию
отправить себе по почте. Ключ в таком случае генерируется в
VMProtect в ручном режиме, какие-то данные обрезаются, чтобы
уместить все необходимое в максимальный размер
ключа.</p>
<h3>Пример использования</h3>
<p>Ниже приведен пример кода, который вызывает две вышеописанные
функции и генерирует серийный номер. Обратите внимание на блок
кода, расположенный в самом начале. Пример не будет работать пока
вы не замените его на блок, выгруженный для продукта из
VMProtect:</p>
<pre class="code">//////////////////////////////////////////////////////////////////////////
// !!! this block should be generated by VMProtect !!! ///
//////////////////////////////////////////////////////////////////////////
<strong>VMProtectAlgorithms</strong> g_Algorithm = ALGORITHM_RSA;
<strong>size_t</strong> g_nBits = 0;
<strong>byte</strong> g_vModulus[1];
<strong>byte</strong> g_vPrivate[1];
<strong>byte</strong> g_vProductCode[1];
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
<strong>int</strong> _tmain(<strong>int</strong> argc, <strong>_TCHAR*</strong> argv[])
{
<strong>VMProtectProductInfo</strong> pi;
pi.algorithm = g_Algorithm;
pi.nBits = g_nBits;
pi.nModulusSize = sizeof(g_vModulus);
pi.pModulus = g_vModulus;
pi.nPrivateSize = sizeof(g_vPrivate);
pi.pPrivate = g_vPrivate;
pi.nProductCodeSize = sizeof(g_vProductCode);
pi.pProductCode = g_vProductCode;
<strong>VMProtectSerialNumberInfo</strong> si = {0};
si.flags = HAS_USER_NAME | HAS_EMAIL;
si.pUserName = L"John Doe";
si.pEMail = L"john@doe.com";
<strong>char *</strong> pBuf = NULL;
<strong>VMProtectErrors</strong> res = <strong>VMProtectGenerateSerialNumber</strong>(&amp;pi, &amp;si, &amp;pBuf);
<strong>if</strong> (res == ALL_RIGHT)
{
<strong>printf</strong>("Serial number:\n%s\n", pBuf);
<strong>VMProtectFreeSerialNumberMemory</strong>(pBuf);
}
else
{
<strong>printf</strong>("Error: %d\n", res);
}
<strong>return</strong> 0;
}
</pre>
<p>Этот пример с проектом для Microsoft Visual Studio находится в
каталоге <strong>Keygen\DLL\Example</strong>, ниже будут описаны
наиболее интересные места кода.</p>
<p>Первые строчки функции <strong>main</strong> заполняют
структуру <strong>VMProtectProductInfo</strong> данными,
выгруженными из VMProtect. Этот код стандартен, его не следует
менять во избежание появления ошибок. Далее создается структура
<strong>VMProtectSerialNumberInfo</strong>, в поле флагов
выставляется комбинация из битов имени пользователя и e-mail.
Строчкой ниже в соответствующие поля структуры заносятся значения
имени пользователя и пароля. Обратите внимание, что значения
принимаются в кодировке UNICODE. Генератор ключей внутри
преобразует их в кодировку UTF-8.</p>
<p>Далее описывается переменная-указатель, куда будет записан
адрес сгенерированного ключа, и вызывается функция
<strong>VMProtectGenerateSerialNumber</strong>, после чего
анализируется код возврата. Если ошибок нет, то сгенерированный
номер печатается на консоль и вызывается функция осовобождения
памяти.</p>
<h3>Остальные поля структуры VMprotectSerialNumberInfo</h3>
<p>Некоторые поля структуры требуют дополнительных поясненений. К
примеру, поля <strong>dwExpDate</strong> и
<strong>dwMaxBuildDate</strong> содержат даты в определенном
формате: <strong>0xYYYYMMDD</strong>, т.е. год хранится в старшем
слове, а месяц и день в старшем и младшем байтах младшего слова.
Для формирования такого числа описан макрос <strong>MAKEDATE(y,
m, d)</strong>, который можно вызвать так: <strong>MAKEDATE(2010,
05, 12)</strong>.</p>
<p>В поле <strong>pHardwareID</strong> должен быть записан
указатель на строку, которую вернул метод
<strong>VMProtectGetCurrentHWID</strong> из SDK
лицензирования.</p><br />
<br />
<br />
<br />
<br />
<hr noshade="noshade" size="1" />
<div align="center">
© 2006-2015 Copyright VMProtect Software
</div>
</body>
</html>