An introduction to how ProGuard works.
ProGuardEdward Dale@scomptFreeleticshttps://www.freeletics.comAugust 31, 2017© Edward Dale, 2017 1
View Slide
Agenda• Overview• Steps• Problems• Future© Edward Dale, 2017 2
PurposeProGuard is the most popular optimizer for Java bytecode. Itmakes your Java and Android applications up to 90% smaller andup to 20% faster. ProGuard also provides minimal protectionagainst reverse engineering by obfuscating the names of classes,fields and methods.— https://www.guardsquare.com/en/proguard© Edward Dale, 2017 3
PurposeProGuard is the most popular optimizer for Java bytecode. Itmakes your Java and Android applications up to 90% smallerand up to 20% faster. ProGuard also provides minimal protectionagainst reverse engineering by obfuscating the names ofclasses, fields and methods.— https://www.guardsquare.com/en/proguard© Edward Dale, 2017 4
Highlights 1• ProGuard is a command-line tool with an optional graphicaluser interface.• ProGuard is easy to configure. A few intuitive command lineoptions or a simple configuration file is all it takes. Allavailable options are detailed in the user manual.1 https://www.guardsquare.com/en/proguard© Edward Dale, 2017 5
Highlights 1 (continued)• ProGuard is fast. It processes small Android applications andentire run-time libraries in seconds.• ProGuard is the default tool in development environmentslike Oracle’s Wireless Toolkit, NetBeans, EclipseME, Intel’sTXE SDK and Google’s Android SDK.1 https://www.guardsquare.com/en/proguard© Edward Dale, 2017 6
Highlights (annotated)• ProGuard is easy to configure. Afew intuitive command line optionsor a simple configuration file is all ittakes. All available options aredetailed in the user manual.• ProGuard is fast. It processes smallAndroid applications and entire run-time libraries in seconds.© Edward Dale, 2017 7
Stepsstart shrink endoptimize obfuscate preverify© Edward Dale, 2017 8
Shrink Step• Enabled by default• Disabled with -dontshrink• Removes all classes, methods, resources not reachable fromfrom an entry point (seeds)• Dynamically referenced classes/methods need to be "kept"using -keep or -keepclasseswithmembers© Edward Dale, 2017 9
Example Class DiagramLoginActivityUserManagerUserApiFeedActivityFeedApi OldUserManagerOldUserApi© Edward Dale, 2017 10
After Shrinking• No seedsLoginActivityUserManagerUserApiFeedActivityFeedApi OldUserManagerOldUserApi© Edward Dale, 2017 11
After Shrinking• -keep MainActivity• -keep SecondActivityLoginActivityUserManagerUserApiFeedActivityFeedApi OldUserManagerOldUserApi© Edward Dale, 2017 12
After Shrinking• -keep public class * extends android.app.ActivityLoginActivityUserManagerUserApiFeedActivityFeedApi OldUserManagerOldUserApi© Edward Dale, 2017 13
Keep Options-keepSpecifies classes and class members (fields and methods) to be preserved asentry points to your code.-keepclassmembersSpecifies class members to be preserved, if their classes are preserved as well.-keepclasseswithmembersSpecifies classes and class members to be preserved, on the condition that all ofthe specified class members are present.© Edward Dale, 2017 14
Optimize Step• Enabled by default• Disabled with -dontoptimize• Performs lots of different bytecode-level optimizations tothe code© Edward Dale, 2017 15
Optimize Step• -optimizationpasses declares how many times tooptimize/shrink• Freeletics does 5 passes© Edward Dale, 2017 16
Optimize Step• -optimizations can be used to disable specificoptimizations• Freeletics disables optimizations that cause problems onAndroid• More information in $ANDROID_HOME/tools/proguard/proguard-android-optimize.txt© Edward Dale, 2017 17
Example Optimizations 2• Marks methods as final, whenever possible.• Removes unused method parameters.• Propagates the values of method parameters from method invocations to theinvoked methods.• Propagates the values of method return values from methods to their invocations.• Inlines short methods.• Inlines methods that are only called once.2 https://www.guardsquare.com/en/proguard/manual/optimizations© Edward Dale, 2017 18
Obfuscate Step• Enabled by default• Disabled with -dontobfuscate• Classes and class members receive new short randomnames, except for the ones listed by the various-keep options• Internal attributes that are useful for debugging areremoved© Edward Dale, 2017 19
After ObfuscationLoginActivityABFeedActivityCOldUserManagerOldUserApi© Edward Dale, 2017 20
Preverification Step• Enabled by default• Disabled with -dontpreverify• When loading class files, the class loader performs somesophisticated verification of the byte code.• Unnecessary on Android© Edward Dale, 2017 21
Problems© Edward Dale, 2017 22
Problem 1Class is unintentionally removed/obfuscatedSymptom: Runtime crashjava.lang.NoClassDefFoundError: Failed resolution of: Lcom/freeletics/LoginActivity;© Edward Dale, 2017 23
Problem 1Class is unintentionally removed/obfuscatedSymptom: Runtime crashjava.lang.NoClassDefFoundError: Failed resolution of: Lcom/freeletics/LoginActivity;Solution: Ensure class is kept-keep com.freeletics.LoginActivity© Edward Dale, 2017 24
Problem 2Code references a class not availableSymptom:: Build failureWarning: rx.internal.util.unsafe.ConcurrentCircularArrayQueue: can't find referenced class sun.misc.Unsafe...Warning: there were 47 unresolved references to classes or interfaces.© Edward Dale, 2017 25
Problem 2Code references a class not availableSymptom:: Build failureWarning: rx.internal.util.unsafe.ConcurrentCircularArrayQueue: can't find referenced class sun.misc.Unsafe...Warning: there were 47 unresolved references to classes or interfaces.Solution: Don't warn about classes unavailable on Android-dontwarn sun.misc.Unsafe© Edward Dale, 2017 26
Problem 3Adding a new library breaks buildSymptom: Build failure© Edward Dale, 2017 27
Problem 3Adding a new library breaks buildSymptom: Build failureSolution: GoogleShould only happen with non-Android-specific libraries.Android-specific Libraries can add a ProGuard configurationthat should be used.© Edward Dale, 2017 28
The Futurewe are also working on R8, which is a Proguard replacement forwhole program minification and optimization3— James Lau, Product Manager3 https://android-developers.googleblog.com/2017/08/next-generation-dex-compiler-now-in.html© Edward Dale, 2017 29
The Future• D8 is a dexer that converts java byte code to dex code.• R8 is a java program shrinking and minification tool thatconverts java byte code to optimized dex code.• R8 is a Proguard replacement for whole-programoptimization, shrinking and minification. R8 uses theProguard keep rule format for specifying the entry points foran application.© Edward Dale, 2017 30
Questions?Edward Dale@scomptFreeleticshttps://www.freeletics.com© Edward Dale, 2017 31
Citations• http://knowyourmeme.com/memes/yao-ming-face-bitch-please© Edward Dale, 2017 32