操作系统名称,在java(不是"操作系统。名称")
-
18-09-2019 - |
题
我想知道如何找到一种操作系统jvm上运行。它必须是"安全"为好,这样 System.getProperty("os.name")
真的不是一个选项,因为它可以平凡避免的-D的指令。
通过"安全",我的意思是平凡的规避。这是一个桌面应用程序。用户可以始终deobfuscate,反编译、编辑和编译代码的,但是明显难度比传D jvm。我们要让平凡的修修补补的,不是不可能的(因为不可能完成的).
解决方案
首先,这是不可能的,以保护代码从通过它的运行时环境任意被操纵。但为了使其至少很难骗过检查,最好的选择可能是某种形式的文件系统为基础的操作系统指纹。
File.listRoots() 是你的起点;类似Unix的系统上它会返回包含像/等,在/ usr等在Windows特性目录单根的,它会返回多个结果,但AFAIK OS安装驱动器不一定是C:和特征目录跨越不同Windows版本和语言环境 - 要小心,不要认为每个人都运行Vista的英语版本
您可以大量的工作投入到识别不同版本的Windows和Linux,以及BSD或者MacOS - 它可能会少走很多工作,从编译的代码删除检查,一旦它在那里。 p>
其他提示
的系统属性是我知道的,以获得操作系统信息的唯一方式。即使是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”
您可以使用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));
}
}