Skip to content

Inserting Protection Macros in EXE/DLLs

This section explains how to mark code blocks in EXEs, DLLs, OCXs, ActiveX controls, screen savers, and other native applications. Device drivers use a different procedure.

You can insert protection macros in three ways:

  • Inline assembly: The macro emits a dummy machine-code sequence recognized by Code Virtualizer.

  • API call: The macro calls a function in VirtualizerSDK.dll. The unprotected application requires this DLL, but Code Virtualizer removes the dependency during protection. You do not need to distribute the DLL with the protected application.

  • ASM module: The application links to an assembly-language file that defines functions with special code sequences. Code Virtualizer identifies macro calls through references to these functions.

Code Virtualizer includes files for several programming languages. Include the appropriate file in your source code to use the protection macros.

VIRTUALIZER is the original generic macro name. We recommend specifying the Virtual Machine in the marker name. For example, use VIRTUALIZER_TIGER_WHITE_START/END instead of VIRTUALIZER_START/END. Select the available architectures in the Virtual Machine panel.

The VIRTUALIZER_MUTATE_ONLY macro mutates code without virtualizing it. It provides less protection than virtualization, but is suitable when you need basic obfuscation and high runtime performance.

Examples in C/C++ and Delphi

The following examples show how to use Code Virtualizer in C/C++ and Delphi.

C/C++ Example

LRESULT CALLBACK MainHandler(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
   switch (message)
   {
   case WM_INITDIALOG:

      VIRTUALIZER_LION_WHITE_START                       // the following block of code is protected under "Lion White" VM

        if (WLRegGetStatus(NULL) == 1)
       {
           WLRegGetLicenseInfo(Name, Company, ExtraData);
           SetDlgItemText(hDlg, IDC_NAMEEDIT, Name);
           SetDlgItemText(hDlg, IDC_COMPANYNAME, Company);
           SetDlgItemText(hDlg, IDC_EXTRAEDIT, ExtraData);
       }

      VIRTUALIZER_LION_WHITE_END                         // end of the block to protect

       return TRUE;

   case WM_COMMAND:

       if (LOWORD(wParam) == IDCANCEL)
       {

          VIRTUALIZER_FLY_WHITE_START                    // the following block of code is protected under "Fly White" VM

           EndDialog(hDlg, LOWORD(wParam));

          VIRTUALIZER_FLY_WHITE_END                      // end of the block to protect

           return TRUE;
       }
       break;
   }
   return FALSE;
}

Delphi Example

function TfmMain.GetCRC32(FileName: string): string;
begin

 {$I VIRTUALIZER_LION_WHITE_START.inc}     // the following block of code is protected under "Lion White" VM

 BuildCRCTable;
 CRC := $FFFFFFFF;

 AssignFile(F, FileName);
 FileMode := 0;
 Reset(F);

{$I VIRTUALIZER_LION_WHITE_END.inc}         // end of the block to protect

 GetMem(Buffer, SizeOf(B));

{$I VIRTUALIZER_FLY_WHITE_START.inc}        // the following block of code is protected under "Fly White" VM

 repeat
   FillChar(b, SizeOf(b), 0);
   BlockRead(F, b, SizeOf(b), e);
   for i := 0 to (e-1) do
    CRC := RecountCRC(b[i], CRC);
 until (e < 255) or (IOresult <> 0);

{$I VIRTUALIZER_FLY_WHITE_END.inc}          // end of the block to protect

 {$I VIRTUALIZER_TIGER_RED_START.inc}       // the following block of code is protected under "Tiger Red" VM

 FreeMem(Buffer, SizeOf(B));
 CloseFile(F);
 CRC := Not CRC;
 Result := '$' + HextL(CRC);

 {$I VIRTUALIZER_TIGER_RED_END.inc}         // end of the block to protect

end;

Note for C/C++ developers

In the VirtualizerSDK.h file, you can find two special definitions:

#define CV_X32_INSERT_VIA_INLINE

#define CV_X64_INSERT_VIA_INLINE

These definitions control whether macros use inline assembly or API calls. We recommend inline assembly for x86 applications and API calls for x64 and ARM64 applications. The insertion method does not affect the strength of the protection.