java - 如何检查我的 Java 程序是否在虚拟机中运行?

标签 java c++ virtual-machine jna

<分区>

我有一个 Java 软件需要授权给客户。我创建了一个许可模块,它只允许软件在激活它的特定硬件上执行。

但是我不希望客户端在虚拟机中激活软件,这意味着软件的多个拷贝可以使用一个许可证。

如何阻止我的软件安装在 VM 中?

注意:

  1. 我已经对此进行了研究并找到了解决方案。我把它贴在这里,这样它可能对 其他开发者。
  2. 它仅适用于 VmWareVirtual PC 不适用于 ParallelsVirtualBox
  3. 我找不到纯 Java 解决方案。它依赖于 native 代码。

如果您知道更好的解决方案,请将其作为答案发布。

最佳答案

检查 VM 存在的一些方法是 -

  1. 寻找 VM guest 工具创建的进程、文件、注册表项等 VM 工件的存在
  2. 使用虚拟化软件公开的非标准 x86 指令

如果您想了解更多信息,here 中有一个讨论这些主题的很好的演示文稿。

由于方法 2 是最简单和直接的,我们将使用它。

以下代码片段可用于检查代码是否在 VMware 虚拟机中运行 -

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;
}

这是从 Code Project 上发布的项目中提取的代码的一部分。由于用于演示,它不包含用于检查 Microsoft Virtual PC 是否存在的代码。您可以访问主站点以获取 Virtual PC 的代码和预编译的演示。该站点上还提供了一个 DLL,但具有讽刺意味的是,这些函数并未导出,这违背了 DLL 的目的,因为您无法在程序中调用它。因此我不得不自己编译上面的代码并创建一个 DLL。

__try__catch 是 Microsoft 特定的 C++ 扩展。您需要使用 Windows 上的 Visual Studio 进行编译,因为使用 gcc 将不起作用。

下载并安装以下组件 -

  1. Visual Studio 2005(或更高版本)
  2. 微软平台 SDK 2003

创建一个新的 DLL 项目并将上面的代码粘贴到主 CPP 文件中。

将此添加到您的代码中以导出您的函数。如果没有这个,您的 DLL 将被编译,但函数将无法从外部调用。

extern "C" __declspec(dllexport) 
bool IsInsideVMWare()
{
  //Code
}

现在通过构建 Visual Studio 项目来编译 DLL。如果您遇到诸如 windows.h not found 之类的错误或其他错误,请咨询这些 stackoverflow 问题 -

要检查该函数是否已导出到 DLL,您可以使用 DLL Export Viewer 查看由您的 DLL 导出(即公开)的函数列表。

现在我们有了检查 VM 存在的组件。我们所需要做的就是从 Java 中调用它。

下载从 Java 调用 native 代码所需的 JNA 库。 创建一个 Eclipse 项目并将 DLLJNA 添加到类路径。

创建以下文件 -

VmCheck.java

package in.ksharma;

import com.sun.jna.Library;

public interface VmCheck extends Library {
    boolean IsInsideVMWare();
    boolean IsInsideVPC();
}

测试.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.");
    }
}

这是一张显示在 VM 中运行的最终代码的屏幕截图 - enter image description here

关于java - 如何检查我的 Java 程序是否在虚拟机中运行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18122711/

相关文章:

java - Android studio 从 2.1 更新到 2.3 后出现错误(无法启动)

C++ 基于栈的对象分配

javascript - 将 Apache Thrift 与 Apache Cordova 相结合

linux - 使用 tomcat 从 vmware 沙箱发送电子邮件

mysql - 远程访问虚拟机上的MySQL服务器

ubuntu - 使用 Gnome Ubuntu : I encounter a Black Screen 安装和运行 XRDP(远程桌面)时出错

java - 如何启动一个新 Activity 并在该 Activity 中启动一个方法

java - Log4j2 编程配置不滚动文件

java - UML 图 - 具有多个参数的方法?

c++ - 将应用程序从 Solaris 移植到 Linux