SlideShare ist ein Scribd-Unternehmen logo
1 von 31
Downloaden Sie, um offline zu lesen
23 June 2016
ProGuard
DexGuard
Tips and Tricks
Thomas Neidhart
Developer @ GuardSquare
23 June 2016
ProGuard Overview
Shrinking
(-dontshrink)
Optimization
(-dontoptimize)
Obfuscation
(-dontobfuscate)
23 June 2016
ProGuard in Android builds
Application
Java bytec.
ProGuard
Processed
Java bytec.
Zip
align
Application
Java source
Libraries
Java bytec.
XML res.
Assets
Aapt
Javac
Libraries
Java bytec.
Dalvik
bytecode
Assets
Compiled
XML res.
Signatures
Assets
Compiled
XML res.
Dalvik
bytecode
Signatures
Assets
Compiled
XML res.
Dalvik
bytecode
Dex
Jar
signer
Application
Native src
Native
libraries
Native
libraries
Native
libraries
Gcc
23 June 2016
android {
buildTypes {
debug {
minifyEnabled false
}
release {
minifyEnabled true
proguardFile getDefaultProguardFile('proguard-android.txt')
// To enable optimization, use the following instead:
// proguardFile getDefaultProguardFile('proguard-android-optimize.txt')
proguardFile 'proguard-project.txt'
}
}
}
Build configuration
Gradle: build.gradle
23 June 2016
Build configuration
Used configurations:
● Specified proguardFiles in build.gradle
● consumerProguardFiles from libraries
(automatically added by Android plugin)
● Proguard rules generated by aapt, located in
build/intermediates/proguard-rules/<build-
type>/aapt_rules.txt
Tip
23 June 2016
Configuration Debugging
Help for figuring out whats going on:
● Use '-printconfiguration config.pro'
● Use '-whyareyoukeeping class xxx.yyy ...'
Tip
com.example.HelloWorldActivity
  is kept by a directive in the configuration.
com.example.HelloWorldActivity: java.lang.String TAG
  is not being kept.
com.example.HelloWorldActivity: HelloWorldActivity() (18:18)
  is kept by a directive in the configuration.
com.example.HelloWorldActivity: void onCreate(android.os.Bundle) 
(25:39)
  implements       android.app.Activity: void 
onCreate(android.os.Bundle)
  is a library method.
23 June 2016
Keep rules
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
Hints:
● '-keep class xxx.yyy' will only keep the class itself
(+ default ctor), not its members
● Avoid '-keep class xxx.yyy { *; }' rules,
prefer '-keep class xxx.yyy { public protected *; }'
23 June 2016
Pattern matching
Pattern types:
● Inclusion patterns: com.example.**
● Exclusion patterns: !com.example.foo.*
Pattern analysis:
● Patterns are analyzed in sequential order
● Exclusion patterns must come first
Tip
23 June 2016
Pattern example
Keep everything in the package com.example and its
subpackages, except for package com.example.internal:
This won't work:
Tip
­keep class !com.example.internal.**,
             com.example.** {
  *;
}
­keep class !com.example.internal.**,
             com.example.** {
  *;
}
­keep class !com.example.internal.** { *; }
­keep class com.example.** { *; }
­keep class !com.example.internal.** { *; }
­keep class com.example.** { *; }
23 June 2016
Notes and warnings
“Closed-world assumption”
● Might lead to problems during optimization
● Better to resolve than to hide
● Warnings and Notes are handled separately (-dontnote)
Tip
Warning: twitter4j.internal.logging.Log4JLoggerFactory:
   can't find referenced class org.apache.log4j.Logger
Warning: twitter4j.internal.logging.SLF4JLoggerFactory:
   can't find referenced class org.slf4j.LoggerFactory
...
Warning: twitter4j.internal.logging.Log4JLoggerFactory:
   can't find referenced class org.apache.log4j.Logger
Warning: twitter4j.internal.logging.SLF4JLoggerFactory:
   can't find referenced class org.slf4j.LoggerFactory
...
­dontwarn twitter4j.internal.logging.**
# last resort
­ignorewarnings
­dontwarn twitter4j.internal.logging.**
# last resort
­ignorewarnings
23 June 2016
Shrinking
Attributes:
Default config only keeps *Annotation*
Other useful / necessary attributes to keep:
● Signature
● InnerClasses
● LineNumberTable
● SourceFile (together with -renamesourcefileattribute '')
Tip
23 June 2016
Optimization
Various techniques:
● Method inlining
● Constant propagation
● Class merging
● Dead code elimination
● Code removal
● Peephole optimizations
● Variable allocations
● Field/Parameter/Exception removal
● ...
23 June 2016
Optimization limitations
Extracted from user guide:
Warning: 3rd party libraries might be obfuscated in a way that breaks these
assumptions.
Mitigations:
● -dontoptimize
●
System property: -Doptimize.conservatively
For best results, ProGuard's optimization algorithms assume that the processed code never intentionally
throws NullPointerExceptions or ArrayIndexOutOfBoundsExceptions, or even OutOfMemoryErrors
or StackOverflowErrors, in order to achieve something useful. For instance, it may remove a method call
myObject.myMethod() if that call wouldn't have any effect. It ignores the possibility that myObject might be
null, causing a NullPointerException. In some way this is a good thing: optimized code may throw fewer
exceptions. Should this entire assumption be false, you'll have to switch off optimization using the
-dontoptimize option.
Tip
23 June 2016
Optimization Methods
Optimization Technique Flags Safe? Impact
Method inlining method/inlining/* Yes
Peephole optimizations code/simplification/* Yes
Unreachable Code removal code/removal/simple Yes
Code removal code/removal/advanced Yes (ex. Obfuscated
libs)
Needed for logging removal, generally
safe, but depends on configuration.
Enum unboxing class/unboxing/enum Mostly yes Might lead to problems, especially when
using EnumMap / EnumSet
Variable allocation code/allocation/variable For Applications. Dx might crash when
-keepparameternames is used (or
LocalVariableTable is kept).
Method de-synchronization method/marking/synchronized Yes Effect might not be noticable, Slow
optimization
Constant propagation field/propagation/value
method/propagation/*
Yes
Class merging class/merging/* Mostly yes Might cause issues in rare cases.
Field removal field/removal/writeonly Yes
Tip
23 June 2016
Logging Removal
Java Source:
Smali:
Log.d(TAG, "Hello world " + this.getClass().getName() + "!");
  .line 31
    invoke­virtual { p0, v5 }, Lcom/example/HelloWorldActivity;­>setContentView(Landroid/view/View;)V
  .line 33
    const­string v0, "Activity"
    new­instance v1, Ljava/lang/StringBuilder;
    invoke­direct { v1 }, Ljava/lang/StringBuilder;­><init>()V
    const­string v2, "Hello world "
    invoke­virtual { v1, v2 }, Ljava/lang/StringBuilder;­>append(Ljava/lang/String;)Ljava/lang/StringBuilder;
    move­result­object v1
    invoke­virtual { p0 }, Ljava/lang/Object;­>getClass()Ljava/lang/Class;
    move­result­object v2
    invoke­virtual { v2 }, Ljava/lang/Class;­>getName()Ljava/lang/String;
    move­result­object v2
    invoke­virtual { v1, v2 }, Ljava/lang/StringBuilder;­>append(Ljava/lang/String;)Ljava/lang/StringBuilder;
    move­result­object v1
    const­string v2, "!"
    invoke­virtual { v1, v2 }, Ljava/lang/StringBuilder;­>append(Ljava/lang/String;)Ljava/lang/StringBuilder;
    move­result­object v1
    invoke­virtual { v1 }, Ljava/lang/StringBuilder;­>toString()Ljava/lang/String;
    move­result­object v1
    invoke­static { v0, v1 }, Landroid/util/Log;­>d(Ljava/lang/String;Ljava/lang/String;)I
  .line 35
23 June 2016
Logging Removal
ProGuard configuration:
­assumenosideeffects class android.util.Log {
    public static boolean isLoggable(java.lang.String, int);
    public static int v(...);
    public static int d(...);
    public static int i(...);
    public static int w(...);
    public static int e(...);
    public static java.lang.String getStackTraceString(java.lang.Throwable);
}
23 June 2016
Logging Removal
Result:
Why are there still objects/method calls?
    const­string v1, "Hello world "
    invoke­direct { v0, v1 }, Ljava/lang/StringBuilder;­><init>(Ljava/lang/String;)V
    invoke­virtual { p0 }, Ljava/lang/Object;­>getClass()Ljava/lang/Class;
    move­result­object v1
    invoke­virtual { v1 }, Ljava/lang/Class;­>getName()Ljava/lang/String;
    move­result­object v1
    invoke­virtual { v0, v1 }, Ljava/lang/StringBuilder;­>append(Ljava/lang/String;)Ljava/lang/StringBuilder;
    move­result­object v0
    const­string v1, "!"
    invoke­virtual { v0, v1 }, Ljava/lang/StringBuilder;­>append(Ljava/lang/String;)Ljava/lang/StringBuilder;
23 June 2016
Logging Removal
Second try:
Smali:
Log.d(TAG, String.format("Hello world %s!", this.getClass().getName());
Tip
const-string v1, "Activity"
const-string v2, "Hello world %s!"
new-array v3, v6, [Ljava/lang/Object;
const/4 v4, 0
invoke-virtual { p0 }, Ljava/lang/Object;->getClass()Ljava/lang/Class;
move-result-object v5
invoke-virtual { v5 }, Ljava/lang/Class;->getName()Ljava/lang/String;
move-result-object v5
aput-object v5, v3, v4
invoke-static { v2, v3 }, Ljava/lang/String;->format(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;
move-result-object v2
invoke-static { v1, v2 }, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
23 June 2016
Logging Removal
ProGuard configuration:
­assumenosideeffects class android.util.Log {
    public static boolean isLoggable(java.lang.String, int);
    public static int v(...);
    public static int d(...);
    public static int i(...);
    public static int w(...);
    public static int e(...);
    public static java.lang.String getStackTraceString(java.lang.Throwable);
}
­assumenosideeffects class java.lang.String {
    public static java.lang.String format(...);
}
Tip
23 June 2016
Logging Removal
Result:
Better!
Tip
    new­array v0, v3, [Ljava/lang/Object;
    const/4 v1, 0
    invoke­virtual { p0 }, Ljava/lang/Object;­>getClass()Ljava/lang/Class;
    move­result­object v2
    invoke­virtual { v2 }, Ljava/lang/Class;­>getName()Ljava/lang/String;
    move­result­object v2
    aput­object v2, v0, v1
23 June 2016
Side Effect Checking
Explicit (for library classes/methods):
Implicit (for program classes/method):
● During optimization by analysing the actual code
● Can be prevented with -keep rules
Note: removes invocations not methods themselves!
-assumenosideeffects class xxx.yyy { … }
23 June 2016
Side Effect Example
public static int sum(int a, int b) {
   return a + b;
}
@Override
public void onCreate(Bundle savedInstanceState)
{
    …
    setContentView(xxx);
    sum(10, 30);
    …
}
  .line 57
    invoke­virtual { p0, p1 }, Lcom/example/HelloWorldActivity;­>setContentView(Landroid/view/View;)V
  .line 66
  .line 57
    invoke­virtual { p0, v2 }, Lcom/example/HelloWorldActivity;­>setContentView(Landroid/view/View;)V
  .line 63
    const/16 v0, 10
    const/16 v1, 30
    invoke­static { v0, v1 }, Lcom/example/HelloWorldActivity;­>sum(II)I
  .line 66
Optimized:
23 June 2016
DexGuard
Commercial extension of ProGuard
Additional protection features:
● String/Class/Asset/Resource/Native library encryption
● Native library interface obfuscation
● Hide sensitive method calls via reflection
● Code obfuscation (control flow, arithmetic obfuscation)
Resource shrinking
Resource / Metadata inlining
Multidex support
...
23 June 2016
DexGuard Overview
Shrinking
(-dontshrink)
Optimization
(-dontoptimize)
Obfuscation
(-dontobfuscate)
String encryption
Class encryption
Asset encryption
Resource
encryption
Native library
encryption
Code obfuscation
Resource inlining
Multidexing
Splitdexing
Zipalign
Signing
Reflect API calls
23 June 2016
DexGuard in Android builds
Compiled
XML res. DexGuard
Application
Java source
Libraries
Java bytec.
XML res.
Assets
Aapt
Javac
Libraries
Java bytec.
Processed
assets
Processed
XML res.
Dalvik
bytecode
Application
Java bytec.
Signatures
Application
Native src
Native
libraries
Processed
native
libraries
Gcc
23 June 2016
DexGuard in Android builds (2)
Jack
Dex
Guard
Application
Java source
Libraries
Java bytec.
XML res.
Assets
Aapt
Jill
Libraries
.jayce
Dalvik
bytecode
Assets
Compiled
XML res.
Signatures
Assets
Compiled
XML res.
Dalvik
bytecode
Signatures
Assets
Compiled
XML res.
Dalvik
bytecode
Jar
signer
Application
Native src
Native
libraries
Native
libraries
Native
libraries
Gcc
23 June 2016
Optimization
Features in addition to ProGuard:
● Parallel Optimization → faster on multi-core machines
● New modifier 'includecode' for -keep rules
● Support for more fine-grained side-effect configuration →
more effective code removal
23 June 2016
Logging Removal
Java Source:
Smali:
Log.d(TAG, "Hello world " + this.getClass().getName() + "!");
  .line 31
    invoke­virtual { p0, v5 }, Lcom/example/HelloWorldActivity;­>setContentView(Landroid/view/View;)V
  .line 33
    const­string v0, "Activity"
    new­instance v1, Ljava/lang/StringBuilder;
    invoke­direct { v1 }, Ljava/lang/StringBuilder;­><init>()V
    const­string v2, "Hello world "
    invoke­virtual { v1, v2 }, Ljava/lang/StringBuilder;­>append(Ljava/lang/String;)Ljava/lang/StringBuilder;
    move­result­object v1
    invoke­virtual { p0 }, Ljava/lang/Object;­>getClass()Ljava/lang/Class;
    move­result­object v2
    invoke­virtual { v2 }, Ljava/lang/Class;­>getName()Ljava/lang/String;
    move­result­object v2
    invoke­virtual { v1, v2 }, Ljava/lang/StringBuilder;­>append(Ljava/lang/String;)Ljava/lang/StringBuilder;
    move­result­object v1
    const­string v2, "!"
    invoke­virtual { v1, v2 }, Ljava/lang/StringBuilder;­>append(Ljava/lang/String;)Ljava/lang/StringBuilder;
    move­result­object v1
    invoke­virtual { v1 }, Ljava/lang/StringBuilder;­>toString()Ljava/lang/String;
    move­result­object v1
    invoke­static { v0, v1 }, Landroid/util/Log;­>d(Ljava/lang/String;Ljava/lang/String;)I
  .line 35
23 June 2016
Logging Removal
Result:
Much better!
Possible due to more fine-grained configuration:
  .line 31
    invoke­virtual { p0, p1 }, Lcom/example/HelloWorldActivity;­>setContentView(Landroid/view/View;)V
  .line 35
­assumenoexternalsideeffects public final class java.lang.StringBuilder {
    public java.lang.StringBuilder();
    public java.lang.StringBuilder(int);
    public java.lang.StringBuilder(java.lang.String);
    public java.lang.StringBuilder append(java.lang.String);
    …
}
23 June 2016
More DexGuard Goodies
● Default configurations for applications/libraries supporting
many 3rd party libs
● Great support :-)
● Many samples
● Configuration debugging
● Java 8 language support → backported to Java 6/7 similar to
retrolambda
● Planned: Stream API support for older Android devices
● Planned: Native code obfuscation
23 June 2016
The End
Thanks for
your attention!

Weitere ähnliche Inhalte

Was ist angesagt?

Java tricks for high-load server programming
Java tricks for high-load server programmingJava tricks for high-load server programming
Java tricks for high-load server programming
Andrei Pangin
 
Java - Exception Handling
Java - Exception HandlingJava - Exception Handling
Java - Exception Handling
Prabhdeep Singh
 

Was ist angesagt? (20)

Lecture 5 sorting and searching
Lecture 5   sorting and searchingLecture 5   sorting and searching
Lecture 5 sorting and searching
 
Java tricks for high-load server programming
Java tricks for high-load server programmingJava tricks for high-load server programming
Java tricks for high-load server programming
 
Basics of reflection in java
Basics of reflection in javaBasics of reflection in java
Basics of reflection in java
 
Exception handling in java
Exception handling  in javaException handling  in java
Exception handling in java
 
Python final ppt
Python final pptPython final ppt
Python final ppt
 
JVM Under The Hood WDI.pdf
JVM Under The Hood WDI.pdfJVM Under The Hood WDI.pdf
JVM Under The Hood WDI.pdf
 
Python
PythonPython
Python
 
How to do Cryptography right in Android Part One
How to do Cryptography right in Android Part OneHow to do Cryptography right in Android Part One
How to do Cryptography right in Android Part One
 
Designing your neural networks – a step by step walkthrough
Designing your neural networks – a step by step walkthroughDesigning your neural networks – a step by step walkthrough
Designing your neural networks – a step by step walkthrough
 
Java - Exception Handling
Java - Exception HandlingJava - Exception Handling
Java - Exception Handling
 
Core Java Tutorial
Core Java TutorialCore Java Tutorial
Core Java Tutorial
 
Welcome to python workshop
Welcome to python workshopWelcome to python workshop
Welcome to python workshop
 
Exception handling in Java
Exception handling in JavaException handling in Java
Exception handling in Java
 
C++ memory leak detection
C++ memory leak detectionC++ memory leak detection
C++ memory leak detection
 
Python Tutorial Part 2
Python Tutorial Part 2Python Tutorial Part 2
Python Tutorial Part 2
 
Exception handling
Exception handling Exception handling
Exception handling
 
Python recursion
Python recursionPython recursion
Python recursion
 
iOS Application Penetration Testing for Beginners
iOS Application Penetration Testing for BeginnersiOS Application Penetration Testing for Beginners
iOS Application Penetration Testing for Beginners
 
Garbage collection
Garbage collectionGarbage collection
Garbage collection
 
Java Exception handling
Java Exception handlingJava Exception handling
Java Exception handling
 

Ähnlich wie ProGuard / DexGuard Tips and Tricks

Ähnlich wie ProGuard / DexGuard Tips and Tricks (20)

Proguard android
Proguard androidProguard android
Proguard android
 
[MOPCON2018] Effectively shrink ProGuard rules for reducing APK size
[MOPCON2018] Effectively shrink ProGuard rules for reducing APK size[MOPCON2018] Effectively shrink ProGuard rules for reducing APK size
[MOPCON2018] Effectively shrink ProGuard rules for reducing APK size
 
[Gstar 2013] Unity Security
[Gstar 2013] Unity Security[Gstar 2013] Unity Security
[Gstar 2013] Unity Security
 
groovy & grails - lecture 7
groovy & grails - lecture 7groovy & grails - lecture 7
groovy & grails - lecture 7
 
Audit your reactive applications
Audit your reactive applicationsAudit your reactive applications
Audit your reactive applications
 
Core Java Programming Language (JSE) : Chapter VIII - Exceptions and Assertions
Core Java Programming Language (JSE) : Chapter VIII - Exceptions and AssertionsCore Java Programming Language (JSE) : Chapter VIII - Exceptions and Assertions
Core Java Programming Language (JSE) : Chapter VIII - Exceptions and Assertions
 
Best Coding Practices For Android Application Development
Best Coding Practices For Android Application DevelopmentBest Coding Practices For Android Application Development
Best Coding Practices For Android Application Development
 
OPM Recipe designer notes
OPM Recipe designer notesOPM Recipe designer notes
OPM Recipe designer notes
 
Mockito with a hint of PowerMock
Mockito with a hint of PowerMockMockito with a hint of PowerMock
Mockito with a hint of PowerMock
 
Advanced iOS Debbuging (Reloaded)
Advanced iOS Debbuging (Reloaded)Advanced iOS Debbuging (Reloaded)
Advanced iOS Debbuging (Reloaded)
 
How to Perform Memory Leak Test Using Valgrind
How to Perform Memory Leak Test Using ValgrindHow to Perform Memory Leak Test Using Valgrind
How to Perform Memory Leak Test Using Valgrind
 
Android reverse engineering - Analyzing skype
Android reverse engineering - Analyzing skypeAndroid reverse engineering - Analyzing skype
Android reverse engineering - Analyzing skype
 
Generic Synchronization Policies in C++
Generic Synchronization Policies in C++Generic Synchronization Policies in C++
Generic Synchronization Policies in C++
 
Java bad coding practices
Java bad coding practicesJava bad coding practices
Java bad coding practices
 
"Xapi-lang For declarative code generation" By James Nelson
"Xapi-lang For declarative code generation" By James Nelson"Xapi-lang For declarative code generation" By James Nelson
"Xapi-lang For declarative code generation" By James Nelson
 
Javascript Deofuscation A manual Approach
Javascript Deofuscation A manual ApproachJavascript Deofuscation A manual Approach
Javascript Deofuscation A manual Approach
 
JavaOne 2017 CON2902 - Java Code Inspection and Testing Power Tools
JavaOne 2017 CON2902 - Java Code Inspection and Testing Power ToolsJavaOne 2017 CON2902 - Java Code Inspection and Testing Power Tools
JavaOne 2017 CON2902 - Java Code Inspection and Testing Power Tools
 
Google I/O 2021 Recap
Google I/O 2021 RecapGoogle I/O 2021 Recap
Google I/O 2021 Recap
 
Bring the fun back to java
Bring the fun back to javaBring the fun back to java
Bring the fun back to java
 
JavaOne 2016: Life after Modularity
JavaOne 2016: Life after ModularityJavaOne 2016: Life after Modularity
JavaOne 2016: Life after Modularity
 

Kürzlich hochgeladen

Obat Penggugur Kandungan Di Apotik Kimia Farma (087776558899)
Obat Penggugur Kandungan Di Apotik Kimia Farma (087776558899)Obat Penggugur Kandungan Di Apotik Kimia Farma (087776558899)
Obat Penggugur Kandungan Di Apotik Kimia Farma (087776558899)
Cara Menggugurkan Kandungan 087776558899
 

Kürzlich hochgeladen (7)

Obat Penggugur Kandungan Di Apotik Kimia Farma (087776558899)
Obat Penggugur Kandungan Di Apotik Kimia Farma (087776558899)Obat Penggugur Kandungan Di Apotik Kimia Farma (087776558899)
Obat Penggugur Kandungan Di Apotik Kimia Farma (087776558899)
 
Bromazolam CAS 71368-80-4 high quality opiates, Safe transportation, 99% pure
Bromazolam CAS 71368-80-4 high quality opiates, Safe transportation, 99% pureBromazolam CAS 71368-80-4 high quality opiates, Safe transportation, 99% pure
Bromazolam CAS 71368-80-4 high quality opiates, Safe transportation, 99% pure
 
Mobile Application Development-Components and Layouts
Mobile Application Development-Components and LayoutsMobile Application Development-Components and Layouts
Mobile Application Development-Components and Layouts
 
Satara Call girl escort *74796//13122* Call me punam call girls 24*7hour avai...
Satara Call girl escort *74796//13122* Call me punam call girls 24*7hour avai...Satara Call girl escort *74796//13122* Call me punam call girls 24*7hour avai...
Satara Call girl escort *74796//13122* Call me punam call girls 24*7hour avai...
 
Mobile Application Development-Android and It’s Tools
Mobile Application Development-Android and It’s ToolsMobile Application Development-Android and It’s Tools
Mobile Application Development-Android and It’s Tools
 
Android Application Components with Implementation & Examples
Android Application Components with Implementation & ExamplesAndroid Application Components with Implementation & Examples
Android Application Components with Implementation & Examples
 
Mobile App Penetration Testing Bsides312
Mobile App Penetration Testing Bsides312Mobile App Penetration Testing Bsides312
Mobile App Penetration Testing Bsides312
 

ProGuard / DexGuard Tips and Tricks

  • 1. 23 June 2016 ProGuard DexGuard Tips and Tricks Thomas Neidhart Developer @ GuardSquare
  • 2. 23 June 2016 ProGuard Overview Shrinking (-dontshrink) Optimization (-dontoptimize) Obfuscation (-dontobfuscate)
  • 3. 23 June 2016 ProGuard in Android builds Application Java bytec. ProGuard Processed Java bytec. Zip align Application Java source Libraries Java bytec. XML res. Assets Aapt Javac Libraries Java bytec. Dalvik bytecode Assets Compiled XML res. Signatures Assets Compiled XML res. Dalvik bytecode Signatures Assets Compiled XML res. Dalvik bytecode Dex Jar signer Application Native src Native libraries Native libraries Native libraries Gcc
  • 4. 23 June 2016 android { buildTypes { debug { minifyEnabled false } release { minifyEnabled true proguardFile getDefaultProguardFile('proguard-android.txt') // To enable optimization, use the following instead: // proguardFile getDefaultProguardFile('proguard-android-optimize.txt') proguardFile 'proguard-project.txt' } } } Build configuration Gradle: build.gradle
  • 5. 23 June 2016 Build configuration Used configurations: ● Specified proguardFiles in build.gradle ● consumerProguardFiles from libraries (automatically added by Android plugin) ● Proguard rules generated by aapt, located in build/intermediates/proguard-rules/<build- type>/aapt_rules.txt Tip
  • 6. 23 June 2016 Configuration Debugging Help for figuring out whats going on: ● Use '-printconfiguration config.pro' ● Use '-whyareyoukeeping class xxx.yyy ...' Tip com.example.HelloWorldActivity   is kept by a directive in the configuration. com.example.HelloWorldActivity: java.lang.String TAG   is not being kept. com.example.HelloWorldActivity: HelloWorldActivity() (18:18)   is kept by a directive in the configuration. com.example.HelloWorldActivity: void onCreate(android.os.Bundle)  (25:39)   implements       android.app.Activity: void  onCreate(android.os.Bundle)   is a library method.
  • 7. 23 June 2016 Keep rules 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 Hints: ● '-keep class xxx.yyy' will only keep the class itself (+ default ctor), not its members ● Avoid '-keep class xxx.yyy { *; }' rules, prefer '-keep class xxx.yyy { public protected *; }'
  • 8. 23 June 2016 Pattern matching Pattern types: ● Inclusion patterns: com.example.** ● Exclusion patterns: !com.example.foo.* Pattern analysis: ● Patterns are analyzed in sequential order ● Exclusion patterns must come first Tip
  • 9. 23 June 2016 Pattern example Keep everything in the package com.example and its subpackages, except for package com.example.internal: This won't work: Tip ­keep class !com.example.internal.**,              com.example.** {   *; } ­keep class !com.example.internal.**,              com.example.** {   *; } ­keep class !com.example.internal.** { *; } ­keep class com.example.** { *; } ­keep class !com.example.internal.** { *; } ­keep class com.example.** { *; }
  • 10. 23 June 2016 Notes and warnings “Closed-world assumption” ● Might lead to problems during optimization ● Better to resolve than to hide ● Warnings and Notes are handled separately (-dontnote) Tip Warning: twitter4j.internal.logging.Log4JLoggerFactory:    can't find referenced class org.apache.log4j.Logger Warning: twitter4j.internal.logging.SLF4JLoggerFactory:    can't find referenced class org.slf4j.LoggerFactory ... Warning: twitter4j.internal.logging.Log4JLoggerFactory:    can't find referenced class org.apache.log4j.Logger Warning: twitter4j.internal.logging.SLF4JLoggerFactory:    can't find referenced class org.slf4j.LoggerFactory ... ­dontwarn twitter4j.internal.logging.** # last resort ­ignorewarnings ­dontwarn twitter4j.internal.logging.** # last resort ­ignorewarnings
  • 11. 23 June 2016 Shrinking Attributes: Default config only keeps *Annotation* Other useful / necessary attributes to keep: ● Signature ● InnerClasses ● LineNumberTable ● SourceFile (together with -renamesourcefileattribute '') Tip
  • 12. 23 June 2016 Optimization Various techniques: ● Method inlining ● Constant propagation ● Class merging ● Dead code elimination ● Code removal ● Peephole optimizations ● Variable allocations ● Field/Parameter/Exception removal ● ...
  • 13. 23 June 2016 Optimization limitations Extracted from user guide: Warning: 3rd party libraries might be obfuscated in a way that breaks these assumptions. Mitigations: ● -dontoptimize ● System property: -Doptimize.conservatively For best results, ProGuard's optimization algorithms assume that the processed code never intentionally throws NullPointerExceptions or ArrayIndexOutOfBoundsExceptions, or even OutOfMemoryErrors or StackOverflowErrors, in order to achieve something useful. For instance, it may remove a method call myObject.myMethod() if that call wouldn't have any effect. It ignores the possibility that myObject might be null, causing a NullPointerException. In some way this is a good thing: optimized code may throw fewer exceptions. Should this entire assumption be false, you'll have to switch off optimization using the -dontoptimize option. Tip
  • 14. 23 June 2016 Optimization Methods Optimization Technique Flags Safe? Impact Method inlining method/inlining/* Yes Peephole optimizations code/simplification/* Yes Unreachable Code removal code/removal/simple Yes Code removal code/removal/advanced Yes (ex. Obfuscated libs) Needed for logging removal, generally safe, but depends on configuration. Enum unboxing class/unboxing/enum Mostly yes Might lead to problems, especially when using EnumMap / EnumSet Variable allocation code/allocation/variable For Applications. Dx might crash when -keepparameternames is used (or LocalVariableTable is kept). Method de-synchronization method/marking/synchronized Yes Effect might not be noticable, Slow optimization Constant propagation field/propagation/value method/propagation/* Yes Class merging class/merging/* Mostly yes Might cause issues in rare cases. Field removal field/removal/writeonly Yes Tip
  • 15. 23 June 2016 Logging Removal Java Source: Smali: Log.d(TAG, "Hello world " + this.getClass().getName() + "!");   .line 31     invoke­virtual { p0, v5 }, Lcom/example/HelloWorldActivity;­>setContentView(Landroid/view/View;)V   .line 33     const­string v0, "Activity"     new­instance v1, Ljava/lang/StringBuilder;     invoke­direct { v1 }, Ljava/lang/StringBuilder;­><init>()V     const­string v2, "Hello world "     invoke­virtual { v1, v2 }, Ljava/lang/StringBuilder;­>append(Ljava/lang/String;)Ljava/lang/StringBuilder;     move­result­object v1     invoke­virtual { p0 }, Ljava/lang/Object;­>getClass()Ljava/lang/Class;     move­result­object v2     invoke­virtual { v2 }, Ljava/lang/Class;­>getName()Ljava/lang/String;     move­result­object v2     invoke­virtual { v1, v2 }, Ljava/lang/StringBuilder;­>append(Ljava/lang/String;)Ljava/lang/StringBuilder;     move­result­object v1     const­string v2, "!"     invoke­virtual { v1, v2 }, Ljava/lang/StringBuilder;­>append(Ljava/lang/String;)Ljava/lang/StringBuilder;     move­result­object v1     invoke­virtual { v1 }, Ljava/lang/StringBuilder;­>toString()Ljava/lang/String;     move­result­object v1     invoke­static { v0, v1 }, Landroid/util/Log;­>d(Ljava/lang/String;Ljava/lang/String;)I   .line 35
  • 16. 23 June 2016 Logging Removal ProGuard configuration: ­assumenosideeffects class android.util.Log {     public static boolean isLoggable(java.lang.String, int);     public static int v(...);     public static int d(...);     public static int i(...);     public static int w(...);     public static int e(...);     public static java.lang.String getStackTraceString(java.lang.Throwable); }
  • 17. 23 June 2016 Logging Removal Result: Why are there still objects/method calls?     const­string v1, "Hello world "     invoke­direct { v0, v1 }, Ljava/lang/StringBuilder;­><init>(Ljava/lang/String;)V     invoke­virtual { p0 }, Ljava/lang/Object;­>getClass()Ljava/lang/Class;     move­result­object v1     invoke­virtual { v1 }, Ljava/lang/Class;­>getName()Ljava/lang/String;     move­result­object v1     invoke­virtual { v0, v1 }, Ljava/lang/StringBuilder;­>append(Ljava/lang/String;)Ljava/lang/StringBuilder;     move­result­object v0     const­string v1, "!"     invoke­virtual { v0, v1 }, Ljava/lang/StringBuilder;­>append(Ljava/lang/String;)Ljava/lang/StringBuilder;
  • 18. 23 June 2016 Logging Removal Second try: Smali: Log.d(TAG, String.format("Hello world %s!", this.getClass().getName()); Tip const-string v1, "Activity" const-string v2, "Hello world %s!" new-array v3, v6, [Ljava/lang/Object; const/4 v4, 0 invoke-virtual { p0 }, Ljava/lang/Object;->getClass()Ljava/lang/Class; move-result-object v5 invoke-virtual { v5 }, Ljava/lang/Class;->getName()Ljava/lang/String; move-result-object v5 aput-object v5, v3, v4 invoke-static { v2, v3 }, Ljava/lang/String;->format(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String; move-result-object v2 invoke-static { v1, v2 }, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
  • 19. 23 June 2016 Logging Removal ProGuard configuration: ­assumenosideeffects class android.util.Log {     public static boolean isLoggable(java.lang.String, int);     public static int v(...);     public static int d(...);     public static int i(...);     public static int w(...);     public static int e(...);     public static java.lang.String getStackTraceString(java.lang.Throwable); } ­assumenosideeffects class java.lang.String {     public static java.lang.String format(...); } Tip
  • 20. 23 June 2016 Logging Removal Result: Better! Tip     new­array v0, v3, [Ljava/lang/Object;     const/4 v1, 0     invoke­virtual { p0 }, Ljava/lang/Object;­>getClass()Ljava/lang/Class;     move­result­object v2     invoke­virtual { v2 }, Ljava/lang/Class;­>getName()Ljava/lang/String;     move­result­object v2     aput­object v2, v0, v1
  • 21. 23 June 2016 Side Effect Checking Explicit (for library classes/methods): Implicit (for program classes/method): ● During optimization by analysing the actual code ● Can be prevented with -keep rules Note: removes invocations not methods themselves! -assumenosideeffects class xxx.yyy { … }
  • 22. 23 June 2016 Side Effect Example public static int sum(int a, int b) {    return a + b; } @Override public void onCreate(Bundle savedInstanceState) {     …     setContentView(xxx);     sum(10, 30);     … }   .line 57     invoke­virtual { p0, p1 }, Lcom/example/HelloWorldActivity;­>setContentView(Landroid/view/View;)V   .line 66   .line 57     invoke­virtual { p0, v2 }, Lcom/example/HelloWorldActivity;­>setContentView(Landroid/view/View;)V   .line 63     const/16 v0, 10     const/16 v1, 30     invoke­static { v0, v1 }, Lcom/example/HelloWorldActivity;­>sum(II)I   .line 66 Optimized:
  • 23. 23 June 2016 DexGuard Commercial extension of ProGuard Additional protection features: ● String/Class/Asset/Resource/Native library encryption ● Native library interface obfuscation ● Hide sensitive method calls via reflection ● Code obfuscation (control flow, arithmetic obfuscation) Resource shrinking Resource / Metadata inlining Multidex support ...
  • 24. 23 June 2016 DexGuard Overview Shrinking (-dontshrink) Optimization (-dontoptimize) Obfuscation (-dontobfuscate) String encryption Class encryption Asset encryption Resource encryption Native library encryption Code obfuscation Resource inlining Multidexing Splitdexing Zipalign Signing Reflect API calls
  • 25. 23 June 2016 DexGuard in Android builds Compiled XML res. DexGuard Application Java source Libraries Java bytec. XML res. Assets Aapt Javac Libraries Java bytec. Processed assets Processed XML res. Dalvik bytecode Application Java bytec. Signatures Application Native src Native libraries Processed native libraries Gcc
  • 26. 23 June 2016 DexGuard in Android builds (2) Jack Dex Guard Application Java source Libraries Java bytec. XML res. Assets Aapt Jill Libraries .jayce Dalvik bytecode Assets Compiled XML res. Signatures Assets Compiled XML res. Dalvik bytecode Signatures Assets Compiled XML res. Dalvik bytecode Jar signer Application Native src Native libraries Native libraries Native libraries Gcc
  • 27. 23 June 2016 Optimization Features in addition to ProGuard: ● Parallel Optimization → faster on multi-core machines ● New modifier 'includecode' for -keep rules ● Support for more fine-grained side-effect configuration → more effective code removal
  • 28. 23 June 2016 Logging Removal Java Source: Smali: Log.d(TAG, "Hello world " + this.getClass().getName() + "!");   .line 31     invoke­virtual { p0, v5 }, Lcom/example/HelloWorldActivity;­>setContentView(Landroid/view/View;)V   .line 33     const­string v0, "Activity"     new­instance v1, Ljava/lang/StringBuilder;     invoke­direct { v1 }, Ljava/lang/StringBuilder;­><init>()V     const­string v2, "Hello world "     invoke­virtual { v1, v2 }, Ljava/lang/StringBuilder;­>append(Ljava/lang/String;)Ljava/lang/StringBuilder;     move­result­object v1     invoke­virtual { p0 }, Ljava/lang/Object;­>getClass()Ljava/lang/Class;     move­result­object v2     invoke­virtual { v2 }, Ljava/lang/Class;­>getName()Ljava/lang/String;     move­result­object v2     invoke­virtual { v1, v2 }, Ljava/lang/StringBuilder;­>append(Ljava/lang/String;)Ljava/lang/StringBuilder;     move­result­object v1     const­string v2, "!"     invoke­virtual { v1, v2 }, Ljava/lang/StringBuilder;­>append(Ljava/lang/String;)Ljava/lang/StringBuilder;     move­result­object v1     invoke­virtual { v1 }, Ljava/lang/StringBuilder;­>toString()Ljava/lang/String;     move­result­object v1     invoke­static { v0, v1 }, Landroid/util/Log;­>d(Ljava/lang/String;Ljava/lang/String;)I   .line 35
  • 29. 23 June 2016 Logging Removal Result: Much better! Possible due to more fine-grained configuration:   .line 31     invoke­virtual { p0, p1 }, Lcom/example/HelloWorldActivity;­>setContentView(Landroid/view/View;)V   .line 35 ­assumenoexternalsideeffects public final class java.lang.StringBuilder {     public java.lang.StringBuilder();     public java.lang.StringBuilder(int);     public java.lang.StringBuilder(java.lang.String);     public java.lang.StringBuilder append(java.lang.String);     … }
  • 30. 23 June 2016 More DexGuard Goodies ● Default configurations for applications/libraries supporting many 3rd party libs ● Great support :-) ● Many samples ● Configuration debugging ● Java 8 language support → backported to Java 6/7 similar to retrolambda ● Planned: Stream API support for older Android devices ● Planned: Native code obfuscation
  • 31. 23 June 2016 The End Thanks for your attention!