Get Demo
  • Windows
  • MacOS
  • Linux

Step 1.6: Limiting the operation time of the program

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:

TimeLimit=1

And modify the program as follows:

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(&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;
}

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:

state = 0
I will run for 1 minute(s)
state = 0
After 1 minute(s):
state = SERIAL_STATE_FLAG_RUNNING_TIME_OVER

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.

Step 1.5: Checking the expiration date of the serial number

Now put a new line to the ini-file in the following format: ExpDate=YYYYMMDD. For example:

ExpDate=20000101

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:

state = SERIAL_STATE_FLAG_DATE_EXPIRED
please register!

Now let’s get some more information before the “please register” message is shown and the program exists:

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;
}

The second run of the app now provides more details to us:

state = SERIAL_STATE_FLAG_DATE_EXPIRED
exp. date: y = 2000, m = 1, d = 1
please register!

Ok, now remove the ExpDate=… line from the ini-file, so it will not influence everything else we are to do.

Step 1.4: Retrieving the name and the e-mail of a user

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:

[TestLicense]
AcceptedSerialNumber=Xserialnumber
UserName=John Doe
[email protected]

And in the program, if the registration is successful, we obtain these data and output them to the screen:

VMProtectSerialNumberData sd = {0};
VMProtectGetSerialNumberData(&sd, sizeof(sd));
printf("name = %ls,\ne-mail = %ls\n", sd.wUserName, sd.wEMail);

The structure contains UNICODE data, so printf() uses %ls specifiers instead of %s. The program should print the following text on the screen:

state = 0
We are registered.
name = John Doe,
e-mail = [email protected]

Step 1.3: Retrieving serial number status flags

A handy function to print flags

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:

#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");
}

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 printf in the code after checking the serial number to the call to print_state, and make changes to the serial number we pass to the licensing system:

char *serial = "Xserialnumber1"; // we set the serial number directly in the code, for simplicity
int res = VMProtectSetSerialNumber(serial);
print_state(res);

Now, if we run this program, the following message will be printed to the console:

state = SERIAL_STATE_FLAG_INVALID
please register!

Now, we put the old key back by removing “1″ and run the program again:

state = 0
We are registered.

Now, as we can see status flags of a serial number, let’s move to retrieving flags and data from a serial number.

Retrieving serial number status

You can get the status of a serial number in three ways: by calling VMProtectSetSerialNumber(), by calling VMProtectGetSerialNumberState() or by calling VMProtectGetSerialNumberData() – 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 VMProtectGetSerialNumberState() 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 VMProtectGetSerialNumberData() function.

Step 1.2: Adding the license checking code

Include VMProtect SDK

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.

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:

#include <windows.h>
#include <stdio.h>
#include "VMProtectSDK.h"

Build the project and make sure it compiles and runs as before. The licensing system is inactive yet.

Sending a serial number to the licensing system

Now, right below the line with the serial number, we add a call to the SDK function of the licensing system:

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 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:

res = 0x00000002

2 corresponds to the SERIAL_STATE_FLAG_INVALID flag described in the API. 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.

Specifying the “correct” serial number

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:

[TestLicense]
AcceptedSerialNumber=Xserialnumber 

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 is_registered() function from the code – the licensing system is now in charge for checking serial numbers:

#include <windows.h>
#include <stdio.h>
#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;
}

Step 1.1: Creating a protected application

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.

#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"; // 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;
}

The program uses a very simple way to check the serial number. The is_registered() 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.

Integration into application

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.

Work modes of the licensing system

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.

Stage 1: Test mode

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 "VMProtectLicense.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.

Stage 2: Real mode

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.

Additional information

Values of all bit flags, structure formats and function call parameters can be found in the Licensing system API 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.

How the licensing system works

Application protection

To protect an application, VMProtect embeds the special code into it. This code checks serial numbers using information specified in the “Licensing” subsection of the “Project” section. A public key is embedded to the application and is used then to decrypt serial numbers. Also, the protection date and some additional information the licensing requires to work is put into the application.

Creating serial numbers

Serial numbers can be created in the Licenses section of the “Project” section or using third-party applications – key generators. A serial number is a set of data about a customer encrypted using the asymmetric algorithm. The serial number then is passed to the customer, he or she enters it to the program, and the licensing system checks it.

Checking a serial number in the program

The licensing system has special functions a program can use to work with serial numbers. The program sends a serial number to the licensing system and queries information about it. The licensing system returns the state of a serial number (valid/invalid and why) and also can provide detailed information about the serial numbers including a user name, an e-mail, the expiration date of this serial number and so on. The protected program analyzes serial number information and decides whether or not to continue operation and to limit the functionality.

Licensing system features

Secure serial numbers

The license system uses an asymmetric algorithm to encrypt serial numbers. The number is encrypted with a private key that only the developer has. The protected product uses the corresponding public key to decrypt the serial number and checks it. Due to the length of keys the system uses (1024 bit or higher for RSA) it is virtually impossible to compute the private key and make a key generator for the application.

Locking the code to a serial number

VMProtect allows execution of a part of the program code on a virtual machine. The set of commands of the virtual machine changes on every build of the protected program. The licensing system allows to encrypt a part of virtual machine commands with the key stored in a serial number. Therefore, even if a hacker modifies a conditional jump in the program, the code still will not work without the correct serial number. And since code decryption is managed by the virtual machine, the decryption algorithm is hard to analyze even if the serial number is available.

Limiting the period of free upgrades

The licensing system can write a date into the key so that all application versions after that date will not work with this key. This mechanism allows you to limit the period of free upgrades. For example, upon purchase the current date plus one year is written to the key, so a user will be able to download new versions from the website within one year. The key will work in these versions only. When the one-year period ends, a user has a choice: either use the last working version of the program or purchase an update for one more year.

Key expiration date

The licensing system allows you to write a date into the key, after which that key stops working. This is a convenient option for products that require systematic updates. For example, upon purchase the current date plus one year is put to the key, and the program works for the given user for one year. Unlike the period of free upgrades, the user has no choice here – he has to purchase a new license if he wants to continue using the program.

Limiting the program operation time

The licensing system allows you to limit the maximum operation time of a copy of the program. This proves to be useful in many demo applications. For example, a user wants to test a full-featured copy of the program. In this case you can send to him or her a serial number that limits the maximum session time of the program with say ten minutes. After that, the program stops functioning. This option is also convenient for various server applications, where a user can’t easily restart the program.

Hardware locking

The licensing system allows the developer to receive a hardware identifier of user’s PC based on information about CPU, network card and OS. The licensing system can produce a serial number that will be only valid on that hardware only. This option allows you to limit usage of the application to several computers.

Black list

If a serial number is compromised, the licensing system allows adding such a number into the black list. The blocked serial number will not work in all further versions of the application.

Data storage

The licensing system stores in a serial number and provides to the program the following dаta: a user name, an e-mail and up to 255 bytes of arbitrary information (the so called custom user data). You can use this capability to show additional information in the “About” window of the program, to implement additional security checks if the entered serial number, to store constants available in the registered version of the product only and so on.

Time-limited demo versions

With the activation system, a software developer can automatically build time-limited serial numbers locked to user’s hardware. This allows you to setup a secure trial period (demo) for an application, because VMProtect does not try to hide trial marks on user’s computer, and instead generates a working, but time-limited serial number. Activation is carried out over the Internet, but the activation API also provides the offline activation mode.

What can’t the licensing system do and why?

100% secure hardware lock

Besides the licensing system allows locking a serial number to a hardware identifier, you should understand that most of hardware data is received using operating system means, so a hacker can intercept them and modify this information. The licensing system uses certain ways to minimize this risk, but if you need 100% secure hardware lock, we recommend to use a solution based on USB keys also supported by VMProtect.

Licensing system

The licensing system creates and checks for validity serial numbers. It supports limiting the protected software by date and time, locking it to specific hardware, encrypting the code with a serial number, limiting the period of free updates and many more. The system is based on asymmetric cryptographic algorithms to minimize chances that an unauthorized serial number generator will be built. To protect the licensing system itself, VMProtect uses virtualization therefore minimizing chances that the application will be cracked or patched on the code level.

!Important

The license system is available for Ultimate edition only.