To protect individual code fragments and string constants, you can insert special markers into the source code of your application. Markers are implemented as calls to functions imported from the SDK library:
For .NET
For Windows
- 32-bit user-mode applications — VMProtectSDK32.dll
- 32-bit kernel drivers — VMProtectDDK32.sys
- 64-bit user-mode applications — VMProtectSDK64.dll
- 64-bit kernel drivers — VMProtectDDK64.sys
For Linux
- 32-bit applications — libVMProtectSDK32.so
- 64-bit applications — libVMProtectSDK64.so
For macOS
The procedures and functions provided by the SDK do not perform any actions and serve only as labels used by VMProtect to determine the boundaries of protected code blocks. The beginning and end of a protected block are marked as follows:
C/C++
#include "VMProtectSDK.h"
VMProtectBegin(MARKER_TITLE);
...
VMProtectEnd();
C#
using System.Reflection;
class Foo
{
[Obfuscation(Feature = "virtualization", Exclude = false)]
// Feature = "virtualization", "ultra", "mutation",
// "virtualizationlockbykey", "ultralockbykey"
public Foo()
{
...
Pascal
uses VMProtectSDK;
VMProtectBegin(MARKER_TITLE);
...
VMProtectEnd;
MASM
include VMProtectSDK.inc
invoke VMProtectBegin,SADD(MARKER_TITLE)
...
invoke VMProtectEnd
Visual Basic
VMProtectBegin (StrPtr(MARKER_TITLE))
...
VMProtectEnd
Instead of VMProtectBegin, you can also use markers with predefined compilation types:
- VMProtectBeginVirtualization — uses the “Virtualization” compilation type.
- VMProtectBeginMutation — uses the “Mutation” compilation type.
- VMProtectBeginUltra — uses the “Ultra” compilation type.
Markers are processed as follows: when VMProtect analyzes the code of the protected application, it locates all calls to VMProtectSDK procedures and functions. The boundaries of protected blocks are determined by pairs of markers such as VMProtectBegin / VMProtectBeginVirtualization / VMProtectBeginMutation / VMProtectBeginUltra and VMProtectEnd. During code processing, VMProtect removes both the markers themselves and all references to VMProtectSDK, so there is no need to include these libraries in your application setup package. Markers are removed regardless of whether they are included in the compilation or not. When named markers are used, their names are also removed.
If a marker title is specified, the marker receives a name in the form “VMProtectMarker MARKER_TITLE”. If no title is specified, a unique name is generated automatically in the form “VMProtectMarker” + marker serial number. However, unnamed markers have a significant disadvantage: if a new marker is inserted into the program code, the numbering of all unnamed markers changes. Therefore, we strongly recommend always using named markers.
A particularly important consideration when working with markers is that jumps from unprotected code areas into protected marker regions must not be allowed. For example, this may happen if only part of a loop is enclosed within markers. If an application that uses markers stops functioning correctly after protection is applied, you can detect jumps from unprotected areas by enabling the “Debug mode” option. In this mode, when the protected application is executed under a debugger, execution will be interrupted whenever a jump from an unprotected area into protected code is detected. After all such jumps are identified, you should either adjust the marker placement or, if this is impossible, mark the corresponding addresses as external using the GUI version of VMProtect.
To protect individual code fragments and string constants, you can insert special markers into the source code of your application. Markers are implemented as calls to functions imported from the SDK library:
For .NET
For Windows
- 32-bit user-mode applications — VMProtectSDK32.dll
- 32-bit kernel drivers — VMProtectDDK32.sys
- 64-bit user-mode applications — VMProtectSDK64.dll
- 64-bit kernel drivers — VMProtectDDK64.sys
For Linux
- 32-bit applications — libVMProtectSDK32.so
- 64-bit applications — libVMProtectSDK64.so
For macOS
The procedures and functions provided by the SDK do not perform any actions and serve only as labels used by VMProtect to determine the boundaries of protected code blocks. The beginning and end of a protected block are marked as follows:
C/C++
#include "VMProtectSDK.h"
VMProtectBegin(MARKER_TITLE);
...
VMProtectEnd();
C#
using System.Reflection;
class Foo
{
[Obfuscation(Feature = "virtualization", Exclude = false)]
// Feature = "virtualization", "ultra", "mutation",
// "virtualizationlockbykey", "ultralockbykey"
public Foo()
{
...
Pascal
uses VMProtectSDK;
VMProtectBegin(MARKER_TITLE);
...
VMProtectEnd;
MASM
include VMProtectSDK.inc
invoke VMProtectBegin,SADD(MARKER_TITLE)
...
invoke VMProtectEnd
Visual Basic
VMProtectBegin (StrPtr(MARKER_TITLE))
...
VMProtectEnd
Instead of VMProtectBegin, you can also use markers with predefined compilation types:
- VMProtectBeginVirtualization — uses the “Virtualization” compilation type.
- VMProtectBeginMutation — uses the “Mutation” compilation type.
- VMProtectBeginUltra — uses the “Ultra” compilation type.
Markers are processed as follows: when VMProtect analyzes the code of the protected application, it locates all calls to VMProtectSDK procedures and functions. The boundaries of protected blocks are determined by pairs of markers such as VMProtectBegin / VMProtectBeginVirtualization / VMProtectBeginMutation / VMProtectBeginUltra and VMProtectEnd. During code processing, VMProtect removes both the markers themselves and all references to VMProtectSDK, so there is no need to include these libraries in your application setup package. Markers are removed regardless of whether they are included in the compilation or not. When named markers are used, their names are also removed.
If a marker title is specified, the marker receives a name in the form “VMProtectMarker MARKER_TITLE”. If no title is specified, a unique name is generated automatically in the form “VMProtectMarker” + marker serial number. However, unnamed markers have a significant disadvantage: if a new marker is inserted into the program code, the numbering of all unnamed markers changes. Therefore, we strongly recommend always using named markers.
A particularly important consideration when working with markers is that jumps from unprotected code areas into protected marker regions must not be allowed. For example, this may happen if only part of a loop is enclosed within markers. If an application that uses markers stops functioning correctly after protection is applied, you can detect jumps from unprotected areas by enabling the “Debug mode” option. In this mode, when the protected application is executed under a debugger, execution will be interrupted whenever a jump from an unprotected area into protected code is detected. After all such jumps are identified, you should either adjust the marker placement or, if this is impossible, mark the corresponding addresses as external using the GUI version of VMProtect.