ProGuardOptimizer and Obfuscator for Android             Eric Lafortune                 Saikoa
Eric Lafortune●    1991 – 1996   K.U.Leuven (Belgium), Phd Eng CompSci●    1996 – 1999   Cornell University (Ithaca, NY)● ...
ProGuardOpen source        Generic                Shrinker               Optimizer               Obfuscator               ...
ProGuard history                   Java applications       Applets                                Android apps            ...
Why use ProGuard?●    Application size●    Performance●    Remove logging, debugging, testing code●    Battery life●    Pr...
Application size                       classes.dex size                              .apk size             Without   With ...
Performance: CaffeineMarkWithout ProGuard                      With ProGuardSieve score      = 6833               Sieve sc...
Battery lifeExtreme example:                  “5 x better battery life,            by removing verbose logging code       ...
Tip        How to enable ProGuard?project.properties:       # To enable ProGuard to shrink and obfuscate           your co...
Build process                                          ProGuard                                           ProGuard[Android...
ShrinkingAlso called treeshaking, minimizing, shrouding
Shrinking●    Classes, fields, methods
Entry points1) Activities, applications, services, fragments,...→ provided automatically by Android build process    -keep...
Tip                    Entry points2) Introspection, e.g. Google License Verification Library→ must be specified in progua...
Entry pointsMore introspection, e.g. Google vending library→ must be specified in proguard-project.txt   -keepclassmembers...
Entry pointsMore introspection, e.g. Guice, RoboGuice→ must be specified in proguard-project.txt:   -keepclassmembers clas...
Tip                Notes and warnings“Closed-world assumption”       Warning:    twitter4j.internal.logging.Log4JLoggerFac...
OptimizationAt the bytecode instruction level:●    Dead code elimination●    Constant propagation●    Method inlining●    ...
Dead code elimination   boolean debug = false;   …   if (debug) Log.v(“.....”);   …Note: showing equivalent source code in...
Dead code elimination   boolean debug = false;   …   if (debug) Log.v(“.....”);   …Note: showing equivalent source code in...
Constant propagationInside methods:   int f1 = 6;   …   int f2 = 7;   …   int answer = f1 * f2;
Constant propagationInside methods:   int f1 = 6;   …   int f2 = 7;   …   int answer = f1 * f2;               …           ...
Constant propagationInside methods:   int f1 = 6;   …   int f2 = 7;   …   int answer = f1 * f2;               …           ...
Constant propagationAcross methods:   int answer = computeAnswer(6, 7);  int computeAnswer(int f1, int f2) {      return f...
Constant propagationAcross methods:   int answer = computeAnswer(6, 7);  int computeAnswer(int f1, int f2) {      return f...
Constant propagationAcross methods:   int answer = computeAnswer(6, 7);  int computeAnswer(int f1, int f2) {      return f...
Constant propagationAcross methods:   int answer = computeAnswer(6, 7);          int answer = 42;  int computeAnswer(int f...
Method inliningShort methods (or methods that are only invoked once):   int answer = image.getPixel(i, j);   int getPixel(...
Method inliningShort methods (or methods that are only invoked once):   int answer = image.getPixel(i, j);   int getPixel(...
Class merging: horizontally          Class A  Class B           Class CClass D     Class E
Class merging: horizontally          Class A                  Class A  Class B           Class C       Class B/CClass D   ...
Class merging: vertically      Class A      Class BClass C     Class D
Class merging: vertically      Class A                          Class A/B      Class BClass C     Class D   Class C     Cl...
Tail recursion simplificationint answer = computeAnswer(1, 2, 3, 7);int computeAnswer(int f1, int f2, int f3, int f4) {   ...
Tail recursion simplificationint answer = computeAnswer(1, 2, 3, 7);int computeAnswer(int f1, int f2, int f3, int f4) {   ...
Tail recursion simplification                                            int answer = 42;int answer = computeAnswer(1, 2, ...
Tip   How to enable optimization?project.properties:  # To enable ProGuard to shrink and obfuscate      your code, uncomme...
Tip              Remove logging codeSpecify assumptions in proguard-project.txt:       ­assumenosideeffects class android....
ObfuscationTraditional name obfuscation:●    Rename identifiers:      class/field/method names●    Remove debug informatio...
Obfuscationpublic class MyComputationClass {    private MySettings settings;    private MyAlgorithm algorithm;    private ...
Complementary stepsOptimization                 Obfuscation      Irreversibly remove information
ProGuard guide – Android SDK             developer.android.com             developer.android.com
ProGuard website       proguard.sourceforge.net       proguard.sourceforge.net
ProGuard manual      proguard.sourceforge.net      proguard.sourceforge.net
Startup: Saikoa●    Open source: ProGuard●    Services:   Professional ProGuard support●    Product:    DexGuard
ProGuard - DexGuard                     CompatibleOpen source          Closed source   Generic             Specialized    ...
Motivations for hacking/cracking●    Anti-malware research    ●                                 Different ads●    Reverse-...
Solutions?●    Ignore it●    Different business model (open source, service)●    Regular updates●    Lock down device●    ...
More application protectionNothing is unbreakable, but you can raise the bar:●    Reflection●    String encryption●    Cla...
Saikoa website        www.saikoa.com        www.saikoa.com
Questions?                       Open sourceProGuard             Shrinking            Optimization            Obfuscation ...
Upcoming SlideShare
Loading in …5
×

OWF12/PAUG Conf Days Pro guard optimizer and obfuscator for android, eric lafortune, ceo at saikoa

2,078 views

Published on

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
2,078
On SlideShare
0
From Embeds
0
Number of Embeds
560
Actions
Shares
0
Downloads
37
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

OWF12/PAUG Conf Days Pro guard optimizer and obfuscator for android, eric lafortune, ceo at saikoa

  1. 1. ProGuardOptimizer and Obfuscator for Android Eric Lafortune Saikoa
  2. 2. Eric Lafortune● 1991 – 1996 K.U.Leuven (Belgium), Phd Eng CompSci● 1996 – 1999 Cornell University (Ithaca, NY)● 1999 – 2011 Java GIS● 2012 Founder SaikoaMaybe more importantly:● 1982 TMS-9900 processor● 1995 ARM2/ARM3 processor● 2001 Java bytecode● 2010 Dalvik bytecode
  3. 3. ProGuardOpen source Generic Shrinker Optimizer Obfuscator For Java bytecode
  4. 4. ProGuard history Java applications Applets Android apps Midlets 2002 2010 2012● May 2002 First download!● Sep 2010 Recommended for protecting LVL● Dec 2010 Part of Android SDK● Jan 2012 Startup Saikoa
  5. 5. Why use ProGuard?● Application size● Performance● Remove logging, debugging, testing code● Battery life● Protection
  6. 6. Application size classes.dex size .apk size Without With Without With Reduction Reduction ProGuard ProGuard ProGuard ProGuardApiDemos 716 K 482 K 33% 2.6 M 2.5 M 4%ApiDemos ~6 M 542 K ~90% ~8 M 2.5 M ~70%in Scala* * [Stéphane Micheloud, http://lampwww.epfl.ch/~michelou/android/library-code-shrinking.html]
  7. 7. Performance: CaffeineMarkWithout ProGuard With ProGuardSieve score = 6833 Sieve score = 6666Loop score = 14831 Loop score = 15473Logic score = 19038 Logic score = 47840String score = 7694 String score = 7717Float score = 6425 Float score = 6488Method score = 4850 Method score = 5229Overall score = 8794 Overall score = 10436 Improvement: 18% [Acer Iconia Tab A500, nVidia Tegra 2, 1.0 GHz, Android 3.2.1]
  8. 8. Battery lifeExtreme example: “5 x better battery life, by removing verbose logging code in a background service”(but dont count on it)
  9. 9. Tip How to enable ProGuard?project.properties: # To enable ProGuard to shrink and obfuscate your code, uncomment this #proguard.config= ${sdk.dir}/tools/proguard/proguard-android.txt: proguard-project.txt→ only applied when building release versions
  10. 10. Build process ProGuard ProGuard[Android documentation]
  11. 11. ShrinkingAlso called treeshaking, minimizing, shrouding
  12. 12. Shrinking● Classes, fields, methods
  13. 13. Entry points1) Activities, applications, services, fragments,...→ provided automatically by Android build process -keep public class * extends android.app.Activity -keep public class * extends android.app.Application -keep public class * extends android.app.Service …
  14. 14. Tip Entry points2) Introspection, e.g. Google License Verification Library→ must be specified in proguard-project.txt -keep public interface com.android.vending.licensing.ILicensingService
  15. 15. Entry pointsMore introspection, e.g. Google vending library→ must be specified in proguard-project.txt -keepclassmembers public class com.google.android.vending.expansion.downloader.impl.DownloadsDB$* { public static final java.lang.String[][] SCHEMA; public static final java.lang.String TABLE_NAME; }
  16. 16. Entry pointsMore introspection, e.g. Guice, RoboGuice→ must be specified in proguard-project.txt: -keepclassmembers class * { @javax.inject.** <fields>; @com.google.inject.** <fields>; @roboguice.** <fields>; @roboguice.event.Observes <methods>; }
  17. 17. Tip Notes and warnings“Closed-world assumption” Warning: twitter4j.internal.logging.Log4JLoggerFactory: cant find referenced class org.apache.log4j.Logger Warning: twitter4j.internal.logging.SLF4JLoggerFactory: cant find referenced class org.slf4j.LoggerFactory ... Warning: com.dropbox.client2.DropboxAPI: cant find referenced class org.json.simple.JSONArray→ if debug build works fine, then ok to ignore in proguard-project.txt: ­dontwarn twitter4j.internal.logging.** ­dontwarn com.dropbox.client2.**
  18. 18. OptimizationAt the bytecode instruction level:● Dead code elimination● Constant propagation● Method inlining● Class merging● Remove logging code● Peephole optimizations● Devirtualization● ...
  19. 19. Dead code elimination boolean debug = false; … if (debug) Log.v(“.....”); …Note: showing equivalent source code instead of bytecode
  20. 20. Dead code elimination boolean debug = false; … if (debug) Log.v(“.....”); …Note: showing equivalent source code instead of bytecode
  21. 21. Constant propagationInside methods: int f1 = 6; … int f2 = 7; … int answer = f1 * f2;
  22. 22. Constant propagationInside methods: int f1 = 6; … int f2 = 7; … int answer = f1 * f2; … int answer = 6 * 7;
  23. 23. Constant propagationInside methods: int f1 = 6; … int f2 = 7; … int answer = f1 * f2; … int answer = 6 * 7; … int answer = 42;
  24. 24. Constant propagationAcross methods: int answer = computeAnswer(6, 7); int computeAnswer(int f1, int f2) {     return f1 * f2; }
  25. 25. Constant propagationAcross methods: int answer = computeAnswer(6, 7); int computeAnswer(int f1, int f2) { return f1 * f2; } int computeAnswer(int f1, int f2) { return 6 * 7; }
  26. 26. Constant propagationAcross methods: int answer = computeAnswer(6, 7); int computeAnswer(int f1, int f2) { return f1 * f2; } int computeAnswer(int f1, int f2) { return 6 * 7; } int computeAnswer() { return 42; }
  27. 27. Constant propagationAcross methods: int answer = computeAnswer(6, 7); int answer = 42; int computeAnswer(int f1, int f2) { return f1 * f2; } int computeAnswer(int f1, int f2) { return 6 * 7; } int computeAnswer() { return 42; }
  28. 28. Method inliningShort methods (or methods that are only invoked once): int answer = image.getPixel(i, j); int getPixel(int x, int y) { return array[y * width + x]; }
  29. 29. Method inliningShort methods (or methods that are only invoked once): int answer = image.getPixel(i, j); int getPixel(int x, int y) { return array[y * width + x]; } int answer = image.array[j * image.width + i];
  30. 30. Class merging: horizontally Class A Class B Class CClass D Class E
  31. 31. Class merging: horizontally Class A Class A Class B Class C Class B/CClass D Class E Class D Class E
  32. 32. Class merging: vertically Class A Class BClass C Class D
  33. 33. Class merging: vertically Class A Class A/B Class BClass C Class D Class C Class D
  34. 34. Tail recursion simplificationint answer = computeAnswer(1, 2, 3, 7);int computeAnswer(int f1, int f2, int f3, int f4) { if (f2 == 1 && f3 == 1 && f4 == 1) { return f1; } else { return computeAnswer(f1 * f2, f3, f4, 1); }}
  35. 35. Tail recursion simplificationint answer = computeAnswer(1, 2, 3, 7);int computeAnswer(int f1, int f2, int f3, int f4) { if (f2 == 1 && f3 == 1 && f4 == 1) { return f1; } else { return computeAnswer(f1 * f2, f3, f4, 1); }} int computeAnswer(int f1, int f2, int f3, int f4) {   do {     if (f2 == 1 && f3 == 1 && f4 == 1) {         return f1;     } else {         f1 = f1 * f2; f2 = f3, f3 = f4, f4 = 1;     }   } while (true); }
  36. 36. Tail recursion simplification int answer = 42;int answer = computeAnswer(1, 2, 3, 7);int computeAnswer(int f1, int f2, int f3, int f4) { if (f2 == 1 && f3 == 1 && f4 == 1) { return f1; } else { return computeAnswer(f1 * f2, f3, f4, 1); }} int computeAnswer(int f1, int f2, int f3, int f4) { do { if (f2 == 1 && f3 == 1 && f4 == 1) { return f1; } else { f1 = f1 * f2; f2 = f3, f3 = f4, f4 = 1; } } while (true); }
  37. 37. Tip How to enable optimization?project.properties: # To enable ProGuard to shrink and obfuscate your code, uncomment this proguard.config= ${sdk.dir}/tools/proguard/proguard-android-optimize.txt: proguard-project.txt
  38. 38. Tip Remove logging codeSpecify assumptions in proguard-project.txt: ­assumenosideeffects class android.util.Log {     public static boolean isLoggable(java.lang.String, int);     public static int v(...);     public static int i(...);     public static int w(...);     public static int d(...);     public static int e(...);     public static java.lang.String getStackTraceString                                          (java.lang.Throwable); }
  39. 39. ObfuscationTraditional name obfuscation:● Rename identifiers: class/field/method names● Remove debug information: line numbers, local variable names,...
  40. 40. Obfuscationpublic class MyComputationClass { private MySettings settings; private MyAlgorithm algorithm; private int answer; public int computeAnswer(int input) { … return answer; } public class a {} private b a; private c b; private int c; public int a(int a) { … return c; } }
  41. 41. Complementary stepsOptimization Obfuscation Irreversibly remove information
  42. 42. ProGuard guide – Android SDK developer.android.com developer.android.com
  43. 43. ProGuard website proguard.sourceforge.net proguard.sourceforge.net
  44. 44. ProGuard manual proguard.sourceforge.net proguard.sourceforge.net
  45. 45. Startup: Saikoa● Open source: ProGuard● Services: Professional ProGuard support● Product: DexGuard
  46. 46. ProGuard - DexGuard CompatibleOpen source Closed source Generic Specialized Shrinker Shrinker Optimizer Optimizer Obfuscator Obfuscator Protector For Java bytecode For Android
  47. 47. Motivations for hacking/cracking● Anti-malware research ● Different ads● Reverse-engineering ● Different market protocols, formats,... ● Extorsion● Fun ● Extract assets● Translation ● Extract API keys● Game cheating ● Insert malware (SMS,...)● Software piracy ● ...● Remove ads
  48. 48. Solutions?● Ignore it● Different business model (open source, service)● Regular updates● Lock down device● Server● Remove motivations● Obfuscation, application protection
  49. 49. More application protectionNothing is unbreakable, but you can raise the bar:● Reflection● String encryption● Class encryption● Tamper detection● Debug detection● Emulator detection● …→ Automatically applied by DexGuard
  50. 50. Saikoa website www.saikoa.com www.saikoa.com
  51. 51. Questions? Open sourceProGuard Shrinking Optimization Obfuscation SaikoaJava bytecode DexGuard Dalvik bytecode

×