I have a Java software that needs to be licensed to clients. I have created a licensing module that would only allow the software to be executed on a specific hardware on which it was activated.
However I don't want the client to activate the software inside a Virtual Machine which would mean that multiple copies of the software could be used with a single license.
How do I stop my software from being installed in a VM?
Note:
VmWare and Virtual PC not on Parallels or VirtualBox
If you know a better solution please post it as an answer.
Some methods to check presence of a VM are -
If you would like to know more, there is a good presentation that discusses these topics here.
Since method 2 is the easiest and straightforward we'd be using it.
Following code snippet can be used to check if the code is running in VMware Virtual Machine -
bool IsInsideVMWare()
{
  bool rc = true;
  __try
  {
    __asm
    {
      push   edx
      push   ecx
      push   ebx
      mov    eax, 'VMXh'
      mov    ebx, 0 // any value but not the MAGIC VALUE
      mov    ecx, 10 // get VMWare version
      mov    edx, 'VX' // port number
      in     eax, dx // read port
                     // on return EAX returns the VERSION
      cmp    ebx, 'VMXh' // is it a reply from VMWare?
      setz   [rc] // set return value
      pop    ebx
      pop    ecx
      pop    edx
    }
  }
  __except(EXCEPTION_EXECUTE_HANDLER)
  {
    rc = false;
  }
  return rc;
}
This is a part of code taken from a project published on Code Project. Being meant for demonstration it does not include code to check presence of Microsoft Virtual PC. You can visit the main site to get code for Virtual PC and a pre-compiled demo. A DLL is also provided on that site but ironically the functions are not exported which defeats the purpose of DLL as you cannot call it in a program. Thus I had to compile the above code myself and create a DLL.
__try and __catch are Microsoft specific C++ extensions. You'll need to compile this with Visual Studio on Windows as using gcc will not work.
Download and install following components -
Create a new DLL project and paste the above code into the main CPP file.
Add this to your code in order to export your function. Without this your DLL would get compiled but function would not be callable from outside.
extern "C" __declspec(dllexport) 
bool IsInsideVMWare()
{
  //Code
}
Now compile the DLL by building the Visual Studio project. In case you get errors like windows.h not found or other errors consult these stackoverflow questions - 
To check whether the function has been exported to DLL or not you can use DLL Export Viewer to see list of functions exported (i.e. exposed) by your DLL.
Now we have our component that checks for presence of VM. All we need to do is call it from Java.
Download the JNA library which is needed to invoke native code from Java.
Create an Eclipse Project and add the DLL and JNA to classpath.
Create following files -
VmCheck.java
package in.ksharma;
import com.sun.jna.Library;
public interface VmCheck extends Library {
    boolean IsInsideVMWare();
    boolean IsInsideVPC();
}
Test.java
package in.ksharma;
import com.sun.jna.Native;
public class Test {
    public static void main(String[] args) {
        VmCheck lib = (VmCheck) Native.loadLibrary("VmDetect.dll", VmCheck.class);
        if(lib.IsInsideVMWare() || lib.IsInsideVPC())
            System.out.println("I'm trapped in the matrix.");
        else 
            System.out.println("I'm for real.");
    }
}
Here is a screenshot showing the final code running in a VM - 

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With