dump.txt···描述apk文件中所有类文件的内部结构
mapping.txt···列出了类、方法、成员的原貌与混淆后的映射表。在收到错误报告时,可以用它翻译混淆后的堆栈信息。
seeds.txt···列出未混淆的类与成员
usage.txt···列出从apk中清除的无用代码
这些文件的位置在:
/bin/proguard if you are using Ant.
/proguard if you are using Eclipse.
但是,proguard.cfg文件在以下情况下可能移除开发者要用到的类:
仅在Manifest.xml文件中用到的类
从JNI中调用的方法
动态引用的fields和methods
这时,便会出现ClassNotFoundException的问题,需要在文件中加入:
-keep public class
The retrace.bat script on Windows or the retrace.shscript on or Mac OS X can convert an obfuscated stack trace to a readableone. It
is located in the /tools/proguard/directory. The syntax
for executing the retrace tool is:
retrace.bat|retrace.sh[-verbose] mapping.txt []
For example: retrace.bat -verbosemapping.txt obfuscated_trace.txt
Proguard manual的学习
经历四步(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
替代符:
matchesany constructor.
matchesany field.
matchesany method.
* matchesany field or method.
Note that the abovewildcards don't have return types. Only the 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()".
阅读(667) | 评论(0) | 转发(0) |