Proguard混淆介绍:
http://blog.csdn.net/Zengyangtech/article/details/6127600
keep语句语法:
http://proguard.sourceforge.net/manual/usage.html#classspecification
A class specification is a template of classes and class members (fields and methods). It is used in the various -keep options and in the -assumenosideeffectsoption. The corresponding option is only applied to classes and class members that match the template.The template was designed to look very Java-like, with some extensions for wildcards. To get a feel for the syntax, you should probably look at the examples, but this is an attempt at a complete formal definition:
[@annotationtype] [[!]public|final|abstract|@ …] [!]interface|class|enumclassname [extends|implements [@annotationtype] classname][{ [@annotationtype] [[!]public|private|protected|static|volatile|transient …] <fields> | (fieldtype fieldname); [@annotationtype] [[!]public|private|protected|static|synchronized|native|abstract|strictfp …] <methods> | <init>(argumenttype,…) | classname(argumenttype,…) | (returntype methodname(argumenttype,…)); [@annotationtype] [[!]public|private|protected|static … ] ; …}]Square brackets "[]" mean that their contents are optional. Ellipsis dots "…" mean that any number of the preceding items may be specified. A vertical bar "|" delimits two alternatives. Non-bold parentheses "()" just group parts of the specification that belong together. The indentation tries to clarify the intended meaning, but white-space is irrelevant in actual configuration files.
The class keyword refers to any interface or class. The interface keyword restricts matches to interface classes. The enum keyword restricts matches to enumeration classes. Preceding the interface or enum keywords by a ! restricts matches to classes that are not interfaces or enumerations, respectively.Every classname must be fully qualified, e.g. java.lang.String. Class names may be specified as regular expressions containing the following wildcards:?matches any single character in a class name, but not the package separator. For example, "mypackage.Test?" matches "mypackage.Test1" and "mypackage.Test2", but not "mypackage.Test12".matches any part of a class name not containing the package separator. For example, "mypackage.Test" matches "mypackage.Test" and "mypackage.YourTestApplication", but not "mypackage.mysubpackage.MyTest". Or, more generally, "mypackage." matches all classes in "mypackage", but not in its subpackages.matches any part of a class name, possibly containing any number of package separators. For example, ".Test" matches all Test classes in all packages except the root package. Or, "mypackage.**" matches all classes in "mypackage" and in its subpackages.For additional flexibility, class names can actually be comma-separated lists of class names, with optional ! negators, just like file name filters. This notation doesn’t look very Java-like, so it should be used with moderation.For convenience and for backward compatibility, the class name
refers to any class, irrespective of its package.The extends and implements specifications are typically used to restrict classes with wildcards. They are currently equivalent, specifying that only classes extending or implementing the given class qualify. Note that the given class itself is not included in this set. If required, it should be specified in a separate option.The @ specifications can be used to restrict classes and class members to the ones that are annotated with the specified annotation types. Anannotationtype is specified just like a classname.Fields and methods are specified much like in Java, except that method argument lists don’t contain argument names (just like in other tools like javadocand javap). The specifications can also contain the following catch-all wildcards:<init>matches any constructor.<fields>matches any field.<methods>matches any method.matches any field or method.Note that the above wildcards don’t have return types. Only the <init> wildcard has an argument list.Fields and methods may also be specified using regular expressions. Names can contain the following wildcards:?matches any single character in a method name.matches any part of a method name.Types in descriptors can contain the following wildcards:%matches any primitive type ("boolean", "int", etc, but not "void").?matches any single character in a class name.matches any part of a class name not containing the package separator.matches any part of a class name, possibly containing any number of package separators.matches any type (primitive or non-primitive, array or non-array).…matches any number of arguments of any type.Note that the ?, , and wildcards will never match primitive types. Furthermore, 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()".
Constructors can also be specified using their short class names (without package) or using their full class names. As in the Java language, the constructor specification has an argument list, but no return type.The class access modifiers and class member access modifiers are typically used to restrict wildcarded classes and class members. They specify that the corresponding access flags have to be set for the member to match. A preceding ! specifies that the corresponding access flag should be unset.Combining multiple flags is allowed (e.g. public static). It means that both access flags have to be set (e.g. public and static), except when they are conflicting, in which case at least one of them has to be set (e.g. at least public or protected).
ProGuard supports the additional modifiers synthetic, bridge, and varargs, which may be set by compilers.
Restoring a stack trace with line numbers:
http://proguard.sourceforge.net/index.html#/manual/retrace/examples.html
Assume for instance ProGuard itself has been obfuscated using the following extra options:-printmapping proguard.map-renamesourcefileattribute ProGuard-keepattributes SourceFile,LineNumberTable
Now assume the processed application throws an exception, and we have saved the stack trace in proguard.trace, shown below. Of course, in real life ProGuard rarely throws exceptions, so this is a purposely generated exception. :)
Exception in thread "main" java.lang.Error: Random exception at pro.bY.a(ProGuard:576) at pro.bO.a(ProGuard:431) at pro.bj.a(ProGuard:145) at pro.bY.a(ProGuard:522) at pro.bj.a(ProGuard:129) at pro.bN.a(ProGuard:125) at pro.bY.a(ProGuard:251) at pro.bY.a(ProGuard:229) at pro.l.a(ProGuard:55) at pro.bo.b(ProGuard:405) at pro.ci.a(ProGuard:51) at pro.bo.a(ProGuard:356) at pro.be.a(ProGuard:109) at pro.bo.a(ProGuard:356) at pro.be.a(ProGuard:186) at pro.bg.a(ProGuard:369) at pro.bY.a(ProGuard:286) at pro.bh.a(ProGuard:55) at pro.bg.b(ProGuard:408) at pro.bY.a(ProGuard:190) at pro.bg.a(ProGuard:369) at pro.M.a(ProGuard:110) at pro.bY.a(ProGuard:449) at pro.M.a(ProGuard:99) at pro.bo.a(ProGuard:372) at pro.bY.a(ProGuard:649) at pro.bY.a(ProGuard:112) at pro.P.a(ProGuard:66) at pro.p.a(ProGuard:83) at pro.bU.a(ProGuard:69) at pro.bo.a(ProGuard:356) at pro.J.a(ProGuard:149) at pro.I.a(ProGuard:49) at pro.J.a(ProGuard:105) at pro.cf.c(ProGuard:370) at pro.cf.a(ProGuard:317) at pro.bc.a(ProGuard:55) at proguard.ProGuard.a(ProGuard:363) at proguard.ProGuard.c(ProGuard:187) at proguard.ProGuard.b(ProGuard:385) at proguard.ProGuard.main(ProGuard:429)We can then use the following command to recover the stack trace:
java -jar retrace.jar proguard.map proguard.traceThe output will look as follows:
Exception in thread "main" java.lang.Error: Random exception at proguard.shrink.UsageMarker.visitInstruction(ProGuard:576) at proguard.classfile.instruction.GenericInstruction.accept(ProGuard:431) at proguard.classfile.CodeAttrInfo.instructionsAccept(ProGuard:145) at proguard.shrink.UsageMarker.visitCodeAttrInfo(ProGuard:522) at proguard.classfile.CodeAttrInfo.accept(ProGuard:129) at proguard.classfile.ProgramMemberInfo.attributesAccept(ProGuard:125) at proguard.shrink.UsageMarker.visitMemberInfo(ProGuard:251) at proguard.shrink.UsageMarker.visitProgramMethodInfo(ProGuard:229) at proguard.classfile.ProgramMethodInfo.accept(ProGuard:55) at proguard.classfile.ProgramClassFile.methodAccept(ProGuard:405) at proguard.classfile.visitor.NamedMethodVisitor.visitProgramClassFile(ProGuard:51) at proguard.classfile.ProgramClassFile.accept(ProGuard:356) at proguard.classfile.visitor.ClassFileUpDownTraveler.visitProgramClassFile(ProGuard:109) at proguard.classfile.ProgramClassFile.accept(ProGuard:356) at proguard.classfile.visitor.ClassFileUpDownTraveler.visitLibraryClassFile(ProGuard:186) at proguard.classfile.LibraryClassFile.accept(ProGuard:369) at proguard.shrink.UsageMarker.visitLibraryMethodInfo(ProGuard:286) at proguard.classfile.LibraryMethodInfo.accept(ProGuard:55) at proguard.classfile.LibraryClassFile.methodsAccept(ProGuard:408) at proguard.shrink.UsageMarker.visitLibraryClassFile(ProGuard:190) at proguard.classfile.LibraryClassFile.accept(ProGuard:369) at proguard.classfile.ClassCpInfo.referencedClassAccept(ProGuard:110) at proguard.shrink.UsageMarker.visitClassCpInfo(ProGuard:449) at proguard.classfile.ClassCpInfo.accept(ProGuard:99) at proguard.classfile.ProgramClassFile.constantPoolEntryAccept(ProGuard:372) at proguard.shrink.UsageMarker.markCpEntry(ProGuard:649) at proguard.shrink.UsageMarker.visitProgramClassFile(ProGuard:112) at proguard.classfile.visitor.VariableClassFileVisitor.visitProgramClassFile(ProGuard:66) at proguard.classfile.visitor.MultiClassFileVisitor.visitProgramClassFile(ProGuard:83) at proguard.classfile.visitor.FilteredClassFileVisitor.visitProgramClassFile(ProGuard:69) at proguard.classfile.ProgramClassFile.accept(ProGuard:356) at proguard.classfile.ClassPool.classFileAccept(ProGuard:149) at proguard.classfile.visitor.NamedClassFileVisitor.visitClassPool(ProGuard:49) at proguard.classfile.ClassPool.accept(ProGuard:105) at proguard.KeepCommand.executeShrinkingPhase(ProGuard:370) at proguard.KeepCommand.execute(ProGuard:317) at proguard.CompoundCommand.execute(ProGuard:55) at proguard.ProGuard.executeCommands(ProGuard:363) at proguard.ProGuard.shrink(ProGuard:187) at proguard.ProGuard.execute(ProGuard:385) at proguard.ProGuard.main(ProGuard:429)
In the previous example, we could also use the verbose flag:
java -jar retrace.jar -verbose proguard.map proguard.trace
The output will then look as follows:
Exception in thread "main" java.lang.Error: Random exception at proguard.shrink.UsageMarker.void visitInstruction(proguard.classfile.ClassFile,proguard.classfile.instruction.Instruction)(ProGuard:576) at proguard.classfile.instruction.GenericInstruction.void accept(proguard.classfile.ClassFile,proguard.classfile.instruction.InstructionVisitor)(ProGuard:431) at proguard.classfile.CodeAttrInfo.void instructionsAccept(proguard.classfile.ClassFile,proguard.classfile.instruction.InstructionVisitor)(ProGuard:145) at proguard.shrink.UsageMarker.void visitCodeAttrInfo(proguard.classfile.ClassFile,proguard.classfile.CodeAttrInfo)(ProGuard:522) at proguard.classfile.CodeAttrInfo.void accept(proguard.classfile.ClassFile,proguard.classfile.visitor.AttrInfoVisitor)(ProGuard:129) at proguard.classfile.ProgramMemberInfo.void attributesAccept(proguard.classfile.ProgramClassFile,proguard.classfile.visitor.AttrInfoVisitor)(ProGuard:125) at proguard.shrink.UsageMarker.void visitMemberInfo(proguard.classfile.ProgramClassFile,proguard.classfile.ProgramMemberInfo)(ProGuard:251) at proguard.shrink.UsageMarker.void visitProgramMethodInfo(proguard.classfile.ProgramClassFile,proguard.classfile.ProgramMethodInfo)(ProGuard:229) at proguard.classfile.ProgramMethodInfo.void accept(proguard.classfile.ProgramClassFile,proguard.classfile.visitor.MemberInfoVisitor)(ProGuard:55) at proguard.classfile.ProgramClassFile.void methodAccept(proguard.classfile.visitor.MemberInfoVisitor,java.lang.String,java.lang.String)(ProGuard:405) at proguard.classfile.visitor.NamedMethodVisitor.void visitProgramClassFile(proguard.classfile.ProgramClassFile)(ProGuard:51) at proguard.classfile.ProgramClassFile.void accept(proguard.classfile.visitor.ClassFileVisitor)(ProGuard:356) at proguard.classfile.visitor.ClassFileUpDownTraveler.void visitProgramClassFile(proguard.classfile.ProgramClassFile)(ProGuard:109) at proguard.classfile.ProgramClassFile.void accept(proguard.classfile.visitor.ClassFileVisitor)(ProGuard:356) at proguard.classfile.visitor.ClassFileUpDownTraveler.void visitLibraryClassFile(proguard.classfile.LibraryClassFile)(ProGuard:186) at proguard.classfile.LibraryClassFile.void accept(proguard.classfile.visitor.ClassFileVisitor)(ProGuard:369) at proguard.shrink.UsageMarker.void visitLibraryMethodInfo(proguard.classfile.LibraryClassFile,proguard.classfile.LibraryMethodInfo)(ProGuard:286) at proguard.classfile.LibraryMethodInfo.void accept(proguard.classfile.LibraryClassFile,proguard.classfile.visitor.MemberInfoVisitor)(ProGuard:55) at proguard.classfile.LibraryClassFile.void methodsAccept(proguard.classfile.visitor.MemberInfoVisitor)(ProGuard:408) at proguard.shrink.UsageMarker.void visitLibraryClassFile(proguard.classfile.LibraryClassFile)(ProGuard:190) at proguard.classfile.LibraryClassFile.void accept(proguard.classfile.visitor.ClassFileVisitor)(ProGuard:369) at proguard.classfile.ClassCpInfo.void referencedClassAccept(proguard.classfile.visitor.ClassFileVisitor)(ProGuard:110) at proguard.shrink.UsageMarker.void visitClassCpInfo(proguard.classfile.ClassFile,proguard.classfile.ClassCpInfo)(ProGuard:449) at proguard.classfile.ClassCpInfo.void accept(proguard.classfile.ClassFile,proguard.classfile.visitor.CpInfoVisitor)(ProGuard:99) at proguard.classfile.ProgramClassFile.void constantPoolEntryAccept(proguard.classfile.visitor.CpInfoVisitor,int)(ProGuard:372) at proguard.shrink.UsageMarker.void markCpEntry(proguard.classfile.ClassFile,int)(ProGuard:649) at proguard.shrink.UsageMarker.void visitProgramClassFile(proguard.classfile.ProgramClassFile)(ProGuard:112) at proguard.classfile.visitor.VariableClassFileVisitor.void visitProgramClassFile(proguard.classfile.ProgramClassFile)(ProGuard:66) at proguard.classfile.visitor.MultiClassFileVisitor.void visitProgramClassFile(proguard.classfile.ProgramClassFile)(ProGuard:83) at proguard.classfile.visitor.FilteredClassFileVisitor.void visitProgramClassFile(proguard.classfile.ProgramClassFile)(ProGuard:69) at proguard.classfile.ProgramClassFile.void accept(proguard.classfile.visitor.ClassFileVisitor)(ProGuard:356) at proguard.classfile.ClassPool.void classFileAccept(proguard.classfile.visitor.ClassFileVisitor,java.lang.String)(ProGuard:149) at proguard.classfile.visitor.NamedClassFileVisitor.void visitClassPool(proguard.classfile.ClassPool)(ProGuard:49) at proguard.classfile.ClassPool.void accept(proguard.classfile.visitor.ClassPoolVisitor)(ProGuard:105) at proguard.KeepCommand.void executeShrinkingPhase(proguard.classfile.ClassPool,proguard.classfile.ClassPool)(ProGuard:370) at proguard.KeepCommand.void execute(int,proguard.classfile.ClassPool,proguard.classfile.ClassPool)(ProGuard:317) at proguard.CompoundCommand.void execute(int,proguard.classfile.ClassPool,proguard.classfile.ClassPool)(ProGuard:55) at proguard.ProGuard.void executeCommands(int)(ProGuard:363) at proguard.ProGuard.void shrink()(ProGuard:187) at proguard.ProGuard.void execute(java.lang.String[])(ProGuard:385) at proguard.ProGuard.void main(java.lang.String[])(ProGuard:429)