DllTest - sample code to call Runtime module in C# 8 using VS 2022 and higher
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This project is written in Visual Studio 2022 but will work in more recent versions of Visual Studio
(they will upgrade the Project to the latest version. If prompted you should also upgrade the .NET
framework the project requires). If you are using an older version of Visual Studio please use the
Visual Studio 2002 sample. The code in this project is written in C# version 10. If you are using an
older version of C# then please use the Visual Studio 2002 project.
This sample is a Console application but the code can be easily adapted to be used for other types
applications.
This sample is very similar to the Visual Studio 2002 sample - however the C# code has been updated
to prevent possible Null reference exceptions - introduced in C# version 8.
The main source files in the project are:
File name Description
program.cs main source code file for C#
dris.cs contains the DRIS structure and low-level functions to manipulate it.
The best approach is to compile the sample code and see how it works and then to take the appropriate code
and apply it to your own project. You should include the dris.cs file in your project and use/modify which
ever functions from program.cs you feel are appropriate. The dris.cs file should not be modified.
The sample code contains 11 functions. You will not need to use all these functions in your code. Just use
which ever functions are most appropriate and customise in your own way. The sample code is just a guide.
You should implement the protection in a stronger way using the techniques described in the
"Increasing your Protection" chapter of the manual.
Code marked with !!!! are places where you should customise the sample code so that it will work properly:
* Change the MY_SDSN value to the value of your SDSN
* Change the MY_PRODCODE value to the Product Code in the dongle
* Change the MyAlgorithm code (if you call a user algorithm)
* Change the CryptDRIS code (if you encrypt the DRIS)
* Change the CryptApiData (if you encrypt Data you send to our API)
* Change the MyRWAlgorithm code (if encrypt Data you send to our API using the R/W algorithm)
You will also probably want to replace our error messages with your own. However, you should still
display or log any error codes returned by the protection check otherwise you will not be able to
identify the cause of the error. (You can look up error codes in our knowledge base: microcosm.com/kb).
Note - as you are using the API method in this sample you should protect the correct Dinkey Pro runtime
(e.g. dpwin64.dll) and not your program directly. Because your program is linked to the DLL it is protected.
You can also protect your program with the Shell Method should you wish.
You need to protect the appropriate runtime module for the Platforms you support.
Windows x64 - dpwin64.dll
Windows x86 - dpwin32.dll
Linux x64 - dplin64.so
macOS x64 - dpmac64debug.dylib
If you are using "Any CPU" then include all of the modules. The protected runtime module should be in the
same directory as your compiled assemblies. e.g. bin\release\net6.0.
Note - if you need to protect multiple runtime modules then you will probably want to protect these modules
to the same licence so that they share a common set of protection parameters.
Make sure you remember to do the following:
1) Insert the following namespaces in your code file:
using System.Runtime.InteropServices;
2) Insert the dris.cs file in your project.
2) You need to output the protected runtime modules(s) (e.g. dpwin64.dll etc) to the folder that contains your
assemblies. Otherwise the System.DllNotFoundException error will appear when you run DllTest.
If you wish you can rename the runtime module(s) to a name of your choice. In this case you will need to
modify the dll name in the dris.cs file.
Note - CSharp is an interpreted language and so it is easier to decompile than other languages. You can
improve security if you use an obfuscator to obfuscate your code. Or - even better - you could use the
Shell Method to protect your assemblies. This encrypts your code (making it impossible to decompile).
Notes on Debugging 64-bit Code
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
When you use the 64-bit runtime module (dpwin64.dll) to protect your software the anti-debug code is so
strong that if you are debugging your code, after the call DDProtCheck then it will crash with an SEH
exception. If you want to be able to debug your code then you can setup your project so that your code calls
the debug module (dpwin64debug.dll) in your "debug" build and the standard module (dpwin64.dll) in your
release build. You can do this by modifying the declaration of DDProtCheck64 in dris.cs like this:
class DDProtCheck64
{
#if DEBUG ' debug module
[DllImport("dpwin64debug.dll", CharSet = CharSet.Ansi)]
public static extern int DDProtCheck([In, Out, MarshalAs(UnmanagedType.LPStruct)]DRIS dris, byte[]? data);
#else ' standard module
[DllImport("dpwin64.dll", CharSet = CharSet.Ansi)]
public static extern int DDProtCheck([In, Out, MarshalAs(UnmanagedType.LPStruct)]DRIS dris, byte[]? data);
#endif
}
Note - the debug module has the following restrictions:
1) It will not correctly start a network user (network dongles only). However, other than that the protection
check will function correctly and return success.
2) You will not be able to encrypt the DRIS. (If you do encrypt the DRIS in your release build then you
should make sure that CryptDRIS does not get called in your debug build).
3) The protection check will take slightly longer than normal.
4) The DDGetNetUserList function will return error 428 (not implemented).
5) A temporary subprocess is created which may be (falsely) detected as malicious by anti-virus programs.
This behaviour does not occur in 32-bit code, so if you are using dpwin32.dll then you can debug your code.
Important Note for Windows Store App Developers
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Universal Windows Platform (UWP) application (previously called Windows Store Apps or Metro Apps) are not
compatible with Lite or Plus dongles because the restrictions imposed by these applications. However, you
can protect these Apps with network dongles (because the restrictive access is performed by the non-UWP
DinkeyServer process). If you do this you will need to enable the "Private Networks (Client and Server)"
Capability in your package manifest.
Other Notes
~~~~~~~~~~~
The Shell Method is compatible with .NET Core Console, Windows.Forms and WPF applications. It is supported
under Windows and Linux but not MacOS. It is only supported for .NET Core version 3.0 or higher. If you are
using the Shell Method then you should protect your compiled dll and not the "appHost" (this is a native
executable which is just a stub program that loads the assemblies in your dll). Also do not use "dotnet run"
to launch your application - it will run the unprotected version. Either launch the executable or run using
"dotnet <program.dll>".
If you publish a "single-file executable" file then although this file can be protected we do not recommend
it because it is not secure. (The single-file executable just comprises a stub loader with your compiled
assemblies and configuration files appended to the end of the executable. These files are just considered as
data appended to the executable file in a custom format and therefore are not protected. When you shell
protect your executable you are just protecting the loader but not your assemblies). Instead you need to
build your code and then add protection before publishing. You should protect your assemblies in the obj
directory (and in the platform type you specified) e.g. obj/Release/net6.0/win-x64, because the publish
process takes your assemblies from this location when it builds the single-file executable. You will also
need to distribute all the extra files that DinkeyAdd generates. e.g. <file>.dp64.dll.
If you publish using the ReadytoRun compilation this will not work because it includes mixtures of .NET
assemblies and native code and the .NET Shell Method does not support that.
Visual Studio Installer Projects Extension
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can use this extension to create a project in your solution that will create an installation program / msi
file. Please note that after your application has been built you need to protect it with DinkeyAdd before you
can invoke the installer project. You can do this manually by building your application project (not the entire
solution); then adding protection to your application using DinkeyAdd; then building your installer project.
Or you can automate this by executing DinkeyAddCmd as a post-build step. For example:
"c:\program files (x86)\Dinkey Pro 7.6.0\DinkeyAdd\DinkeyAddCmd.exe" c:\adir\mydapf.dapfj /a2
Note - if you specify "primary output" in your installer project then it will take the files from
obj\Release\net5.0 (for example), rather than bin\Release\net5.0. So, you need to add protection to your files
in this folder.
Note - you will also need to include in your installer project all of the output files mentioned by DinkeyAdd.
e.g. <application_name>.dp64.dll