Подтвердить что ты не робот

Как использовать аннотации java для изменения исходного кода перед окончательной компиляцией?

Я прочитал на странице инструмента apt, что можно создать AnnotationProcessors для генерировать новые производные файлы (исходные файлы, файлы классов, дескрипторы развертывания и т.д.).. Я ищу пример для этого.

Мне нужно кодировать все аннотированные строки во время компиляции, поэтому чтение файла класса не позволяет читать статические строки:

Базовый код:

String message = (@Obfuscated "a string that should not be readable in class file");

Необходимо переработать как:

String message = new ObfuscatedString(new long[] {0x86DD4DBB5166C13DL, 0x4C79B1CDC313AE09L, 0x1A353051DAF6463BL}).toString();

На основе статического метода ObfuscatedString.obfuscate(String) структуры TrueLicense процессор может сгенерировать код для замены аннотированной строки. В самом деле, этот метод генерирует строку "новый ObfuscatedString ([numeric_code]). ToString()". Во время выполнения метод toString() ObfuscatedString может возвращать строку, закодированную в числовом коде.

Любая идея о том, как написать метод process() AnnotationProcessor для редактирования аннотированного кода?

Спасибо заранее,

4b9b3361

Ответ 1

У вас может быть

String message = Obfuscated.decode("a string that should not be readable in class file");

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

String message = Obfuscated.decode("\u86DD\u4DBB\u5166\uC13D\u4C79\uB1CD\uC313\uAE09\u1A35\u3051\uDAF6\u463B");

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

String s = "Obfuscate: a string that should not be readable in class file";
// later
String message = Obfuscated.decode(s);

Ответ 2

Я уверен, что spoon может быть тем, что вы ищете. Но почему вы хотите обфускать статические строки?

Ответ 3

Zelix KlassMaster предлагает эту возможность. Если память работает, она была бесплатной для компаний в возрасте до 3 разработчиков, но я только что проверил их страницу покупки, и кажется, что теперь они взимают плату за небольшие разработчики для небольших компаний. Я не использовал его в течение нескольких лет (по крайней мере 5 или 7), но он сделал фантастическую работу, запутывая строки и код в целом.

Ответ 4

Когда я собираюсь сгенерировать версию для его распространения, у меня есть класс, который переопределяет все константы с вызовом Ofuscated String:

Это процесс:

  • Я запустил свой ANT, который копирует весь код в другое место.
  • ANT вызов OfuscateJavaConstant.
  • Компилируем код.

ANT:

 <java classname="de.schlichtherle.util.ObfuscatedString">
     <arg value="${of.constant}" />
     <classpath>
         <pathelement location="${exit.path}/${buildDir}" />
         <path refid="myclasspath" />
     </classpath>
  </java>

Код Java Ofuscate (ObfuscatedString):

public static void main(String[] args) {
    if ( args!=null ){
        String[] ficheros = args[0].split(";");

        if ( args!=ficheros )
            for (String ruta:ficheros)
                ofuscateConstantClass( ruta );
    }
}

private static void ofuscateConstantClass( String fileName ){

    File archivo = null;
    FileReader fr = null;
    BufferedReader br = null;
    List<String> sb  = new ArrayList<String>();
    FileWriter fichero = null;
    PrintWriter pw = null;

    try{
        archivo = new File( fileName );
        fr = new FileReader (archivo);
        br = new BufferedReader(fr);
        String linea;
        while( (linea=br.readLine())!=null ){

            String noWhite = linea.trim().replaceAll(" +", " ");

            if ( noWhite.toLowerCase().startsWith("public static final string") && noWhite.endsWith("\";") ){

                String firstPart = noWhite.substring(0, noWhite.indexOf("\"") );
                String constant = noWhite.substring(noWhite.indexOf("\"")+1, noWhite.lastIndexOf("\"") );
                String ofuscatedConstant = obfuscate( constant );
                String secondPart = noWhite.substring(noWhite.lastIndexOf("\"")+1 );
                sb.add( firstPart + ofuscatedConstant + secondPart );
                System.out.println( constant + "-->" + ofuscatedConstant );
            } else
                sb.add( linea );
        }

        fichero = new FileWriter( fileName );
        pw = new PrintWriter(fichero);
        for (String s:sb)
            pw.println( s );

    } catch ( Exception e){

    } finally {
         try{
             if( null != fr )
                 fr.close();
             if( null != pw )
                 pw.close();
             if( null != fichero )
                 fichero.close();
         }catch (Exception e2){
            e2.printStackTrace();
         }
    }

}

Надеюсь, это поможет:)