【问题标题】:Obfuscating Java in Gradle using yGuard ~ How to exclude methods?使用 yGuard 在 Gradle 中混淆 Java ~ 如何排除方法?
【发布时间】:2020-08-22 09:07:32
【问题描述】:

我想在 Gradle 中使用 yGuard 混淆 Java 代码。到目前为止,我已经设法使混淆工作使用:

dependencies {
    compile 'com.yworks:yguard:2.9.2'
}

task yGuardObfuscate {
    group 'yGuard'
    description 'Obfuscates existing archives.'
    dependsOn "installDist"

    doLast {
        ant.taskdef(
            name: 'yguard',
            classname: 'com.yworks.yguard.YGuardTask',
                classpath: sourceSets.main.runtimeClasspath.asPath
            )

        ant.yguard {
            inoutpairs {
                fileset(dir: "./build/install/module") {
                    include(name: "module*.jar")
                    exclude(name: "*_obf.jar")
                }
            }

            rename(logFile: "./build/install/module/rename.log") {
                property(name: "naming-scheme", value: "mix")
            }
        }
    }
}

但是,问题是 main 函数被遮盖了,我无法再使用 java -jar module_obf.jar 运行它(它适用于未混淆的 jar)。

我尝试了几种方法将main 函数从混淆中排除。

首先,我尝试使用文档 (https://yworks.github.io/yGuard/task_documentation/#controlling-obfuscation-exclusion-with-annotations) 中描述的 @Obfuscate 注释,如下所示:

  @com.yworks.util.annotation.Obfuscation( exclude = true, applyToMembers = false)
  public static void main(String[] args) {
    try {
      new Start();
    } catch (SQLException e) {
      LOGGER.error(e, e);
    }
  }

在我的 IDE(Eclipse 2019-14)中,此行显示为有效。但是,当尝试使用我创建的 gradle 任务对其进行编译时,出现以下错误:

...\Start.java:22: error: package com.yworks.util.annotation does not exist
  @com.yworks.util.annotation.Obfuscation( exclude = true, applyToMembers = false)
                             ^

我尝试了很多方法来使其正常工作,但无法找到可行的解决方案。

接下来,我尝试在yGuardObfuscate 任务中使用keep > 方法元素来显式保留Start 类的main 函数,如下所示:

task yGuardObfuscate {
    group 'yGuard'
    description 'Obfuscates existing archives.'
    dependsOn "installDist"

    doLast {
        ant.taskdef(
            name: 'yguard',
            classname: 'com.yworks.yguard.YGuardTask',
                classpath: sourceSets.main.runtimeClasspath.asPath
            )

        ant.yguard {
            inoutpairs {
                fileset(dir: "./build/install/module") {
                    include(name: "module*.jar")
                    exclude(name: "*_obf.jar")
                }
            }

            rename(logFile: "./build/install/module/rename.log") {
                property(name: "naming-scheme", value: "mix")
                keep {
                    method("class": "com.company.project.module.Start", name: "public static void main(String[] args)")
                }
            }
        }
    }
}

这导致 Gradle 构建失败并出现以下异常:

: java.lang.IllegalArgumentException: '(' expected but found void
[...]
Caused by: java.lang.IllegalArgumentException: '(' expected but found void
    at com.yworks.yguard.ObfuscatorTask.toNativeMethod(ObfuscatorTask.java:188)
    at com.yworks.yguard.ant.MethodSection.addEntries(MethodSection.java:35)
    at com.yworks.yguard.ant.ExposeSection.createEntries(ExposeSection.java:170)
    at com.yworks.yguard.ObfuscatorTask.execute(ObfuscatorTask.java:745)
    at com.yworks.yguard.YGuardTask.execute(YGuardTask.java:116)
[...]
Root cause: java.lang.IllegalArgumentException: '(' expected but found void
    at com.yworks.yguard.ObfuscatorTask.toNativeMethod(ObfuscatorTask.java:188)
    at com.yworks.yguard.ant.MethodSection.addEntries(MethodSection.java:35)
    at com.yworks.yguard.ant.ExposeSection.createEntries(ExposeSection.java:170)
    at com.yworks.yguard.ObfuscatorTask.execute(ObfuscatorTask.java:745)
    at com.yworks.yguard.YGuardTask.execute(YGuardTask.java:116)

再次,我在这里尝试了几件事,例如写“class”而不带“”,添加额外的 {},但没有任何帮助。

所以这里的问题是:我做错了什么?以及如何防止 yGuard 混淆main 函数?

【问题讨论】:

    标签: java gradle obfuscation yguard


    【解决方案1】:

    我现在想出了一种让它发挥作用的方法,尽管它感觉更像是一种变通方法而不是正确的解决方案,所以如果有人知道我在“官方”解决方案中做错了什么,请告诉我。

    为此,我使用了注释方法,而不是使用默认注释,我创建了一个自定义注释,它几乎是我项目中的一个精确副本。

    注解类如下所示:

    package com.company.project.module.annotations;
    
    public @interface Obfuscation {
          boolean exclude() default true;
    
          boolean applyToMembers() default true;
    }
    

    我在我的 Start 类中这样使用它:

    import com.company.project.module.annotations.*;
    
    [...]
    
      @Obfuscation( exclude = true, applyToMembers = false)
      public static void main(String[] args) {
        [...]
      }
    

    最后,我将此自定义注释类添加到我的任务的rename 元素中,如下所示:

                rename(logFile: "./build/install/module/rename.log", annotationClass: "com.company.project.module.annotations.Obfuscation") {
                    property(name: "naming-scheme", value: "mix")
                }
    

    所以整个 gradle 任务现在看起来像这样:

    task yGuardObfuscate {
        group 'yGuard'
        description 'Obfuscates existing archives.'
        dependsOn "installDist"
    
        doLast {
            ant.taskdef(
                name: 'yguard',
                classname: 'com.yworks.yguard.YGuardTask',
                    classpath: sourceSets.main.runtimeClasspath.asPath
                )
    
            ant.yguard {
                inoutpairs {
                    fileset(dir: "./build/install/module") {
                        include(name: "module*.jar")
                        exclude(name: "*_obf.jar")
                    }
                }
    
                rename(logFile: "./build/install/module/rename.log", annotationClass: "com.company.project.module.annotations.Obfuscation") {
                    property(name: "naming-scheme", value: "mix")
                }
            }
        }
    }
    

    这样,构建现在可以工作了,我可以使用java -jar module_obf.jar 成功运行我的程序。

    【讨论】:

      猜你喜欢
      • 2021-04-16
      • 1970-01-01
      • 1970-01-01
      • 2010-09-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多