java中操作系统的名称(不是"os.name")

Wou*_*ens 4 java operating-system jvm runtime.exec

我想知道如何掌握jvm运行的那种操作系统.它也必须是"安全的",所以System.getProperty("os.name")不是一个真正的选择,因为它可以通过-D指令轻易绕过.

通过"安全",我的意思是不容置疑.它适用于桌面应用程序.用户总是可以对代码进行反混淆,反编译,编辑和重新编译,但这比将-D传递给jvm要困难得多.我们想要修补不平凡,而不是不可能(因为那是不可能做到的).

Mic*_*rdt 15

首先,保护代码不被其运行时环境任意操纵是不可能的.但是为了使它至少难以欺骗你的支票,最好的选择可能是某种基于文件系统的操作系统指纹识别.

File.listRoots()是你的出发点; 在类Unix系统上,它将返回一个包含/ etc,/ usr等特征目录的根.在Windows上,它将返回多个结果,但AFAIK OS安装驱动器不一定是C:并且特征目录不同Windows版本和区域设置 - 小心不要假设每个人都运行英文版的Vista.

你可以投入大量的工作来识别不同版本的Windows和Linux,以及BSD或MacOS - 一旦它在那里,从编译后的代码中删除支票可能会花费很少的工作.


Kev*_*vin 8

系统属性是我所知道的获取操作系统信息的唯一方法.甚至OperatingSystemMXBean也从os.X系统属性中获取其值.

如果有人可以修改你的应用程序的启动方式,那么你遇到的问题比os.name是正确的要大.

但是,如果您担心在应用程序运行时设置该属性的恶意代码,则可以使用Java安全管理器确保安全地保护属性.


Kit*_*YMG 8

你为什么担心这个?如果最终用户愚蠢到捣乱os.*属性,为什么不让应用程序爆炸呢?

话虽如此,这些可能适合您的目的

//can be defeated by adding com.apple.eawt.Application to the classpath
public boolean isMac() {
    try {
        Class.forName("com.apple.eawt.Application");
        return true;
    } catch(Exception e) {
        return false;
    }
}

//can be defeated by creating a cmd.exe in PATH
public boolean isWin() {
    try{
        Runtime.getRuntime().exec( new String[]{"cmd.exe","/C","dir"} ).waitFor();
        return true;
    } catch (Exception e) {
        return false;
    }
}

public boolean isLinux() {
    if(isMac()) return false;
    try{
        Runtime.getRuntime().exec(  new String[]{"sh","-c","ls"} ).waitFor();
        return true;
    } catch (Exception e) {
        return false;
    }
}
Run Code Online (Sandbox Code Playgroud)