SlideShare a Scribd company logo
1 of 31
Download to read offline
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!

More Related Content

What's hot

One Step Ahead of Cheaters -- Instrumenting Android Emulators
One Step Ahead of Cheaters -- Instrumenting Android EmulatorsOne Step Ahead of Cheaters -- Instrumenting Android Emulators
One Step Ahead of Cheaters -- Instrumenting Android EmulatorsPriyanka Aash
 
Java Serialization Deep Dive
Java Serialization Deep DiveJava Serialization Deep Dive
Java Serialization Deep DiveMartijn Dashorst
 
Java Crash分析(2012-05-10)
Java Crash分析(2012-05-10)Java Crash分析(2012-05-10)
Java Crash分析(2012-05-10)Kris Mok
 
Android Storage - Vold
Android Storage - VoldAndroid Storage - Vold
Android Storage - VoldWilliam Lee
 
XXE: How to become a Jedi
XXE: How to become a JediXXE: How to become a Jedi
XXE: How to become a JediYaroslav Babin
 
Java Input Output and File Handling
Java Input Output and File HandlingJava Input Output and File Handling
Java Input Output and File HandlingSunil OS
 
Black Hat EU 2010 - Attacking Java Serialized Communication
Black Hat EU 2010 - Attacking Java Serialized CommunicationBlack Hat EU 2010 - Attacking Java Serialized Communication
Black Hat EU 2010 - Attacking Java Serialized Communicationmsaindane
 
Overview of Android binder IPC implementation
Overview of Android binder IPC implementationOverview of Android binder IPC implementation
Overview of Android binder IPC implementationChethan Pchethan
 
Android crash debugging
Android crash debuggingAndroid crash debugging
Android crash debuggingAshish Agrawal
 
Tegra 186のu-boot & Linux
Tegra 186のu-boot & LinuxTegra 186のu-boot & Linux
Tegra 186のu-boot & LinuxMr. Vengineer
 
A Case Study in Attacking KeePass
A Case Study in Attacking KeePassA Case Study in Attacking KeePass
A Case Study in Attacking KeePassWill Schroeder
 
Prerequisite knowledge for shared memory concurrency
Prerequisite knowledge for shared memory concurrencyPrerequisite knowledge for shared memory concurrency
Prerequisite knowledge for shared memory concurrencyViller Hsiao
 
Why Rust? - Matthias Endler - Codemotion Amsterdam 2016
Why Rust? - Matthias Endler - Codemotion Amsterdam 2016Why Rust? - Matthias Endler - Codemotion Amsterdam 2016
Why Rust? - Matthias Endler - Codemotion Amsterdam 2016Codemotion
 
Exploiting Deserialization Vulnerabilities in Java
Exploiting Deserialization Vulnerabilities in JavaExploiting Deserialization Vulnerabilities in Java
Exploiting Deserialization Vulnerabilities in JavaCODE WHITE GmbH
 
JavaOne 2012 - JVM JIT for Dummies
JavaOne 2012 - JVM JIT for DummiesJavaOne 2012 - JVM JIT for Dummies
JavaOne 2012 - JVM JIT for DummiesCharles Nutter
 
Java Foundations: Data Types and Type Conversion
Java Foundations: Data Types and Type ConversionJava Foundations: Data Types and Type Conversion
Java Foundations: Data Types and Type ConversionSvetlin Nakov
 

What's hot (20)

One Step Ahead of Cheaters -- Instrumenting Android Emulators
One Step Ahead of Cheaters -- Instrumenting Android EmulatorsOne Step Ahead of Cheaters -- Instrumenting Android Emulators
One Step Ahead of Cheaters -- Instrumenting Android Emulators
 
Java Serialization Deep Dive
Java Serialization Deep DiveJava Serialization Deep Dive
Java Serialization Deep Dive
 
Java Crash分析(2012-05-10)
Java Crash分析(2012-05-10)Java Crash分析(2012-05-10)
Java Crash分析(2012-05-10)
 
Android Storage - Vold
Android Storage - VoldAndroid Storage - Vold
Android Storage - Vold
 
XXE: How to become a Jedi
XXE: How to become a JediXXE: How to become a Jedi
XXE: How to become a Jedi
 
Java Input Output and File Handling
Java Input Output and File HandlingJava Input Output and File Handling
Java Input Output and File Handling
 
Black Hat EU 2010 - Attacking Java Serialized Communication
Black Hat EU 2010 - Attacking Java Serialized CommunicationBlack Hat EU 2010 - Attacking Java Serialized Communication
Black Hat EU 2010 - Attacking Java Serialized Communication
 
OOP V3.1
OOP V3.1OOP V3.1
OOP V3.1
 
Overview of Android binder IPC implementation
Overview of Android binder IPC implementationOverview of Android binder IPC implementation
Overview of Android binder IPC implementation
 
Rust-lang
Rust-langRust-lang
Rust-lang
 
Android crash debugging
Android crash debuggingAndroid crash debugging
Android crash debugging
 
Tegra 186のu-boot & Linux
Tegra 186のu-boot & LinuxTegra 186のu-boot & Linux
Tegra 186のu-boot & Linux
 
A Case Study in Attacking KeePass
A Case Study in Attacking KeePassA Case Study in Attacking KeePass
A Case Study in Attacking KeePass
 
Prerequisite knowledge for shared memory concurrency
Prerequisite knowledge for shared memory concurrencyPrerequisite knowledge for shared memory concurrency
Prerequisite knowledge for shared memory concurrency
 
Why Rust? - Matthias Endler - Codemotion Amsterdam 2016
Why Rust? - Matthias Endler - Codemotion Amsterdam 2016Why Rust? - Matthias Endler - Codemotion Amsterdam 2016
Why Rust? - Matthias Endler - Codemotion Amsterdam 2016
 
Exploiting Deserialization Vulnerabilities in Java
Exploiting Deserialization Vulnerabilities in JavaExploiting Deserialization Vulnerabilities in Java
Exploiting Deserialization Vulnerabilities in Java
 
JavaOne 2012 - JVM JIT for Dummies
JavaOne 2012 - JVM JIT for DummiesJavaOne 2012 - JVM JIT for Dummies
JavaOne 2012 - JVM JIT for Dummies
 
Practice of Android Reverse Engineering
Practice of Android Reverse EngineeringPractice of Android Reverse Engineering
Practice of Android Reverse Engineering
 
Java Foundations: Data Types and Type Conversion
Java Foundations: Data Types and Type ConversionJava Foundations: Data Types and Type Conversion
Java Foundations: Data Types and Type Conversion
 
Core java
Core javaCore java
Core java
 

Similar to ProGuard / DexGuard Tips and Tricks

[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 sizeAnsgar Lin
 
[Gstar 2013] Unity Security
[Gstar 2013] Unity Security[Gstar 2013] Unity Security
[Gstar 2013] Unity SecuritySeungmin Shin
 
Audit your reactive applications
Audit your reactive applicationsAudit your reactive applications
Audit your reactive applicationsOCTO Technology
 
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 AssertionsWebStackAcademy
 
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 DevelopmentKetan Raval
 
OPM Recipe designer notes
OPM Recipe designer notesOPM Recipe designer notes
OPM Recipe designer notested-xu
 
Mockito with a hint of PowerMock
Mockito with a hint of PowerMockMockito with a hint of PowerMock
Mockito with a hint of PowerMockYing Zhang
 
Advanced iOS Debbuging (Reloaded)
Advanced iOS Debbuging (Reloaded)Advanced iOS Debbuging (Reloaded)
Advanced iOS Debbuging (Reloaded)Massimo Oliviero
 
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 ValgrindRapidValue
 
Android reverse engineering - Analyzing skype
Android reverse engineering - Analyzing skypeAndroid reverse engineering - Analyzing skype
Android reverse engineering - Analyzing skypeMário Almeida
 
Generic Synchronization Policies in C++
Generic Synchronization Policies in C++Generic Synchronization Policies in C++
Generic Synchronization Policies in C++Ciaran McHale
 
"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 NelsonGWTcon
 
Javascript Deofuscation A manual Approach
Javascript Deofuscation A manual ApproachJavascript Deofuscation A manual Approach
Javascript Deofuscation A manual ApproachGregory Hanis
 
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 ToolsJorge Hidalgo
 
Google I/O 2021 Recap
Google I/O 2021 RecapGoogle I/O 2021 Recap
Google I/O 2021 Recapfurusin
 
Bring the fun back to java
Bring the fun back to javaBring the fun back to java
Bring the fun back to javaciklum_ods
 
JavaOne 2016: Life after Modularity
JavaOne 2016: Life after ModularityJavaOne 2016: Life after Modularity
JavaOne 2016: Life after ModularityDanHeidinga
 

Similar to 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
 

Recently uploaded

9892124323 | Book Call Girls in Juhu and escort services 24x7
9892124323 | Book Call Girls in Juhu and escort services 24x79892124323 | Book Call Girls in Juhu and escort services 24x7
9892124323 | Book Call Girls in Juhu and escort services 24x7Pooja Nehwal
 
CALL ON ➥8923113531 🔝Call Girls Gomti Nagar Lucknow best Night Fun service
CALL ON ➥8923113531 🔝Call Girls Gomti Nagar Lucknow best Night Fun serviceCALL ON ➥8923113531 🔝Call Girls Gomti Nagar Lucknow best Night Fun service
CALL ON ➥8923113531 🔝Call Girls Gomti Nagar Lucknow best Night Fun serviceanilsa9823
 
BDSM⚡Call Girls in Sector 71 Noida Escorts >༒8448380779 Escort Service
BDSM⚡Call Girls in Sector 71 Noida Escorts >༒8448380779 Escort ServiceBDSM⚡Call Girls in Sector 71 Noida Escorts >༒8448380779 Escort Service
BDSM⚡Call Girls in Sector 71 Noida Escorts >༒8448380779 Escort ServiceDelhi Call girls
 
Call US Pooja 9892124323 ✓Call Girls In Mira Road ( Mumbai ) secure service,
Call US Pooja 9892124323 ✓Call Girls In Mira Road ( Mumbai ) secure service,Call US Pooja 9892124323 ✓Call Girls In Mira Road ( Mumbai ) secure service,
Call US Pooja 9892124323 ✓Call Girls In Mira Road ( Mumbai ) secure service,Pooja Nehwal
 
CALL ON ➥8923113531 🔝Call Girls Saharaganj Lucknow best sexual service
CALL ON ➥8923113531 🔝Call Girls Saharaganj Lucknow best sexual serviceCALL ON ➥8923113531 🔝Call Girls Saharaganj Lucknow best sexual service
CALL ON ➥8923113531 🔝Call Girls Saharaganj Lucknow best sexual serviceanilsa9823
 
FULL ENJOY - 9999218229 Call Girls in {Mahipalpur}| Delhi NCR
FULL ENJOY - 9999218229 Call Girls in {Mahipalpur}| Delhi NCRFULL ENJOY - 9999218229 Call Girls in {Mahipalpur}| Delhi NCR
FULL ENJOY - 9999218229 Call Girls in {Mahipalpur}| Delhi NCRnishacall1
 
Powerful Love Spells in Arkansas, AR (310) 882-6330 Bring Back Lost Lover
Powerful Love Spells in Arkansas, AR (310) 882-6330 Bring Back Lost LoverPowerful Love Spells in Arkansas, AR (310) 882-6330 Bring Back Lost Lover
Powerful Love Spells in Arkansas, AR (310) 882-6330 Bring Back Lost LoverPsychicRuben LoveSpells
 

Recently uploaded (7)

9892124323 | Book Call Girls in Juhu and escort services 24x7
9892124323 | Book Call Girls in Juhu and escort services 24x79892124323 | Book Call Girls in Juhu and escort services 24x7
9892124323 | Book Call Girls in Juhu and escort services 24x7
 
CALL ON ➥8923113531 🔝Call Girls Gomti Nagar Lucknow best Night Fun service
CALL ON ➥8923113531 🔝Call Girls Gomti Nagar Lucknow best Night Fun serviceCALL ON ➥8923113531 🔝Call Girls Gomti Nagar Lucknow best Night Fun service
CALL ON ➥8923113531 🔝Call Girls Gomti Nagar Lucknow best Night Fun service
 
BDSM⚡Call Girls in Sector 71 Noida Escorts >༒8448380779 Escort Service
BDSM⚡Call Girls in Sector 71 Noida Escorts >༒8448380779 Escort ServiceBDSM⚡Call Girls in Sector 71 Noida Escorts >༒8448380779 Escort Service
BDSM⚡Call Girls in Sector 71 Noida Escorts >༒8448380779 Escort Service
 
Call US Pooja 9892124323 ✓Call Girls In Mira Road ( Mumbai ) secure service,
Call US Pooja 9892124323 ✓Call Girls In Mira Road ( Mumbai ) secure service,Call US Pooja 9892124323 ✓Call Girls In Mira Road ( Mumbai ) secure service,
Call US Pooja 9892124323 ✓Call Girls In Mira Road ( Mumbai ) secure service,
 
CALL ON ➥8923113531 🔝Call Girls Saharaganj Lucknow best sexual service
CALL ON ➥8923113531 🔝Call Girls Saharaganj Lucknow best sexual serviceCALL ON ➥8923113531 🔝Call Girls Saharaganj Lucknow best sexual service
CALL ON ➥8923113531 🔝Call Girls Saharaganj Lucknow best sexual service
 
FULL ENJOY - 9999218229 Call Girls in {Mahipalpur}| Delhi NCR
FULL ENJOY - 9999218229 Call Girls in {Mahipalpur}| Delhi NCRFULL ENJOY - 9999218229 Call Girls in {Mahipalpur}| Delhi NCR
FULL ENJOY - 9999218229 Call Girls in {Mahipalpur}| Delhi NCR
 
Powerful Love Spells in Arkansas, AR (310) 882-6330 Bring Back Lost Lover
Powerful Love Spells in Arkansas, AR (310) 882-6330 Bring Back Lost LoverPowerful Love Spells in Arkansas, AR (310) 882-6330 Bring Back Lost Lover
Powerful Love Spells in Arkansas, AR (310) 882-6330 Bring Back Lost Lover
 

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!