如何在最终编译之前使用java注释修改源代码?

如何在最终编译之前使用java注释修改源代码?,java,annotations,apt,Java,Annotations,Apt,我从apt工具页上读到,可以创建注释处理器。我正在寻找这样做的例子 我需要在编译时对所有带注释的字符串进行编码,以便读取类文件时不允许读取静态字符串: 基本代码: String message = (@Obfuscated "a string that should not be readable in class file"); 应返工为: String message = new ObfuscatedString(new long[] {0x86DD4DBB5166C13DL, 0x4C7

我从apt工具页上读到,可以创建注释处理器。我正在寻找这样做的例子

我需要在编译时对所有带注释的字符串进行编码,以便读取类文件时不允许读取静态字符串:

基本代码:

String message = (@Obfuscated "a string that should not be readable in class file");
应返工为:

String message = new ObfuscatedString(new long[] {0x86DD4DBB5166C13DL, 0x4C79B1CDC313AE09L, 0x1A353051DAF6463BL}).toString();
基于静态,处理器可以生成代码来替换带注释的字符串。实际上,此方法生成字符串“new ObfuscatedString([numeric_code]).toString()。 在运行时,ObfuscatedString的toString()方法能够返回数字代码中编码的字符串

您知道如何编写AnnotationProcessor的process()方法来编辑带注释的代码吗

提前谢谢,

您可以

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

我打赌这可能就是你要找的。但是为什么要混淆静态字符串呢?

提供了这种功能。如果内存可用的话,3个开发者以下的公司过去是免费的,但我刚刚查看了他们的购买页面,他们现在似乎向小公司收取小开发者费用。我已经好几年没有使用它了(至少5年或7年),但它在混淆字符串和一般代码方面做得非常出色。

当我要生成分发它的版本时,我有一个类,它使用OfDiscated字符串调用覆盖所有常量:

这是一个过程:

  • 我运行我的ANT,它将所有代码复制到其他地方
  • ANT对OfuscateJavaConstant的调用
  • 我编译代码
  • 蚂蚁:

     <java classname="de.schlichtherle.util.ObfuscatedString">
         <arg value="${of.constant}" />
         <classpath>
             <pathelement location="${exit.path}/${buildDir}" />
             <path refid="myclasspath" />
         </classpath>
      </java>
    
    
    
    散乱代码的Java(混淆):

    publicstaticvoidmain(字符串[]args){
    如果(args!=null){
    字符串[]ficheros=args[0]。拆分(;);
    if(args!=ficheros)
    对于(字符串ruta:ficheros)
    乌鲁塔;
    }
    }
    ScateConstantClass的私有静态无效(字符串文件名){
    文件archivo=null;
    FileReader fr=null;
    BufferedReader br=null;
    List sb=new ArrayList();
    FileWriter-fichero=null;
    PrintWriter pw=null;
    试一试{
    archivo=新文件(文件名);
    fr=新文件读取器(archivo);
    br=新的缓冲读取器(fr);
    弦线;
    而((linea=br.readLine())!=null){
    字符串noWhite=linea.trim().replaceAll(“+”,”);
    if(noWhite.toLowerCase().startsWith(“公共静态最终字符串”)&&noWhite.endsWith(“\”;”){
    String firstPart=noWhite.substring(0,noWhite.indexOf(“\”);
    字符串常量=noWhite.substring(noWhite.indexOf(“\”)+1,noWhite.lastIndexOf(“\”);
    分散常数字符串=模糊(常数);
    String secondPart=noWhite.substring(noWhite.lastIndexOf(“\”)+1);
    添加(第一部分+分散常数+第二部分);
    System.out.println(常数+“-->”+分散常数);
    }否则
    某人加上(直线);
    }
    fichero=新文件编写器(文件名);
    pw=新的印刷撰稿人(菲舍罗);
    (s:sb)
    pw.println(s);
    }捕获(例外e){
    }最后{
    试一试{
    如果(null!=fr)
    fr.close();
    if(null!=pw)
    关闭();
    if(null!=fichero)
    fichero.close();
    }捕获(异常e2){
    e2.printStackTrace();
    }
    }
    }
    

    希望对您有所帮助:)

    ASM似乎是一个非常有趣的工具,我很高兴您提到了它!我找到了一位介绍该工具的优秀医生().但是,由于代码编辑相当简单,我想知道我是否可以使用注释来避免ASM学习曲线…并学习注释!这正是在编译源代码后模糊处理程序所做的。请使用正确的工具来完成此工作。Proguard不支持字符串模糊处理。您知道其他一些免费的模糊处理程序吗他的功能?我在编译代码中混淆了字符串,使得很难找到处理软件许可部分的类。没有这些,就很容易对代码进行反向工程并找到“如果”“将被删除以解锁软件。Spoon似乎是执行此类任务的一个非常好的工具,它的eclipse集成使它与ObjectWeb的ASM一样吸引人。您对使用第一种或另一种方法的优缺点有什么看法吗?最后,似乎很难找到示例代码或有原始java注释经验的人来执行我的任务。我想我会使用其中一个建议的工具。
    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();
             }
        }
    
    }