2012-04-11 3 views
15

Вдоль линий «Эта лента будет самоуничтожения в пять секунд. Успехов, Джим» ...самоуничтожающимися применение

Будет ли возможность для приложения удалить себя (или его исполняемым форма обертки) после достижения заданного времени использования или другого условия?

В качестве альтернативы, какие другие подходы могут быть использованы для того, чтобы приложение было бесполезным?

Цель состоит в том, чтобы истечь срок действия бета-версии, предлагая пользователям получить более актуальную версию.

+2

уверен, что это возможно. Предполагая, что вы развернули приложение в банке, вы можете получить путь к классам через свойства системы, найти банку и удалить ее (при условии, что Java работает с достаточными привилегиями), и ОС позволяет удалить банку во время ее использования. – ControlAltDel

+1

Другой способ сделать это - сохранить начальную дату использования в файловой системе или в системном реестре. – ControlAltDel

+1

Есть несколько вопросов о stackoverflow о том, как сделать демо/пробную/оценочную версию. – mbatchkarov

ответ

8

Возможно. Чтобы обойти блокировку JAR-файла, вашему приложению может потребоваться создать фоновый процесс, ожидающий, пока JVM не выйдет перед удалением файлов.

Однако это не является взрывозащищенным. Кто-то может установить приложение, а затем сделать установленные файлы и каталоги доступными только для чтения, чтобы ваше приложение не могло удалять себя. Пользователь (или их администратор) через систему контроля доступа OS's имеет окончательное мнение о том, какие файлы создаются и удаляются.

+0

Вы правы. Это также победит любую перезапись или модификации, предложенную @PeterMmm. Как насчет необходимости доступа в Интернет? Это разделило бы часть логики управления. –

+0

Это можно победить, отключив соответствующий код в приложении. Обфускация не помешает этому ... только занять больше времени. –

+4

Включение временной бомбы в ваше приложение является плохим сервисом для ваших потенциальных будущих клиентов. Убедите их модернизировать, предлагая им хороший продукт, а не нанося ущерб вашему существующему. –

-1

вполне возможно, я думаю. возможно, вы можете удалить банку, как это, и убедитесь, что приложение исчезает, учитывая, что у вас есть права.

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

также использовать что-то вроде Nullsoft Scriptable Install System, который позволит вам написать свой собственный установлен/деинсталлятор должен помочь.

+1

Дополнительно вы можете перезаписать файл со случайными данными, которые будут удалены, и он не восстановится. – PeterMmm

+0

Просто попробовал, похоже, не работает. – Reg

+0

@PeterMmm Это возможность, которую я рассмотрел. Спасибо, что вспомнил об этом. –

5

Если вы контролируете, где тестеры загрузить приложение, вы можете использовать автоматизированную систему сборки (например Jenkins), которые вы можете создать новые бета-версию каждую ночь, которая имеет жестко запрограммированный срок годности:

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

выше дата автоматически вставляется в процессе сборки

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

Mix, что с signed and sealed jars, ставить препятствия на пути декомпиляции байткода и обеспечивая альтернативную реализацию, что Безразлично» t включить этот код, вы можете выдать бета-версию кода, истекающего по времени.

Автоматическая система сборки может быть настроена на автоматическую загрузку бета-версии на сервер, на котором установлена ​​версия для загрузки.

+1

Спасибо за упоминание Дженкинса. Знаете ли вы, можно ли это изменить, изменив системную дату? –

+1

Это может быть да, но никакая мера безопасности не является абсолютно стойкой к царапинам. Например, если вы должны проверить время на веб-службу, это можно обойти, перехватив вызов службы и т. Д., И я думаю, что решительные взломщики обойдутся чем угодно. Тем не менее, я не думаю, что обычный пользователь захочет изменить системное время, поскольку это, вероятно, будет мешать другим инструментам (например, календарям). – beny23

+1

Не нужно быть взломщиком здесь, просто измените системное время. – atamanroman

0

Поскольку Windows блокирует JAR файл, пока он работает, вы не можете удалить его из своего собственного кода Java, следовательно, вам нужен 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 класс:

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

Решения вдохновенного по this вопрос.


Вот лучший способ для 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 оригинальный ответ.