1 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
THOMAS RICHARDS
Dancing with Dalvik
2 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
About me
• Thomas Richards• Security Consultant @ Cigital, Inc• @g13net - Twitter• OSCP, GPEN, OSWP• Developer
o Goofile and Pwnberry Pi
• Organizer for BsidesROC• Presented before at GrrCON and DerbyCON• Really enjoy tearing apart Android
3 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
Toc
• 0x1 – Intro to Dalvik
• 0x2 – Dalvik Opcode Primer
• 0x3 – Case Studies
4 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
0x01 Intro to Dalvik
5 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
What is Dalvik?
• A town in Iceland• A lightweight register-based VM• Optimized for embedded/mobile
platformso Low RAM/CPU
6 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
Dalvik optimizations
• Duplicate code is reused within DEX• 16-bit instruction set that works directly
on local variableso Lowers instruction count and increased
interpreter speed
• Slimmed down VM to run in less space
7 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
Stack vs register based
• Java JVM is Stack Basedo real or emulated computer that uses a pushdown stack rather
than individual machine registers to evaluate each sub-expression in the program
• Register Basedo Dalvik uses registers as primarily units of data storage instead
of the stack. Google is hoping to accomplish 30 percent fewer instructions as a result.
• http://stackoverflow.com/questions/2719469/why-is-the-jvm-stack-based-and-the-dalvik-vm-register-based
• http://en.wikipedia.org/wiki/Stack_machine
8 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
Register Vs. Stack Cont.
9 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
Getting to dalvik
• Android apps are traditionally written in Java
• Compiled into Java bytecode then converted to Dalvik bytecode
• Java class files converted into .dex
10 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
Java vs Dalvik
11 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
Inside the APK
• AndroidManifest.xml• Classes.dex• Res/• Lib/• META-INF/
12 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
Disassembling classes.dex
• Typical toolso Apktoolo Baksmali
• The result is several .smali files
13 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
Apktool decoding
me@Mentos ~/android/ghost $ apktool d ghost-meter.apk I: Baksmaling...I: Loading resource table...I: Loaded.I: Decoding AndroidManifest.xml with resources...I: Loading resource table from file: /home/me/apktool/framework/1.apkI: Loaded.I: Regular manifest package...I: Decoding file-resources...I: Decoding values */* XMLs...I: Done.I: Copying assets and libs...
14 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
Directories Created
15 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
Files created
me@Mentos ~/android/ghost $ ls ghost-meter/smali/a.smali c$a.smali c$c.smali c$e.smali c.smali e.smali g.smali i.smali k.smali m.smali o.smali q.smali s.smali u.smali w.smalib.smali c$b.smali c$d.smali com d.smali f.smali h.smali j.smali l.smali n.smali p.smali r.smali t.smali v.smali x.smalime@Mentos ~/android/ghost $
16 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
Apktool building
me@Mentos ~/android/ghost $ apktool b ghost-meter/ ghost.apkI: Checking whether sources has changed...I: Smaling...I: Checking whether resources has changed...I: Building resources...I: Building apk file...me@Mentos ~/android/ghost $ • After building you must use jarsigner to sign the APK
before it can be installed!
17 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
Signing the APK
• Creating the certo keytool -genkey -v -keystore my-release-
key.keystore -alias alias_name -keyalg RSA -validity 10000
• Signing the APKo jarsigner -verbose -keystore my-release-
key.keystore GhostMeter.apk alias_name
18 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
Cydia Substrate
• Originally on iOS, recently released on Android.
• Tool for hooking methods within an application or the system.
• Modify runtime behavior of Android Application without recompiling code
19 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
0x2 Dalvik Opcode Primer
20 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
Smali files
• Disassembled DEX files• Not as scary as x86 ASM• ASCII representation of Dalvik Opcodes• Mostly correspond to the original .java
files
21 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
Types
V void - can only be used for return types Z boolean B byte S short C char I int J long (64 bits) F float D double (64 bits)
22 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
Helloworld example
.class public LHelloWorld;#this is a comment.super Ljava/lang/Object;
.method public static main([Ljava/lang/String;)V
.registers 2
sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;
const-string v1, "Hello World!"
invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V
return-void.end method
http://code.google.com/p/smali/source/browse/examples/HelloWorld/HelloWorld.smali
23 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
Variables
• Registerso v0, v1, etc.o Variables defined in the original java code
• Parameterso p0, p1, etcoMust be the same as defined by the method
• Both are defined at the beginning of the method
24 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
Example
.class public LHelloWorld;#this is a comment.super Ljava/lang/Object;
.method public static main([Ljava/lang/String;)V
.registers 2
sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;
const-string v1, "Hello World!"
invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V
return-void.end method
25 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
Assigning variables
• const• const-string• Etc,
• Exampleso const v0, 0x1o const-string v1, “This is a test”
26 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
Example
.class public LHelloWorld;#this is a comment.super Ljava/lang/Object;
.method public static main([Ljava/lang/String;)V
.registers 2
sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;
const-string v1, "Hello World!"
invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V
return-void.end method
27 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
Calling methods
• invoke-* { parameters }, method-to-callo Static – static methodo Virtual – virtual method
28 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
Example
.class public LHelloWorld;#this is a comment.super Ljava/lang/Object;
.method public static main([Ljava/lang/String;)V
.registers 2
sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;
const-string v1, "Hello World!"
invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V
return-void.end method
29 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
Conditional statements
• If-* - If statementso If-eq vx, vy, target – If equalo If-nez vx, target – If vx is a nonzeroo If-eqz vx, target – If vx is zeroo If-ge vx, vy, target – if vx>=vyo Etc
• Targetso Shown as cond_0, cond_1
30 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
example
invoke-virtual {v0}, Ljava/lang/Class;->desiredAssertionStatus()Z
move-result v0
if-nez v0, :cond_0
.line 100 :cond_0 const/4 v0, 0x0
goto/16 :goto_0
31 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
Get/put
• Apps could declare constants.• Get/Put will retrieve or store values into
those constants• Examples:
o iput v0, v1, Lcom/greencod/pinball/gameengine/zones/Table0Zone;->ZORDER_TABLE:I
o iget v0, v0, Lcom/greencod/pinball/gameengine/xinterface/persistence/Settings;->friction:F
32 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
Return
• Unless the method is declared as a void, it will return a value.
• Return types:oReturn-voidoReturn-objectoReturn v0
33 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
0x3 case studies
34 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
Removing ads
• Ads are annoying• Take up screen realestate• My 4 yr old mistakenly clicks them
o “Look daddy!”
35 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
solitare
• Ad function is called inbetween deals• Ads are annoying
oMusico Video
• Disable calling the ads?
36 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
Short video showing ad calling
37 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
The code
• After an exhaustive search in com/mobilityware/solitare/solitare.smali:
.method public displayAd()V .locals 1
.prologue .line 572 iget-object v0, p0, Lcom/mobilityware/solitaire/Solitaire;->adControl:Lcom/mobilityware/solitaire/AdControl;
if-eqz v0, :cond_0
.line 573 iget-object v0, p0, Lcom/mobilityware/solitaire/Solitaire;->adControl:Lcom/mobilityware/solitaire/AdControl;
invoke-virtual {v0}, Lcom/mobilityware/solitaire/AdControl;->displayAd()Z
.line 574 :cond_0 return-void.end method
38 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
The code
• After an exhaustive search in com/mobilityware/solitare/solitare.smali:
.method public displayAd()V .locals 1
.prologue .line 572 iget-object v0, p0, Lcom/mobilityware/solitaire/Solitaire;->adControl:Lcom/mobilityware/solitaire/AdControl;
if-eqz v0, :cond_0
.line 573 iget-object v0, p0, Lcom/mobilityware/solitaire/Solitaire;->adControl:Lcom/mobilityware/solitaire/AdControl;
#invoke-virtual {v0}, Lcom/mobilityware/solitaire/AdControl;->displayAd()Z
.line 574 :cond_0 return-void.end method
39 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
After the change is made
• Recompile the code and use apktool to create a new APKo You will have to sign this with your own cert
• After the APK is created:oRemove old Solitare APKo Install new hax0rd one
40 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
Short video showing no more ad
41 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
chess
• Most apps display the ads at all times• When the network is disabled, the ads
don’t show• Can we force this behavior?
42 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
Screenshot of chess with ads
43 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
Google ads
• Most apps rely on Google’s ad provider network• Good for us!
o Code to break this should be the same for many apps
• How to make it look like there is no network connectivity?
• Log Entry when Network is disabledo adRequestWebView was null while trying to load an ad
44 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
The original code
• From com/google/ads/c.smali::try_start_0iget-object v0, p0, Lcom/google/ads/c;->f:Landroid/webkit/WebView; if-eqz v0, :cond_0
iget-object v0, p0, Lcom/google/ads/c;->c:Lcom/google/ads/b;
if-nez v0, :cond_1
:cond_0const-string v0, "adRequestWebView was null while trying to load an ad."
invoke-static {v0}, Lcom/google/ads/util/a;->e(Ljava/lang/String;)V
sget-object v0, Lcom/google/ads/AdRequest$ErrorCode;->INTERNAL_ERROR:Lcom/google/ads/AdRequest$ErrorCode
45 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
The modified code
• From com/google/ads/c.smali::try_start_0iget-object v0, p0, Lcom/google/ads/c;->f:Landroid/webkit/WebView;
const v0, 0x0
if-eqz v0, :cond_0
iget-object v0, p0, Lcom/google/ads/c;->c:Lcom/google/ads/b;
if-nez v0, :cond_1
:cond_0const-string v0, "adRequestWebView was null while trying to load an ad."
invoke-static {v0}, Lcom/google/ads/util/a;->e(Ljava/lang/String;)V
46 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
Screenshot showing no ads
47 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
Removing Ads with Cydia
• Write once, use everywhere• Using reflection, hook a method • Stop ads from loading
48 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
Google Mobile Ads
• Again, very common to see used.• Plan:
oHook loadDataWithBaseUrl methodoRender it useless
49 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
Cydia Code
MS.hookClassLoad("com.google.ads.internal.AdWebView", new MS.ClassLoadHook() {
public void classLoaded(Class<?> resources) {
Method loadAd;
try {
loadAd = resources.getMethod("loadDataWithBaseURL", String.class, String.class, String.class, String.class, String.class);
} catch (NoSuchMethodException d) {
loadAd = null;
}
if (loadAd != null) {
final MS.MethodPointer old = new MS.MethodPointer();
MS.hookMethod(resources, loadAd, new MS.MethodHook() {
public Object invoked(Object _this, Object... args) throws Throwable {
return null;
}
}, old);
50 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
Screenshot of App with Ads
51 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
Screenshot after Cydia App Installed
52 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
Pinball wizard
• How about getting a high score?• Values are most likely in the source• Totally impress your friends with l33t
pinball skillz
53 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
Picture of game after normal score
54 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
The code
.local v12, scorer:Lcom/greencod/gameengine/behaviours/ScorerBehaviour; const/16 v1, 0x2c7
const/16 v3, 0x5aa
invoke-virtual {v12, v1, v3}, Lcom/greencod/gameengine/behaviours/ScorerBehaviour;->addScoreMessage(II)V
.line 508 const/16 v1, 0x204
const/16 v3, 0x10fe
invoke-virtual {v12, v1, v3}, Lcom/greencod/gameengine/behaviours/ScorerBehaviour;->addScoreMessage(II)V
55 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
Altered code
.local v12, scorer:Lcom/greencod/gameengine/behaviours/ScorerBehaviour; const/16 v1, 0x2c7
const/16 v3, 0xfff
invoke-virtual {v12, v1, v3}, Lcom/greencod/gameengine/behaviours/ScorerBehaviour;->addScoreMessage(II)V
.line 508 const/16 v1, 0x204
const/16 v3, 0xffff
invoke-virtual {v12, v1, v3}, Lcom/greencod/gameengine/behaviours/ScorerBehaviour;->addScoreMessage(II)V
56 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
Picture of new high score
57 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
Leaderboard
58 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
What now?
• Explore!• Bypass restrictions?
o Very useful in mobile app assessment
59 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
References
• http://pallergabor.uw.hu/androidblog/dalvik_opcodes.html
• http://code.google.com/p/android-apktool/
• http://code.google.com/p/smali/source/browse/examples/HelloWorld/HelloWorld.smali
• http://www.cydiasubstrate.com/inject/dalvik/
60 | Copyright © 2013, Cigital and/or its affiliates. All rights reserved. | Cigital Confidential Restricted.
QUESTIONS?