Instrumenting android apps: Reverse engineering and injecting code.
Gaurav Lochan
Little Eye Labs
Outline
Why?
Instrumentation
Guts of an
android app
Reverse engineering tools
Instrumentation options
Chosen approach
Why?
Little Eye Measures, Analyzes and helps Optimize app resource usage on Android
Network usage is just an aggregate number of bytes
Why?
Need granular Network stats - each endpoint/url, latency, data transferred
Considered various approaches:
VPN
Proxy
OS stats
JDWP
Instrumentation
Instrumentation
Rewriting parts of a binary (in this case, an android app)
Allows us to intercept http calls, with code-level context on each call
Works on any released app
Works on practically any android version / phones
Opens up a lot of
exciting possibilities...
Real reason - Putting my "Instrumentation engineering" degree into practice :-)
Instrumentation (2)
Two modes:
Static
Runtime
Examples:
Android TraceView
(android
.
os
.
Debug
.
startMethodTracing)
Android Instrumentation
(android
.
app
.
instrumentation)
iOS instruments
Purify (rational, now IBM)
JVM javaAgent
AspectJ
Guts of an app
Non-Code
AndroidManifest.xml
Resources
Certificates + Signatures
Other Assets
Code: classes.dx
Dex = Dalvik EXecutable format.
A custom bytecode format for android
Dalvik is the android VM (and differs from JVM)
Build Process:
compile .java code into .class files
dx converts .class files into dex representation.
All the dex's are then stored in classes.dex
Even any library code (e.g. from jars) goes in this classes.dx
Build Process
Reverse Engineering tools
Smali (JesusFreke)
Dex disassembler - also name of format.
ApkTool
Decodes resources, debug binary, repackage app
dex2jar
Converts dex to .class format
JD-GUI
Java decompiler - convert .class to .java
Androguard
ApkAnalyzer
Smali example
Smali example (2)
ApkTool
Androguard
ApkAnalyzer
Instrumentation
approaches
1- Runtime instrumentation
A regular JVM allows passing in a
java.lang.instrumentation (through the -javaAgent flag) which can transform classes at class-load.
Dalvik doesn't support that.
It supports a
ndroid.app.Instrumentation, but that has a limited set of methods, more suited for testing
2- Instrument class files
We considered modifying .class files.
JavaAssist - instrument JVM bytecode
AspectJ
Well-understood tools, but need to be done during build.
Requires a dev process change, plus our users don't always have build-level access (e.g. outsourced QA)
Tried dex2jar to convert .dex into .class, but isn't reliable
3- Instrument dex
dexpler - research project (.dex -> Jimple)
redexer - research project (OCaml, Ruby)
apkil - GSOC project (python, smali)
dex-tools - part of dex2jar (.dex ->jasmin)
None looked good enough.
Smali
Simple and popular format (used in ApkTool, ApkAnalyzer and apkil)
Active project, well supported by JesusFreke (@google)
Disassembled, modified smali code by hand, and re-packaged app, and it just worked!
Instrumenting Smali
Challenges:
Need a way to find all the calls in the app to replace
Need to do it without side-effects (e.g. register count)
Tried many failed/hacky approaches to do this (ask me later), but the Smali author pointed me to MutableMethod.
Figured out a good way to use it (with him) - and planning to clean it up and make the source available.
Voila!
Resume presentation
Instrumenting android apps: Reverse engineering and injecting code. Gaurav Lochan Little Eye Labs
Made with Slides.com
BESbswy
BESbswy
BESbswy
BESbswy