2011-07-01 13 views
11

Przeczytałem na stronie narzędzia apt, że można utworzyć AnnotationProcessors na generate new derived files (source files, class files, deployment descriptors, etc.). Szukam na to przykładu.Jak używać adnotacji java do modyfikowania kodu źródłowego przed ostateczną kompilacją?

Moja potrzeba kodować wszystkie adnotacją ciągi w czasie kompilacji, dzięki czemu czytanie plik klasy nie zezwala przeczytaniu statyczne ciągi:

kod bazowy:

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

Powinny być przerobione jak:

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

Na podstawie statycznego ObfuscatedString.obfuscate(String) method of the TrueLicense framework procesor może wygenerować kod zastępujący łańcuch z adnotacjami. Rzeczywiście, ta metoda generuje ciąg "new ObfuscatedString ([numeric_code]). ToString()". W czasie wykonywania metoda toString() z ObfuscatedString może zwrócić ciąg znaków zakodowany w kodzie numerycznym.

Każdy pomysł, jak napisać metodę process() AnnotationProcessor, aby edytować kod z adnotacjami?

Dzięki z góry,

+0

To ** ** dokładnie co zrobić obfuscators ** po ** skompilowałeś swój kod źródłowy. Użyj odpowiedniego narzędzia do zadania. –

+1

Program Proguard nie obsługuje obfuskacji ciągów. Czy znasz innych darmowych obfuscatorów obsługujących tę funkcję? – Martin

Odpowiedz

2

Mogłeś

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

który kompiluje się normalnie, jednak po kompilacji masz narzędzie, które analizuje kod bajtowy np używając ASM ObjectWeb jest, zmienia String dosłowny tak wygląda

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

Aby uczynić go łatwiejszym do identyfikacji ciągi, które muszą zostać zmienione, można dodać prefiks do nich, i można zapewnić ten przedrostek jest wyświetlany po kod został zaciemniony.

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

ASM wydaje się bardzo interesującym narzędziem. Cieszę się, że o tym rozmawiałeś! Znalazłem świetny dokument wprowadzający narzędzie (http://download.forge.objectweb.org/asm/asm-guide.pdf). Ponieważ jednak edycja kodu jest dość prosta, zastanawiam się, czy mogę to zrobić z adnotacją, aby uniknąć krzywej uczenia ASM ... i nauczyć się adnotacji! – Martin

2

Założę się, że spoon może być tym, czego szukasz. Ale dlaczego chcesz zaciemnić struny statyczne?

+0

Rozmyślam ciągi w skompilowanym kodzie, aby trudno było znaleźć klasy, które zajmują się licencjonowaniem części naszego oprogramowania. Bez tego jest całkiem łatwo odwrócić kod i znaleźć "jeśli", które należy usunąć, aby odblokować oprogramowanie. Łyżka wydaje się naprawdę świetnym narzędziem do takiego zadania, a jej zaćmienie sprawia, że ​​jest równie atrakcyjna jak ASM ObjectWeb. Czy masz jakieś pomysły na temat zalet i wad korzystania z pierwszego lub drugiego? – Martin

+0

W końcu wydaje się bardzo trudno znaleźć przykładowy kod lub ludzi doświadczonych z surowymi adnotacjami java do wykonywania mojego zadania. Myślę, że przejdę przez jedno z tych sugerowanych narzędzi. – Martin

1

Zelix KlassMaster oferuje tę zdolność. Jeśli pamięć działa, było to bezpłatne dla firm poniżej 3 deweloperów, ale właśnie sprawdziłem ich stronę zakupu i wydaje się, że teraz pobierają opłatę dla małych deweloperów dla małych firm. Nie używałem tego od kilku lat (co najmniej 5 lub 7), ale wykonałem fantastyczną pracę obfuskując łańcuchy i ogólnie kod.

1

Kiedy jadę do generowania wersję dla dystrybucji IT, mam klasy, które zastępują wszystkie stałe z wezwaniem Ofuscated wyrażenie:

Jest to proces:

  1. uruchomić mój ANT , który kopiuje cały kod w innym miejscu.
  2. Wywołanie ANT do OfuscateJavaConstant.
  3. I Skompiluj kod.

ANT:

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

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

} 

Nadzieja to pomaga :)