2012-04-11 9 views
15

Lungo le linee di "Questo nastro si autodistruggerà in cinque secondi. In bocca al lupo, Jim" ...autodistruggersi applicazione

Sarebbe possibile per un'applicazione per cancellare se stesso (o è eseguibile modulo wrapper) una volta raggiunto il tempo di utilizzo preimpostato o altre condizioni?

In alternativa, quali altri approcci potrebbero essere utilizzati per rendere l'applicazione inutile?

L'obiettivo è di far scadere la versione beta, invitando gli utenti a ottenere una versione più aggiornata.

+2

sicuro che sia possibile. Supponendo di aver distribuito l'app in un jar, è possibile ottenere il classpath tramite le proprietà di sistema, trovare il jar ed eliminarlo (presupponendo che Java sia in esecuzione con privilegi sufficienti) e il sistema operativo consente di eliminare un jar mentre è in uso. – ControlAltDel

+1

Un altro modo per eseguire questa operazione è memorizzare la data iniziale di utilizzo nel file system o nel registro di sistema. – ControlAltDel

+1

Ci sono diverse domande su StackOverflow su come creare una versione demo/di prova/di valutazione. – mbatchkarov

risposta

8

È possibile. Per aggirare il blocco del file JAR, è possibile che la tua applicazione debba generare un processo in background che attende fino all'uscita dalla JVM prima di eliminare del materiale.

Tuttavia, questo non è a prova di bomba. Qualcuno potrebbe installare l'applicazione e quindi fare in modo che i file e le directory installati siano di sola lettura, in modo che l'applicazione non possa cancellarsi. L'utente (o il suo amministratore) tramite il sistema di controllo accessi del sistema operativo ha l'ultima parola su quali file vengono creati ed eliminati.

+0

Hai ragione. Ciò eliminerebbe anche qualsiasi sovrascrittura o modifica come suggerito da @PeterMmm. Che ne dici di richiedere l'accesso a Internet? Separerebbe parte della logica di controllo. –

+0

Ciò può essere annullato disabilitando il codice pertinente nell'applicazione. L'offuscamento non impedirà che ... ci vorrà solo più tempo. –

+4

Inserire una timebomb di qualsiasi tipo nella tua applicazione è un disservizio per i potenziali clienti futuri. Persuaderli a migliorare offrendo loro un buon prodotto piuttosto che paralizzando quello esistente. –

-1

è praticamente possibile credo. forse puoi cancellare il vaso in questo modo e assicurarti che l'applicazione sparisca dato che hai i diritti.

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

anche usando qualcosa come Nullsoft Scriptable Install System che consente di scrivere il proprio installato/disinstallazione dovrebbe aiutare.

+1

Inoltre è possibile sovrascrivere il file con dati casuali per evitare che non si ripristini. – PeterMmm

+0

Appena provato, non sembra funzionare. – Reg

+0

@PeterMmm Questa è una possibilità che ho considerato. Grazie per averlo riportato in mente. –

5

Se controlli dove i tester scaricare l'applicazione, è possibile utilizzare un sistema di compilazione automatica (ad es Jenkins) che si potrebbe creare un nuovo versioni beta ogni notte che ha una data di scadenza hard-coded:

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

la data sopra viene inserito automaticamente dal processo di generazione

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

miscela che con signed and sealed jars, per mettere ostacoli nel modo di decompilazione bytecode e fornendo un'implementazione alternativa che non include t codice hat, puoi distribuire una beta scadente del codice.

Il sistema di generazione automatica può essere configurato per caricare automaticamente la versione beta sul server che ospita la versione di download.

+1

Grazie per la menzione di Jenkins. Sai se questo può essere aggirato cambiando la data del sistema? –

+1

Potrebbe essere sì, ma nessuna misura di sicurezza è assolutamente a prova di crack. Per esempio, se dovessi controllare il tempo contro un servizio web, questo potrebbe essere aggirato intercettando la chiamata di servizio, ecc. E penso che i cracker risolti possano aggirare qualsiasi cosa. Tuttavia, non penso che un utente normale vorrebbe modificare l'ora del sistema poiché probabilmente interferirebbe con altri strumenti (ad es. Calendari). – beny23

+1

Non c'è bisogno di essere un cracker qui, basta cambiare il tempo di sistema. – atamanroman

0

Dal momento che Windows blocca il file JAR mentre è in esecuzione, non è possibile eliminarlo dal proprio codice Java, quindi, è necessario un file Batch:

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 classe:

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()); 
    } 
} 

soluzione ispirata per domanda this.


Ecco un metodo migliore per 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 è la risposta originale.