Обфускация Java в Gradle с помощью yGuard ~ Как исключить методы? - PullRequest
1 голос
/ 07 мая 2020

Я хочу скрыть код Java в Gradle с помощью yGuard. До сих пор мне удалось заставить работать обфускацию, используя:

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 ( который работает с необфусцированной банкой).

Я пробовал несколько способов исключить функцию main из обфускации.

Во-первых, я попытался использовать аннотацию @Obfuscate, как описано в документации ( https://yworks.github.io/yGuard/task_documentation/#controlling -obfuscation-exclusion-with-annotations ), например:

  @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)
                             ^

Я попробовал несколько вещей, чтобы заставить это работать, но не смог прийти к рабочему решению.

Итак, затем я попытался использовать элемент метода keep> в задаче yGuardObfuscate, чтобы явно сохранить функцию main класса Start, например:

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?

1 Ответ

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

Теперь я выяснил, как заставить его работать, хотя это скорее похоже на обходной путь, чем на правильное решение, поэтому, если кто-нибудь знает, что я сделал не так с "официальными" решениями, пожалуйста, сообщите мне.

Для этого я использовал подход аннотации, и вместо использования аннотации по умолчанию я создал собственную аннотацию, которая в значительной степени является точной копией в моем проекте.

Класс аннотации выглядит следующим образом:

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.

...