我想知道如何找到一种操作系统jvm上运行。它必须是"安全"为好,这样 System.getProperty("os.name") 真的不是一个选项,因为它可以平凡避免的-D的指令。

通过"安全",我的意思是平凡的规避。这是一个桌面应用程序。用户可以始终deobfuscate,反编译、编辑和编译代码的,但是明显难度比传D jvm。我们要让平凡的修修补补的,不是不可能的(因为不可能完成的).

有帮助吗?

解决方案

首先,这是不可能的,以保护代码从通过它的运行时环境任意被操纵。但为了使其至少很难骗过检查,最好的选择可能是某种形式的文件系统为基础的操作系统指纹

File.listRoots() 是你的起点;类似Unix的系统上它会返回包含像/等,在/ usr等在Windows特性目录单根的,它会返回多个结果,但AFAIK OS安装驱动器不一定是C:和特征目录跨越不同Windows版本和语言环境 - 要小心,不要认为每个人都运行Vista的英语版本

您可以大量的工作投入到识别不同版本的Windows和Linux,以及BSD或者MacOS - 它可能会少走很多工作,从编译的代码删除检查,一旦它在那里

其他提示

的系统属性是我知道的,以获得操作系统信息的唯一方式。即使是OperatingSystemMXBean从os.X系统属性取其值。

如果有人能与你的应用程序是如何启动鼓捣,你有更大的问题比如果os.name是正确的。

不过,如果你担心恶意代码设置该属性的应用程序运行时,您可以使用Java安全管理,以确保性能安全防护。

你为什么要担心呢?如果最终用户是足够哑与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;
    }
}

可以通过Runtime类(exec方法)运行外部CMD像“VER”获取OS的版本(如果在视窗)或“UNAME -a”

Apache 公共-vf 摘要的某些处理,所以你可以处理 OsOsFamily.但在内部,这仍然使用系统。getProperty(..)获得价值。我不知道的任何其他方式JVM获得这些价值观。

如果有人在一个位置改变的特性的传递给JVM你已经有了更大的问题要处理,而不他们改变的奇怪的酒店。

你能详细说明你是什么意思通过的安全。安全从谁?

您可以使用exec来尝试运行,你可以期望一个操作系统或其他存在着一些无害的程序 - 如“C:\ WINDOWS \ SYSTEM \ dir.exe”的窗口和“/斌/ LS”为* nix中 - 看看他们是否成功运行或弹了出来。不过,当然是有人知道你这样做,并试图破坏它,他们可以用这些名字创建可执行文件。

它究竟是什么,你想从安全的?如果有人故意搞砸了启动您的应用程序,然后将其炸毁因为你想运行不存在的命令,不会适当的回应是,“如果你的脚受伤,停止拍摄自己的脚。”如果你正在做的是运行OS命令,想必用户能够访问你的应用程序以外的人,所以我看不出谎报OS危及安全性。

有在VM比使用你提到的性质的其它没有公共API。

我的希望是,由于Java的应该是安全的,该VM会忽略任何企图通过命令行覆盖这些值,但事实并非如此。

您可以尝试一个安全管理器,其不允许写这些值,但我的猜测是,那么,该值将是干脆为空(因为VM不能改变它,要么)。

您还可以检查通过System.getenv()的环境变量,但用户可自由地修改这些以及之前启动。这只是不是很容易(至少在Windows上)来修改变量作为命令行的一部分来启动应用程序。

如果安全是您的首要目标,你可能会想尝试一些JNI补充。 首先,如果你试图在Linux或OS X加载DLL,我打赌它会崩溃/无法加载。 其次,从DLL可以调用OS” API,这样你就不会局限于什么Java环境中提供。

我同意jni/南国防军是一个更好的选择。刚才叫什么样的人。loadLibrary("myLib"),并在windows它将负荷myLib.dll上linux-myLib.此。这是最安全的方式之一就是不可能的混乱。把所有的操作系统特定的代码图书馆和保持汇编的版本在你的瓶子。

现代Linux系统有一个特殊的文件/proc/version,这给内核版本ID。因此,如果该文件存在一个匹配合适的模式(例如,字Linux开始),你增加你在Linux计算机上运行的概率。相反,如果它不存在或不匹配的模式,你可以肯定你是不是在Linux上运行。

你为什么不结合以下,并用它来进行插值,方式规避可能是困难的。

public class OpertingSystemInfo 
{
    public static void main(String[] args)
    {
        String nameOS = "os.name";        
        String versionOS = "os.version";        
        String architectureOS = "os.arch";
    System.out.println("\n    The information about OS");
        System.out.println("\nName of the OS: " + 
System.getProperty(nameOS));
        System.out.println("Version of the OS: " + 
System.getProperty(versionOS));
        System.out.println("Architecture of THe OS: " + 
System.getProperty(architectureOS));
    }
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top