A Song of Bluetooth chinese lamp & excruciating reverse engineering - Day 1

Prologue

'twas a cold november evening, and it was probably raining (or maybe it's just how I picture it now).

Christmas was fast-approaching and I learned through bad experiences that dropping hints on what family and friends could gift me would save me from awkward fake smiles and celebrations later.

One thing I thought of was one of those cloud-enabled smart bulbs that already have integrations with Amazon Alexa or Google Home. You just put the bulb in the socket, swiftly navigate through 2 or 3 web UIs and boom, you should be all set and already living in the future.

So I dropped that hint during a family dinner and my mom immediately started asking more info, but I neglected her with some brief answers. Oh boy, if only I knew what was going to happen.

Christmas night came, and with it came the time to unwrap my mom's gift. Something was off. It wasn't a bulb, it was an entire lamp, and not from a brand I knew. While opening the box I remember thinking "Please be WiFi, please be WiFi". It was Bluetooth.

Well, maybe not all hope is lost, maybe the company manufacturing these lamps is a good, well versed company. Nope, they make you download the android app from a shady website (not from Google Play).

No Alexa/Google Home integration: you can only turn it on from the app. And the app displays some random chinese ads every time I open it (which is a lot).

Maybe reverse engineering the app is easy?

Start of the downfall

Holidays were still ongoing and I still had ~6-7 free (as in not working) days left.

I decided it could be fun to no matter what it takes, go as deep in the rabbit hole as necessary to reverse engineer the app (for at least 8 hours-per-day), have my Raspberry PI that was lying around unused for more than a year control the lights and control that via a smart home assistant.

I had literally no idea on how Bluetooth communication works, so the plan also included to learn that. I guessed that learning from the app code once reversed properly was the right thing to do.

The journey started searching for reverse engineering tooling for android (I have a very basic understanding on how Android works), and I immediately found enjarify, apktool and cfr. After a round of apktool + enjarify + cfr I could already see that something was off: cfr found the main Activity to be empty and the smali only consisted of a bunch of nops.

As I was feeling the start of an headache I knew it was time to go deeper. Googling for smali tooling found baksmali. Manually baksmaling all the dex files (I was starting to doubt apktool) only found an endless and soulless list of nops in all the methods.

Was there a possibility of multiple entrypoints? Googling out and about finally led me to this page, explaining that there could be an Application class defined in the AndroidManifest, and there it was: s/h/e/l/l/S (what a peculiar name choice btw). Cfr did not work on this class (it decompiled to a bunch of nonsense), and when this news hit me I could feel my head starting to catch fire.

After a big and deep breath I dived into the S class smali with the help of the almighty reference. S calls the method ra of the class N, which is a JNI native method. N seems to load a native libexec.so, which I found under assets/ijm_lib/{armeabi, x86}. At this point my head was almost exploding.

It was 3 AM, and I was googling if somebody encountered this already and perhaps wrote something to unpack it? This paper described exactly what I was looking for, but I could not get any of that to work. I also ended up on a random chinese forum which I tried translating with Google Translate. Turns out people usually use IDA and dump the process memory to unpack this particular packer. That seemed a bit convoluted to work for me, so I decided to continue with static analysis. And also go to bed for the day.

Notes

I couldn't find the exact lamp but it comes from the same company that makes this lamp (Horevo). The app also appears to be the same from the screenshots.