Android
Reverse Engineering &
Defenses
Bluebox Labs
Patrick Schulz, Felix Matenaar
23./24. May 2013
Who we are
Patrick Schulz & Felix Matenaar
I Sr. Developer and Researcher
I working for Bluebox Security
I Mobile Enterprise Data Security Startup
I Stealth mode
A motivating example
A motivating example
A motivating example
RE: The Developer’s perspective
Imagine you would develop an Android application.
The App includes...
I Fancy tricks and patterns
I Algorithms which have cost you lots of resources to develop
I Knowledge gained from company internal research projects
Then you release through an official market, and people start looking into your app...
A motivating example
RE: The Developer’s perspective
Imagine you would develop an Android application. The App includes...
I Fancy tricks and patterns
I Algorithms which have cost you lots of resources to develop
I Knowledge gained from company internal research projects
Then you release through an official market, and people start looking into your app...
A motivating example
RE: The Developer’s perspective
Imagine you would develop an Android application. The App includes...
I Fancy tricks and patterns
I Algorithms which have cost you lots of resources to develop
I Knowledge gained from company internal research projects
Then you release through an official market, and people start looking into your app...
A motivating example Static Information Gathering
Static Information Gathering
A motivating example Static Information Gathering
Decompilation
A motivating example Static Information Gathering
Examining the Type System
A motivating example Static Information Gathering
Examining APIs
A motivating example Dynamic Analysis
Dynamic Analysis
A motivating example Dynamic Analysis
Dynamic Analysis
I Some Sandbox implementations out there
http://www.honeynet.org/node/783
I APKTool uses DDMS to debug disassembled Android applications
http://code.google.com/p/android- apktool/wiki/SmaliDebugging
I Locate
I licensing checks
I data validation
I client-side security
I ...
A motivating example App Modification
App Modification
A motivating example App Modification
Application Modification
A motivating example App Modification
Application Modification
A motivating example App Modification
Application Modification
A motivating example Consequences
Consequences
A motivating example Consequences
Consequences
I Trivial to reverse engineer Android applications
I Static Analysis supported by available metadata
I Dynamic Analysis using debugging or sandboxes
I Easy to repack applications
I Add Malware to a benign application I Circumvent licensing checks
Agenda
Agenda
Agenda
How can we address these problems?
I Static Analysis
I Identifier & Code Obfuscation (not in this talk)
I Callgraph obfuscation
I Dynamic code loading
I App Modification
I Manifest cheating
I Runtime integrity checks
I Dynamic Analysis
I Debugger detection
I Debugger prevention
Anti-Static Analysis
Anti-Static Analysis
Anti-Static Analysis
Anti-Static Analysis
I Plenty of analysis tools available
http://resources.infosecinstitute.com/android- malware- analysis/
I Manual analysis
I make code harder to read
I crash analysis tool
I fool analysis tool
I Automated analysis
I crash analysis tool
I fool analysis tool
Anti-Static Analysis Callgraph obfuscation
Callgraph obfuscation
I An app starts with a fork of zygote process
I Has preloaded lib as well as the Android framework
I Include classes in your APK which are defined in preloaded libs
I Bytecode points to the APK internal definition
I During runtime the preloaded definition will be used
Example:
android.os.Process
Anti-Static Analysis Callgraph obfuscation
Callgraph obfuscation
15 / 41
Zygote Java
Library
Zygote Process Android Application (.apk)
Dexfile Manifest Resources
Running Application
Java
Anti-Static Analysis Callgraph obfuscation
Callgraph obfuscation - IDA Pro
Anti-Static Analysis Callgraph obfuscation
Callgraph obfuscation - androguard
Anti-Static Analysis Callgraph obfuscation
Callgraph obfuscation - Fix
I Know the execution environment
I Filter for classes that are preloaded
I Keep an eye on vendor specific preloaded libraries
Anti-Static Analysis Dynamic Bytecode Loading
Dynamic Bytecode Loading
I Static analysis can only consider statically available bytecode
I Further bytecode can be loaded during runtime
I using classloader
I using "class DexFile"
I using native builtin Dalvik functionality
Anti-Static Analysis Dynamic Bytecode Loading
Dynamic Bytecode Loading
I Bytecode distribution:
I Encrypted in the APK, e.g shipped as asset or resource I Downloaded during runtime
I Makes static analysis very expensive
I Ask dynamic guys for help ;)
Tamper Proofing
Tamper Proofing
Tamper Proofing
Tamper Proofing
I React to the fact that your app has been modified or repacked
I Hide interesting code paths from dynamic analysis
I Make it harder for malware authors to repack your app
X ARM’s Trustzone
X Signed by vendor to get system level access
× Not applicable for the usual app developer
Tamper Proofing Static Repack Protection
Manifest cheating
I AndroidManifest.xml included in APK file
I Purpose: Define application meta data
I Requested permissions
I Registered components like services and activities
I Represented using binary format in APK
22 / 41
1 < a p p l i c a t i o n android:name="optional.entry.class">
2 < a c t i v i t y android:name="com.example.manifestexample.MainActivity"> 3 < i n t e n t−f i l t e r >
4 < a c t i o n android:name="android.intent.action.MAIN" / > 5 < / i n t e n t−f i l t e r >
Tamper Proofing Static Repack Protection
Ambiguity during Transformation
I When parsed in Android, attributes are identified according to an id rather than based on the representing attribute name string:
<public type="attr" name="name" id="0x01010003" />
I Text -> Binary: Works just fine (aapt)
I Binary -> Text: Drops attribute id info (apktool)
→Inject a "name" attribute into <application> with an unknown id, so Android will not recognize it as a name attribute
Tamper Proofing Static Repack Protection
Ambiguity during Transformation
I When parsed in Android, attributes are identified according to an id rather than based on the representing attribute name string:
<public type="attr" name="name" id="0x01010003" />
I Text -> Binary: Works just fine (aapt)
I Binary -> Text: Drops attribute id info (apktool)
→Inject a "name" attribute into <application> with an unknown id, so Android will not recognize it as a name attribute
Tamper Proofing Static Repack Protection
Manifest cheating
24 / 41 <application>
<activity android:name=
"com.example.manifestexample.MainActivity"> <intent−filter>
<action android:name=
"android.intent.action.MAIN" / > </intent−filter > </activity> </application> Manifest (Text) Manifest (binary) aapt install
application.attr(“name”, “some.class”, 0x0)
Manifest (binary)
apktool repackaging
<application android:name=”detect.class”> <activity android:name=
"com.example.manifestexample.MainActivity"> <intent−filter>
<action android:name=
"android.intent.action.MAIN" / > </intent−filter > </activity> </application> Manifest (text) Execution
Tamper Proofing Static Repack Protection
Apply to existing application
1. Modify manifest by injecting a "name" attribute into the application tag with id 0 and value "detect.class"
2. Android:ignores the attribute, does not interpret as "android:name"
3. Apktoolconverts the binary xml into text; thus will include a proper "name" attribute when rebuilding the apk
Application output after repacking with apktool:
Tamper Proofing Static Repack Protection
Consequences
I Practical repack detection for apktool:
1. Implement "detect.class"
2. If it’s being executed, the app knows it has been repacked
I Android Application can read its own manifest, be creative ;)
Android Binary-XML format is not properly representable using the Text-based form without additional metadata (recall: attribute id)
Tamper Proofing Static Repack Protection
Consequences
I Practical repack detection for apktool:
1. Implement "detect.class"
2. If it’s being executed, the app knows it has been repacked
I Android Application can read its own manifest, be creative ;)
Android Binary-XML format is not properly representable using the Text-based form without additional metadata (recall: attribute id)
Tamper Proofing Runtime integrity checks
Runtime integrity checks
I Check app signature (signed by the developer)
I Try to do it on your own
I Use system services to check the signature
I Google Play Licensing Service
http://developer.android.com/google/play/licensing/ overview.html
Anti-Runtime Analysis
Anti-Runtime Analysis
Anti-Runtime Analysis Debugger Detection
Anti-Runtime Analysis Layers
1. Detecting a debugger in Java
2. Detecting and preventing a debugger
by interacting the Dalvik Virtual Machine directly
Anti-Runtime Analysis Debugger Detection
Example 1: Debugger Detection (Java)
29 / 41
1 s t a t i c i n t d e t e c t _ i s D e b u g g e r P r e s e n t( ) { 2 i f(Debug.isDebuggerConnected( ) ) 3 r e t u r n 1 ;
4 else
Anti-Runtime Analysis Debugger Detection
Example 2: Debugger Detection (Java)
30 / 41
1 s t a t i c boolean detect_threadCpuTimeNanos( ) { 2 long s t a r t = Debug.threadCpuTimeNanos( ) ; 3 f o r(i n t i= 0 ; i<1000000; ++i)
4 continue;
5 long s t o p = Debug.threadCpuTimeNanos( ) ; 6 i f(s t o p − s t a r t < 10000000)
7 r e t u r n f a l s e; 8 else
Anti-Runtime Analysis Debugger Detection
Example 3: Debugger Detection (Java)
31 / 41
1 s t a t i c boolean d e t e c t _ w a i t F o r D e b u g g e r( ) {
2 WaitForDebuggerThread t h r e a d = new WaitForDebuggerThread( ) ; 3 t h r e a d.s t a r t( ) ;
4 long s t a r t _ t s = Calendar.g e t I n s t a n c e( ) .g e t T i m e I n M i l l i s( ) / 1000; 5 long end_ts;
6 do {
7 end_ts = Calendar.g e t I n s t a n c e( ) .g e t T i m e I n M i l l i s( ) / 1000; 8 long d u r a t i o n = end_ts − s t a r t _ t s;
9 i f(d u r a t i o n > 1 ) 10 r e t u r n f a l s e;
11 } while( !WaitForDebuggerThread.done) ; 12 r e t u r n t r u e;
13 } 14
15 / / p u b l i c Class WaitForDebuggerThread 16 p ub li c void run( ) {
17 Debug.waitForDebugger( ) ; 18 done = t r u e;
Anti-Runtime Analysis Debugger Detection (Native)
Debugger Detection (Native)
Anti-Runtime Analysis Debugger Detection (Native)
Android Application Debugging
Anti-Runtime Analysis Debugger Detection (Native)
Pro’s and Con’s compared to ptrace
X DVM implements debugging mechanisms
I Breakpoints
I Single-Stepping I Java object observation I Profiling
× No OS in between
I Additional Debug-Thread inside DVM
I State tracking is done in the application context
I Debugger communicates with the application directly instead of the OS
→What if the application denies following debugging protocols?
Anti-Runtime Analysis Debugger Detection (Native)
Pro’s and Con’s compared to ptrace
X DVM implements debugging mechanisms
I Breakpoints
I Single-Stepping I Java object observation I Profiling
× No OS in between
I Additional Debug-Thread inside DVM
I State tracking is done in the application context
I Debugger communicates with the application directly instead of the OS
→What if the application denies following debugging protocols?
Anti-Runtime Analysis Debugger Detection (Native)
Relevant Data Structure
34 / 41
1 s t r u c t DvmGlobals { 2 /∗ . . . ∗/
3 b o o l debuggerConnected; 4 b o o l d e b u g g e r A c t i v e;
5 JdwpState∗ j d w p S t a t e; / / jdwp c o n n e c t i o n s t a t e 6 HashTable∗ d b g R e g i s t r y; / / o b j e c t t r a c k i n g 7 B r e a k p o i n t S e t∗ b r e a k p o i n t S e t;
8
9 / / org . apache . harmony . d a l v i k . ddmc . DdmServer 10 Method∗ methDalvikDdmcServer_dispatch; 11 /∗ . . . ∗/
12 }
Anti-Runtime Analysis Debugger Detection (Native)
Example: Debugger Detection (Native)
35 / 41
1 JNIEXPORT j b o o l e a n JNICALL Java_poc_c_detectdebuggerConnected(JNIEnv∗ env,
2 j o b j e c t dontuse) {
3 i f(gDvm.debuggerConnected | | gDvm.d e b u g g e r A c t i v e) 4 r e t u r n JNI_TRUE;
Anti-Runtime Analysis Debugger Prevention
Example 1: Debugger Prevention
I Crashes the debugging thread upon initialization
I Point to a valid location and have fun implementing your own endpoint
36 / 41
1 JNIEXPORT j b o o l e a n JNICALL J a v a _ p o c _ c _ c r a s h O n I n i t(JNIEnv∗ env, 2 j o b j e c t dontuse) { 3 gDvm.methDalvikDdmcServer_dispatch = NULL;
Anti-Runtime Analysis Debugger Prevention
Example 2: Debugger Prevention
I Crashes the debugging thread upon breakpoint usage
37 / 41
1 JNIEXPORT j b o o l e a n JNICALL Java_poc_c_crashOnBreakpoint(JNIEnv∗ env, 2 j o b j e c t dontuse) { 3 gDvm.b r e a k p o i n t S e t = NULL;
Anti-Runtime Analysis Debugger Prevention
Example 3: Debugger Manipulation
I Free all references to tracked objects
38 / 41
1 JNIEXPORT j b o o l e a n JNICALL Java_poc_c_paralyseDebugger(JNIEnv∗ env,
2 j o b j e c t dontuse) {
3 dvmHashTableLock(gDvm.d b g R e g i s t r y) ; 4 dvmHashTableFree(gDvm.d b g R e g i s t r y) ;
5 gDvm.d b g R e g i s t r y = dvmHashTableCreate( 1 0 0 0 , NULL) ; 6 dvmHashTableUnlock(gDvm.d b g R e g i s t r y) ;
Anti-Runtime Analysis Comparison
Anti-Debugging comparison
I Java based
X trivial
X stable
× Not many different methods (yet?)
I Native code based
X Variety of methods nearly unlimited (be creative)
X Enables crashing or manipulating the debugger
× Relatively easy to isolate code due to JNI interfacing
Conclusion
Conclusion
X Protect Android applications from being easily RE’d
X Pitfalls in Android application analysis
I Therefore we’ve presented some ideas including:
I Callgraph obfuscation I Dynamic bytecode loading
I Static repack protection using "Manifest Cheating" I Runtime integrity checks
I Anti-Debugging using Java and native code
Conclusion
Find us...
41 / 41
please find us at
www.bluebox.com