Dissecting an APK: Permissions and Dependencies

I work at CameraKit, an open source platform to provide a reliable and easy to use Camera implementation in any Android application. We were recently interested in testing an APK to see whether or not it used CameraKit. Going one step further we wanted to test if an APK requested camera permissions.

We weren’t able to find a tool like this after a quick few Google searches so we decided to make our own!

Here’s what we learned about APKs along the way.

The Approach

If you want to follow along with this article, you can download an APK from APKMirror.com and use it with all the tools below!

We first turned to the Android Studio APK inspector to see what exactly makes up an APK.

Android Studio APK Analyzer

There are a few different types of files; AndroidManifest.xml, assets, meta information, and .dex classes.

Looking into the AndroidManifest.xml file you see almost exactly what was written when the application was created: SDK and version information, and most importantly, permissions!

So that will provide the permissions, now what about dependencies? Selecting the classes.dex file expands to reveal something like this:

classes.dex

Dex files

.dex is the file extension of the byte code format read by the Android Runtime (ART). This runtime environment operates and runs the bytecode on Android devices. Dex files are not Java bytecode, but its own format with entirely different bytecode instructions. These files contain a translated version of all the code and classes of the application. Aside from the lib, classes.dex is the largest component of this APK.

Huzzah! Our package com.camerakit is there, along with all the other packages requested by the application. You can see things like Kotlin, Android Support and Java IO.

All that’s left to do is find a way to automate this process and extract those package names.

Automation

The goal of this project is to quickly analyze any APK. Opening the APK through Android Studio and manually searching the classes.dex is far from efficient.

Unzipping

After further investigation I learned that APKs are a specific type of zip-format archive file. APKs are based on the Java Archive (JAR) format that’s used to compress Java class files and resources. APKs are also signed with an SHA1 Digest and a certificate. Both of these components are contained in the META-INF directory.

With these special considerations, renaming the file to .zip and unzipping it with a standard unzip tool most likely will not work. But we tried it anyways.

The result looked promising:

unzip APK

But opening any of the files confirms our suspicion.

����������.�����������������������������(���4���L���j���������������������������4��Z�����������������������2��x��������(��l��������8������������\�������2��F��X���������������t�h�e�m�e����l�a�b�e�l����i�c�o�n����n�a�m�e���
�d�e�b�u�g�g�a�b�l�e���

Simply unzipping the package leaves the files encoded resulting in unreadable text. Another method is needed to unpack and decode the APK.

APKTool

From their GitHub:

A tool for reverse engineering 3rd party, closed, binary Android apps. It can decode resources to nearly original form and rebuild them after making some modifications. It also makes working with an app easier because of the project like file structure and automation of some repetitive tasks like building apk, etc.

APKTool does just what we wanted, unzips and decodes the APK turning the files into human readable text. Now opening the same APK with APKTool gives the following output.

APKTool output

The output includes an assets folder, and something called smali. We’ll get back to that in a second. AndroidManifest.xml is now readable and contains exactly what we saw from the Android Studio APK Analyzer.

<?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="com.example.emerson.camerakittest" platformBuildVersionCode="1" platformBuildVersionName="1.0">
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
...

Reading the permissions is as easy as loading AndroidManifest.xml and grabbing all of the <uses-permission> lines. The dependencies will take a tad more effort.

Smali

As you can see in the above screenshot, the smali and smali_classes2 folders contain the same packages we saw in the classes.dex of the Android Studio APK Analyzer. Wouldn’t you know it our com.camerakit package is right there!

What is smali? Smali is the product of running a disassembler on a .dex file. Smali is a human readable but maintains the procedural structure of the dex file format. The process of converting dex to smali is called “backsmaling” and is done with APKTool by way of this GitHub repository.

Here’s an example of a smali file.

.method public getFacing()I
.locals 1
.line 674
iget v0, p0, Lcom/camerakit/CameraKitView;->mFacing:I
return v0
.end method

If you compare it to the Java source code you can see the close resemblance for a simple function like getFacing().

@CameraKit.Facing
public int getFacing() {
return mFacing;
}

However the contents of the smali file are not important for this project. All we need is the names of the folders, formatted as com.camerakit. This can be achieved by traversing through the folder structure, saving the names of the above directories to create one final package name. The package name is made up of all the directories that came before the folder containing smali files, which is most often the final name of the package.

For example the structure:

Turns into:

androidx.versionedparcelable
com.camerakit

APK Inspector

With access to both the permissions and packages used by the application, we created a command line tool APK Inspector to wrap it all up.

The main function is to run APKTool on a specified APK to reveal AndroidManifest.xml as well as the smali folders. From here, APK Inspector searches through AndroidManifest.xml for permissions and outputs them to the console. Then our program recursively iterates over the smali folders, concatenating the folder names into package names.

There are some basic options for the tool that you can see on the README. One can output permissions only, dependencies, or search for a specific permission or dependency.

Future Improvement

This is only the first draft of the project and I’m looking to keep making improvements to increase the speed and functionality. We’re open to feedback and love to hear your ideas, but we plan to refine APK Inspector to our own needs as we go forward.

As we continue to development, keep your eye out for more blog posts on the topic of APKs, how to deconstruct them, and possibly even other application formats.

Thanks for reading!