Although I've never actually written any Android app, I've been playing around with its internals a bit. I own a phone that has CyanogenOS by default (that's already history), of course I've rooted it as well as bricking my previous phone during ROM changes.
I also tried reversing some android apps with various degrees of success. My main project was 'hacking' the Xiaomi YeeLight bedside lamp app to be able to control it programatically. Xiaomi did not provide any API but if I can modify the APK to accept commands, that's all I need.
Here are the slides for a talk I gave about basic reverse engineering in Codeaholics Hong Kong meeting. After that you can find some more details about the YeeLight case.
Roadblocks
- obfuscation (great against getting a general view but not if I'm targeting one specific thing)
- anti-decompilers (can be always bypassed)
- anti-debuggers (can also be bypassed)
- time investment (can not be bypassed)
.apk contents
- Java code compiled to
smali
register VM, saved all inclasses.dex
AndroidManifest.xml
in some kind of binary form- native machine libraries
.so
(ARM, x86, ..) - resources
smali
- Icelandic "assembler"
- register based, as opposed to standard JVM stack-based
- closer to the CPU, less work for JIT compiler
- reasonably readable
const-string v5, "UTF8"
invoke-static {p0, v3, v4, v5}, Lcom/google/zxing/client/result/optional/NDEFURIResultParser;->bytesToString([BIILjava/lang/String;)Ljava/lang/String;
move-result-object v2
decompiled
- no variable names (unless debug symbols)
try/catch
blocks often broken- usually can't use Java compiler to put it back together
- obfuscation -> all methods and classes are now named alphabetically (
cd.i(a, b, c, d)
)
BCV front-end
- Makes it easy to run decompilers on
.dex
or.jar
- still not quite there for more in-depth analysis
- so I use ... a text editor!
- decompile everything to
.java
, put in git and write comments
Patching APKs
- Example: YeeLight
- write a new class in Android Studio (add
YeeLight.jar
to project) - compile to
.smali
- add the smali to already extracted
apk folder/smali
modify
.smali
files to construct and invoke the new class- rebuild using
apktool
- sign
- zipalign
- Install on your device!
Working on the YeeLight app
This app is obfuscated and, quite honestly, contains a lot of code. It has a screen with a colour gradient where touching the colour would change the light color accordingly. I started by finding this Activity
and trying to find the click handler. I planned to go deeper and eventually end up in the code that's sending Bluetooth commands but I got lost.
Then I tried to watch the logcat
while using the app and found that the colour changes are being echoed in the log. One code search for this particular string got me into a class that was fully obfuscated but probably was somewhere on the way to sending the commands. Further reading the decompiled code revealed a consumer for these messages as well as conversion from a colour object to the Bluetooth message.
The next step was to write a network listener class in Java. It would run in its own thread and accept UDP packets sent to the broadcast address. Each colour change requires only 4 bytes of data so UDP is the simplest choice. Broadcast address is used to avoid needing any configuration - I can just send it out on my home network.
This Java code now needs to be converted to a .smali
file. There are tools that should be able to convert it directly from a .class
or a .jar
but at that time, they did not work. So I ended up creating a dummy Android project in Android Studio to achieve the same result:
- Create a project in Android Studio.
- Convert
classes.dex
from the YeeLight apk into aYeeLight.jar
usingdex2jar
. - Add the
YeeLight.jar
to the project as dependency. This will allow you to call methods from the original APK. - Build APK from the project.
- Use
apktool
to disassemble the result, obtaining a.smali
file for your class.
Now you can add this new .smali
file to the original APK. You also need to actually create an instance and call this new code in an appropriate place. That requires manually editing the existing .smali
code of the app. If you can find where, it's not too difficult.
Finally, rebuild the APK using apktool
, zip-align and sign it. This process is a bit more complicated than it should be so I have a little script for it right here: My Apk Scripts
Now you can install the app and try it out. If it works, you may want to disable updates for it otherwise the Play store will overwrite your efforts.
With a custom plugin for Kodi that sends the colour commands over UDP, the result is this:
This comment has been removed by the author.
ReplyDeleteThis comment has been removed by the author.
ReplyDeleteThis is such a great resource that you are providing and you it away for free. I love seeing blog that understand the value. Im glad to have found this post as its such an interesting one! I am always on the lookout for quality posts and articles so i suppose im lucky to have found this! I hope you will be adding more in the future...
ReplyDeleteBest Golf Rangefinder
The article was up to the point and described the information very effectively. Thanks to blog author for wonderful and informative post.
ReplyDeletetell the bell
This is highly informatics, crisp and clear. I think everything has been described in systematic manner so that reader could get maximum information and learn many things.
ReplyDeleteClick Here
The article was up direct and depicted the data viably.
ReplyDeletekrogerfeedback
This one is good. keep up the good work!..
ReplyDeletemcdvoicee.site
The most important element we want is the fee receipt that the patron must have with him.
ReplyDeleteClick here Tellthebell