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

发布于 2024-11-18 13:27:40 字数 902 浏览 4 评论 0原文

我从 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();

基于静态 TrueLicense 框架的ObfuscatedString.obfuscate(String)方法,处理器可以生成代码来替换带注释的字符串。事实上,此方法生成字符串“new ObfuscatedString([numeric_code]).toString()”。 在运行时,ObfuscatedString 的 toString() 方法能够返回以数字代码编码的字符串。

关于如何编写 AnnotationProcessor 的 process() 方法来编辑带注释的代码有什么想法吗?

提前致谢,

I've read from the apt tool page that one can create AnnotationProcessors to generate new derived files (source files, class files, deployment descriptors, etc.). I am looking for example to do so.

My need is to encode all annotated strings at compile time, so that reading the class file does not allow reading the static strings:

Base code:

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

Should be reworked as:

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

Based on the static ObfuscatedString.obfuscate(String) method of the TrueLicense framework, the processor can generate the code to replace the annotated string. Indeed, this method generates the string "new ObfuscatedString([numeric_code]).toString()".
At runtime the toString() method of ObfuscatedString is able to return the string encoded in the numeric code.

Any idea on how to write the process() method of the AnnotationProcessor to edit the annotated code?

Thanks in advance,

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

笑,眼淚并存 2024-11-25 13:27:40

你可以

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

You could have

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

which compiles normally, however after compilation you have a tool which examines the bytecode e.g. using ObjectWeb's ASM, changes the String literal so it looks like

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

To make it easer to identify strings which need to be changed, you could add a prefix to them, and you could ensure this prefix does appear after the code has been obfuscated.

String s = "Obfuscate: a string that should not be readable in class file";
// later
String message = Obfuscated.decode(s);
小姐丶请自重 2024-11-25 13:27:40

我敢打赌 spoon 可能就是您正在寻找的东西。但为什么要混淆静态字符串呢?

I bet spoon may be what you are looking for. But why do you want to obfuscate static strings?

潦草背影 2024-11-25 13:27:40

Zelix KlassMaster 提供了此功能。如果没记错的话,以前对3个开发者以下的公司是免费的,但我刚刚查看了他们的购买页面,他们现在似乎对小公司收取小开发者费用。我已经好几年没有使用它了(至少有五七年了),但它在混淆字符串和一般代码方面做得非常出色。

Zelix KlassMaster offers this ability. If memory serves, it used to be free for companies under 3 developers, but I just checked their purchase page, and it seems that they now charge a small-developers fee for small companies. I haven't used it in several years (at least 5 or 7), but it did a fantastic job obfuscating strings, and code in general.

怀中猫帐中妖 2024-11-25 13:27:40

当我要生成用于分发的版本时,我有一个类,它使用 Ofuscated String 调用覆盖所有常量:

这是过程:

  1. 我运行 ANT,将所有代码复制到其他位置。
  2. ANT 调用 OfuscateJavaConstant。
  3. 我编译代码。

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

}

希望有帮助:)

When I am going to generate the version for distribution it, I have a class that override all the constants with the Ofuscated String call:

This is the process:

  1. I run my ANT, that copy all the code in other place.
  2. The ANT call to OfuscateJavaConstant.
  3. I Compile the code.

The ANT:

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

The Java Ofuscate code (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();
         }
    }

}

Hope it helps :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文