A handy function to print flags
First of all, we need a convenient function to convert numeric flag values into readable serial number status messages. 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 its size, the function is quite simple — it checks all bit flags one by one and prints those that are present in the status variable. Replace printf in the code after checking the serial number with a call to print_state, and update 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 restore the original key by removing the “1” and run the program again:
state = 0
We are registered.
Now that we can see status flags of a serial number, let’s move on 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 stored in one of the fields of the structure. Each method is intended for a specific use case.
The first check of a serial number is performed during installation. At this moment, you should reject invalid numbers, expired numbers, blacklisted numbers, and so on. Some limitations, such as maximum program runtime or serial number expiration date, should also be checked at runtime. In such cases, the VMProtectGetSerialNumberState() method is the fastest and most convenient approach. And if you need full information about the serial number, you can use the more powerful VMProtectGetSerialNumberData() function.