2012-04-11 3 views
15

Nach dem Vorbild der „Dieses Band wird sich selbst zerstören in fünf Sekunden. Viel Glück, Jim“ ...Selbstzerstörende Anwendung

Wäre es möglich, für eine Anwendung selbst zu löschen (oder es ist ausführbar Wrapper Form) sobald eine voreingestellte Nutzungszeit oder eine andere Bedingung erreicht wurde?

Alternativ, welche anderen Ansätze könnten verwendet werden, um die Anwendung nutzlos zu machen?

Ziel ist es, eine Betaversion ablaufen zu lassen, die Benutzer zu einer aktuelleren Version auffordert.

+2

sicher ist es möglich. Angenommen, Sie haben Ihre App in einem Jar bereitgestellt, können Sie den Klassenpfad über Systemeigenschaften abrufen, das Jar finden und löschen (vorausgesetzt, Java läuft mit ausreichenden Rechten), und das Betriebssystem erlaubt Ihnen, ein Jar zu löschen, während es verwendet wird. – ControlAltDel

+1

Eine andere Möglichkeit besteht darin, das Anfangsdatum der Verwendung im Dateisystem oder in der Systemregistrierung zu speichern. – ControlAltDel

+1

Es gibt einige Fragen zu stackoverflow zum Erstellen einer Demo/Testversion/Testversion. – mbatchkarov

Antwort

8

Es ist möglich. Um die Sperrung der JAR-Datei zu umgehen, muss Ihre Anwendung möglicherweise einen Hintergrundprozess generieren, der wartet, bis die JVM beendet wurde, bevor sie gelöscht wurde.

Dies ist jedoch nicht bombensicher. Jemand könnte die Anwendung installieren und dann die installierten Dateien und Verzeichnisse schreibgeschützt machen, damit sich Ihre Anwendung nicht selbst löschen kann. Der Benutzer (oder sein Administrator) über das Zugriffskontrollsystem des OS hat das letzte Wort darüber, welche Dateien erstellt und gelöscht werden.

+0

Sie haben Recht. Dies würde auch jegliches Überschreiben oder Modifikationen verhindern, wie von @PeterMmm vorgeschlagen. Wie wäre es mit Zugriff auf das Internet? Es würde einige der Steuerlogik trennen. –

+0

Das kann besiegt werden, indem der entsprechende Code in der Anwendung deaktiviert wird. Verschleierung wird das nicht verhindern ... es nur länger dauern lassen. –

+4

Eine Zeitbombe jeglicher Art in Ihre Anwendung zu setzen, ist für Ihre potenziellen zukünftigen Kunden ein Nachteil. Überreden Sie sie zu aktualisieren, indem Sie ihnen ein gutes Produkt anbieten, anstatt Ihr bestehendes zu lähmen. –

-1

ist es ziemlich möglich, denke ich. Vielleicht können Sie das Glas so löschen und sicherstellen, dass die Anwendung verschwindet, da Sie die Rechte haben.

File jar = new File(".\\app.jar"); 
jar.deleteOnExit(); 
System.exit(0); 

auch so etwas wie Nullsoft Scriptable Install System mit dem Sie Ihre eigenen installiert schreiben können/Deinstallationsprogramm helfen sollte.

+1

Zusätzlich können Sie die Datei mit zufälligen Daten überschreiben, damit sie nicht wiederhergestellt werden. – PeterMmm

+0

Habe es einfach versucht, scheint nicht zu funktionieren. – Reg

+0

@PeterMmm Das ist eine Möglichkeit, die ich in Betracht gezogen hatte. Danke, dass du es dir in Erinnerung hast. –

5

Wenn Sie steuern, wo Tester Ihre Anwendung herunterladen, können Sie ein automatisiertes Build-System (zB Jenkins), die Sie könnte jede Nacht eine neue Beta-Versionen erstellen, die eine hartcodierte Ablaufdatum hat:

private static final Date EXPIRY_DATE = <90 days in the future from build date>; 

der obige Zeitpunkt wird durch den Bauprozess

if (EXPIRY_DATE.before(new Date()) { 
    System.out.println("Get a new beta version, please"); 
    System.exit(1); 
} 

Mischung, die mit signed and sealed jars, setzen Hindernisse in dem Weg des decompiling Bytecode und zum Bereitstellen eine alternative Implementierung, die nicht automatisch eingefügt umfassen t Hat Code, können Sie eine zeitlich auslaufende Beta des Codes vergeben.

Das automatische Build-System könnte so konfiguriert werden, dass die Beta-Version automatisch auf den Server hochgeladen wird, auf dem sich die Download-Version befindet.

+1

Danke für die Erwähnung von Jenkins. Wissen Sie, ob dies durch Änderung des Systemdatums behoben werden kann? –

+1

Es könnte ja sein, aber keine Sicherheitsmaßnahme ist absolut knacksicher. Zum Beispiel, wenn Sie die Zeit gegen einen Web-Service überprüfen würden, könnte das umgangen werden, indem der Service-Anruf abgefangen wird, usw. und ich denke, entschlossene Cracker werden alles umgehen. Trotzdem glaube ich nicht, dass ein normaler Benutzer die Systemzeit ändern möchte, da dies wahrscheinlich andere Tools (z. B. Kalender) beeinträchtigen würde. – beny23

+1

Keine Notwendigkeit, ein Cracker hier zu sein, nur Systemzeit ändern. – atamanroman

0

Da Windows die JAR Datei sperrt, während er läuft, können Sie löschen Sie es nicht von einer eigenen Java-Code daher benötigen Sie eine Batch Datei:

private static void selfDestructWindowsJARFile() throws Exception 
{ 
    String resourceName = "self-destruct.bat"; 
    File scriptFile = File.createTempFile(FilenameUtils.getBaseName(resourceName), "." + FilenameUtils.getExtension(resourceName)); 

    try (FileWriter fileWriter = new FileWriter(scriptFile); 
     PrintWriter printWriter = new PrintWriter(fileWriter)) 
    { 
     printWriter.println("taskkill /F /IM \"java.exe\""); 
     printWriter.println("DEL /F \"" + ProgramDirectoryUtilities.getCurrentJARFilePath() + "\""); 
     printWriter.println("start /b \"\" cmd /c del \"%~f0\"&exit /b"); 
    } 

    Desktop.getDesktop().open(scriptFile); 
} 

public static void selfDestructJARFile() throws Exception 
{ 
    if (SystemUtils.IS_OS_WINDOWS) 
    { 
     selfDestructWindowsJARFile(); 
    } else 
    { 
     // Unix does not lock the JAR file so we can just delete it 
     File directoryFilePath = ProgramDirectoryUtilities.getCurrentJARFilePath(); 
     Files.delete(directoryFilePath.toPath()); 
    } 

    System.exit(0); 
} 

ProgramDirectoryUtilities Klasse:

public class ProgramDirectoryUtilities 
{ 
    private static String getJarName() 
    { 
     return new File(ProgramDirectoryUtilities.class.getProtectionDomain() 
       .getCodeSource() 
       .getLocation() 
       .getPath()) 
       .getName(); 
    } 

    public static boolean isRunningFromJAR() 
    { 
     String jarName = getJarName(); 
     return jarName.contains(".jar"); 
    } 

    public static String getProgramDirectory() 
    { 
     if (isRunningFromJAR()) 
     { 
      return getCurrentJARDirectory(); 
     } else 
     { 
      return getCurrentProjectDirectory(); 
     } 
    } 

    private static String getCurrentProjectDirectory() 
    { 
     return new File("").getAbsolutePath(); 
    } 

    public static String getCurrentJARDirectory() 
    { 
     try 
     { 
      return getCurrentJARFilePath().getParent(); 
     } catch (URISyntaxException exception) 
     { 
      exception.printStackTrace(); 
     } 

     throw new IllegalStateException("Unexpected null JAR path"); 
    } 

    public static File getCurrentJARFilePath() throws URISyntaxException 
    { 
     return new File(ProgramDirectoryUtilities.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath()); 
    } 
} 

Lösung inspiriert von this Frage.


Hier ist eine bessere Methode für Windows:

private static void selfDestructWindowsJARFile() throws Exception 
{ 
    String currentJARFilePath = ProgramDirectoryUtilities.getCurrentJARFilePath().toString(); 
    Runtime runtime = Runtime.getRuntime(); 
    runtime.exec("cmd /c ping localhost -n 2 > nul && del \"" + currentJARFilePath + "\""); 
} 

Here ist die ursprüngliche Antwort.