Как использовать Java-аннотации для изменения исходного кода перед окончательной компиляцией? - PullRequest
11 голосов
/ 01 июля 2011

Я прочитал со страницы инструмента 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 процессор может сгенерировать код для заменыаннотированная строка.Действительно, этот метод генерирует строку «new ObfuscatedString ([numeric_code]). ToString ()».Во время выполнения метод toString () объекта ObfuscatedString может возвращать строку, закодированную в числовом коде.

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

Заранее спасибо,

Ответы [ 4 ]

2 голосов
/ 06 июля 2011

Бьюсь об заклад ложка может быть то, что вы ищете.Но почему вы хотите скрыть статические строки?

2 голосов
/ 01 июля 2011

Вы могли бы иметь

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

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

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);
1 голос
/ 07 мая 2012

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

Это процесс:

  1. Я запускаю свой ANT, который копирует весь код в другом месте.
  2. Вызов ANT для OfuscateJavaConstant.
  3. Я скомпилирую код.1013 *
     <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();
             }
        }
    
    }
    

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

1 голос
/ 07 мая 2012

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

...