Friday, February 10, 2017

Bali Impressions

  • They still have rainforests! It is one of the places where the oil palm tree monoculture has not (yet, gasp!) replaced the orignal old forest.
  • Local bell music sounds very nice.
  • There seems to be a local tape with flute and bamboo stick music that's supposed to be chill and relaxing. Our hotel played it every morning at breakfast. From 6 am. From a speaker right under my window. It woke me up reliably every morning and I hate it now. But it seems to be pretty popular in Bali anyway, I heard it in Ubud a few times.
  • If you like exotic arts, you want a wood, stone or bone sculpture from Bali.
  • It's not super cheap. If you've read one of those 'personal finance' blogs saying that 'you can afford to live abroad and it'll be cheaper than home' then, well, don't come to tourist centers of Bali.
  • It's touristy. Nusa Dua, Jimbaran and Ubud are all already rather urbanized and tourism is well established. Not for you if you're trying to get away from people. Better stay at home with your computer.
  • The people are friendly and merry. Our Uber driver was joking all the time that his eyes are not good and that he likes funny mushrooms from Lombok. We survived so it was funny in the end.
  • Did I mention the beautiful nature? Rainforest (with authentic rain as well!), sandstone cliffs, deep blue sea, reefs. And I was lucky to see a few manta rays. Majestic.
  • Food is great too. Curry and curry-like seasonings or peanut sauce is what I will remember most as local flavours and crackers, skewers and sugar peanuts is what I will remember in terms of ... shapes?

There are some downsides too:

  • Taxi mafia. Uber, on the other hand, has been a great user friendly experience.
  • Hawkers trying to push you into buying stuff you don't need. They don't worry about lying about it either.

9 / 10, would visit again

Sunday, January 29, 2017

Reverse Engineering Android APKs

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 in classes.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:

  1. Create a project in Android Studio.
  2. Convert classes.dex from the YeeLight apk into a YeeLight.jar using dex2jar.
  3. Add the YeeLight.jar to the project as dependency. This will allow you to call methods from the original APK.
  4. Build APK from the project.
  5. 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:

List of resources and tools