Apktool is a tool 😉 for reverse engendering 3rd party, closed, binary Android *.apk files. It can decode resources to nearly original form and then also rebuild them. Rebuild them also when you provide some modifications.

I create two simple apps to try apktool and basically check how it’s work. In directory we have two apps. First: app-debug.apk and app-debug-unaligned.apk. In this case, not matter really what’s are these apps for.

andrzejdubaj  staff  4530973 22 maj 23:15 app-debug-unaligned.apk
andrzejdubaj  staff  4531823 22 maj 23:15 app-debug.apk

To use apktool simply open terminal and go to this directory where are yours app’s(app). Type:

apktool d <name_of_your_app.apk>

and press ENTER. If everything it’s ok output should be similar to this one below:

$ apktool d app-debug.apk
I: Using Apktool 2.1.1 on app-debug.apk
I: Loading resource table...
I: Decoding AndroidManifest.xml with resources...
I: Loading resource table from file: /Users/andrzejdubaj/Library/apktool/framework/1.apk
I: Regular manifest package...
I: Decoding file-resources...
I: Decoding values */* XMLs...
I: Baksmaling classes.dex...
I: Copying assets and libs...
I: Copying unknown files...
I: Copying original files...

In our directory, a new folder was created with name of the app. It contains all folders and files that are contained in the *.apk file, for example:

  • res folder
  • smali folder
  • original
  • AndroidManifest.xml
  • apktool.yml
drwxr-xr-x    7 andrzejdubaj  staff   238 22 maj 23:18 .
drwxr-xr-x    5 andrzejdubaj  staff   170 22 maj 23:18 ..
-rw-r--r--    1 andrzejdubaj  staff  3588 22 maj 23:18 AndroidManifest.xml
-rw-r--r--    1 andrzejdubaj  staff   394 22 maj 23:18 apktool.yml
drwxr-xr-x    4 andrzejdubaj  staff   136 22 maj 23:18 original
drwxr-xr-x  137 andrzejdubaj  staff  4658 22 maj 23:18 res
drwxr-xr-x    4 andrzejdubaj  staff   136 22 maj 23:18 smali

From now ok we can:

  • analyze code
  • create modes

After we perform some edits, we can build our app. For this purpose I create separate folder and copy there decompile folder with all my changes:

total 0
drwxr-xr-x  3 andrzejdubaj  staff  102 23 maj 21:55 .
drwxr-xr-x  6 andrzejdubaj  staff  204 23 maj 21:54 ..
drwxr-xr-x  7 andrzejdubaj  staff  238 22 maj 23:18 app-debug

To build application, we can use:

apktool b <name_of_your_app.apk>

We can get something like that:

$ apktool b app-debug/
I: Using Apktool 2.1.1
I: Checking whether sources has changed...
I: Smaling smali folder into classes.dex...
I: Checking whether resources has changed...
I: Building resources...
I: Building apk file...
I: Copying unknown files/dir...

But I can’t get any *.apk file. But also at that point I was wrong. Why ? Because default directory for output file is:

... /app/app-01/app-debug/dist

Top build and receive *.apk file in the same catalog use:

apktool b <folder_name> -o <file_name.apk>

If everything it’s ok output should be similar to this one below:

$ apktool b app-debug -o apk-debug.apk
I: Using Apktool 2.1.1
I: Checking whether sources has changed...
I: Checking whether resources has changed...
I: Building apk file...
I: Copying unknown files/dir...

Now we can so that our new *.apk file is in the same directory like rest of files:

-rw-r--r--  1 andrzejdubaj  staff  4512866 23 maj 22:13 apk-debug.apk
drwxr-xr-x  9 andrzejdubaj  staff      306 23 maj 21:57 app-debug
drwxr-xr-x  9 andrzejdubaj  staff      306 23 maj 22:07 app-debug-unaligned

But sometimes command described before really don’t work, and you can receive similar android Exception:

I: Checking whether sources has changed...
I: Checking whether resources has changed...
I: Building resources...
Exception in thread "main" brut.androlib.AndrolibException: brut.common.BrutException: could not exec command: [aapt, p, -F, /tmp/APKTOOL3630495287059303807.tmp, -I, /home/awesomename/apktool/framework/1.apk, -S, /home/awesomename/out/./res, -M, /home/awesomename/out/./AndroidManifest.xml]
    at brut.androlib.res.AndrolibResources.aaptPackage(Unknown Source)
    at brut.androlib.Androlib.buildResourcesFull(Unknown Source)
    at brut.androlib.Androlib.buildResources(Unknown Source)
    at brut.androlib.Androlib.build(Unknown Source)
    at brut.androlib.Androlib.build(Unknown Source)
    at brut.apktool.Main.cmdBuild(Unknown Source)
    at brut.apktool.Main.main(Unknown Source)
Caused by: brut.common.BrutException: could not exec command: [aapt, p, -F, /tmp/APKTOOL3630495287059303807.tmp, -I, /home/windows/apktool/framework/1.apk, -S, /home/windows/out/./res, -M, /home/windows/out/./AndroidManifest.xml]
    at brut.util.OS.exec(Unknown Source)
    ... 7 more
Caused by: java.io.IOException: Cannot run program "aapt": error=2, No such file or directory
    at java.lang.ProcessBuilder.start(ProcessBuilder.java:1041)
    at java.lang.Runtime.exec(Runtime.java:617)
    at java.lang.Runtime.exec(Runtime.java:485)
    ... 8 more
Caused by: java.io.IOException: error=2, No such file or directory
    at java.lang.UNIXProcess.forkAndExec(Native Method)
    at java.lang.UNIXProcess.(UNIXProcess.java:135)
    at java.lang.ProcessImpl.start(ProcessImpl.java:130)
    at java.lang.ProcessBuilder.start(ProcessBuilder.java:1022)
    ... 10 more

I found soloution for that:

apktool d -f -r apkfilename.apk

-f replace previous decompiled apk’s code

-r ignore the decompiling of resources

This would prevent the resources from being decompiled, will copy the same resources when you recompile the apk.


Reference:

  1. A tool for reverse engineering Android apk files
  2. iBotPeaches/Apktool
  3. iBotPeaches/Apktool GITTER
  4. Download repository