These days I intensively read maybe all posts and topics based on software security, but I couldn't find any solution that would be acceptable for me (if there are any of them matching my requirements). So I have .EXE application written in the c# programming language and I have an installation which places all necessary DLLs and config files on the chosen path in the system. The system is always a windows environment with no internet connection to the outside world.

So my question is: Is there any good approach for licensing my application, most importantly can I prevent propagation and installation of my application on different systems (machines)? How I can detect if for example, the same license file or product key are used in different windows/machines? With every approach that I found there is always a problem with this part of licensing or most of them were an online approach. Additionally even a server machine in offline mode isn't an option. Is there any solution?

  • 1
    If there's no way of returning data to you from EVERY install, then you can't "detect" anything useful... So find another solution...
    – svin83
    Feb 8 '21 at 18:07

Is there any solution?


For there to be a complete, perfect solution, you cannot be in a situation where the licensee has full control over the whole runtime environment; for, when this happens, by definition the program can be made to run in any number of copies one desires.

Control must be taken away from the licensee, which means there need to be something they do not control. So, you can have a solution if you change your premises to include this:

  • obviously they cannot control an external license server (but you want to work offline)
  • it was believed (wrongly) that they could not control some specific characteristics or features of the hardware (disk serial numbers, MAC addresses...). Virtual environments put paid to that notion (but maybe you can do something there?)
  • they cannot control an embedded license server - that is, a smart key/dongle (this is another option. Keep in mind that this goes against ease of use, and often leads to a loss of customer base - would you rather have 50% licensing on 10000 customers, or 100% on one thousand?).
  • they cannot control the flow of time and the software's inputs both.

Any other setup will fail in a very simple way like this:

  • I install the software on a computer. That computer is actually a virtual machine residing on a server I control. This, by the way, is where the market is going: few, redundated physical machines with VMs that share storage and CPU resources. Requiring a software to run in an "unvirtualized environment" might soon become similar to requiring the OS to be 32 bit.
  • I make however many separated, isolated copies of that VM as I want. Each of them "believes" to be the original one and "sees" itself in a computer that is indistinguishable from the original, because it is.
  • I now have however many copies of the software as I want.

Some protection schemes try to leverage blockchain and a periodic update system to prevent the software from being "reverted" to a previous state. This way, the software can ensure that it has been running more than a specific set time or that it has processed more than a given quantity of information; when this happens, the software requires an "update" to continue running, and the "update" embeds a random public key. As a result, the update released for instance #1 of the software will not work to update any other instances, that, lacking the update, will legitimately refuse to run (and you cannot require ten updates for the two licenses you have). Thwarting this scheme is sometimes possible but typically requires a premeditated, expensive hacking effort, and therefore is usually never done; which makes this approach perhaps suitable for your purposes.

For example, a software that examines invoice information for tax optimization purposes will refuse to examine invoices dated farther in the future than 180 days from the last update. To force it to work, it would need to be fed invoices whose dates are artificially set back, then the optimization data would need to be reprocessed to bring the dates back to normal, at the risk of introducing calculation errors that could result in huge fines instead of the expected deductions. So, cracking the program is not feasible. In this case, the thing the licensee cannot (afford to) control is the program's input.

However, the larger part of the "license" battle is fought and won on licensing and software flexibility and affordability. You might... let's say "not discourage" copying, if that allows you to get new customers (this is common for those softwares that require significant customizations to reap the full benefits). Knowing you're not going to gouge the customers for additional licenses will go a long way against plans to replace your software altogether in a few months' time. Also, much depends on the customers themselves: a large firm has a strong incentive towards running a tight ship and only using fully licensed software, just in case they might get audited. The savings from pirate copies might simply not be worth it.

  • Software can be written to detect VMs and quit with an error message...
    – svin83
    Feb 8 '21 at 17:51
  • 2
    @svin83 yes, of course - but which VM? Note that in some environments, even the normal execution on a physical hardware is virtualized to some extent nonetheless. And actually you might need to run on a legitimate virtual server, unless you want to have a hard requirement that the machine be a physical one - at the risk of losing market.
    – LSerni
    Feb 8 '21 at 18:24
  • 1
    Losing market is indeed a real risk when it comes to "overprotect" a software Feb 8 '21 at 18:31
  • 1
    @svin83 I've been working on VM detection stuff for years. Every trick can be defeated.
    – Polynomial
    Feb 9 '21 at 3:12
  • Just like every security measure or drm scheme can be defeated...
    – svin83
    Feb 10 '21 at 19:00

As long as you talk about software protection, there are as many ways to protect software as ways to defeat those protections.

All you can do is make it hard to break. As svin83 commented you can indeed make sure that your software detects its running inside a VM (which obviously could be bypassed too). There are really plenty of technics to do so the easiest way could be :

  • Get Hardware Serial Number: WMIC BIOS GET SERIALNUMBER

You can read Registry key value artifacts (non exhaustive list):

  • HARDWARE\DEVICEMAP\Scsi\Scsi Port 0\Scsi Bus 0\Target Id 0\Logical Unit Id 0 (Identifier) (VBOX)
  • HARDWARE\DEVICEMAP\Scsi\Scsi Port 0\Scsi Bus 0\Target Id 0\Logical Unit Id 0 (Identifier) (QEMU)
  • HARDWARE\Description\System (SystemBiosVersion) (VBOX)
  • HARDWARE\Description\System (SystemBiosVersion) (QEMU)
  • HARDWARE\Description\System (VideoBiosVersion) (VIRTUALBOX)
  • HARDWARE\Description\System (SystemBiosDate) (06/23/99)
  • HARDWARE\DEVICEMAP\Scsi\Scsi Port 0\Scsi Bus 0\Target Id 0\Logical Unit Id 0 (Identifier) (VMWARE)
  • HARDWARE\DEVICEMAP\Scsi\Scsi Port 1\Scsi Bus 0\Target Id 0\Logical Unit Id 0 (Identifier) (VMWARE)
  • HARDWARE\DEVICEMAP\Scsi\Scsi Port 2\Scsi Bus 0\Target Id 0\Logical Unit Id 0 (Identifier) (VMWARE)
  • SYSTEM\ControlSet001\Control\SystemInformation (SystemManufacturer) (VMWARE)
  • SYSTEM\ControlSet001\Control\SystemInformation (SystemProductName) (VMWARE)

Check for File system artifacts (non exhaustive list):

  • "system32\drivers\VBoxMouse.sys"
  • "system32\drivers\VBoxGuest.sys"
  • "system32\drivers\VBoxSF.sys"
  • "system32\drivers\VBoxVideo.sys"
  • "system32\vboxdisp.dll"
  • "system32\vboxhook.dll"
  • "system32\vboxmrxnp.dll"
  • "system32\vboxogl.dll"
  • "system32\vboxoglarrayspu.dll"
  • "system32\vboxoglcrutil.dll"
  • "system32\vboxoglerrorspu.dll"
  • "system32\vboxoglfeedbackspu.dll"
  • "system32\vboxoglpackspu.dll"
  • "system32\vboxoglpassthroughspu.dll"
  • "system32\vboxservice.exe"
  • "system32\vboxtray.exe"
  • "system32\VBoxControl.exe"
  • "system32\drivers\vmmouse.sys"
  • "system32\drivers\vmhgfs.sys"
  • "system32\drivers\vm3dmp.sys"
  • "system32\drivers\vmci.sys"
  • "system32\drivers\vmhgfs.sys"

You have to add some Anti-Dumping/Anti-injection/Anti-debugging features (absolutely not exhaustive list):

  • IsDebuggerPresent
  • CheckRemoteDebuggerPresent
  • Process Environment Block (BeingDebugged)
  • Process Environment Block (NtGlobalFlag)
  • ProcessHeap (Flags)
  • ProcessHeap (ForceFlags)
  • Low Fragmentation Heap (LFH)
  • NtQueryInformationProcess (ProcessDebugPort)
  • NtQueryInformationProcess (ProcessDebugFlags)
  • NtQueryInformationProcess (ProcessDebugObject)
  • WudfIsAnyDebuggerPresent
  • Enumerate modules with EnumProcessModulesEx (32-bit, 64-bit, and all options)
  • Enumerate modules with ToolHelp32
  • Enumerate the process LDR structures with LdrEnumerateLoadedModules
  • Erase PE header from memory
  • SizeOfImage

Your software is a C# assembly, you must be aware of how easy it is to be decompiled/debugged so think of obfuscating it, there are several tools that could do this, but keep in mind that anything that could be obfuscated automatically, could be deobfuscated automatically! so choose wisely and try to test your obfuscator against some deobfuscators (like https://github.com/de4dot/de4dot).

There are several packers that wrap your .NET assembly into an encrypted Win32, Themida is a great one (https://www.oreans.com/).

Another thing, try to make it hard to tamper your software, the easiest way to do it is using a strong name signature (even if it's not meant to protect against tampering, it does it quite well).

What to say more... Use asymmetric encryption to generate your product licenses, at least you can be sure no keygen will be released.

An interesting topic here.

Anyway, and whatever you do, keep in mind that if a skillfully reverse engineer wants to crack your app, he/she will!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.