Slide 1

Slide 1 text

ProGuard Edward Dale @scompt Freeletics https://www.freeletics.com August 31, 2017 © Edward Dale, 2017 1

Slide 2

Slide 2 text

Agenda • Overview • Steps • Problems • Future © Edward Dale, 2017 2

Slide 3

Slide 3 text

Purpose ProGuard is the most popular optimizer for Java bytecode. It makes your Java and Android applications up to 90% smaller and up to 20% faster. ProGuard also provides minimal protection against reverse engineering by obfuscating the names of classes, fields and methods. — https://www.guardsquare.com/en/proguard © Edward Dale, 2017 3

Slide 4

Slide 4 text

Purpose ProGuard is the most popular optimizer for Java bytecode. It makes your Java and Android applications up to 90% smaller and up to 20% faster. ProGuard also provides minimal protection against reverse engineering by obfuscating the names of classes, fields and methods. — https://www.guardsquare.com/en/proguard © Edward Dale, 2017 4

Slide 5

Slide 5 text

Highlights 1 • ProGuard is a command-line tool with an optional graphical user interface. • ProGuard is easy to configure. A few intuitive command line options or a simple configuration file is all it takes. All available options are detailed in the user manual. 1 https://www.guardsquare.com/en/proguard © Edward Dale, 2017 5

Slide 6

Slide 6 text

Highlights 1 (continued) • ProGuard is fast. It processes small Android applications and entire run-time libraries in seconds. • ProGuard is the default tool in development environments like Oracle’s Wireless Toolkit, NetBeans, EclipseME, Intel’s TXE SDK and Google’s Android SDK. 1 https://www.guardsquare.com/en/proguard © Edward Dale, 2017 6

Slide 7

Slide 7 text

Highlights (annotated) • ProGuard is easy to configure. A few intuitive command line options or a simple configuration file is all it takes. All available options are detailed in the user manual. • ProGuard is fast. It processes small Android applications and entire run- time libraries in seconds. © Edward Dale, 2017 7

Slide 8

Slide 8 text

Steps start shrink end optimize obfuscate preverify © Edward Dale, 2017 8

Slide 9

Slide 9 text

Shrink Step • Enabled by default • Disabled with -dontshrink • Removes all classes, methods, resources not reachable from from an entry point (seeds) • Dynamically referenced classes/methods need to be "kept" using -keep or -keepclasseswithmembers © Edward Dale, 2017 9

Slide 10

Slide 10 text

Example Class Diagram LoginActivity UserManager UserApi FeedActivity FeedApi OldUserManager OldUserApi © Edward Dale, 2017 10

Slide 11

Slide 11 text

After Shrinking • No seeds LoginActivity UserManager UserApi FeedActivity FeedApi OldUserManager OldUserApi © Edward Dale, 2017 11

Slide 12

Slide 12 text

After Shrinking • -keep MainActivity • -keep SecondActivity LoginActivity UserManager UserApi FeedActivity FeedApi OldUserManager OldUserApi © Edward Dale, 2017 12

Slide 13

Slide 13 text

After Shrinking • -keep public class * extends android.app.Activity LoginActivity UserManager UserApi FeedActivity FeedApi OldUserManager OldUserApi © Edward Dale, 2017 13

Slide 14

Slide 14 text

Keep Options -keep Specifies classes and class members (fields and methods) to be preserved as entry points to your code. -keepclassmembers Specifies class members to be preserved, if their classes are preserved as well. -keepclasseswithmembers Specifies classes and class members to be preserved, on the condition that all of the specified class members are present. © Edward Dale, 2017 14

Slide 15

Slide 15 text

Optimize Step • Enabled by default • Disabled with -dontoptimize • Performs lots of different bytecode-level optimizations to the code © Edward Dale, 2017 15

Slide 16

Slide 16 text

Optimize Step • -optimizationpasses declares how many times to optimize/shrink • Freeletics does 5 passes © Edward Dale, 2017 16

Slide 17

Slide 17 text

Optimize Step • -optimizations can be used to disable specific optimizations • Freeletics disables optimizations that cause problems on Android • More information in $ANDROID_HOME/tools/proguard/ proguard-android-optimize.txt © Edward Dale, 2017 17

Slide 18

Slide 18 text

Example Optimizations 2 • Marks methods as final, whenever possible. • Removes unused method parameters. • Propagates the values of method parameters from method invocations to the invoked 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

Slide 19

Slide 19 text

Obfuscate Step • Enabled by default • Disabled with -dontobfuscate • Classes and class members receive new short random names, except for the ones listed by the various -keep options • Internal attributes that are useful for debugging are removed © Edward Dale, 2017 19

Slide 20

Slide 20 text

After Obfuscation LoginActivity A B FeedActivity C OldUserManager OldUserApi © Edward Dale, 2017 20

Slide 21

Slide 21 text

Preverification Step • Enabled by default • Disabled with -dontpreverify • When loading class files, the class loader performs some sophisticated verification of the byte code. • Unnecessary on Android © Edward Dale, 2017 21

Slide 22

Slide 22 text

Problems © Edward Dale, 2017 22

Slide 23

Slide 23 text

Problem 1 Class is unintentionally removed/obfuscated Symptom: Runtime crash java.lang.NoClassDefFoundError: Failed resolution of: Lcom/freeletics/LoginActivity; © Edward Dale, 2017 23

Slide 24

Slide 24 text

Problem 1 Class is unintentionally removed/obfuscated Symptom: Runtime crash java.lang.NoClassDefFoundError: Failed resolution of: Lcom/freeletics/LoginActivity; Solution: Ensure class is kept -keep com.freeletics.LoginActivity © Edward Dale, 2017 24

Slide 25

Slide 25 text

Problem 2 Code references a class not available Symptom:: Build failure Warning: 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

Slide 26

Slide 26 text

Problem 2 Code references a class not available Symptom:: Build failure Warning: 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

Slide 27

Slide 27 text

Problem 3 Adding a new library breaks build Symptom: Build failure © Edward Dale, 2017 27

Slide 28

Slide 28 text

Problem 3 Adding a new library breaks build Symptom: Build failure Solution: Google Should only happen with non-Android-specific libraries. Android-specific Libraries can add a ProGuard configuration that should be used. © Edward Dale, 2017 28

Slide 29

Slide 29 text

The Future we are also working on R8, which is a Proguard replacement for whole program minification and optimization3 — James Lau, Product Manager 3 https://android-developers.googleblog.com/2017/08/next-generation-dex-compiler-now-in.html © Edward Dale, 2017 29

Slide 30

Slide 30 text

The Future • D8 is a dexer that converts java byte code to dex code. • R8 is a java program shrinking and minification tool that converts java byte code to optimized dex code. • R8 is a Proguard replacement for whole-program optimization, shrinking and minification. R8 uses the Proguard keep rule format for specifying the entry points for an application. © Edward Dale, 2017 30

Slide 31

Slide 31 text

Questions? Edward Dale @scompt Freeletics https://www.freeletics.com © Edward Dale, 2017 31

Slide 32

Slide 32 text

Citations • http://knowyourmeme.com/memes/yao-ming-face-bitch- please © Edward Dale, 2017 32