
Androguard is a full python tool to play with Android files. It is designed to work with Python 3 only.
- DEX, ODEX
- APK
- Android’s binary XML
- Android resources
- Disassemble DEX/ODEX bytecodes
- Decompiler for DEX/ODEX files
You can either use the CLI or graphical frontend for androguard, or use androguard purely as a library for your own tools and scripts.
Authors: Androguard Team
Androguard + tools: Anthony Desnos (desnos at t0t0.fr).
DAD (DAD is A Decompiler): Geoffroy Gueguen (geoffroy dot gueguen at gmail dot com)
Installation
There are several ways how to install androguard.
Before you start, make sure you are using a supported python version! For Windows, we recommend using the Anaconda python 3.6.x package.
Warning: The magic library might not work out of the box. If your magic library does not work, please refer to the installation instructions of python-magic.
PIP
The usual way to install python packages is by using pypi.python.org and it’s package installer pip. Just use:
$ pip install -U androguard[magic,GUI]
to install androguard including the GUI and magic file type detection. In order to use features that use dot
, you need Graphviz installed. This is not a python dependency but a binary package! Please follow the installation instructions for GraphvizInstall.
You can also make use of an virtualenv, to separate the installation from your system-wide packages:
$ virtualenv venv-androguard
$ source venv-androguard/bin/activate
$ pip install -U androguard[magic,GUI]
pip should install all required packages too.
Debian / Ubuntu
Debian has androguard in its repository. You can just install it using apt install androguard
. All required dependencies are automatically installed.
Install from Source
Use git to fetch the sources, then install it. Please install git and python on your own. Androguard requires Python at least 3.4 to work. Pypy >= 5.9.0 should work as well but is not tested.
$ git clone --recursive https://github.com/androguard/androguard.git
$ cd androguard
$ virtualenv -p python3 venv-androguard
$ source venv-androguard/bin/activate
$ pip install .[magic,GUI]
The dependencies, defined in setup.py
will be automatically installed.
For development purposes, you might want to install the extra dependencies for docs and tests as well:
$ git clone --recursive https://github.com/androguard/androguard.git
$ cd androguard
$ virtualenv -p python3 venv-androguard
$ source venv-androguard/bin/activate
$ pip install -e .[magic,GUI,tests,docs]
You can then create a local copy of the documentation:
$ python3 setup.py build_sphinx
Which is generated in build/sphinx/html
.
Getting Started
Using Androguard tools
There are already some tools for specific purposes.
To just decode the AndroidManifest.xml or resources.arsc, there are androguard axml and androguard arsc. To get information about the certificates use androguard sign.
If you want to create call graphs, use androguard cg, or if you want control flow graphs, you can use androguard decompile.
Using Androlyze and the python API
The easiest way to analyze APK files is by using androguard analyze
. It will start an iPython shell and has all modules loaded to get into action.
For analyzing and loading APK or DEX files, some wrapper functions exist. Use AnalyzeAPK(filename)
or AnalyzeDEX(filename)
to load a file and start analyzing it. There are already plenty of APKs in the androguard repo, you can either use one of those or start your own analysis.
$ androguard analyze
Androguard version 3.1.1 started
In [1]: a, d, dx = AnalyzeAPK("examples/android/abcore/app-prod-debug.apk")
# Depending on the size of the APK, this might take a while...
In [2]:
The three objects you get are a
an APK
object, d
an array of DalvikVMFormat
object and dx
an Analysis
object.
Inside the APK
object, you can find all information about the APK, like the package name, permissions, the AndroidManifest.xml, or its resources.
The DalvikVMFormat
corresponds to the DEX file found inside the APK file. You can get classes, methods, or strings from the DEX file. But when using multi-DEX APK’s it might be a better idea to get those from another place. The Analysis
object should be used instead, as it contains special classes, which link information about the classes.dex and can even handle many DEX files at once.
Getting Information about an APK
If you have successfully loaded your APK using AnalyzeAPK
, you can now start getting information about the APK.
For example, getting the permissions of the APK:
In [2]: a.get_permissions()
Out[2]:
['android.permission.INTERNET',
'android.permission.WRITE_EXTERNAL_STORAGE',
'android.permission.ACCESS_WIFI_STATE',
'android.permission.ACCESS_NETWORK_STATE']
or getting a list of all activities, which are defined in the AndroidManifest.xml:
In [3]: a.get_activities()
Out[3]:
['com.greenaddress.abcore.MainActivity',
'com.greenaddress.abcore.BitcoinConfEditActivity',
'com.greenaddress.abcore.AboutActivity',
'com.greenaddress.abcore.SettingsActivity',
'com.greenaddress.abcore.DownloadSettingsActivity',
'com.greenaddress.abcore.PeerActivity',
'com.greenaddress.abcore.ProgressActivity',
'com.greenaddress.abcore.LogActivity',
'com.greenaddress.abcore.ConsoleActivity',
'com.greenaddress.abcore.DownloadActivity']
Get the package name, app name, and path of the icon:
In [4]: a.get_package()
Out[4]: 'com.greenaddress.abcore'
In [5]: a.get_app_name()
Out[5]: u'ABCore'
In [6]: a.get_app_icon()
Out[6]: u'res/mipmap-xxxhdpi-v4/ic_launcher.png'
Get the numeric version and the version string, and the minimal, maximal, target and effective SDK version:
In [7]: a.get_androidversion_code()
Out[7]: '2162'
In [8]: a.get_androidversion_name()
Out[8]: '0.62'
In [9]: a.get_min_sdk_version()
Out[9]: '21'
In [10]: a.get_max_sdk_version()
In [11]: a.get_target_sdk_version()
Out[11]: '27'
In [12]: a.get_effective_target_sdk_version()
Out[12]: 27
You can even get the decoded XML for the AndroidManifest.xml:
In [15]: a.get_android_manifest_axml().get_xml()
Out[15]: '<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="2162" android:versionName="0.62" package="com.greenaddress.abcore">\n<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="27">\n</uses-sdk>\n<uses-permission android:name="android.permission.INTERNET">\n</uses-permission>\n<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE">\n</uses-permission>\n<uses-permission android:name="android.permission.ACCESS_WIFI_STATE">\n</uses-permission>\n<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE">\n</uses-permission>\n<application android:theme="@7F0F0006" android:label="@7F0E001D" android:icon="@7F0D0000" android:debuggable="true" android:allowBackup="false" android:supportsRtl="true">\n<activity android:name="com.greenaddress.abcore.MainActivity">\n<intent-filter>\n<action android:name="android.intent.action.MAIN">\n</action>\n<category android:name="android.intent.category.LAUNCHER">\n</category>\n</intent-filter>\n</activity>\n<service android:name="com.greenaddress.abcore.DownloadInstallCoreIntentService" android:exported="false">\n</service>\n<service android:name="com.greenaddress.abcore.RPCIntentService" android:exported="false">\n</service>\n<service android:name="com.greenaddress.abcore.ABCoreService" android:exported="false">\n</service>\n<activity android:name="com.greenaddress.abcore.BitcoinConfEditActivity">\n<intent-filter>\n<category android:name="android.intent.category.DEFAULT">\n</category>\n<action android:name="com.greenaddress.abcore.BitcoinConfEditActivity">\n</action>\n</intent-filter>\n</activity>\n<activity android:name="com.greenaddress.abcore.AboutActivity">\n</activity>\n<activity android:label="@7F0E0038" android:name="com.greenaddress.abcore.SettingsActivity" android:noHistory="true">\n</activity>\n<activity android:label="@7F0E0035" android:name="com.greenaddress.abcore.DownloadSettingsActivity" android:noHistory="true">\n</activity>\n<activity android:theme="@7F0F0006" android:label="@7F0E0036" android:name="com.greenaddress.abcore.PeerActivity">\n</activity>\n<activity android:theme="@7F0F0006" android:label="@7F0E0037" android:name="com.greenaddress.abcore.ProgressActivity">\n</activity>\n<activity android:name="com.greenaddress.abcore.LogActivity">\n</activity>\n<activity android:name="com.greenaddress.abcore.ConsoleActivity">\n</activity>\n<activity android:name="com.greenaddress.abcore.DownloadActivity">\n</activity>\n<receiver android:name="com.greenaddress.abcore.PowerBroadcastReceiver">\n<intent-filter>\n<action android:name="android.intent.action.ACTION_POWER_CONNECTED">\n</action>\n<action android:name="android.intent.action.ACTION_POWER_DISCONNECTED">\n</action>\n<action android:name="android.intent.action.ACTION_SHUTDOWN">\n</action>\n<action android:name="android.intent.action.ACTION_BATTERY_LOW">\n</action>\n<action android:name="android.net.wifi.STATE_CHANGE">\n</action>\n</intent-filter>\n</receiver>\n</application>\n</manifest>\n'
Or if you like to use the AndroidManifest.xml as an ElementTree object, use the following method:
In [13]: a.get_android_manifest_xml()
Out[13]: <Element manifest at 0x7f9d01587b00>
There are many more methods to explore, just take a look at the API for APK
.
Using the Analysis object
The ~androguard.core.analysis.analysis.Analysis
the object has all information about the classes, methods, fields and strings inside one or multiple DEX files.
Additionally, it enables you to get call graphs and crossreferences (XREFs) for each method, class, field and string.
This means you can investigate the application for certain API calls or create graphs to see the dependencies of different classes.
As a first example, we will get all classes from the Analysis:
In [2]: dx.get_classes()
Out[2]:
[<analysis.ClassAnalysis Ljava/io/FileNotFoundException; EXTERNAL>,
<analysis.ClassAnalysis Landroid/content/SharedPreferences; EXTERNAL>,
<analysis.ClassAnalysis Landroid/support/v4/widget/FocusStrategy$BoundsAdapter;>,
<analysis.ClassAnalysis Landroid/support/v4/media/MediaBrowserCompat$MediaBrowserServiceCallbackImpl;>,
<analysis.ClassAnalysis Landroid/support/transition/WindowIdImpl;>,
<analysis.ClassAnalysis Landroid/media/MediaMetadataEditor; EXTERNAL>,
<analysis.ClassAnalysis Landroid/support/v4/app/BundleCompat$BundleCompatBaseImpl;>,
<analysis.ClassAnalysis Landroid/support/transition/MatrixUtils$1;>,
<analysis.ClassAnalysis Landroid/support/v7/widget/ShareActionProvider;>,
...
As you can see, get_classes()
returns a list of ClassAnalysis
objects. Some of them are marked as EXTERNAL, which means that the source code of this class is not defined within the DEX files that are loaded inside the Analysis. For example the first class java.io.FileNotFoundException
is an API class.
A ClassAnalysis
does not contain the actual code but the ClassDefItem
can be loaded using theget_vm_class()
:
In [5]: dx.get_classes()[2].get_vm_class()
Out[5]: <dvm.ClassDefItem Ljava/lang/Object;->Landroid/support/v4/widget/FocusStrategy$BoundsAdapter;>
If the class is EXTERNAL, a ExternalClass
is returned instead.
The ClassAnalysis
also contains all the information about XREFs, which are explained in more detail in the next section.
XREFs
Consider the following Java source code:
class Foobar {
public int afield = 23;
public void somemethod() {
String astring = "hello world";
}
}
class Barfoo {
public void othermethod() {
Foobar x = new Foobar();
x.somemethod();
System.out.println(x.afield);
}
}
There are two classes and the class Barfoo
instantiates the other class Foobar
as well as calling methods and reading fields.
XREFs are generated for four things:
- Classes
- Methods
- Fields
- Strings
XREFs work in two directions: xref_from and xref_to. To means, that the current object is calling another object. From means, that the current object is called by another object.
All XREFs can be visualized as a directed graph and if some object A
is contained in the xref_to
, the called object will contain A
in their xref_from
.
In the case of our Java example, the string astring
is called in Foobar.somethod
, therefore it will be contained in the xref_to
of Foobar.somethod
.
The Field afield
will be contained in the xref_to
of Barfoo.othermethod
as well as the call to Foobar.somethod
.
More on XREFs can be found in xrefs.
Documentation
Find the documentation for master on ReadTheDocs.
There are some (probably broken/outdated) examples and demos in the folders demos and examples.
Projects using Androguard
In alphabetical order
- AndroPyTool
- AppKnox
- Cuckoo Sandbox
- Deckard
- Droidbot
- Droidstatx
- εxodus
- F-Droid Server
- gplaycli
- Koodous
- MobSF
- qiew
- Quark-Engine
- Viper Framework
- ... and many more!
You are using Androguard and are not listed here? Just create a ticket or send us a pull request with your project!
Author
