HACKING APKS FOR FUN AND FOR PROFIT (MOSTLY FOR FUN)
DAVID TEITELBAUM
MAY 2013
@davtbaum
2 © 2013 Apkudo LLC. www.apkudo.com
OBJECTIVES
Android app disassembly Fundamentals of code injectionSmali/Baksmali and reading Dalvik byte codeBest practices in hardening your app
Expect to learn:
3 © 2013 Apkudo LLC. www.apkudo.com
ROADMAPPART I - CLASS PART II – DEMO/HACK
Approach to hackingTools – apktool, baksmali, smali The APKAll things byte code
Snapchat deep diveApp disassembly and analysisCode injectionRecap
4 © 2013 Apkudo LLC. www.apkudo.com
PART I - CLASS
5 © 2013 Apkudo LLC. www.apkudo.com
1. Unzip APK and disassemble classes.dex (baksmali)2. Analyze – what is the application doing?3. Inject byte code into the application to modify execution4. Reassemble classes.dex (smali) and rezip/sign APK
APK HACKINGApproach
Disassemble(baksmali)
.smali
Static analysis
Reassemble(smali)
Code injection
6 © 2013 Apkudo LLC. www.apkudo.com
CODE INJECTION
Write patches in Java, compile, then use the Smali/Baksmali tools to disassemble into Dalvik byte code
Stick to public static methods in Dalvik byte code which have no register dependencies.
Let the compiler do the work - this hack was achieved with only one line of code injection!
Best Practices:
7 © 2013 Apkudo LLC. www.apkudo.com
TOOLS Access to a terminal environment (preferably Linux or Mac
osx) Android SDK keytool and jarsigner Smali/Baksmali - http://code.google.com/p/smali/ Apktool - http://code.google.com/p/android-apktool/ Editor of choice (emacs!)
You’ll need…
8 © 2013 Apkudo LLC. www.apkudo.com
SMALI/BAKSMALI
Baksmali disassembles Dalvik executable (.dex) into readable Dalvik byte code (.smali)
Smali re-assembles .smali files back into .dex Dalvik executable
Gives developers the ability to modify execution of an APK without having access to source code
Dalvik Assembler/Disassembler
9 © 2013 Apkudo LLC. www.apkudo.com
APKTOOL Wraps smali/baksmali and Android asset packaging tool
(aapt) Decodes resources and decompresses xml Great for manifest introspection Buggy :/
All in one reverser
10 © 2013 Apkudo LLC. www.apkudo.com
THE APKA container for your app Zipped file formatted based on JAR
META-INF/
AndroidManifest.xml
classes.dex
lib/
res/
resources.arsc
11 © 2013 Apkudo LLC. www.apkudo.com
EXAMPLES
$ unzip foobar.apk –d foobar
$ cd ./foobar
$ lsAndroidManifest.xml META-INF classes.dex res resources.arsc lib
$ baksmali –a 10 –d ~/boot_class_path classes.dex
baksmali
API level boot class path dex file
12 © 2013 Apkudo LLC. www.apkudo.com
EXAMPLES
$ lsAndroidManifest.xml META-INF classes.dex res resources.arsc libout
$ smali –a 10 ./out –o classes.dex
$ zip –r ~/hacked.apk ./*
smali
API level output dex file
recursive
13 © 2013 Apkudo LLC. www.apkudo.com
EXAMPLES
$ apktool d foobar.apk foobar
$ cd ./foobar
$ lsAndroidManifest.xml apktool.yml assets res smali
$ cd ../
$ apktool b ./foobar
apktool
decode out directory
build
14 © 2013 Apkudo LLC. www.apkudo.com
EXAMPLES
$ keytool -genkeypair -v -alias default –keystore ~/.keystore –storepass password
$ jarsigner –keystore ~/.keystore ./foobar.apk default
keytool and jarsigner
alias
15 © 2013 Apkudo LLC. www.apkudo.com
SMALI FILESclass representation in byte code
.class public Lcom/apkudo/util/Serializer;
.super Ljava/lang/Object;
.source "Serializer.java”
# static fields.field public static final TAG:Ljava/lang/String; = "ApkudoUtils”
# direct methods.method public constructor <init>()V .registers 1
.prologue .line 5 invoke-direct {p0}, Ljava/lang/Object;-><init>()V
return-void.end method
Class information
Static fields
MethodsDirectVirtual
16 © 2013 Apkudo LLC. www.apkudo.com
SYNTAX
V void Z booleanB byteS shortC charF floatI intJ long D double [ array
types .method private doSomething()V
64 bit – special instructions
17 © 2013 Apkudo LLC. www.apkudo.com
SYNTAX
• full name space slash separated • prefixed with L• suffixed with ;
Lcom/apkudo/util/Serializer; classes
const-string v0, "ApkudoUtils"
new-instance v1, Ljava/lang/StringBuilder;
invoke-direct {v1}, Ljava/lang/StringBuilder;-><init>()V
const-string v2, "docId: ["
invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v1
18 © 2013 Apkudo LLC. www.apkudo.com
SYNTAX
Method definitions .method <[keyword]> <name>(<[param]>)<return type>
Method invocations invoke-static – any method that is static invoke-virtual – any method that isn’t private, static, or
final invoke-direct – any non-static direct method invoke-super – any superclass's virtual method Invoke-interface – any interface method
Virtual methods require their class instance as a parameter!
.method private doSomething()Vmethods
19 © 2013 Apkudo LLC. www.apkudo.com
SYNTAX.method private doSomething()Vmethods
.method private delayedAnimationFrame(J)Z .registers 8 .parameter "currentTime”
keyword method name parameters/return
# Static invocation invoke-static {p2}, Landroid/text/TextUtils;->isEmpty(Ljava/lang/CharSequence;)Z
# Virtual invocation invoke-virtual {v0, v1}, Lcom/google/android/finsky/FinskyApp;->drainAllRequests(I)V
20 © 2013 Apkudo LLC. www.apkudo.com
SYNTAX
All registers are 32 bits Declaration
.registers – total number of registers .locals – total minus method parameter registers
Naming scheme P registers – parameter registers
implicit p0 = ‘this’ instance (non-static) V registers – local registers
P registers are always at the end of the register list
.locals 16
.registers 18Registers
21 © 2013 Apkudo LLC. www.apkudo.com
SYNTAX
.method public onCreate()V .registers 7
...
Register Example
v0 First local register
v1 Second local register
v2 …
v3 …
v4 …
v5 …
v6 p0 First param – ‘this’
p0 == v6
22 © 2013 Apkudo LLC. www.apkudo.com
SYNTAX
.method public doIt(Ljava/lang/String;II)V .registers 7
Register Example 2
v0 First local register
v1 Second local register
v2 …
v3 p0 ‘this’
v4 p1 String
v5 p2 int
v6 p3 int
p3 == v6p2 == v5p1 == v4p0 == v3
23 © 2013 Apkudo LLC. www.apkudo.com
SYNTAX
.method public doIt(JI)V .registers 7
# hint, j == long
Register Example 3
v0 First local register
v1 Second local register
v2
v3
v4
v5
v6
Third local registerp0 ‘this’ instance
p1 long p2 long p3 int
v3 - is it…A) Fourth local register?B) This instance?C) Long?D) Int?
v4 - is it…A) Fourth local register?B) This instance?C) Long?D) Int?
v5 - is it…A) Fourth local register?B) This instance?C) Long?D) Int?
v6 - is it…A) Fourth local register?B) This instance?C) Long?D) Int?
24 © 2013 Apkudo LLC. www.apkudo.com
SYNTAX
.method public static doIt(IJ)V .registers 7
Register Example 4
v0 First local register
v1 Second local register
v2
v3
v4
v5
v6
Third local register Fourth local register
p0 Int p1 Long p2 Long
v3 - is it…A) Fourth local register?B) This instance?C) Long?D) Int?
v4 - is it…A) Fourth local register?B) This instance?C) Long?D) Int?
v5 - is it…A) Fourth local register?B) This instance?C) Long?D) Int?
v6 - is it…A) Fourth local register?B) This instance?C) Long?D) Int?
25 © 2013 Apkudo LLC. www.apkudo.com
SYNTAX
jumps goto <offset>
jumping.method public doIt(JI)V .registers 7
...
goto :goto_31
...
:goto_31return-void
26 © 2013 Apkudo LLC. www.apkudo.com
SYNTAX
Conditionals If-eq If-ne If-le If-lt If-ge If-gt
Add z for zero If-eqz If-nez
conditionalsmethod public foobar()V .registers 2
const/4 v0, 0x0
if-eqz v0, :cond_6
return-void
:cond_6
# Do something
.end method
27 © 2013 Apkudo LLC. www.apkudo.com
PUTTING IT ALL TOGETHERExample - Javapackage com.google.android.finsky;
import android.app.Application;import android.accounts.Account;
public class FinskyApp() extends Application { Account mCurrentAccount;
public String getCurrentAccountName() { if (mCurrentAccount != null) { return mCurrentAccount.name; } else {
return null; } }}
28 © 2013 Apkudo LLC. www.apkudo.com
PUTTING IT ALL TOGETHERSame example - smali
.method public getCurrentAccountName()Ljava/lang/String; .registers 2
.prologue .line 617 iget-object v0, p0, Lcom/google/android/finsky/FinskyApp;->mCurrentAccount:Landroid/accounts/Account;
if-nez v0, :cond_6
const/4 v0, 0x0
:goto_5 return-object v0
:cond_6 iget-object v0, v0, Landroid/accounts/Account;->name:Ljava/lang/String;
goto :goto_5.end method
v0 First local register
v1 p0 ‘this’ instance
Getting this field! of type …
into this reg
29 © 2013 Apkudo LLC. www.apkudo.com
ONE FINALSTEPObfuscation!
• Renames classes, class members and and method
• Preserves OS entry points and java namespace classes
• Slows down the static analysis process
• Not a silver bullet, but an easy first line of defense
iget-object v0, p0, Lcom/a/a/g;->a:Lcom/a/a/f;
invoke-static {v0}, Lcom/a/a/f;->a(Lcom/a/a/f;)Landroid/webkit/WebView;
30 © 2013 Apkudo LLC. www.apkudo.com
PART II - DEMO
https://github.com/davtbaum/adc-demo
31 © 2013 Apkudo LLC. www.apkudo.com
HACKING SNAPCHAT
32 © 2013 Apkudo LLC. www.apkudo.com
1. Picture messenger with a catch…2. Self-destructive pictures!3. Pictures only last up to 10 seconds, ensures the receiver cannot
save them4. Alerts the sender if the receiver tries to take a screenshot5. Net-worth $70M – over 20M snaps sent a day!1
WHAT ISSNAPCHAT?Real-time picture messenger
1. http://techcrunch.com/2012/12/12/sources-snapchat-raising-north-of-10m-at-around-70m-valuation-led-by-benchmarks-mitch-lasky/
33 © 2013 Apkudo LLC. www.apkudo.com
SNAPCHATIN ACTION
34 © 2013 Apkudo LLC. www.apkudo.com
1. Unzip APK and disassemble classes.dex 2. Analyze for target resource (snapchat picture AKA ‘snap’)3. Inject code to store or transmit resource4. Reassemble classes.dex and rezip/resign APK
HACKING SNAPCHATApproach
Disassemble(baksmali)
.smali
Static analysis/Code Injection
Reassemble(smali)
35 © 2013 Apkudo LLC. www.apkudo.com
TOOLS Access to a terminal environment (preferably Linux or Mac
osx) Android SDK keytool and jarsigner Smali/Baksmali - http://code.google.com/p/smali/ Apktool - http://code.google.com/p/android-apktool/ Editor of choice (emacs!)
You’ll need…
36 © 2013 Apkudo LLC. www.apkudo.com
STEP 1
Query device for list of applications and associated file paths adb shell pm list packages –f (optional) | grep –si “snapchat”
Pull the files adb pull <file> ~/snapchat/snapchat.apk
GET THE APP
37 © 2013 Apkudo LLC. www.apkudo.com
STEP 2
Extract classes.dex and remove keys unzip snapchat.apk rm –r ./META-INF
Disassemble: baksmali -a 10 –d <framework_path> ./classes.dex -a = api-level -d = bootclasspath dir
‘adb pull /system/framework/ ./framework’
DECOMPRESS AND DISASSEMBLE
38 © 2013 Apkudo LLC. www.apkudo.com
STEP 3
apktool dump and inspect AndroidManifest.xml for activities
apktool d snapchat.apk emacs AndroidManifest.xml
Find the resource Use tools
uiautomator to retrieve view hierarchy (buggy)
adb shell dumpsys window | grep –si “mCurrentFocus”
Resolve resource in code
ANDROID FORENSICS
39 © 2013 Apkudo LLC. www.apkudo.com
STEP 3 Resource located! Now we need to retrieve it… Don’t write everything in byte code - build an application
that contains the resource retrieval code. Disassemble donor application and copy appropriate
methods into target app Easy enough, right?
RESOURCE RETRIEVAL
Java resourceretrievalcode
Build Bytecode
40 © 2013 Apkudo LLC. www.apkudo.com
DONOR APPRESOURCE RETRIEVAL
package com.apkudo.util;
import android.app.Activity;import android.graphics.Bitmap;import java.io.FileOutputStream;Import android.os.Bundle;
public class HackUtils extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); }
public void saveSnap(Bitmap bmp) {try {
FileOutputStream out = new FileOutputStream(“/sdcard/test.png”);
bmp.compress(Bitmap.CompressFormat.PNG, 90, out);} catch (Exception e) {
e.printStackTrace();}
}}
41 © 2013 Apkudo LLC. www.apkudo.com
STEP 4CODE INJECTION
.method private showImage()V Isolate Bitmap Pass into resource retrieval method
invoke-virtual {v1, v2}, Lcom/snapchat/android/model/ReceivedSnap;->getImageBitmap(Landroid/content/Context;)Landroid/graphics/Bitmap;
move-result-object v0
# Patches invoke-static {v0}, Lcom/apkudo/util/HackUtils;->saveSnap(Landroid/graphics/Bitmap;)V
# End of Patches
42 © 2013 Apkudo LLC. www.apkudo.com
STEP 5 Re-assemble
smali –a 10 ./out –o classes.dex Compress
zip –z0 –r ../snapchat.apk ./* Sign APK
jarsigner -verbose -keystore my-release-key.keystore ./snapchat.apk alias_name
REBUILD APK
43 © 2013 Apkudo LLC. www.apkudo.com
STEP 6
Install adb install –r ../snapchat.apk
Run the app!
INSTALL AND EXECUTE
44 © 2013 Apkudo LLC. www.apkudo.com
RECAP
Obfuscate? Very simple to navigate using method name
E.g. “showSnap()”. Push images to native layer
OpenGL? Native code is much harder to reverse.
Dynamic signature verification?
There is no silver bullet!
ROOM FOR IMPROVEMENTS
Thank you.
DAVID@ .COM@davtbaum
Top Related