Sitemap

How Reverse Engineering Saved Me ~87% Cost on Car Mods!

8 min readFeb 10, 2024

--

Disclaimer: The information provided is intended for educational purposes only. It should not be considered as professional advice or used for any commercial purposes. Users are encouraged to conduct their own research and consult with relevant experts before making any decisions based on the content provided.

Introduction: A Lazy Saturday Discovery

August 5th, 2023, a lazy Saturday. There I was, casually swiping through YouTube shorts, procrastinating like a pro.

and came across a video

Research and Purchase: From Google to Amazon

As an economical car owner, this intrigued me, and I was keen to make the purchase. So, I Googled “Wrumer Sound Buy” and found the website.e

Press enter or click to view image in full size

It costs around $40, but before making the purchase, I wanted to grasp how it actually operates. Upon opening the “How it works” section, here’s what I found:

Press enter or click to view image in full size

I came to understand that it utilizes something called an “OBD2” reader, which sends the RPM value to the app. Based on this data, the app plays the corresponding rev sound. However, it was the last section, “Also works with other similar apps,” that really grabbed my attention. I couldn’t help but think, “If this OBD2 hardware is compatible with other apps, then perhaps other OBD2 readers might also be compatible with this app.”

I jumped onto Amazon.in and searched for “OBD2 reader,” and voila!

Press enter or click to view image in full size

Yes, it only cost ₹411, which is roughly $4.95. That’s like ~87% cheaper! Without a second thought, I placed the order and received it within three days.

Installation Woes: The Excitement and Disappointment

Press enter or click to view image in full size

Excitedly, I installed the app on my phone and dashed to my car with the newly acquired, budget-friendly OBD2 reader in hand.

I found the OBD2 port, connected the device, and saw a LED light blinking. Excitedly, I opened the app and pressed the “CONNECT” button, but it didn’t connect. 😔

Press enter or click to view image in full size

Code Investigation: Unraveling the React Native App

I returned to my desk, pondering, “Why didn’t it work? 🤔 There must be something going on inside the app. 🤨” Turning to my trusted ally, Stackzy, I delved into its depths to uncover the mystery, and bam!.

Press enter or click to view image in full size

Yep, the lazy me skipped out on implementing React Native support, and now it’s come back to haunt me. But hey, every cloud has a silver lining! Now that I know it’s built using React Native, all the logic will be tucked away in a JavaScript file, which is a good news 💖

I clicked on the top right <> button to see the code

Modification Attempt: Modifying the App

Press enter or click to view image in full size

The red part is something I don’t have to focus on. Since this is a React Native app, the “Resources” directory holds most of the interesting stuff.

I delved into the structure and stumbled upon an intriguing extension, .bank. After a bit of Googling, I discovered that .bank files are essentially adaptive audio files generated by a software called FMOD Studio, commonly used in video games. I figured this was likely used for the rev sound, so I brushed it off.

Then, there it was, the infamous index.android.bundle, housing the brain of the app. I opened it up, unminified, and copied the ~50k lines of JavaScript into VSCode for easier reading.

Press enter or click to view image in full size

With approximately 50k lines, going through them line by line was out of the question. So, I opted to use the search function, looking for the title of the connect button, which was “Click to Connect.”

Press enter or click to view image in full size
Press enter or click to view image in full size

“Yes, there it is!”! I renamed the function from w() to getButtonTitle() to make it easier to read. From there, I navigated back upwards and stumbled upon many interesting discoveries along the way.

Press enter or click to view image in full size

I noticed a variable called t holding most of the state, which led me to believe it must be the core state holder. I decided to rename it to state. Then, I focused on the first variable, connected, to pinpoint the “write” spot.

Press enter or click to view image in full size

There it is! Found the “write” spot!

Below that, I noticed the property connect, which accepts a function, and inside that function, I found the BLE scan spot.

Press enter or click to view image in full size

Here, the startDeviceScan function initiates a call to the native layer (iOS/Android), while the function geappears to be the callback responsible for holding the business logic. Upon further inspection of the ge function, I discovered this:

Press enter or click to view image in full size

The condition looked interesting.

  • If n has a name (n.name), and if that name is "OBDII", it calls a function me with the n parameter and then stops device scanning (b.stopDeviceScan()).
  • It also checks if a variable y is truthy and if n's name is "VEEPEAK". If both conditions are true, it calls the me function with the n parameter and stops device scanning (b.stopDeviceScan()).

Overall, this function seems to be handling device scanning and logging messages related to device detection, with specific actions taken based on the names of detected devices.

Get theapache64’s stories in your inbox

Join Medium for free to get updates from this writer.

The string “OBD11” is familiar, but what is “VEEPEAK”? Curiosity piqued, I turned to Google and uncovered this:

Press enter or click to view image in full size

Ohh, it’s an OBD scanner, and it seems the Wrumer OBD scanner is likely just a rebranded version of the same hardware.

I thought, why not just hardcode these conditions to true, which would accept all devices? Then, I could replace the original index.android.bundle file with my version and repackage the APK.

I replaced the name check condition with true, and here’s how the ge function looks now:

Press enter or click to view image in full size

I saved the file on my desktop as index.android.bundle and reopened Stackzy to retrieve the APK.

Press enter or click to view image in full size

I clicked on the 📁 icon to get the source APK file we previously decompiled

Press enter or click to view image in full size

Got it! Now it’s time to edit the APK. While I could repackage it manually, that would take some time, so I opted for APK Editor Studio.

First, I replaced the original bundle file with the modified one.

Press enter or click to view image in full size

Next, I changed the title to “Wrumer Mod” to make it easier to distinguish from the original app. Then, I uninstalled the original version from my phone and pressed the “Install” button (see below).

Press enter or click to view image in full size

and its done Done ✅

Crash Landing: Learning from Mistakes

I opened the app, expecting greatness, but all I got was a crash landing. Looks like my coding escapades took a nosedive!

Press enter or click to view image in full size

Ah, this crash is all too familiar to me from work! 😄 It’s like when you’re missing a puzzle piece — in this case, the split APKs. I only installed the main APK, forgetting about its companions. Time for a reinstallation from the PlayStore to grab both the main and split APKs.

Split APK Revelation: Navigating Through Logcat

Now comes the million-dollar question: where’s this split APK located? Well, there’s a neat little trick for that. Just open the app and check out Logcat.

Press enter or click to view image in full size

I saw that the app is trying to access a particular directory for Wrumer app resources, ie

/data/app/~~mozoli-cFdyGFTFwo17onw==/com.wrumer.wrumerapp-SitkcCXofoehaOQQZNLtzA==/

I cd -ed into it and ls -l showed this

Press enter or click to view image in full size

Yes. The split APKs have been located. Here we need the main split APK ie, “split_config.arm64_v8a.apk”, and I now I know the full path. So I exited adb shell and executed

adb pull /data/app/~~mozoli-cFdyGFTFwo17onw==/com.wrumer.wrumerapp-SitkcCXofoehaOQQZNLtzA==/split_config.arm64_v8a.apk

This copies the split APK to the computer and all we need to do is sign with the same key. To do this, I used “Sign External APK” of APK Editor Studio

Press enter or click to view image in full size
Press enter or click to view image in full size

Successful Installation: Victory Lap

Now that we have a signed main APK and a signed split APK, it’s time to install them together. To do this, I used theadb install-multiple command.

Press enter or click to view image in full size

And voila! No more crashy-crashy for the app! 🎉

Press enter or click to view image in full size

Excited me dashed to the car this time! And let me tell you, it was pure magic. 🚗✨

Press enter or click to view image in full size

Conclusion: Another Tech Triumph

With the app finally sorted out, I couldn’t wait to give it a spin. Excitedly, I hopped into my car, fired up the engine, and tapped on the screen. And you know what? It worked like a charm! The revs kicked in, synced perfectly with my ride. It was one of those moments where you just sit back and go, “Yep, that’s how it’s done.” So, off I went, cruising down the road with a big grin on my face. Another day, another tech victory 😜

Hardware Performance: Budget vs. Original

The cheap OBD2 reader saved costs, but it came with a slight delay sometimes. Opting for authentic hardware may provide better results. While the cheaper option worked fine for me, users who prioritize performance might benefit from investing in the original Wrumer hardware for a smoother experience, although I haven’t tried it myself.

I know what you’re thinking now

I know, I know — the time I spent probably cost more than what I saved. But hey, sometimes, the fun of figuring things out is priceless! IYKYK

--

--