limkopi ☕️

security | dev | finance | life

github instagram
Attempting to Reverse Engineer The SJCAM Android App
May 25, 2019
6 minutes read

Last year, I bought SJCAM SJ4000 (with WIFI), a China-manufactured action camera, to use during my overseas trip.

There are three ways you can download your videos on the camera:

  • Download through a physical wire to your PC
  • Download through a card reader from the micro-SD card
  • Download through the SJCAM app on your phone via WIFI

I opted for the 3rd option because I didn’t have a convenient way of connecting my camera to the Macbook (meh). The app is downloaded from Google Play Store and I’m always very curious to know what are the data that are regularly sent to the Chinese companies.

Android Application Package (APK)

An APK is the package file format used by Android operating system. It contains all the necessary files to run the Android application on the OS.

How APK is created?

Android programs are commonly written in Java. Once done, all the Java code files will be compiled into Java byte code (.class) files. These will be converted into Dalvik executable (classes.dex) in order to execute on Android system. Android system will compiled classes.dex into an OAT file, which stores the native machine code to execute in the Android RunTime system.

Eack APK file is generated from DEX files and several resources such as AndroidManifest.xml and various other media files. The AndroidManifest file contains the essential information about the application. For instance, it describes the components of the application and determine all the permissions that are needed to run the application.

This information is important to help us understand what we will be looking at when we decompressed the APK later on.

Obtaining the SJCAM SJ4000 APK

I have wiped out all my applications when I rooted my phone last week. I didn’t want to install SJCAM again so I decided to get from a 3rd party app store. I googled for 3rd party app store and downloaded the SJCAM app from the top result.

If you have a rooted phone, you can extract the applications from /data/app. You can find the binary in each sub-folder in the directory.

Extracting the Necessary Files

The very first thing that I will do to a special file is to use Linux’s file to identify the the binary’s format. It turns out that an APK is a zip-archive data, which can be unzipped easily using any unzip tools.

➜  Android file SJCAMZone.apk
SJCAMZone.apk: Zip archive data, at least v2.0 to extract

This makes our life a lot easier. I used 7z x SJCAM Zone.apk to extract all the files into a folder.

As expected, we are able to extract classes.dex and AndroidManifest.xml from the APK. AndroidManifest.xml is encrypted (as expected) and we need to decrypt the file to gain a quicker insights into this package.

This step is necessary if we want to read the decompiled Java codes.

Disassemble the APK

Let’s try our luck if we can disassemble the APK files automatically. This step helps to obtain a decrypted AndroidManifest.xml file. I will use apktool to disassemble the APK files so that we can extract a decrypted AndroidManifest.xml file.

➜  Android ./apktool d SJCAMZone.apk --output apk_SJCAM
I: Using Apktool 2.4.0 on SJCAMZone.apk
I: Loading resource table...
I: Decoding AndroidManifest.xml with resources...
S: WARNING: Could not write to (/Users/dorbee/Library/apktool/framework), using /var/folders/15/h6wtvct55w780g_24l6h_fnm0000gn/T/ instead...
S: Please be aware this is a volatile directory and frameworks could go missing, please utilize --frame-path if the default storage directory is unavailable
I: Loading resource table from file: /var/folders/15/h6wtvct55w780g_24l6h_fnm0000gn/T/1.apk
I: Regular manifest package...
I: Decoding file-resources...
I: Decoding values */* XMLs...
I: Baksmaling classes.dex...
I: Baksmaling classes2.dex...
I: Baksmaling classes3.dex...
I: Copying assets and libs...
I: Copying unknown files...
I: Copying original files...

I’m really lucky that I didn’t encounter any errors for this! If you encounter errors using apktool, your best bet is to use the extracted classes.dex, convert into jar file and decompile into the soure codes.

Let’s try to understand more about the APK using AndroidManifest.xml.

Exploring AndroidManifest.xml

First of all, we need to take note of the package that we need to study later on. The name of the package org.jght.sjcam.zone is found in the header of the XML file.

<?xml version="1.0" encoding="utf-8" standalone="no"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" android:compileSdkVersion="28" android:compileSdkVersionCodename="9" package="org.jght.sjcam.zone" platformBuildVersionCode="9890" platformBuildVersionName="5.5.8">

Apart from normal Android permissions, I realised that SJCAM is requesting permission to use JPUSH SDK (by a China big data analytics company). I might remember wrongly but I didn’t remember that I was asked if I want to send my usage data to that company.

<permission android:name="org.jght.sjcam.zone.permission.JPUSH_MESSAGE" android:protectionLevel="signature"/>
<uses-permission android:name="org.jght.sjcam.zone.permission.JPUSH_MESSAGE"/>

Apparently, it is using something from Tencent as we can seen in the activity below:

<activity android:name="com.tencent.bugly.beta.ui.BetaActivity" android:theme="@android:style/Theme.Translucent"/>

Using my limited Chinese, it seems like Tencent has provided a SDK for developers to use for crash analysis. This is probably equivalent to Google’s crashlytics.com.

MyWrapperProxyApplication

Something caught my eyes when I was exploring the manifest file.

<application android:allowBackup="true" android:appComponentFactory="android.support.v4.app.CoreComponentFactory" android:configChanges="orientation|screenLayout|screenSize" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:name="MyWrapperProxyApplication" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme">

There is only one file in the smali folder - MyWrapperProxyApplication.smali. And this probably means that we are dealing with a packed APK.

Decompile classes.dex to source code

To confirm our findings, let’s try to decompile the dex files into source code. We will need to use dex2jar to convert dex into jar.

$ dex2jar-2.0 ./d2j-dex2jar.sh ../SJCAM\ Zone/classes.dex -o SJCAM_dex2jar.jar
dex2jar ../SJCAM Zone/classes.dex -> SJCAM_dex2jar.jar

Next, we use JD-GUI to decompile jar file into source codes. It’s not difficult to realise that org.jght.sjcam.zone has too little source files.

We can find that the WrapperProxyApplication.class is using a Util class to do something.

Digging into the Util.class shows that it is using libtosprotection.so, which is developed by Tencent (腾讯御安全) to pack the app.

Unpacking?

We can extract the unpacked DEX codes from the memory when the app is running on a rooted phone. After that, we can convert the machine codes to jar and potentially decompile that into source codes.

This requires a rooted phone as we need to access the process files (e.g. /proc/) to find out the base address of the running application. We will also need to find out the length and the offset of the source codes in the memory from the base address.

I decided to stop here because I didn’t want to install the app on my phone anymore. And… I’m not very sure if I really want to meddle with my phone’s memory as this is my personal phone.

Closing Thoughts

In general, it is not difficult to decompile android apps… well it’s not unless it is packed with a commercial packer.

Perhaps I will attempt to write a tool (or find one) to extract the codes from the memory next time when I have a new phone to replace my current phone.

For now, I shall halt my attempts and proceed to my next target.


category: security

Back to posts