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