java如何使用ProGuard进行混淆,但在测试时保持名称的可读性?
我的应用程序处于发布前阶段,我开始编译发布版本assembleRelease
,而不是assembleDebug
。然而,混淆会破坏事物,很难破译什么是什么。调试几乎是不可能的,即使保留行号,变量类也无法读取。虽然发布版本不稳定,但我想让模糊处理变得不那么痛苦,但它的行为应该仍然是完全模糊的
通常,预先发布的版本会将名称从
net.twisterrob.app.pack.MyClass
到
b.a.c.b.a
如果反射和安卓布局/菜单资源遇到了我们没有保留名称的类,它们可以使用这些资源中断
对于发布前测试来说,能够混淆代码真的很有帮助,但“没有那么多”,比如从
net.twisterrob.app.pack.MyClass
到
net.twisterrob.app.pack.myclass // or n.t.a.p.MC or anything in between :)
proguard -dontobfuscate
当然有帮助,但它会让所有坏的东西再次工作,因为类名是正确的
我所寻找的将打破完全模糊的东西,但同时不使用映射就可以很容易地找出什么是什么。txt,因为名字是人类可读的
我四处看了看http://proguard.sourceforge.net/manual/usage.html#obfuscationoptions,但是-*dictionary
选项似乎没有这样做
我可以自己生成一个重命名文件(只需运行所有类,并给它们一个toLowerCase
之类的文件):
net.twisterrob.app.pack.MyClassA -> myclassa
net.twisterrob.app.pack.MyClassB -> myclassb
问题是我如何将这样一个文件提供给ProGuard,格式是什么
# 1 楼答案
看起来我已经跳过了我链接的部分中的选项^{}
TL;DR
跳转到Implementation/details部分,将这两段Gradle/Groovy代码复制到Android子项目的
build.gradle
文件中地图。txt
映射的格式。txt非常简单:
缩小的班级和成员根本没有列出。所以所有可用的信息,如果我能生成相同的信息或转换这些信息,就有很大的成功机会
解决方案1:转储所有类[失败]
我试图生成一个输入映射。基于当前传递给proguard的类路径(
-injars
)。我在一个URLClassLoader
中加载了所有的类,这个URLClassLoader
中有所有的程序JAR和LibraryJAR(例如用于解析超类)。然后遍历每个类和每个声明的成员,并输出我希望使用的名称这有一个大问题:这个解决方案包含了应用程序中每一个可重命名对象的模糊名称。这里的问题是
-applymapping
按字面意思处理,并尝试应用输入映射文件中的所有映射,忽略-keep
规则,导致有关冲突重命名的警告。所以我放弃了这条路,因为我不想复制proguard配置,也不想自己实现proguard配置解析器解决方案2:运行
proguardRelease
两次[失败]基于上述失败,我想到了另一个解决方案,它将利用所有的配置并保持现有的配置。流程如下:
proguardRelease
做它的工作这将输出源
mapping.txt
mapping.txt
转换为新文件proguardRelease
gradle任务,并使用转换后的映射运行它问题是,复制整个任务非常复杂,包括
inputs
、outputs
、doLast
、doFirst
、@TaskAction
等等。。。我其实是从这条路线开始的,但很快就加入了第三种解决方案解决方案3:使用
proguardRelease
的输出[success]在尝试复制整个任务并分析proguard/android插件代码时,我意识到,只需再次模拟
proguardRelease
正在做的事情,就会容易得多。以下是最终流程:proguardRelease
做它的工作这将输出源
mapping.txt
mapping.txt
转换为新文件但这次使用我的映射文件进行重命名
结果就是我想要的:
(例如,模式为
<package>.__<class>__.__<field>__
,类名和字段名大小写颠倒)或者注意下面的下划线:
实施/细节
我试着让它尽可能简单,同时保持最大的灵活性。 我叫它unfousation,因为它取消了适当的模糊处理,但仍然考虑了模糊处理的反射
我实施了一些防护措施,因为第二轮有一些假设。很明显,如果没有混淆,就没有必要解开。此外,如果调试被关闭,那么取消暂停(可能会被意外释放)几乎毫无意义,因为取消暂停在IDE中最有帮助。如果应用程序经过测试和模糊处理,AndroidDrugardTask的内部正在使用映射文件,我现在不想处理这个问题
所以我继续创建了一个未更新的任务,它进行转换并运行proguard。遗憾的是,proguard配置没有在
proguard.gradle.ProguardTask
中公开,但这什么时候阻止了任何人有一个缺点,它需要两倍的时间来升级,我想如果你真的需要调试它,这是值得的
以下是Gradle的android挂钩代码:
整体的另一部分是转变。我成功地快速构建了一个完全匹配的正则表达式模式,所以它非常漂亮易于理解的可以安全地忽略类结构和remap方法。键是 }s),并且在中间改变名称。更改为
processLine
,每行调用它。该行被拆分为部分,模糊名称前后的文本保留为IS(2^ {unfuscate
中的return
语句以满足您的需要可能的未污染
您应该能够对包名应用转换,但我没有测试它
警告:不可逆转换容易出错。考虑以下事项:
当然,上面所有的转换都可能以这样或那样的方式被欺骗,但不常见的前置后缀和文本转换则不太可能