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()".

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章