Question

Je voudrais savoir comment obtenir le type de Système d'Exploitation de la jvm en cours d'exécution sur.Il doit être en "sécurité", ainsi System.getProperty("os.name") n'est pas vraiment une option, car il peut être trivialement contournée avec l'option-D de la directive.

Par "sécurité", je veux dire non triviaux de la contourner.C'est pour une application de bureau.L'utilisateur peut toujours deobfuscate, décompiler, modifier et recompiler le code, mais c'est beaucoup plus difficile que le passage de l'-D de la jvm.Nous voulons faire de bricolage non trivial, pas impossible (car il ne peut pas être fait).

Était-ce utile?

La solution

Tout d'abord, il est impossible de protéger le code d'être manipulé de façon arbitraire par son environnement d'exécution.Mais pour le rendre au moins difficiles à tromper votre chèque, le meilleur pari est probablement une sorte de système de fichiers basé OS fingerprinting.

Fichier.listRoots() est votre point de départ;sur un système de type Unix, il sera de retour une racine unique contenant caractéristique des répertoires comme /etc, /usr, etc.Sur Windows, il renvoie plusieurs résultats, mais autant que je sache, l'installation de l'OS lecteur n'est pas nécessairement C:et la caractéristique de répertoires diffèrent selon les versions de Windows et les paramètres régionaux - être prudent de ne pas supposer que tout le monde s'exécute une version anglaise de Vista.

Vous pouvez investir beaucoup de travail en reconnaissant les différentes versions de Windows et Linux, BSD ou MacOS - et il serait probablement prendre beaucoup moins de travail pour supprimer la case code compilé une fois qu'elle est là.

Autres conseils

Les propriétés du système sont la seule façon que je connaisse pour obtenir des informations du système d'exploitation. Même le OperatingSystemMXBean prend ses valeurs des propriétés du système OS.X.

Si quelqu'un peut bricoler avec la façon dont votre application est lancée, vous avez des problèmes plus graves que si os.name est correct.

Cependant, si vous êtes inquiet au sujet du code malveillant mise que la propriété pendant que votre application est en cours d'exécution, vous pouvez utiliser le gestionnaire de sécurité Java pour faire en sorte que les propriétés sont protégées en toute sécurité.

Pourquoi êtes-vous inquiet à ce sujet? Si un utilisateur final est assez stupide pour jouer avec os. * Propriétés pourquoi ne pas laisser l'application exploser?

Cela étant dit, ceux-ci peuvent fonctionner assez bien pour vos besoins

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

Vous pouvez exécuter par la classe d'exécution (méthode exec) une cmd externes comme « ver » pour obtenir la version de l'OS (si dans les fenêtres) ou « uname -a »

commons-VFS abstracts une partie du traitement de sorte que vous pouvez simplement traiter Os et OsFamily . Cependant interne utilise encore ce System.getProperty (..) pour obtenir les valeurs. Je ne connais pas d'autre moyen pour la machine virtuelle Java pour obtenir ces valeurs.

Si quelqu'un est en mesure de modifier les propriétés transmises à la machine virtuelle Java que vous avez de plus gros problèmes à traiter que les changer la propriété bizarre.

Pouvez-vous préciser ce que vous entendez par sécurité. Sécurisez à qui?

Vous pouvez utiliser exec pour essayer d'exécuter certains programmes inoffensifs que vous pouvez attendre d'exister sur un système d'exploitation ou d'une autre - comme « c: \ windows \ system \ dir.exe » pour Windows et « / bin / ls » pour * nix - et voir si elles fonctionnent avec succès ou bombarder. Mais bien sûr, est que quelqu'un sait que vous faites cela et tente de saper, ils pourraient créer avec ces noms executables.

Ce que vous est-ce que vous exactement essayer d'être sûr de? Si quelqu'un délibérément plisse le lancement de votre application et il explose parce que vous essayez d'exécuter des commandes inexistantes, ne serait pas la réponse appropriée soit: « Si vos pieds mal, arrêtez de vous tirer dans le pied. » Si tout ce que vous faites est d'exécuter des commandes OS, probablement l'utilisateur est en mesure d'accéder à ceux à l'extérieur de votre application, donc je ne vois pas comment mentir sur le système d'exploitation compromet la sécurité.

Il n'y a pas d'API publique dans la machine virtuelle autre que d'utiliser les propriétés que vous avez mentionnés.

Mon espoir était que, puisque Java est censé être sûr que la machine virtuelle ignorerait toute tentative de remplacer ces valeurs de la ligne de commande, mais ce n'est pas le cas.

Vous pouvez essayer un SecurityManager qui interdit d'écrire ces valeurs mais je pense que là, la valeur sera tout simplement vide (puisque la machine virtuelle ne peut pas changer, que ce soit).

Vous pouvez également examiner les variables d'environnement par System.getenv (), mais l'utilisateur est libre de les modifier aussi bien avant le démarrage. Il est tout simplement pas aussi facile (au moins sous Windows) pour modifier les variables dans le cadre de la ligne de commande pour démarrer votre application.

Si la sécurité est votre objectif principal, vous pouvez essayer d'ajouter dans certains JNI. Tout d'abord, si vous essayez de charger une DLL sous Linux ou sous Mac OS X, je parie qu'il va planter / ne se charge pas. En second lieu, à partir de cette DLL, vous pouvez appeler l'API du système d'exploitation, de sorte que vous n'êtes pas limité à ce que l'environnement Java offre.

Je suis d'accord que JNI / est une meilleure jna alternative. Il suffit d'appeler quelque chose comme Native.loadLibrary ( « myLib »), et sur les fenêtres, il chargera MYLIB.DLL, sur linux - myLib.so. Il est le plus sûr moyen, on ne peut tout simplement pas salir avec elle. Mettez tout le code spécifique os dans les bibliothèques et conserver des versions compilées dans votre pot.

Les systèmes modernes de Linux ont un /proc/version de fichier spécial, qui donne l'ID de version du noyau. Donc, si ce fichier est présente un correspond à un modèle approprié (par exemple, en commençant par le mot Linux), vous avez augmenté la probabilité que vous exécutez sur un ordinateur Linux. A l'inverse, si elle est absente ou ne correspond pas à ce modèle, vous pouvez être sûr que vous n'êtes pas en cours d'exécution sur Linux.

Pourquoi ne pas vous combinez les suivantes et l'utiliser pour interpoler, que le contournement de façon peut être difficile.

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));
    }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top