ProGuard工作原理
ProGuar由shrink、optimize、obfuscate和preveirfy四个步骤组成,每个步骤都是可选的,我们可以通过配置脚本来决定执行其中的哪几个步骤。
史上最全ProGuard使用及相光配置
(1)压缩(Shrink):检测并移除代码中无用的类、字段、方法和特性(Attribute)。
(2)优化(Optimize):对字节码进行优化,移除无用的指令。
(3)混淆(Obfuscate):使用a,b,c,d这样简短而无意义的名称,对类、字段和方法进行重命名。
(4)预检(Preveirfy):在Java平台上对处理后的代码进行预检,确保加载的class文件是可执行的。

ProGuard操作步骤:
1.前往proGuard 官网下载地址下载并解压proguard,执行 bin目录下的proguardgui.bat
https://sourceforge.net/projects/proguard/
史上最全ProGuard使用及相光配置

2.左下角Load configuration可加载已存在的配置文件进行代码加密混淆,若没有现成的配置文件(xxx.pro),可参照如下步骤

史上最全ProGuard使用及相光配置

Add input:导入需要操作的文件。
Add Outinput: 需要输入的文件。
Filter: 过滤导入文件内那些不需要操作的文件。
Add an enty:添加支持库library jars. 对添加的项目支持 jar文件或者其他文件不会进行处理。
史上最全ProGuard使用及相光配置
史上最全ProGuard使用及相光配置

点击左边“input/output”菜单,然后点击右边的“Add input”按钮,添加需要混淆的jar包,然后点击“add output”,选择输出的路径和包名。
页面右下角“”ADD“”开始添加支持库, 需要添加项目里所以依赖的jar包,我使用的是idea
打包工具,图二,添加完需要打包的项目之后Build或者Rebuild后将在对应文件下生成artifacts文件,里面有依赖的jar包和主程序包;(使用maven工具栏打包项目默认将项目和及其依赖打包成一个jar包,影响后续proguard执行)

4.压缩

—print usage 指定列出输入类文件的无效代码

Keep一些保留选项,可自行配置,一般采用默认配置。

史上最全ProGuard使用及相光配置

  1. 混淆
    史上最全ProGuard使用及相光配置
    我测试了如下几项
    . User mixed-case class names 指定在混淆的时候使用大小写混用的类名
    . Keep package names 声明不混淆指定的包名
    . Flatten package hierarchy 所有重新命名的包都重新打包
    . Keep attributes 指定要保留的所有可选属性
    . Keep parameter names 指定被保护的方法的参数类型和参数名不被混淆

  2. obfuscate 代码混淆,除-keep指定的类及成员外,都会被替换成简短、随机的名称,以达到混淆的目的。

  3. Print Mapping 输出映射文件即混淆后与混淆前的映射

  4. Apply mapping 根据指定的mapping映射文件进行混淆。

  5. Obfuscation dictionary 自定义混淆的类名,方法名,变量名字典,替换原先的a,b,c.这种格式的

  6. Class Obfuscation dictionary 指定一个文本文件,所有有效单词都用作混淆的类名

  7. Package Obfuscation dictionary 该文件中的所有有效词均用作混淆的程序包名称

  8. Overload aggressively 混淆的时候大量使用重载,减小包体积,增加理解难度,然后,只要Java字节码要求参数和返回类型不同(而不是Java语言要求的参数),多个字段和方法就可以使用相同的名称。此选项可以使处理后的代码更小(更难理解)。

  9. User unique clssmember names 指定相同的混淆名对应相同的方法名,将不同的混淆名称分配给具有不同名称的类成员

  10. User mixed-case class names 指定在混淆的时候使用大小写混用的类名

  11. Keep package names 声明不混淆指定的包名

  12. Flatten package hierarchy 所有重新命名的包都重新打包

  13. Repackage Classes 所有重新命名过的类都重新打包

  14. Keep attributes 指定要保留的所有可选属性,例如
    -keepattributes Exceptions,InnerClasses,Signature
    -keepattributes SourceFile,LineNumberTable
    -keepattributes Annotation

  15. Keep parameter names 指定被保护的方法的参数类型和参数名不被混淆

  16. Rename sourceFile attribute 指定一个字符串常量设置到源文件的类的属性中

  17. Adapt class strings 指定字符串常量如果与类名相同,也需要被混淆

  18. Adapt resource file names 如果资源文件与某类名同,那么混淆后资源文件被命名为与之对应的类的混淆名

  19. Adapt resource file names 指定资源文件的中的类名随混淆后的名字更新

6.代码优化
史上最全ProGuard使用及相光配置
-dontoptimize
不对class进行优化,默认开启优化。
注意:由于优化会进行类合并、内联等多种优化,-applymapping可能无法完全应用,需使用热修复的应用,建议使用此配置关闭优化。
-optimizations优化配置,可进行字段优化、内联、类合并、代码简化、算法指令精简等操作。例如:
#只进行移除未使用的局部变量、算法指令精简
-optimizations code/removal/variable,code/simplification/arithmetic
#进行除算法指令精简、字段、类合并外的所有优化
-optimizations !code/simplification/arithmetic,!field/,!class/merging/

-optimizationpasses n
指定要执行的优化遍数。默认情况下,执行一次通过。多次通过可能会导致进一步的改进。

一般采用默认配置。

7.预验证选项
史上最全ProGuard使用及相光配置
-preverify
预先验证已处理的类文件
-micro edition
声明目标平台是java micro版本。预校验会根据这项配置加载合适的StackMap,而不是标准的StackMap。
-android
指定已处理的类文件针对Android平台。然后,ProGuard确保某些功能与Android兼容。
-verbose
指定在处理期间写出更多信息。如果程序因异常终止,则此选项将打印出整个堆栈跟踪,而不仅仅是异常消息。
-dontnote
指定不打印有关配置中潜在错误或遗漏的注释,例如类名中的错字或可能有用的缺失选项。可选过滤器是一个正则表达式;ProGuard不会打印有关名称匹配的类的注释。
-dontwarn
指定根本不警告尚未解决的引用和其他重要问题。可选过滤器是一个正则表达式;ProGuard不会打印有关名称匹配的类的警告。
-ignorewarnings
指定打印有关未解决的引用和其他重要问题的任何警告,但在任何情况下都将继续处理。

  1. ProGuard一些注意事项
    a. 反射使用。比如 setName()方法通过混淆被映射为了a()如果我们希望通过方法名 setName 来调用类中的该方法,在写代码的时候,我们也不会知道这个名字将会被映射为 a,混淆之后,会找不到方法的。混淆使得方法名发生改变,而我们还在使用原来的方法名进行反射。
    b. bean 文件使用。对于 bean 文件,很多时候,它们作为和服务器之间的通信实体。如果在这种情况下进行了混淆,当数据发给服务器之后,服务器是看不懂的,因为属性名都变了,而服务端保存的是原来的 bean 文件(序列化问题,json问题)。
    c. 回调函数。这是一个值得注意的地方。比如在 Activity 中的 onTouchEvent 回调,如果被你混淆了,而系统实际上不知道的,混淆是你的个人行为。它不会知道到该回调的,同样因为找不到。
    d. 枚举。在使用枚举类型的时候,应当注意不要对它们进行混淆。因为枚举会使用反射进行操作。
    e. native 方法不要混淆。
    f. 内嵌类经常会被混淆,结果在调用的时候为空就崩溃了。(开发尽量避免内嵌类)

保留内嵌类不被混淆 列:-keep class com.example.xxx.MainActivity$* { *; }

为了获得最佳结果,ProGuard的优化算法假定处理后的代码从不故意抛出NullPointerExceptions或ArrayIndexOutOfBoundsExceptions甚至OutOfMemoryErrors或StackOverflowErrors,以实现有用的功能。
例如,myObject.myMethod()如果该方法调用无效,它可能会删除该方法调用。它忽略myObject可能为null 的可能性,从而导致NullPointerException。在某种程度上,这是件好事:优化的代码可能会抛出更少的异常。如果整个假设都是错误的,则必须使用-dontoptimize选项关闭优化。

9点击NEXT->Process,进行混淆处理。
测试结果如下,使用JD-GUI工具反编译已混淆的JAR
史上最全ProGuard使用及相光配置
如上混淆处理的结果,可以看做一个重命名的过程,即实现名字(类名、方法名、属性名)的映射,但是无法改变程序主结构。

10
另外,如需后期更改配置,可在混淆处理结束后,Process->Save configguration,保存本次混淆处理配置文件(xxx.pro),以便后续更改。
史上最全ProGuard使用及相光配置

相关文章:

  • 2021-06-24
  • 2021-11-13
  • 2021-11-13
  • 2021-06-18
  • 2021-06-19
  • 2021-04-05
  • 2021-05-15
猜你喜欢
  • 2021-12-31
  • 2021-12-25
  • 2022-01-16
  • 2021-12-27
  • 2022-03-06
  • 2022-12-23
  • 2022-02-07
相关资源
相似解决方案