proguard学习

ProGuard runs only when you build your application in release mode,so you do not have to deal with obfuscated code when you build your applicationin debug mode.

http://developer.android.com/intl/zh-CN/tools/help/proguard.html

default.properties中配置:(如果隐藏在某个路径中,则需要加上路径)

proguard.config=proguard.cfg

 

When you build yourapplication in release mode, either by running antrelease or by using the Export Wizard inEclipse, the build system automatically checks to see if theproguard.config property is set. If it is, ProGuardautomatically processes the application's bytecode before packaging everythinginto an .apk file. Building in debug mode does not invoke ProGuard,because it makes debugging more cumbersome.

 

ProGuard outputs thefollowing files after it runs:

dump.txt···描述apk文件中所有类文件的内部结构

mapping.txt···列出了类、方法、成员的原貌与混淆后的映射表。在收到错误报告时,可以用它翻译混淆后的堆栈信息。

seeds.txt···列出未混淆的类与成员

usage.txt···列出从apk中清除的无用代码

这些文件的位置在:

<project_root>/bin/proguard if you are using Ant.

<project_root>/proguard if you are using Eclipse.

 

 

但是,proguard.cfg文件在以下情况下可能移除开发者要用到的类:

仅在AndroidManifest.xml文件中用到的类

JNI中调用的方法

动态引用的fieldsmethods

这时,便会出现ClassNotFoundException的问题,需要在文件中加入:

-keep public class<MyClass>

 

 

The retrace.bat script on Windows or the retrace.shscript on Linux or Mac OS X can convert an obfuscated stack trace to a readableone. It is located in the <sdk_root>/tools/proguard/directory. The syntax for executing the retrace tool is:

retrace.bat|retrace.sh[-verbose] mapping.txt [<stacktrace_file>]

For example: retrace.bat -verbosemapping.txt obfuscated_trace.txt

 

 

Proguard manual的学习

http://proguard.sourceforge.net/index.html#manual/introduction.html

 

经历四步(shrink 瘦身-去除无用代码,optimize 优化-优化方法的字节码 ,obfuscate 混淆-用无意义段短名称替代 ,preverify 预验证-添加预验证信息)。

对于使用反射的类,类名称设置可能从配置文件中读出,故需要专门指定为entry points.

不过,proguard还是对以下情况做了处理:

Class.forName("SomeClass")

SomeClass.class

SomeClass.class.getField("someField")

SomeClass.class.getDeclaredField("someField")

SomeClass.class.getMethod("someMethod",new Class[] {})

SomeClass.class.getMethod("someMethod",new Class[] { A.class })

SomeClass.class.getMethod("someMethod",new Class[] { A.class, B.class })

SomeClass.class.getDeclaredMethod("someMethod",new Class[] {})

SomeClass.class.getDeclaredMethod("someMethod",new Class[] { A.class })

SomeClass.class.getDeclaredMethod("someMethod",new Class[] { A.class, B.class })

AtomicIntegerFieldUpdater.newUpdater(SomeClass.class,"someField")

AtomicLongFieldUpdater.newUpdater(SomeClass.class,"someField")

AtomicReferenceFieldUpdater.newUpdater(SomeClass.class,SomeType.class, "someField")

瘦身阶段,保留以上类与方法;混淆阶段,更新上面的字串。

 

指定injar/outjar时,可以使用文件夹或者非jar文件,而libraryjars允许我们处理android,j2ee等运行文件,例子:

-injars      bin/classes

-injars      libs

-outjars     bin/classes-processed.jar

-libraryjars/usr/local/java/android-sdk/platforms/android-9/android.jar

 

 

-skipnonpubliclibraryclasses

跳过库中非public的类,可以加快proguard处理速度;

但是有些类库包含从public类中继承来的非public类,

这时如果加了这条会产生一个warning(find classes)

-dontskipnonpubliclibraryclasses

prog4.5开始,这时默认设置

-dontskipnonpubliclibraryclassmembers

默认会跳过,不过有时位于同一个包中的程序类作为库类,

且他们引用了包内可见的类成员。

-printmapping myapplication.map

指定输出映射文件

-keep

保留某类

-keepclassmembers

保留某类成员

-keepclasseswithmembers

保留类和类成员

-keepnames

相当于-keep,allowshrinking class_specification.同理,

对于其他的-keepXXXXXnames,同样是加了allowshrinking 的简称

 

 

 

 

通配符:

?        matchesany single character in a file name.

*        matchesany part of a filename not containing the directory separator.

**        matches any part of a filename, possibly containingany number of directory separators(可以跨文件夹或者包).

For example,"java/**.class,javax/**.class" matches all class files in the javaand javax.

 

Keep

From being removed or renamed

From being renamed

Classes and class members

-keep

-keepnames

Class members only

-keepclassmembers

-keepclassmembernames

Classes and class members, if class members present

-keepclasseswithmembers

-keepclasseswithmembernames

 

替代符:

<init>        matchesany constructor.

<fields>        matchesany field.

<methods>        matchesany method.

*        matchesany field or method.

Note that the abovewildcards don't have return types. Only the <init> wildcard has anargument list.

 

%        matchesany primitive type ("boolean", "int", etc, but not"void").

?        matchesany single character in a class name.

*        matchesany part of a class name not containing the package separator.

**        matchesany part of a class name, possibly containing any number of package separators.

***        matchesany type (primitive or non-primitive, array or non-array).

...        matchesany number of arguments of any type.

Note,only the ***wildcards will match array types of any dimension. For example, "**get*()" matches "java.lang.Object getObject()", but not"float getFloat()", nor "java.lang.Object[] getObjects()".

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值