0% found this document useful (0 votes)
189 views44 pages

Syssec Summer School Android Code Injection

The document discusses reverse engineering Android applications by disassembling Android application packages (APKs) and injecting code. It describes unzipping an APK, disassembling the classes.dex file using apktool or baksmali to generate smali code, performing static analysis on the smali code, injecting additional byte-code by modifying the smali files, and then reassembling the APK by compiling the smali code back into a classes.dex and repacking the APK.

Uploaded by

thariqsatria
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
189 views44 pages

Syssec Summer School Android Code Injection

The document discusses reverse engineering Android applications by disassembling Android application packages (APKs) and injecting code. It describes unzipping an APK, disassembling the classes.dex file using apktool or baksmali to generate smali code, performing static analysis on the smali code, injecting additional byte-code by modifying the smali files, and then reassembling the APK by compiling the smali code back into a classes.dex and repacking the APK.

Uploaded by

thariqsatria
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 44

Reverse Engineering Android:

Disassembly & Code Injection


Thanasis Petsas
[email protected]

[email protected] - www.syssec-project.eu 1
Roadmap
The APK Structure
The Tools
Hacking Approach
Disassembly & App Analysis
Code Injection

[email protected] - www.syssec-project.eu 2
The APK Structure
AndroidManifest.xml

classes.dex

res/

lib/ (sometimes)

META-INF

[email protected] - www.syssec-project.eu 3
The Tools

Youll need

Android SDK
apktool (based on Smali/Baksmali)
jarsigner
keytool

[email protected] - www.syssec-project.eu
Hacking Approach

[email protected] - www.syssec-project.eu
Hacking Approach
1. Unzip APK & disassemble classes.dex

Disassemble (1)
(apktool/baksmali)
.smali

[email protected] - www.syssec-project.eu
Hacking Approach
1. Unzip APK & disassemble classes.dex
2. Perform static analysis on the app

Static analysis (2)

Disassemble (1)
(apktool/baksmali)
.smali

[email protected] - www.syssec-project.eu
Hacking Approach
1. Unzip APK & disassemble classes.dex
2. Perform static analysis on the app
3. Inject byte-code into the app

Static analysis (2)

Disassemble (1)
(apktool/baksmali)
.smali
Code injection (3)
[email protected] - www.syssec-project.eu
Hacking Approach
1. Unzip APK & disassemble classes.dex
2. Perform static analysis on the app
3. Inject byte-code into the app
4. Reassemble classes.dex & zip/sign APK
Static analysis (2)

Disassemble (1) Reassemble (4)


(apktool/baksmali) (apktool/smali)
.smali
Code injection (3)
[email protected] - www.syssec-project.eu
Disassembling APK

$ apktool d r MyApp.apk Myapp


decode Exclude out directory
resources
$ cd MyApp

$ ls
$ AndroidManifest.xml apktool.yml
assets res smali

[email protected] - www.syssec-project.eu
Analyzing the APK

$ ls Myapp/smali/com/example/myapp
StartActivity.smali
R$attr.smali
R$drawable.smali
R$layout.smali
R$string.smali
R.smali

[email protected] - www.syssec-project.eu
Analyzing the APK

$ ls Myapp/smali/com/example/myapp
StartActivity.smali com.example.myapp
R$attr.smali
R$drawable.smali
R$layout.smali
R$string.smali
R.smali

[email protected] - www.syssec-project.eu
Analyzing the APK

$ ls Myapp/smali/com/example/myapp
StartActivity.smali com.example.myapp
R$attr.smali
R$drawable.smali StartActivity.java
R$layout.smali R.java
R$string.smali
R.smali

[email protected] - www.syssec-project.eu
Java to Smali

# virtual methods
public class StartActivity extends Activity { .method protected onCreate(Landroid/os/Bundle;)V
.locals 3
@Override .parameter "savedInstanceState"
protected void onCreate( .prologue
Bundle savedInstanceState) { invoke-super {p0, p1}, Landroid/app/Activity
super.onCreate(savedInstanceState); ;->onCreate(Landroid/os/Bundle;)V
setContentView(R.layout.activity_start);
const/high16 v0, 0x7f03
Log.i("StartActivity:", Message");
const-string v0, "StartActivity:"
} const-string v1, Message"
invoke-static {v0, v1}, Landroid/util/Log;
->d(Ljava/lang/String;Ljava/lang/String;)I
move-result v0

return-void
Java code .end method Smali Byte code
[email protected] - www.syssec-project.eu 8
Java to Smali

# virtual methods
public class StartActivity extends Activity { .method protected onCreate(Landroid/os/Bundle;)V
.locals 3
@Override .parameter "savedInstanceState"
protected void onCreate( .prologue
Bundle savedInstanceState) { invoke-super {p0, p1}, Landroid/app/Activity
super.onCreate(savedInstanceState); ;->onCreate(Landroid/os/Bundle;)V
setContentView(R.layout.activity_start);
const/high16 v0, 0x7f03
Log.i("StartActivity:", Message");
const-string v0, "StartActivity:"
} const-string v1, Message"
invoke-static {v0, v1}, Landroid/util/Log;
->d(Ljava/lang/String;Ljava/lang/String;)I
move-result v0

return-void
Java code .end method Smali Byte code
[email protected] - www.syssec-project.eu 8
Java to Smali

# virtual methods
public class StartActivity extends Activity { .method protected onCreate(Landroid/os/Bundle;)V
.locals 3
@Override .parameter "savedInstanceState"
protected void onCreate( .prologue
Bundle savedInstanceState) { invoke-super {p0, p1}, Landroid/app/Activity
super.onCreate(savedInstanceState); ;->onCreate(Landroid/os/Bundle;)V
setContentView(R.layout.activity_start);
const/high16 v0, 0x7f03
Log.i("StartActivity:", Message");
const-string v0, "StartActivity:"
} const-string v1, Message"
invoke-static {v0, v1}, Landroid/util/Log;
->d(Ljava/lang/String;Ljava/lang/String;)I
move-result v0

return-void
Java code .end method Smali Byte code
[email protected] - www.syssec-project.eu 8
Class Representation in Smali

.class public Lcom/apkudo/util/Serializer;


.super Ljava/lang/Object; Class information
.source "Serializer.java

# static fields
.field public static final TAG:Ljava/lang/String; = String Static fields

# direct methods
.method public constructor <init>()V
.registers 1

.prologue
.line 5 Methods
invoke-direct {p0}, Ljava/lang/Object;-><init>()V Direct
Virtual
return-void
.end method

[email protected] - www.syssec-project.eu
Class Representation in Smali

.class public Lcom/apkudo/util/Serializer;


.super Ljava/lang/Object; Class information
.source "Serializer.java

# static fields
.field public static final TAG:Ljava/lang/String; = String Static fields

# direct methods
.method public constructor <init>()V
.registers 1

.prologue
.line 5 Methods
invoke-direct {p0}, Ljava/lang/Object;-><init>()V Direct
Virtual
return-void
.end method

[email protected] - www.syssec-project.eu
Class Representation in Smali

.class public Lcom/apkudo/util/Serializer;


.super Ljava/lang/Object; Class information
.source "Serializer.java

# static fields
.field public static final TAG:Ljava/lang/String; = String Static fields

# direct methods
.method public constructor <init>()V
.registers 1

.prologue
.line 5 Methods
invoke-direct {p0}, Ljava/lang/Object;-><init>()V Direct
Virtual
return-void
.end method

[email protected] - www.syssec-project.eu
Class Representation in Smali

.class public Lcom/apkudo/util/Serializer;


.super Ljava/lang/Object; Class information
.source "Serializer.java

# static fields
.field public static final TAG:Ljava/lang/String; = String Static fields

# direct methods
.method public constructor <init>()V
.registers 1

.prologue
.line 5 Methods
invoke-direct {p0}, Ljava/lang/Object;-><init>()V Direct
Virtual
return-void
.end method

[email protected] - www.syssec-project.eu
Class Representation in Smali

.class public Lcom/apkudo/util/Serializer;


.super Ljava/lang/Object; Class information
.source "Serializer.java

# static fields
.field public static final TAG:Ljava/lang/String; = String Static fields

# direct methods
.method public constructor <init>()V
.registers 1

.prologue
.line 5 Methods
invoke-direct {p0}, Ljava/lang/Object;-><init>()V Direct
Virtual
return-void
.end method

[email protected] - www.syssec-project.eu
Class Representation in Smali

.class public Lcom/apkudo/util/Serializer;


.super Ljava/lang/Object; Class information
.source "Serializer.java

# static fields
.field public static final TAG:Ljava/lang/String; = String Static fields

# direct methods
.method public constructor <init>()V
.registers 1

.prologue
.line 5 Methods
invoke-direct {p0}, Ljava/lang/Object;-><init>()V Direct
Virtual
return-void
.end method

[email protected] - www.syssec-project.eu
Class Representation in Smali

.class public Lcom/apkudo/util/Serializer;


.super Ljava/lang/Object; Class information
.source "Serializer.java

# static fields
.field public static final TAG:Ljava/lang/String; = String Static fields

# direct methods
.method public constructor <init>()V
.registers 1

.prologue
.line 5 Methods
invoke-direct {p0}, Ljava/lang/Object;-><init>()V Direct
Virtual
return-void
.end method

[email protected] - www.syssec-project.eu
Smali Syntax Types
.method private doSomething()V
V void
Z boolean
B byte
S short
C char
F float
I int
J long
D double
[ array
[email protected] - www.syssec-project.eu
Smali Syntax Classes
Lcom/example/myapp/MyClass;

full name space slash separated


prefixed with L
suffixed with ;
StringBuilder sb = new StringBuilder(str)

new-instance v1, Ljava/lang/StringBuilder;


const-string v2, str"

invoke-direct {v1, v2}, Ljava/lang/StringBuilder;-


><init>(Ljava/lang/String;)V
[email protected] - www.syssec-project.eu
Smali Syntax Methods
.method private doSomething()V

keyword method name parameters/return

.method private delayedAnimationFrame(J)Z


.registers 8
.parameter "currentTime

# 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
[email protected] - www.syssec-project.eu
Smali Syntax Registers

.locals # registers of a method


without parameters
#parameters # input parameters +
(p0: this reference)

v0 - local 0
p0 - parameter 0 (this)
p1 - parameter 1

[email protected] - www.syssec-project.eu
Smali Syntax Opcodes

invoke-super vx, vy,


new-instance vx
invoke-direct vx, vy,
const-string vx
invoke-virtual vx, vy,
return-void

[email protected] - www.syssec-project.eu
Hacking the App
Lets inject some code in the APK:
A toast message hacked!

Java code:
Toast.makeText(getApplicationContext(),
"Hacked!", Toast.LENGTH_SHORT).show();

How do we do this in smali?


Easy, lets just compile this into another app
(e.g., MyApp2) and disassemble

[email protected] - www.syssec-project.eu
Result
Toast.makeText(getApplicationContext(),
"Hacked!", Toast.LENGTH_SHORT).show();
Java code

invoke-virtual {p0}, Lcom/example/myapp2/TestActivity;


->getApplicationContext()Landroid/content/Context;
move-result-object v1
const-string v2, "Hacked! Smali Byte code
const/4 v3, 0x0
invoke-static {v1, v2, v3}, Landroid/widget/Toast;
->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)
Landroid/widget/Toast;
move-result-object v1
invoke-virtual {v1}, Landroid/widget/Toast;->show()V

[email protected] - www.syssec-project.eu
Result
Toast.makeText(getApplicationContext(),
"Hacked!", Toast.LENGTH_SHORT).show();
Java code

invoke-virtual {p0}, Lcom/example/myapp2/TestActivity;


->getApplicationContext()Landroid/content/Context;
move-result-object v1
const-string v2, "Hacked! Smali Byte code
const/4 v3, 0x0
invoke-static {v1, v2, v3}, Landroid/widget/Toast;
->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)
Landroid/widget/Toast;
move-result-object v1
invoke-virtual {v1}, Landroid/widget/Toast;->show()V

[email protected] - www.syssec-project.eu
Result
Toast.makeText(getApplicationContext(),
"Hacked!", Toast.LENGTH_SHORT).show();
Java code

invoke-virtual {p0}, Lcom/example/myapp2/TestActivity;


->getApplicationContext()Landroid/content/Context;
move-result-object v1
const-string v2, "Hacked! Smali Byte code
const/4 v3, 0x0
invoke-static {v1, v2, v3}, Landroid/widget/Toast;
->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)
Landroid/widget/Toast;
move-result-object v1
invoke-virtual {v1}, Landroid/widget/Toast;->show()V

[email protected] - www.syssec-project.eu
Rebuilding the APK

$ apktool b ./MyApp
build out directory (produced previously)

This will instruct apktool to rebuild the app


The path to the new APK: ./Myapp/dist/Myapp.apk
But this app is not yet signed
[email protected] - www.syssec-project.eu
Signing the APK

$ keytool -genkey -v -keystore my-release-


key.keystore -alias alias_name -keyalg RSA
-validity 10000

$ jarsigner -verbose -sigalg MD5withRSA -


digestalg SHA1 -keystore my-release-
key.keystore ./MyApp/dist/MyApp.apk
alias_name

[email protected] - www.syssec-project.eu
Installing the APK

# remove it first, if it is already


installed using its package name
$ adb uninstall com.example.myapp

# then, install it
$ adb install ./MyApp/dist/MyApp.apk

[email protected] - www.syssec-project.eu
Practical Session

You have received a malicious app named


Cthulhu.apk
This app sends some sensitive information to a
malicious server
Enhance the app with a static evasion heuristic
so that it will expose its malicious activity only
when running on a device
You dont have access to the apps source code

[email protected] - www.syssec-project.eu 20
Steps to follow

a. First make Cthulhu app to display a toast


message hacked! (hint: use MyApp)

b. Patch Cthulhu app with the evasion heuristic


IMEI check (hint: use again MyApp)

c. Submit the app to an online analysis service


(e.g., Andrubis)

[email protected] - www.syssec-project.eu 21
Step a. Inject a Toast Message
ToastMessage(Hacked!)

Build

MyApp (source code) eclipse MyApp (APK) MyApp (.smali)

Cthulhu (APK) Cthulhu (.smali)

[email protected] - www.syssec-project.eu 22
Step a. Inject a Toast Message
ToastMessage(Hacked!)

Build

MyApp (source code) eclipse MyApp (APK) MyApp (.smali)

Cthulhu (APK) Cthulhu (.smali)

[email protected] - www.syssec-project.eu 22
Step a. Inject a Toast Message
ToastMessage(Hacked!)

Build

MyApp (source code) eclipse MyApp (APK) MyApp (.smali)

Cthulhu (APK) Cthulhu (.smali)

[email protected] - www.syssec-project.eu 22
Step a. Inject a Toast Message
ToastMessage(Hacked!)

Build

MyApp (source code) eclipse MyApp (APK) MyApp (.smali)

Cthulhu (APK) Cthulhu (.smali) Cthulhu (APK) +


evasion heuristic
[email protected] - www.syssec-project.eu 22
Step b. Inject an Evasion Heuristic
Same procedure as in a. but the code we want
to inject is a static VM evasion heuristic

Simply check the Build.DEVICE field to find


out if app is running on Emulator
String device = Build.DEVICE;
if (device.equals("generic")) {
String env = "Emulator";
}
else {
String env = "Device";
}

[email protected] - www.syssec-project.eu 23
Step c. Verify the repackaged app

Submit both the original and the repackaged


app on an online analysis service
(e.g., Andrubis)

Compare the produced reports

[email protected] - www.syssec-project.eu 24
HINTS & TIPS

Always ensure you have sufficient amount of


registers when patching .locals
Always fix the package name path in any
injected method call

invoke-virtual p0, Lcom/example/myapp/StartActivity;->


getApplicationContext()Landroid/content/Context;

invoke-virtual p0, Lcom/example/cthulhu/MainActivity;->


getApplicationContext()Landroid/content/Context;

[email protected] - www.syssec-project.eu 25

You might also like