Proguard 混淆之乱谈 2

时间:2024-04-02 10:34:27

之前说了产品不进行安全措施的后果,没看的童鞋可以看下。

《Proguard 混淆之乱谈1》

接下来欢迎Proguard闪亮登场!

1.什么是Proguard?

ProGuard is a Java class file shrinker, optimizer, obfuscator, and preverifier. The shrinking step detects and removes unused classes, fields, methods and attributes. The optimization step analyzes and optimizes the bytecode of the methods. The obfuscation step renames the remaining classes, fields, and methods using short meaningless names. These first steps make the code base smaller, more efficient, and harder to reverse-engineer. The final preverification step adds preverification information to the classes, which is required for Java Micro Edition and for Java 6 and higher.

Each of these steps is optional. For instance, ProGuard can also be used to just list dead code in an application, or to preverify class files for efficient use in Java 6.

Proguard是用来对java文件进行压缩,优化,混淆和预校验的工具,压缩阶段检测并移除没有用的class,field,method,attribute,优化阶段分析并优化字节编码,混淆阶段用较短的名称重命名剩下的class,field,method,第一阶段可以使代码量更少,更有效,也更难被反编译,最后阶段是预校验,在上面三完成后,JVM,Java6或者更高版本运行前进行校验。

注意:每步都是可选的,并不是说1234挨个要都执行,你可以选择你需要的使用,下面插入来自官网的各阶段图,证明咱是一本正经的在胡谈,不是乱说。

Proguard 混淆之乱谈 2

2.Proguard如何工作的?

首先在介绍Proguard如何工作前,先了解下EntryPoint,这是认识Proguard工作的基本,不会爬就想飞,小心摔得疼呀。

照例,我们看看官方是怎么说的,咱好对应胡谈。

In order to determine which code has to be preserved and which code can be discarded or obfuscated, you have to specify one or more entry points to your code. These entry points are typically classes with main methods, applets, midlets, activities, etc.In the shrinking step, ProGuard starts from these seeds and recursively determines which classes and class members  are used. All other classes and class members are discarded.The preverification step is the only step that doesn't have to know the entry points.In the optimization step, ProGuard further optimizes the code. Among other optimizations, classes and methods that are not entry points can be made private, static, or final, unused parameters can be removed, and some methods may be inlined.In the obfuscation step, ProGuard renames classes and class members that are not entry points. In this entire process, keeping the entry points ensures that they can still be accessed by their original names.

看,官方老爷说了,entrypoint就是为了标记哪些code在各个阶段是否要做哪个操作。压缩阶段,ProGuard会从上述的EntryPoint中开始遍历搜索出哪些类和类的成员在使用(虽然标记了,但不代表会被用到,切记!),对于那些没有被使用的类和成员,就会在此阶段阶段被丢弃。优化阶段,没有被标记的的类和方法都会被设置为private,static或者final,而且不使用的参数都会被移除。混淆阶段,ProGuard对没标记的类和方法进行重命名。预校验阶段,对代码进行预检测,以便保证稳定性。

3.Proguard 使用语法

官方文档在这里,可以查看,接下来对其中部分做下介绍

3.1 Input/Output Options

@filename
-inlude filename
从filename文件中读取配置信息
-basedirectory 基本路径,之后可以作为相对路径根路径使用
-injars,-outjars 输入输出包
-libraryjars 作为库文件处理不会在outjar中包含
-skipnonpubliclibraryclasses    指定忽略非公共的库类。 
-dontskipnonpubliclibraryclasses    指定不去忽略非公共的库类。 
-dontskipnonpubliclibraryclassmembers    指定不去忽略包非公共的库类的成员。 
-keepdirectories  保留outjar中的路径,可能导致资源获取异常
-target
-version

-keepprocessing

3.2 Keep Options

-keep {Modifier} {class_specification} 保护指定的类文件和类的成员

-keepclassmembers {modifier} {class_specification} 保护指定类的成员,如果此类受到保护他们会保护的更好
-keepclassmembernames {class_specification} 保护指定的类的成员的名称(如果他们不会压缩步骤中删除)
-printseeds {filename} 列出类和类的成员-keep选项的清单,标准输出到给定的文件

-keepclasseswithmembers {class_specification} 保护指定的类和类的成员,但条件是所有指定的类和类成员是要存在。

-keepnames {class_specification} 保护指定的类和类的成员的名称(如果他们不会压缩步骤中删除)

-keepclasseswithmembernames {class_specification} 保护指定的类和类的成员的名称,如果所有指定的类成员出席(在压缩步骤之后)



  • 3.3 Shrinking Options

  •  -dontshrink 不压缩输入的类文件
  •  -printusage {filename} 输出未被压缩的文件列表到usage.txt中
  •  -whyareyoukeeping {class_specification} 打印为何保留指定class的原因

  • 3.4 Optimization Options

-dontoptimize 不优化输入的类文件

-optimizations 高手使用,进行部分优化

-assumenosideeffects {class_specification} 优化时假设指定的方法,没有任何副作用

-allowaccessmodification 优化时允许访问并修改有修饰符的类和类的成员

-mergeinterfaceaggressively

  • 3.5 Obfuscation Options

  •    -dontobfuscate 不混淆输入的类文件
  • -printmapping 输出映射关系
  • -applymapping 复用映射关系表
  • -obfuscationdictionary {filename} 使用给定文件中的关键字作为要混淆方法的名称
  • -classofuscationdictionary {filename}使用给定文件中的关键字作为要混淆类的名称
  • -packageofuscationdictionary {filename}使用给定文件中的关键字作为要混淆包的名称
  • -overloadaggressively 混淆时应用侵入式重载
  • -useuniqueclassmembernames 确定统一的混淆类的成员名称来增加混淆
  • -keeppackagenames 保留包名
  • -flattenpackagehierarchy {package_name} 重新包装所有重命名的包并放在给定的单一包中
  • -repackageclass {package_name} 重新包装所有重命名的类文件中放在给定的单一包中
  • -dontusemixedcaseclassnames 混淆时不会产生形形色色的类名
  • -keepattributes {attribute_name,...} 保护给定的可选属性,例如LineNumberTable, LocalVariableTable, SourceFile, Deprecated, Synthetic, Signature, and InnerClasses.
  • -keepparameters 保留方法的参数名称和类型
  • -renamesourcefileattribute {string} 设置源文件中给定的字符串常量
  • -adaptclassstring
  • -adaptresourcesfilenames
  • -adaptresourcefilecontents

  • 3.6 Preverification Options

  • -dontpreverify 不进行预校验
  • -microedtion

  • 3.7 General Options

  • -verbose
  • -dontwarn 不警告
  • -dontnote 不提醒可能存在的错误
  • -ignorewarning 忽略warning
  • -printconfiguration 打印配置信息
  • -dump 输出文件结构

  • 3.8 Class Paths

  • 路径,可以加过滤条件

  • 3.9 File Names

  • 可带上相对路径或者绝对路径

  • 3.10 File Filters

? matches any single character in a file name.
* matches any part of a filename not containing the directory separator.
** matches any part of a filename, possibly containing any number of directory separators.

  • 3.11 Filters

  • 同上

  • 3.12 Keep Option Modifiers

  • -includdescriptorclass 输出文件包括描述类
  • -allowshrunk
  • -allowoptimization
  • -allowobfuscation

  • 3.13 Class Specifications

Proguard 混淆之乱谈 2