Android ApkTool

/ AndroidJava / 没有评论 / 2051浏览

官网

https://ibotpeaches.github.io/Apktool/documentation/

Basic


First lets take a lesson into apk files. Apks are nothing more than a zip file containing resources and assembled java code. If you were to simply unzip an apk like so, you would be left with files such as classes.dex and resources.arsc.

$ unzip testapp.apk
Archive:  testapp.apk
 inflating: AndroidManifest.xml
 inflating: classes.dex
 extracting: res/drawable-hdpi/ic_launcher.png
 inflating: res/xml/literals.xml
 inflating: res/xml/references.xml
 extracting: resources.arsc

However, at this point you have simply inflated compiled sources. If you tried to view

AndroidManifest.xml

. You'd be left viewing this.

P4F0\fnversionCodeversionNameandroid*http://schemas.android.com/apk/res/androidpackageplatformBuildVersionCodeplatformBuildVersionNamemanifestbrut.apktool.testapp1.021APKTOOL

Obviously, editing or viewing a compiled file is next to impossible. That is where Apktool comes into play.

$ apktool d testapp.apk
I: Using Apktool 2.0.0 on testapp.apk
I: Loading resource table...
I: Decoding AndroidManifest.xml with resources...
I: Loading resource table from file: 1.apk
I: Regular manifest package...
I: Decoding file-resources...
I: Decoding values */* XMLs...
I: Baksmaling classes.dex...
I: Copying assets and libs...
$

Viewing

AndroidManifest.xml

again results in something much more human readable

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android" package="brut.apktool.testapp"
platformBuildVersionCode="21" platformBuildVersionName="APKTOOL" />

In addition to XMLs, resources such as 9 patch images, layouts, strings and much more are correctly decoded to source form.

Decoding


The decode option on Apktool can be invoked either from d or decode like shown below.

$ apktool d foo.jar
// decodes foo.jar to foo.jar.out folder

$ apktool decode foo.jar
// decodes foo.jar to foo.jar.out folder

$ apktool d bar.apk
// decodes bar.apk to bar folder

$ apktool decode bar.apk
// decodes bar.apk to bar folder

$ apktool d bar.apk -o baz
// decodes bar.apk to baz folder

Building


The build option can be invoked either from b or build like shown below

$ apktool b foo.jar.out
// builds foo.jar.out folder into foo.jar.out/dist/foo.jar file

$ apktool build foo.jar.out
// builds foo.jar.out folder into foo.jar.out/dist/foo.jar file

$ apktool b bar
// builds bar folder into bar/dist/bar.apk file

$ apktool b .
// builds current directory into ./dist

$ apktool b bar -o new_bar.apk
// builds bar folder into new_bar.apk

$ apktool b bar.apk
// WRONG: brut.androlib.AndrolibException: brut.directory.PathNotExist: apktool.yml
// Must use folder, not apk/jar file

Info In order to run a rebuilt application. You must resign the application. Android documentation can help with this.

Frameworks


Frameworks can be installed either from if or install-framework, in addition two parameters

Allow for a finer control over how the files are named and how they are stored.

$ apktool if framework-res.apk
I: Framework installed to: 1.apk 
// pkgId of framework-res.apk determines number (which is 0x01)

$ apktool if com.htc.resources.apk
I: Framework installed to: 2.apk 
// pkgId of com.htc.resources is 0x02

$ apktool if com.htc.resources.apk -t htc
I: Framework installed to: 2-htc.apk 
// pkgId-tag.apk

$ apktool if framework-res.apk -p foo/bar
I: Framework installed to: foo/bar/1.apk

$ apktool if framework-res.apk -t baz -p foo/bar
I: Framework installed to: foo/bar/1-baz.apk

Intermediate


Framework Files


As you probably know, Android apps utilize code and resources that are found on the Android OS itself. These are known as framework resources and Apktool relies on these to properly decode and build apks.

Every Apktool release contains internally the most up to date AOSP framework at the time of the release. This allows you to decode and build most apks without a problem. However, manufacturers add their own framework files in addition to the regular AOSP ones. To use apktool against these manufacturer apks you must first install the manufacturer framework files.

Example

Lets say you want to decode

HtcContacts.apk

from an HTC device. If you try you will get an error message.

$ apktool d HtcContacts.apk
I: Loading resource table...
I: Decoding resources...
I: Loading resource table from file: 1.apk
W: Could not decode attr value, using undecoded value instead: ns=android, name=drawable
W: Could not decode attr value, using undecoded value instead: ns=android, name=icon
Can't find framework resources for package of id: 2. You must install proper framework files, see project website for more info.

We must get HTC framework resources before decoding this apk. We pull

com.htc.resources.apk

from our device and install it

$ apktool if com.htc.resources.apk
I: Framework installed to: 2.apk

Now we will try this decode again.

$ apktool d HtcContacts.apk 
I: Loading resource table...
I: Decoding resources...
I: Loading resource table from file: /home/brutall/apktool/framework/1.apk
I: Loading resource table from file: /home/brutall/apktool/framework/2.apk
I: Copying assets and libs...

As you can see. Apktool leveraged both

1.apk

and

2.apk

framework files in order to properly decode this application.

Finding Frameworks

For the most part any apk in

/system/framework

on a device will be a framework file. On some devices they might reside in

/data/system-framework

and even cleverly hidden in

/system/app

or

/system/priv-app

. They are usually named with the naming of "resources", "res" or "framework".

Example HTC has a framework called com.htc.resources.apk, LG has one called lge-res.apk

After you find a framework file you could pull it via

adb pull /path/to/file

or use a file manager application. After you have the file locally, pay attention to how Apktool installs it. The number that the framework is named during install corresponds to the pkgId of the application. These values should range from 1 to 30. Any APK that installs itself as

127

is

0x7F

which is an internal pkgId.

Internal Frameworks

Apktool comes with an internal framework like mentioned above. This file is copied to

$HOME/apktool/framework/1.apk

during use.

Warning Apktool has no knowledge of what version of framework resides there. It will assume its up to date, so delete the file during Apktool upgrades

Managing framework files

Frameworks are stored in different places depending on the OS in question.

If these directories are not available it will default to

java.io.tmpdir

which is usually

/tmp

. This is a volatile directory so it would make sense to take advantage of the parameter

--frame-path

to select an alternative folder for framework files.

Since these locations are in sometimes hidden directories, managing these frameworks becomes a challenge. A simple helper function (added in v2.2.1) allows you to run

apktool empty-framework-dir

to empty out frameworks.

Note Apktool has no control over the frameworks once installed, but you are free to manage these files on your own.

Tagging framework files

Frameworks are stored in the naming convention of:

<id>-<tag>.apk

. They are identified by pkgId and optionally custom tag. Usually tagging frameworks isn't necessary, but if you work on apps from many different devices and they have incompatible frameworks, you will need some way to easily switch between them. You could tag frameworks by:

$ apktool if com.htc.resources.apk -t hero
I: Framework installed to: /home/brutall/apktool/framework/2-hero.apk
$ apktool if com.htc.resources.apk -t desire
I: Framework installed to: /home/brutall/apktool/framework/2-desire.apk

Then:

$ apktool d HtcContacts.apk -t hero
I: Loading resource table...
I: Decoding resources...
I: Loading resource table from file: /home/brutall/apktool/framework/1.apk
I: Loading resource table from file: /home/brutall/apktool/framework/2-hero.apk
I: Copying assets and libs...
$ apktool d HtcContacts.apk -t desire
I: Loading resource table...
I: Decoding resources...
I: Loading resource table from file: /home/brutall/apktool/framework/1.apk
I: Loading resource table from file: /home/brutall/apktool/framework/2-desire.apk
I: Copying assets and libs...

You don't have to select a tag when building apk - apktool automatically uses the same tag, as when decoding.

Smali Debugging


Warning SmaliDebugging has been marked as deprecated in 2.0.3, and removed in 2.1. Please check SmaliIdea for a debugger.

9Patch Images


Docs exist for the mysterious 9patch images here and there. (Read these first). These docs though are meant for developers and lack information for those who work with already compiled 3rd party applications. There you can find information how to create them, but no information about how they actually work.

I will try and explain it here. The official docs miss one point that 9patch images come in two forms: source & compiled.

There are problems related to the above two points.

The only solution to this problem is to easily convert between these two types. The encoder (which takes source to compiled) is built into the aapt tool and is automatically used during build. This means we only need to build a decoder which has been in apktool since

v1.3.0

and is automatically ran on all 9patch images during decode.

So if you want to modify 9patch images, don't do it directly. Use apktool to decode the application (including the 9patch images) and then modify the images. At that point when you build the application back, the source 9patch images will be compiled.

Other


FAQ


What about the -j switch shown from the original YouTube videos? Read Issue 199. In short - it doesn't exist.

Is it possible to run apktool on a device? Sadly not. There are some incompatibilities with running the aapt binary on the device. Additionally, older builds of Android have problems with java.nio.

Where can I download sources of apktool? From our Github or Bitbucket project.

Resulting apk file is much smaller than original! Is there something missing? There are a couple of reasons that might cause this.

These points might have contributed to a smaller than normal apk

There is no META-INF dir in resulting apk. Is this ok?

Yes.

META-INF

contains apk signatures. After modifying the apk it is no longer signed. You can use

-c / --copy-original

to retain these signatures. However, using

-c

uses the original

AndroidManifest.xml

file, so changes to it will be lost.

What do you call "magic apks"?

For some reason there are apks that are built using modified build tools. These apks don't work on a regular AOSP Android build, but usually are accompanied by a modified system that can read these modified apks. Apktool cannot handle these apks, therefore they are "magic".

Could I integrate apktool into my own tool? Could I modify apktool sources? Do I have to credit you?

Actually the Apache License, which apktool uses, answers all these questions. Yes you can redistribute and/or modify apktool without my permission. However, if you do it would be nice to add our contributors (brut.all, iBotPeaches and JesusFreke) into your credits but it's not required.

Where does apktool store its framework files?