Initial commit

This commit is contained in:
Alukym
2023-05-12 20:16:10 +08:00
commit a8433f06ee
1167 changed files with 1036549 additions and 0 deletions

View File

@ -0,0 +1,259 @@
<!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>Licensing API functions</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>Licensing API functions</h1>
<p>The licensing system API is an integral part of VMProtect API and its SDK. API allows you to specify a serial number and retrieve all information about it: whether it suits the program or not, is the serial number expired, the name this product is registered to and so on. Also, the API provides a hardware identifier of the computer the program runs on.</p><strong id=
"VMProtectSetSerialNumber">VMProtectSetSerialNumber</strong>
<p>This function loads a serial number to the licensing system. Call syntax:</p>
<pre class="code">int VMProtectSetSerialNumber(const char *SerialNumber);
</pre>
<p>The input <strong>SerialNumber</strong> parameter must contain a pointer to a null-terminated string ('\0') containing a base-64 encoded serial number. The function returns a bit mask of serial number status flags, the same as the one <strong>VMProtectGetSerialNumberState()</strong> returns. You can read more about flags below. The serial number is "good" if the function returned 0.</p><br />
<strong id=
"VMProtectGetSerialNumberState">VMProtectGetSerialNumberState</strong>
<p>This function returns status flags for the serial number specified by a call to
<strong>VMProtectSetSerialNumber()</strong>.</p>
<pre class="code">int VMProtectGetSerialNumberState();
</pre>
<p>If at least one flag is set, there is a problem with the serial number. The program shouldn't work if at least one bit is set. The detailed description of flags and their values is listed in the table below:</p>
<table border="1" cellspacing="0" cellpadding="2">
<tr>
<th>Flag</th>
<th>Value</th>
<th>Description</th>
</tr>
<tr>
<td>SERIAL_STATE_FLAG_CORRUPTED</td>
<td>0x00000001</td>
<td>The licensing system is corrupted. Possible reasons are: incorrect setup of the protection project, cracking attempt.</td>
</tr>
<tr>
<td>SERIAL_STATE_FLAG_INVALID</td>
<td>0x00000002</td>
<td>The serial number is incorrect. The flag is set if the licensing system cannot decrypt the serial number.</td>
</tr>
<tr>
<td>SERIAL_STATE_FLAG_BLACKLISTED</td>
<td>0x00000004</td>
<td>The serial number matches the product, but is black listed in VMProtect.</td>
</tr>
<tr>
<td>SERIAL_STATE_FLAG_DATE_EXPIRED</td>
<td>0x00000008</td>
<td>The serial number is expired. You can obtain the detailed information about the expiration date by calling
<strong>VMProtectGetSerialNumberData()</strong></td>
</tr>
<tr>
<td>SERIAL_STATE_FLAG_RUNNING_TIME_OVER</td>
<td>0x00000010</td>
<td>Operating time of the program is depleted. You can obtain the detailed information about the operating time of the program by calling
<strong>VMProtectGetSerialNumberData()</strong></td>
</tr>
<tr>
<td>SERIAL_STATE_FLAG_BAD_HWID</td>
<td>0x00000020</td>
<td>Hardware identifier does not match the hardware identifier prescribed in the key.</td>
</tr>
<tr>
<td>SERIAL_STATE_FLAG_MAX_BUILD_EXPIRED</td>
<td>0x00000040</td>
<td>The serial number does not match the current version of the protected program. You can obtain the maximum build date of the program this serial number matches by calling
<strong>VMProtectGetSerialNumberData()</strong>.</td>
</tr>
</table><br /><br />
<strong id=
"VMProtectGetSerialNumberData">VMProtectGetSerialNumberData</strong>
<p>This function obtains information about contents of the serial number acquired with a call to
<strong>VMProtectSetSerialNumber()</strong>. Call syntax:</p>
<pre class="code">bool VMProtectGetSerialNumberData(VMProtectSerialNumberData *Data, int Size);
</pre>
<p>The first parameter is a pointer to the
<strong>VMProtectSerialNumberData</strong> structure, where all necessary information will be written to. The second parameter is the size of the structure passed in the first parameter. It is required to control the structure's format. The function returns FALSE if the licensing system is corrupted (see the SERIAL_STATE_FLAG_CORRUPTED flag), if a zero address of the structure is provided or if the passed size of the structure is incorrect. In all other cases, the function returns TRUE and records all information about the serial number to the provided address. Below are the elements of the structure:</p>
<table border="1" cellspacing="0" cellpadding="2">
<tr>
<th>Element</th>
<th>Type</th>
<th>Description</th>
</tr>
<tr>
<td>nState</td>
<td>int</td>
<td>A bit flag mask indicating the status of a key. Similar to the one returned by
<strong>VMProtectGetSerialNumberState()</strong>.</td>
</tr>
<tr>
<td>wUserName</td>
<td>wchar_t[256]</td>
<td>The name of a customer in UNICODE, null-terminated.</td>
</tr>
<tr>
<td>wEMail</td>
<td>wchar_t[256]</td>
<td>The e-Mail of a customer in UNICODE, null-terminated.</td>
</tr>
<tr>
<td>dtExpire</td>
<td>VMProtectDate</td>
<td>The key expiration date. The format of the
VMProtectDate structure is described below.</td>
</tr>
<tr>
<td>dtMaxBuild</td>
<td>VMProtectDate</td>
<td>The maximum product build date the given key can work with. The format of the VMProtectDate structure is described below.</td>
</tr>
<tr>
<td>bRunningTime</td>
<td>int</td>
<td>The amount of minutes the program will work (maximum duration of a session). The value in minutes counts from the moment the program starts.</td>
</tr>
<tr>
<td>nUserDataLength</td>
<td>unsigned char</td>
<td>The length of user data in the
<strong>bUserData</strong> field.</td>
</tr>
<tr>
<td>bUserData</td>
<td>unsigned char[255]</td>
<td>User data put into the key. The actual number of bytes is specified in
<strong>nUserDataLength</strong>.</td>
</tr>
</table><br />
<p>The <strong>VMProtectDate</strong> structure is a compact representation of date. Its fields are listed in the table below:</p>
<table border="1" cellspacing="0" cellpadding="2">
<tr>
<th>Element</th>
<th>Type</th>
<th>Description</th>
</tr>
<tr>
<td>wYear</td>
<td>unsigned short</td>
<td>Year.</td>
</tr>
<tr>
<td>bMonth</td>
<td>unsigned char</td>
<td>Month, starts from 1.</td>
</tr>
<tr>
<td>bDay</td>
<td>unsigned char</td>
<td>Day, starts from 1.</td>
</tr>
</table><br />
<br />
<strong id=
"VMProtectGetCurrentHWID">VMProtectGetCurrentHWID</strong>
<p>This function obtains a hardware identifier of the PC the program is working on. Call syntax:</p>
<pre class="code">int VMProtectGetCurrentHWID(char * HWID, int Size);
</pre>
<p>The first parameter is a pointer to a memory area where the identifier is written to. The second parameter is the size of this area. The function returns the number of bytes written inclusive of the trailing zero byte ('\0'). If NULL is provided in the first parameter, the function returns the number of bytes required to store the hardware identifier. Here is the correct way to use the function:</p>
<pre class="code"><strong>int</strong> nSize = <strong>VMProtectGetCurrentHWID</strong>(NULL, 0); // get the required buffer size
<strong>char *</strong>pBuf = <strong>new char</strong>[nSize]; // allocate memory for the buffer
<strong>VMProtectGetCurrentHWID</strong>(pBuf, nSize); // obtain the identifier
// use the identifier
<strong>delete</strong> [] pBuf; // release memory
</pre><br />
<br />
<br />
<br />
<br />
<hr noshade="noshade" size="1" />
<div align="center">
© 2006-2015 Copyright VMProtect Software
</div>
</body>
</html>

View File

@ -0,0 +1,74 @@
<!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>Integrating to application</title>
<style type="text/css">
</style>
</head>
<body>
<h1>Integrating to application</h1>
<p>In the several steps described below we will create a test application that queries the licensing system: provides serial numbers to it, receives the status of a serial number and its contents. On the first stage, we use the license system in the test mode; one the second stage we use it as it would be used in actual practice.</p><strong>Work modes of the licensing system</strong>
<p>Building protection always goes through two main steps: development and release. As for licensing, at first you create an application, integrate protection into it, then add checks and functional limitations. And only after thorough testing you can make the product available to users and begin the second stage. Testing of a protected application is a complex process, because you need to make sure all checks and conditional jumps operate correctly. Making "real" serial numbers for all possible test cases is inconvenient. That is why the licensing system offers the "developer mode" (AKA "test mode") as well. In this work mode, no protection is applied to the app, and reaction of the system to supplied serial numbers is adjusted in the configuration file. When the application is free from bugs and it correctly works with the licensing system, VMProtect replaces the "test" licensing module with the real one that do perform real serial number checking. This is done when the application is protected, so you can't avoid this step by mistake.</p><strong id="TestMode">Stage 1:
Test mode</strong>
<p>In the test mode, all reactions of the licensing system (statuses and data it returns) to supplied serial numbers is described in the configuration file. The file is called VMPLicense.ini and should be located in the working folder of the application. In 10 steps provided below we will go from creating the simplest application to full-featured use of the licensing system in the test mode with hardware locking and limiting the period of free upgrades.</p>
<ul>
<li><a href="step11_app.htm">Step 1.1: Creating a protected application</a></li>
<li><a href="step12_code.htm">Step 1.2: Adding the license checking code</a></li>
<li><a href="step13_flags.htm">Step 1.3: Retrieving serial number status flags</a></li>
<li><a href="step14_name.htm">Step 1.4: Retrieving the name and the e-mail of a user</a></li>
<li><a href="step15_exp.htm">Step 1.5: Checking the expiration date of the serial number</a></li>
<li><a href="step16_time.htm">Step 1.6: Limiting the operation time of the program</a></li>
<li><a href="step17_maxbuild.htm">Step 1.7: Limiting the free upgrades period</a></li>
<li><a href="step18_blacklist.htm">Step 1.8: Serial numbers in the black list</a></li>
<li><a href="step19_hwid.htm">Step 1.9: Hardware lock</a></li>
<li><a href="step1A_userdata.htm">Step 1.10: User data</a></li>
</ul><strong id="RealMode">Stage 2: Real mode</strong>
<p>In the real mode VMProtect licensing system puts a special licensing module to the protected application. This module carries out the same functions as the test one in the SDK, but works with contents of a serial number instead of the configuration ini-file. The next five steps illustrate the process of protecting a simple application with a full-featured protection based on VMProtect and the licensing system.</p>
<ul>
<li><a href="step21_src.htm">Step 2.1: Creating a new protected application</a></li>
<li><a href="step22_vmp.htm">Step 2.2: Creating a VMProtect protection project</a></li>
<li><a href="step23_product.htm">Step 2.3: First start of the protected product</a></li>
<li><a href="step24_test.htm">Step 2.4: Testing the results</a></li>
<li><a href="step25_codelock.htm">Step 2.5: Locking the code to a serial number</a></li>
</ul><strong>Additional information</strong>
<p>Values of all bit flags, structure formats and function call parameters can be found in the <a href="api.htm">Licensing system API
</a> section of this help file. Use this section as a reference, while Steps provided above help to easily implement a typical ready-to-use protection.</p><br />
<br />
<br />
<br />
<br />
<hr noshade="noshade" size="1" />
<div align="center">
© 2006-2015 Copyright VMProtect Software
</div>
</body>
</html>

View 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>Step 1.1: Creating a protected application</title>
</head>
<body>
<h1>Step 1.1: Creating a protected application</h1>
<p>The first step is to create an application. This would be a simple app without any user interface and with no serious capabilities. Our goal is to pass a serial number to the licensing system and receive its answer..</p>
<pre class="code">#include &lt;windows.h&gt;
#include &lt;stdio.h&gt;
bool is_registered(const char *serial)
{
return serial &amp;&amp; serial[0] == 'X';
}
int main(int argc, char **argv)
{
char *serial = "Xserialnumber"; // we set the serial number directly in the code, for simplicity
if (!is_registered(serial))
{
printf("please register!\n");
return 0;
}
printf("We are registered.\n");
return 0;
}
</pre>
<p>The program uses a very simple way to check the serial number. The <strong>is_registered()</strong> function compares the first symbol of the serial number with 'X' and thinks the number is correct if this they match. For an incorrect serial number, a registration message is displayed, while if a user enter the correct key, "We are registered." is shown instead</p>
<p>The <a href="step12_code.htm">next step</a> is to add the code to check the serial number using the licensing system of
VMProtect.</p><br />
<br />
<br />
<br />
<br />
<hr noshade="noshade" size="1" />
<div align="center">
© 2006-2015 Copyright VMProtect Software
</div>
</body>
</html>

View 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>Step 1.2: Adding the license checking code</title>
</head>
<body>
<h1>Step 1.2: Adding the license checking code</h1><strong>Include VMProtect SDK</strong>
<p>If you haven't do this before, it is time to include VMProtect SDK to your project. The SDK is three files: the header file (VMProtectSDK.h), the library file (VMProtectSDK32.lib) and the dll-file with implementation (VMProtectSDK32.dll). There are individual implementations of the library and the dll-file for 64-bit systems.</p>
<p>Put the dll-file, the header file and the library file to the working folder of our application, where the source files are, and include the header file to the main file:</p>
<pre class="code">#include &lt;windows.h&gt;
#include &lt;stdio.h&gt;
#include "VMProtectSDK.h"
</pre>
<p>Build the project and make sure it compiles and runs as before. The licensing system is inactive yet.</p><strong>Sending a serial number to the licensing system</strong>
<p>Now, right below the line with the serial number, we add a call to the SDK function of the licensing system:</p>
<pre class="code">char *serial = "Xserialnumber"; // we set the serial number directly in the code, for simplicity
int res = VMProtectSetSerialNumber(serial);
printf("res = 0x%08X\n", res);
</pre>
<p>If after you did this the program stops with an error saying the required dll-file is missing, make sure you put the corresponding DLL-file to the working folder of our application. In case of a successful execution, you should see the following message:</p>
<pre class="code">res = 0x00000002
</pre>
<p>2 corresponds to the SERIAL_STATE_FLAG_INVALID flag
<a href="api.htm">described in the API</a>. This means the licensing system thinks our key is incorrect, which is pretty true, as we didn't "explain" to the system which keys are correct, and which ones are not.</p><strong>Specifying the "correct" serial number</strong>
<p>In the test mode, the licensing system analyzes the
VMProtectLicense.ini file and reacts to function calls in accordance with the specified settings. We will thoroughly review the file on later steps, and now we simply create such a file and add the following text there:</p>
<pre class="code">[TestLicense]
AcceptedSerialNumber=Xserialnumber
</pre>
<p>Now, run our program again. If you still receive the "2" error code, make sure the ini-file is located in the working folder of the app. This time we should receive "0". That's the sign that the licensing system accepted and approved the serial number. Now we can remove the
<strong>is_registered()</strong> function from the code - the licensing system is now in charge for checking serial numbers:</p>
<pre class="code">#include &lt;windows.h&gt;
#include &lt;stdio.h&gt;
#include "VMProtectSDK.h"
int main(int argc, char **argv)
{
char *serial = "Xserialnumber"; // we set the serial number directly in the code, for simplicity
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">Next step</a>
<br />
<br />
<br />
<br />
<hr noshade="noshade" size="1" />
<div align="center">
© 2006-2015 Copyright VMProtect Software
</div>
</body>
</html>

View File

@ -0,0 +1,75 @@
<!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>Step 1.3: Retrieving serial number status flags</title>
</head>
<body>
<h1>Step 1.3: Retrieving serial number status flags</h1><strong>A handy function to print flags</strong>
<p>First of all, we need a handy function to transform numeric values of flags to comprehensible statuses of a serial number. Here is the code of this function:</p>
<pre class="code">#define PRINT_HELPER(state, flag) if (state &amp; 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>Despite the size, function is really simple - checks all bit flags one by one and print all that are present in the status variable. Replace
<strong>printf</strong> in the code after checking the serial number to the call to
<strong>print_state</strong>, and make changes to the serial number we pass to the licensing system:</p>
<pre class="code">char *serial = "Xserialnumber1"; // we set the serial number directly in the code, for simplicity
int res = VMProtectSetSerialNumber(serial);
print_state(res);
</pre>
<p>Now, if we run this program, the following message will be printed to the console:</p>
<pre class="code">state = SERIAL_STATE_FLAG_INVALID
please register!
</pre>
<p>Now, we put the old key back by removing "1" and run the program again:</p>
<pre class="code">state = 0
We are registered.
</pre>
<p>Now, as we can see status flags of a serial number, let's move to retrieving flags and data from a serial number.</p><strong>Retrieving serial number status</strong>
<p>You can get the status of a serial number in three ways: by calling
<strong>VMProtectSetSerialNumber()</strong>, by calling
<strong>VMProtectGetSerialNumberState()</strong> or by calling
<strong>VMProtectGetSerialNumberData()</strong> - status flags are put into one of fields of the structure. Each method is intended to use in specific time. The first check of the serial number is performed during installation. At this moment you should decline incorrect numbers, expired numbers, numbers in the black list and so on. Some limitations, for example, the maximum operation time of the program or serial number expiration date should also be checked in run-time. And the <strong>VMProtectGetSerialNumberState()</strong> method is the fastest and the most convenient way here. And if you need to receive complete information about the serial number, you can use the more powerful
<strong>VMProtectGetSerialNumberData()</strong> function.</p><br />
<a href="step14_name.htm">Next step</a>
<br />
<br />
<br />
<br />
<hr noshade="noshade" size="1" />
<div align="center">
© 2006-2015 Copyright VMProtect Software
</div>
</body>
</html>

View File

@ -0,0 +1,48 @@
<!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>Step 1.4: Retrieving the name and the e-mail of a user</title>
</head>
<body>
<h1>Step 1.4: Retrieving the name and the e-mail of a user</h1>
<p>Let's start with simple things. We want to get the name and the e-mail of a user from a serial number to show them in the About window (or anywhere else). To do this, we have to add two more lines to our ini-file:</p>
<pre class="code">[TestLicense]
AcceptedSerialNumber=Xserialnumber
UserName=John Doe
EMail=john@doe.com
</pre>
<p>And in the program, if the registration is successful, we obtain these data and output them to the screen:</p>
<pre class="code">VMProtectSerialNumberData sd = {0};
VMProtectGetSerialNumberData(&amp;sd, sizeof(sd));
printf("name = %ls,\ne-mail = %ls\n", sd.wUserName, sd.wEMail);
</pre>
<p>The structure contains UNICODE data, so <strong>printf()</strong> uses %ls specifiers instead of %s.
The program should print the following text on the screen:</p>
<pre class="code">state = 0
We are registered.
name = John Doe,
e-mail = john@doe.com
</pre><br />
<a href="step15_exp.htm">Next step</a>
<br />
<br />
<br />
<br />
<hr noshade="noshade" size="1" />
<div align="center">
© 2006-2015 Copyright VMProtect Software
</div>
</body>
</html>

View File

@ -0,0 +1,55 @@
<!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>Step 1.5: Checking the expiration date of the serial number</title>
</head>
<body>
<h1>Step 1.5: Checking the expiration date of the serial number</h1>
<p>Now put a new line to the ini-file in the following format: ExpDate=YYYYMMDD. For example:</p>
<pre class="code">ExpDate=20000101
</pre>
<p>The date specified in this line must be already passed, that is, the maximum date is yesterday. When we run the program, we should see the following:</p>
<pre class="code">state = SERIAL_STATE_FLAG_DATE_EXPIRED
please register!
</pre>
<p>Now let's get some more information before the "please register" message is shown and the program exists:</p>
<pre class="code">if (res)
{
VMProtectSerialNumberData sd = {0};
VMProtectGetSerialNumberData(&amp;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>The second run of the app now provides more details to us:</p>
<pre class="code">state = SERIAL_STATE_FLAG_DATE_EXPIRED
exp. date: y = 2000, m = 1, d = 1
please register!
</pre>
<p>Ok, now remove the ExpDate=... line from the ini-file, so it will not influence everything else we are to do.</p><br />
<a href="step16_time.htm">Next step</a>
<br />
<br />
<br />
<br />
<hr noshade="noshade" size="1" />
<div align="center">
© 2006-2015 Copyright VMProtect Software
</div>
</body>
</html>

View 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>Step 1.6: Limiting the operation time of the program</title>
</head>
<body>
<h1>Step 1.6: Limiting the operation time of the program</h1>
<p>You can limit the program operates since the moment it is started. This can be useful for demonstration purposes: you provide a real serial number to a user, but the program works no longer than 5 minutes. The licensing system doesn't force such a program to shut down, but merely sets the status flag. So, let's set a maximum working time of one minute, by adding the following line to the ini-file:</p>
<pre class="code">TimeLimit=1
</pre>
<p>And modify the program as follows:</p>
<pre class="code">int main(int argc, char **argv)
{
char *serial = "Xserialnumber"; // we set the serial number directly in the code, for simplicity
int res = VMProtectSetSerialNumber(serial);
print_state(res);
if (res) return 0;
VMProtectSerialNumberData sd = {0};
VMProtectGetSerialNumberData(&amp;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>The program prints the status of the serial number upon start up, then calculates the maximum operating time and waits it to expire. Then the serial number status is printed again. With the maximum operation time set to one minute we should receive the following result:</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>The protected program should analyze the status of a serial number periodically and shut down if the flag is set. The licensing system does not do this automatically, because the program may need to free memory, save data to a file and so on. Also, you may want the program to not stop after the operation time has expired, but instead switch to a more restricted mode. The licensing system leaves this up to the developer.</p><br />
<a href="step17_maxbuild.htm">Next step</a>
<br />
<br />
<br />
<br />
<hr noshade="noshade" size="1" />
<div align="center">
© 2006-2015 Copyright VMProtect Software
</div>
</body>
</html>

View File

@ -0,0 +1,69 @@
<!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>Step 1.7: Limiting the free upgrades period</title>
</head>
<body>
<h1>Step 1.7: Limiting the free upgrades period</h1><strong>How it works</strong>
<p>When VMProtect protects an application it records the date. The licensing system treats this date as a build date of the application. And you can put into a serial number the maximum build date this serial number can work with. Therefore, if you put the current date plus one year to the serial number, it will work with all versions of your programs you will be releasing in a year. A version you release one year and a day after will not work with this serial number, and a user will have a choice: use older version of your program or purchase a new key to work with the latest version of the program for one more year.</p><strong>Let's try it</strong>
<p>Put the line formatted as MaxBuildDate=YYYYMMDD into the ini-file:</p>
<pre class="code">MaxBuildDate=20000101
</pre>
<p>In the test mode, the licensing system treats today as the build date, so it is important that the date specified in this line already passed. That is, the maximum date is yesterday. Modify the code of the <strong>main()</strong> function so that it looked like this:</p>
<pre class="code">int main(int argc, char **argv)
{
char *serial = "Xserialnumber"; // we set the serial number directly in the code, for simplicity
int res = VMProtectSetSerialNumber(serial);
print_state(res);
if (res)
{
VMProtectSerialNumberData sd = {0};
VMProtectGetSerialNumberData(&amp;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>Then, upon program run you should see the following:</p>
<pre class="code">state = SERIAL_STATE_FLAG_MAX_BUILD_EXPIRED
max. build date: y = 2000, m = 1, d = 1
please register!
</pre>
<p>By replacing the date in the ini-file to today or tomorrow, we end up with the "working" program:</p>
<pre class="code">state = 0
I'm registered
</pre>
<p>Remove the MaxBuildDate=... line from the ini-file so that it would not influence our further steps.</p><br />
<a href="step18_blacklist.htm">Next step</a>
<br />
<br />
<br />
<br />
<hr noshade="noshade" size="1" />
<div align="center">
© 2006-2015 Copyright VMProtect Software
</div>
</body>
</html>

View File

@ -0,0 +1,55 @@
<!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>Step 1.8: Serial numbers in the black list</title>
</head>
<body>
<h1>Step 1.8: Serial numbers in the black list</h1>
<p>A serial number marked in VMProtect as "blocked" should not be accepted by the licensing system. When you will rebuild your application next time, VMProtect will add the hash of blacklisted serial numbers to the protected application. As a result, the licensing system of the application will decline these serial numbers in the future.</p>
<p>Firstly, lets minimize the contents of the <strong>main()</strong> function:</p>
<pre class="code">int main(int argc, char **argv)
{
char *serial = "Xserialnumber"; // we set the serial number directly in the code, for simplicity
int res = VMProtectSetSerialNumber(serial);
print_state(res);
return 0;
}
</pre>
<p>Now, run the program and make sure the licensing system do accept our serial number:</p>
<pre class="code">state = 0
</pre>
<p>Now, add this serial number to the black list of the licensing system. Add the following line to the ini-file:</p>
<pre class="code">BlackListedSerialNumber=Xserialnumber
</pre>
<p>And run the program again:</p>
<pre class="code">state = SERIAL_STATE_FLAG_BLACKLISTED
</pre>
<p>Should we inform a user that the serial number he or she enters is blacklisted? It is up to you. You can simply tell the serial number is incorrect or inform the user that the key is compromised. The licensing system simply informs the program about the fact of using the blacklisted serial number.</p><br />
<a href="step19_hwid.htm">Next step</a>
<br />
<br />
<br />
<br />
<hr noshade="noshade" size="1" />
<div align="center">
© 2006-2015 Copyright VMProtect Software
</div>
</body>
</html>

View File

@ -0,0 +1,98 @@
<!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>Step 1.9: Hardware lock</title>
<style type="text/css">
/*<![CDATA[*/
div.c2 {text-align: center}
p.c1 {color:red;}
/*]]>*/
</style>
</head>
<body>
<h1>Step 1.9: Hardware lock</h1><strong>Receiving a hardware identifier</strong>
<p>Before we lock to hardware, we must receive a hardware identifier. The identifier is put into a serial number, and when the number is passed to the licensing system, it checks if identifiers match. So, first we need to receive the identifier of our hardware. Let's reduce the
<strong>main()</strong> function to the bare minimum:</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>By running the program, we receive a default test hardware identifier:</p>
<pre class="code">HWID: myhwid
</pre>
<p>To change the identifier, add the following line to the ini-file:</p>
<pre class="code">MyHWID=test
</pre>
<p>If we run the program afterwards, we can see the system thinks "test" is a hardware identifier of our PC:</p>
<pre class="code">HWID: test
</pre>
<p class="c1"><strong>Important!</strong> The program will display the real hardware identifier only after it is processed with VMProtect.</p><br />
<strong>Hardware-locked serial number</strong>
<p>To lock our test serial number to hardware, we should add one more line to the ini-file. This time we define the identifier that is "put into" the serial number:</p>
<pre class="code">KeyHWID=test
</pre>
<p>Then we complicate <strong>main()</strong> back a bit. Now it will pass a serial number and analyze the result it gets:</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>After running the code we will see the following result:</p>
<pre class="code">HWID: test
state = 0
</pre>
<p>The licensing system has compared the current hardware identifier with the one written in the serial number. Identifiers are equal, so the
<strong>VMProtectSetSerialNumber()</strong> function returned 0 - the serial number matches.</p>
<p>Now let's try to "run" our program on another hardware. We simply change the value of the MyHWID parameter in the ini-file from "test" to "new test". Run the program again:</p>
<pre class="code">HWID: new test
state = SERIAL_STATE_FLAG_BAD_HWID
</pre>
<p>This time the licensing system returned the
SERIAL_STATE_FLAG_BAD_HWID flag, which means the real hardware identifier and the one stored in the serial number are not matching. The current identifier we see on the screen is "new test", while the serial number holds "test". If we change the KeyHWID parameter in the ini-file to "new test" we can make our serial number work on this "hardware" too.</p><br />
<a href="step1A_userdata.htm">Next step</a>
<br />
<br />
<br />
<br />
<hr noshade="noshade" size="1" />
<div align="center">
© 2006-2015 Copyright VMProtect Software
</div>
</body>
</html>

View File

@ -0,0 +1,65 @@
<!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>Step 1.10: User data</title>
</head>
<body>
<h1>Step 1.10: User data</h1>
<p>A serial number can hold up to 255 bytes of arbitrary data that the licensing system passes to the program as they are. The data can hold any additional information about the sale, data required for operation of the full version or something else. Let's modify our
<strong>main()</strong> function so that it would read data from a serial number and display them on the screen:</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(&amp;sd, sizeof(sd));
printf("Serial number has %d byte(s) of data\n", sd.nUserDataLength);
for (int i = 0; i &lt; sd.nUserDataLength; i++)
printf("%02X ", sd.bUserData[i]);
printf("\n");
return 0;
}
</pre>
<p>We also reduce the Ini-file to this:</p>
<pre class="code">[TestLicense]
AcceptedSerialNumber=Xserialnumber
</pre>
<p>Now, we run the program and make sure our serial number works well, but doesn't contain any data:</p>
<pre class="code">state = 0
Serial number has 0 byte(s) of data
</pre>
<p>To add new user data into the serial number, we need to create the UserData variable in the ini-file and assign data to it in the HEX format. Symbols must go in pairs, that is the length of a line must be a multiple of 2. Like this:</p>
<pre class="code">UserData=010203A0B0C0D0E0
</pre>
<p>In this case, if we runthe program we will receive the following result:</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>

View File

@ -0,0 +1,98 @@
<!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>Step 2.1: Creating a new protected application</title>
</head>
<body>
<h1>Step 2.1: Creating a new protected application</h1>
<p>At the first stage we made several simple apps to test the API of the licensing system. Now, on the second stage we'll create just one application. It will also be a console app with the <strong>foo()</strong> function working only in the registered version. Here is the code of our test application:</p>
<pre class="code">#include &lt;windows.h&gt;
#include &lt;stdio.h&gt;
#include "VMProtectSDK.h"
#define PRINT_HELPER(state, flag) if (state &amp; 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(&amp;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;
}
// The foo() method is very short, but we need it to be an individual function
// so we asked the compiler to not compile it 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>Compile the program without the debug information, but in the linker settings we enable creating of the MAP-file - we will need it to work with VMProtect. After we run the program, we should see the following text:</p>
<pre class="code">serial number is bad
state = SERIAL_STATE_FLAG_INVALID
</pre>
<p>Currently, the licensing system still works in the test mode, because the file wasn't processed by VMProtect and doesn't contain a licensing module in it. On the <a href=
"step22_vmp.htm">next step</a> we will create a VMProtect project and will try to protect our application.</p><br />
<br />
<br />
<br />
<br />
<hr noshade="noshade" size="1" />
<div align="center">
© 2006-2015 Copyright VMProtect Software
</div>
</body>
</html>

View File

@ -0,0 +1,37 @@
<!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>Step 2.2: Creating a VMProtect protection project</title>
<style type="text/css">
</style>
</head>
<body>
<h1>Step 2.2: Creating a VMProtect protection project</h1>
<p>Now, as our test app is ready, compiled and has an assigned MAP-file in the same folder, we can run VMProtect
Ultimate and open the executable file. We need to add two functions to the project: _main (this is how Visual Studio renamed our main()) and foo(). Both functions can be seen in the list of functions in the "Functions" section in VMProtect.</p>
<!-- <p class="c1"><br /><img src="../../images/real_project_functions.png" alt="Дерево проекта" /></p> -->
<p>Then, we need to initialize the licensing system.
Open the "Licenses" section and create a pair of keys with the length of 2048 bit.</p><br />
<a href="step23_product.htm">Next step</a>
<br />
<br />
<br />
<br />
<hr noshade="noshade" size="1" />
<div align="center">
© 2006-2015 Copyright VMProtect Software
</div>
</body>
</html>

View File

@ -0,0 +1,54 @@
<!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>Step 2.3: First start of the protected product</title>
<style type="text/css">
</style>
</head>
<body>
<h1>Step 2.3: First start of the protected product</h1>
<p>The licensing system is initialized, so let's try to compile the VMProtect project and run the protected file. After running it from the command line we will receive the following message:</p>
<pre class="code">C:\test&gt;dummy_app.vmp.exe
serial number is bad
state = SERIAL_STATE_FLAG_INVALID
</pre>
<p>If you run depends.exe and can see that our protected executable file doesn't use the VMProtectSDK.dll any more. This means the licensing module is already built into the program. You can also review the list of used DLL from VMProtect, in the "Details | Imports" section.</p>
<p><img src="../../images/depends.png" /></p>
<p>Our protected program reads a serial number from the serial.txt file. Since there is no such file yet, the licensing module receives an empty serial number that is interpreted as incorrect.
Now we switch to the "Licenses" section and generate a serial number.
This procedure is described <a href=
"../licenses.htm">here</a> in all details, and now we merely create a simple serial number without any limitations.</p>
<p><img src="../../images/project_add_license.png" /></p>
<p>Then, we copy the serial number (select the "Serial number" field in the license properties and precc Ctrl+C), create a file named serial.txt in the same folder as the protected application, and paste the copied number there. Now, if we run our application we will see this:</p>
<pre class="code">C:\test&gt;dummy_app.vmp.exe
serial number is correct, calling foo()
I'm foo
done
</pre>
<p>The licensing system checked the serial number and found it correct. On the <a href="step24_test.htm">next step</a> we will try to apply some limitations will watch the results.</p><br />
<br />
<br />
<br />
<br />
<hr noshade="noshade" size="1" />
<div align="center">
© 2006-2015 Copyright VMProtect Software
</div>
</body>
</html>

View File

@ -0,0 +1,65 @@
<!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>Step 2.4: Testing the results</title>
</head>
<body>
<h1>Step 2.4: Testing the results</h1><strong>Serial number expiration date</strong>
<p>Let's create another serial number with a certain expiration date. For example, 2005. This date has already passed and therefore our serial number must be incorrect. Switch to the "Licenses" section and click the "Add license" button on the toolbar. In the "Add license" dialog window enable the "Expiration date" option and specify September 30, 2005.
Create the serial number, copy it and paste to serial.txt, then run the program:</p>
<pre class="code">C:\test&gt;dummy_app.vmp.exe
serial number is bad
state = SERIAL_STATE_FLAG_DATE_EXPIRED
</pre>
<p>the licensing module returned the "serial number is expired" flag. Now, put the working serial number back to the serial.txt file and make sure the licensing module accepts it perfectly.</p>
<pre class="code">C:\test&gt;dummy_app.vmp.exe
serial number is correct, calling foo()
I'm foo
done
</pre><strong>Adding a serial number to the black list</strong>
<p>Let's imagine our "good" serial number has leaked to the Internet and is compromised now. We need to block it so that it will not work in future versions of the program. To do this, select the serial number in the list and set the "Blocked" property in the main panel to "Yes". For now, the serial number is not yet blocked, but when you protect the file again, the application will not accept this number any more. Let's make sure this is really so. If we run our program now, it should accept the blocked serial number without any problems, because this is the old version that knows nothing about the blocked number:</p>
<pre class="code">C:\test&gt;dummy_app.vmp.exe
serial number is correct, calling foo()
I'm foo
done
</pre>
<p>Now we make a copy of our program and name it as
"dummy_app1.vmp.exe", then open VMProtect and protect the application again. Then run this new version:</p>
<pre class="code">C:\test&gt;dummy_app.vmp.exe
serial number is bad
state = SERIAL_STATE_FLAG_BLACKLISTED
</pre>
<p>And the old version again, for comparison:</p>
<pre class="code">C:\test&gt;dummy_app1.vmp.exe
serial number is correct, calling foo()
I'm foo
done
</pre>
<p>The older version doesn't know about the blocked serial number and works as before.</p><br />
<br /><p>On the <a href=
"step25_codelock.htm">next step</a> we will try to lock the code to a serial number. But before we proceed, unblock the serial number and reapply protection in VMProtect to the application to make it accept this serial number again. Or simply create a new license.</p><br />
<br />
<br />
<br />
<br />
<hr noshade="noshade" size="1" />
<div align="center">
© 2006-2015 Copyright VMProtect Software
</div>
</body>
</html>

View File

@ -0,0 +1,69 @@
<!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>Step 2.5: Locking the code to a serial number</title>
<style type="text/css">
/*<![CDATA[*/
p.c2 {color:red;}
span.c1 {background-color:yellow;}
/*]]>*/
</style>
</head>
<body>
<h1>Step 2.5: Locking the code to a serial number</h1>
<p>One of the most common ways to crack programs is to locate the place where the serial number is checked and the nearby conditional jump that follows it. If the serial number is correct, the execution of the program goes one way, if not - the other way. A hacker locates this jump and replaces it with a jump to the "correct" way. Let's "crack" our test program using this technique. Directly in the source code, of course. Let's "switch off" our conditional jump:</p>
<pre class="code">char *serial = read_serial("serial.txt");
int res = VMProtectSetSerialNumber(serial);
delete [] serial;
if (<span class="c1">false &amp;&amp;</span> res)
{
</pre>
<p>Now, our program accepts any serial number and works normally. Of course, if the file is protected with VMProtect, even an experienced hacker would spend months to locate and modify the conditional jump as we did it. And taking into account the program check the serial number multiple times and under different conditions, even such a simple check is quite secure. But let's go further.</p><strong>locking the code to a serial number</strong>
<p class="c2"><strong>Important!</strong> The demo-version of VMProtect has a limitation on the number of processed function: only one function is processed. So if you use the demo-version, you should only include the foo() function to the project, otherwise the demo-version of VMProtect can choose the main() function and locking to a serial number will not work.</p>
<p>The licensing system of VMProtect allows you to lock the code of one or more functions to a serial number so, that they will not work without the correct serial number provided. the body of the function is virtualized, then encrypted and can only be decrypted with the correct serial number. This means, even if a hacker finds and fixes the conditional jump in the serial number check, functions locked to the serial number still will not work. Let's try this. In the "Functions" section choose the <strong>foo()</strong> function and at the right panel change the "Lock to Serial Number" option to "Yes".</p>
<p><img src="../../images/lock_to_serial.png" /></p>
<p>Then, protect the application. Since, we already "hacked" it, put an arbitrary text into the serial.txt file and run the application. The following text appears in the console:</p>
<pre class="code">C:\test&gt;dummy_app.vmp.exe
serial number is correct, calling foo()
</pre>
<p>This means, the hacker "fixed" the conditional jump, and the program runs on the "correct" way. But when the
<strong>foo()</strong> is invoked, the program displays a message:</p>
<p><img src="../../images/codelock_error.png" /></p>
<p>Since we locked the <strong>foo()</strong> function to the serial number, and the hacker does not have it, an attempt to decrypt the code of the function resulted in malfunction and inability to continue execution of the program. When "OK" is pressed, the program shuts down and the "done" message is never displayed in the console.
</p><strong>What should be locked to a serial number?</strong>
<p>It makes sense to lock to a serial number a function that should only run in the registered version of the program. Since locking requires virtualization, you should take into account some loss of performance. For instance, if a text editor does not allow saving result in a demo-version, you can lock the save document function to a serial number. If during its operation this function calls other functions, it is not necessary to lock them too, as they won't be of any use without the main function.</p>
<p>You should also remember that invoking the locked function without the serial number leads to program shut down, without a chance to save result of the work. that is why you should thoroughly test the application to make sure it doesn't calls such functions in the trial mode. In the above example, the text editor must disable the "Save" command in the demo mode and do not react on Ctrl+S shortcut as well. Of course, it also shouldn't ask to save the document on exit too. If you don't pay attention to this, a user may be disappointed with your "buggy" demo-version.</p><strong>Locking to a serial number and invalid serial numbers</strong>
<p>When the <strong>VMProtectSetSerialNumber()</strong> function is invoked, the licensing module checks the serial number passed to this function. Encrypted fragments of the code are only executed if the serial number was absolutely correct at the moment of check - not blacklisted, with the correct hardware identifier, not expired and so on. In this case all encrypted procedures are executed until the application is closed, or <strong>VMProtectSetSerialNumber()</strong> is invoked again.</p>
<p>Some limitations can "trigger" during execution of the program: for example, the operating time of the program may expire or the serial number expiration date comes. In this case the licensing module still encrypts and executes functions locked to the serial number. This is so, because it is hard for the protected application to detect the moment those limitations trigger and change the behaviour accordingly (block corresponding menu items and so on). If the licensing module suddenly stops execution of the code fragments that are locked to the serial number, this will very likely lead to malfunction of the application. That is why the decision is made when a serial number is set, and the corresponding execution mode is selected.</p><br />
<br />
<br />
<br />
<br />
<hr noshade="noshade" size="1" />
<div align="center">
© 2006-2015 Copyright VMProtect Software
</div>
</body>
</html>