如何剖析Android应用程式

众所周知,Android应用以Android应用程序包文件(或简称APK)的形式分发。 可是,大多数人将APK视做黑匣子,殊不知道其建立方式或内部内容。 即便是大多数应用程序开发人员,也只能对APK的结构有一个肤浅的了解。 在集成开发环境(例如Android Studio)中,只需单击一下便可将Android项目转换为APK。
html

在本教程中,咱们将剖析一个Android应用程序。 换句话说,咱们将打开其APK并查看其内容。 另外,因为APK是二进制文件,只能由机器读取,所以我还将向您介绍一些工具,您可使用这些工具将其内容转换为更易理解的形式。
java

先决条件

要继续进行,您须要:
android

  • 最新版本的Android SDK
  • 运行Android 4.4或更高版本的Android设备或模拟器

1.为何要查看APK内部?

许多人出于好奇而这么作。 其余人则能够直接访问本身喜欢的游戏或应用程序的图像,声音和其余资产。 可是,还有一些更重要的缘由使您想要查看APK内部。
git

学习

若是您刚刚开始学习Android应用程序开发,则能够经过查看流行应用程序或由专业人士建立的应用程序的APK文件查看不少内容。 例如,经过查看在多个屏幕尺寸上看起来不错的应用程序的XML布局文件,您能够提升本身的布局建立技能。
github

安全

从不受信任的来源下载的应用可能包含恶意代码。 若是您已是熟练的应用程序开发人员,则能够经过分解此类应用程序查看其代码,以更好地了解其实际功能。 shell

2.如何建立APK?

若是没有对APK的建立方式有基本的了解,那么从APK中能够学到的东西就不少。 实际上,用于剖析APK的最重要的工具也是用于建立APK的工具。
windows

Android项目主要由Java源代码,XML布局,XML元数据和资产(例如图像,视频和声音)组成。 在Android操做系统可使用全部这些文件以前,须要将它们转换为它能够理解的格式。 这种转换涉及许多中间任务,一般称为Android构建过程。 构建过程的最终输出是APK或Android应用程序包
浏览器

在Android Studio项目中, Android Gradle插件可处理构建过程当中的全部中介任务。
安全

最重要的任务之一是生成名为R.java的文件。 该文件使开发人员可使用数字常量轻松地在其Java代码中访问项目的布局和可绘制资源。 为了生成文件,使用了一个名为aapt的工具,它是Android Asset Packaging Tool的缩写。 该工具还将全部XML资源以及项目的清单文件转换为二进制格式。
bash

而后使用Java编译器将全部Java文件(包括R.java)转换为类文件。 您可能已经知道,类文件由字节码组成,能够由Java运行时引擎解释。 可是,Android使用一种特殊的运行时类型,称为Android运行时 (ART),该运行时已针对移动设备进行了优化。 所以,一旦生成了全部类文件,就会使用一个名为dx的工具将字节码转换为Dalvik字节码 (ART能够理解的格式)。

处理完资源和Java文件后,将它们放置在与JAR文件很是类似的存档文件中。 而后使用属于应用程序开发人员的私钥对存档文件进行签名。 这两个操做由Gradle插件执行,而无需使用任何外部工具。 可是,开发人员的密钥是从keytool管理的密钥库中得到的。

最后,使用zipalign工具对存档文件进行了一些优化,以确保将应用在运行时占用的内存保持在最低水平。 此时,存档文件是有效的APK,能够由Android操做系统使用。

3.分析APK的内容

如今您已经了解了APK文件的建立和使用方式,让咱们打开其中一个文件并查看其内容。 在本教程中,咱们使用Android模拟器上预先安装的名为Sample Soft Keyboard的应用程序的APK。 可是,若是您喜欢使用物理设备,则能够轻松使用已安装在该设备上的任何应用程序的APK。

步骤1:将APK传输到计算机

要检查APK的内容,必须首先将其从仿真器传输到计算机。 在执行此操做以前,您须要了解APK的软件包名称和绝对路径。 使用adb在模拟器上打开Shell会话。

adb shell

看到shell提示后,请使用pm list命令列出全部已安装应用程序的软件包名称。

pm list packages

咱们感兴趣的应用程序的软件包名称为com.example.android.softkeyboard 您应该能够在列表中看到它。 经过将软件包名称传递给pm path命令,能够肯定APK的绝对路径。

pm path com.example.android.softkeyboard

上面命令的输出以下所示:

package:/data/app/SoftKeyboard/SoftKeyboard.apk

如今,您已经知道了它的路径,您能够退出外壳,并使用adb pull命令将APK传输到计算机。 下面的命令将其传输到计算机的/ tmp目录:

adb pull /data/app/SoftKeyboard/SoftKeyboard.apk /tmp

步骤2:提取APK的内容

在本教程的前面,您了解到APK只是压缩的存档文件。 这意味着您可使用操做系统的默认存档管理器来提取其内容。 若是您使用的是Windows,则可能首先必须将文件的扩展名从.apk更改成.zip 提取APK的内容后,您应该可以看到APK内部的文件。

APK内容

若是您是应用程序开发人员,APK中的许多文件应该看起来很熟悉。 可是,除了res文件夹中的图像以外,文件的格式是没有一些工具没法使用的格式。

步骤3:解密二进制XML文件

Android SDK包含分析APK内容所需的全部工具。 您以前了解到, aapt用于在构建过程当中打包XML资源。 它也能够用来从APK中读取不少信息。

例如,您可使用其dump xmltree选项来读取APK中任何二进制XML文件的内容。 这是您如何读取名为res / layout / input.xml的布局文件的方法:

aapt dump xmltree /tmp/SoftKeyboard.apk res/layout/input.xml

输出应以下所示:

N: android=http://schemas.android.com/apk/res/android
  E: com.example.android.softkeyboard.LatinKeyboardView (line=21)
    A: android:id(0x010100d0)=@0x7f080000
    A: android:layout_width(0x010100f4)=(type 0x10)0xffffffff
    A: android:layout_height(0x010100f5)=(type 0x10)0xfffffffe
    A: android:layout_alignParentBottom(0x0101018e)=(type 0x12)0xffffffff

它不是XML,可是因为缩进和标签,例如N表明名称空间, E表明元素, A表明属性,您应该可以读取它。

步骤4:解密字符串

在上一步中,您看到解密后的XML具备十六进制数字而不是字符串。 这些数字是对名为resources.arsc的文件中的字符串的引用,该文件表示应用程序的资源表。

您可使用aaptdump resources选项来查看资源表。 这是如何作:

aapt dump --values resources /tmp/SoftKeyboard.apk

从命令的输出中,您能够肯定应用程序中使用的字符串的确切值。 这是XML中十六进制数字之一的条目:

resource 0x7f080000 com.example.android.softkeyboard:id/keyboard: t=0x12 d=0x00000000 (s=0x0008 r=0x00)

步骤5:反汇编Dalvik字节码

APK中最重要的文件是classes.dex 这是运行该应用程序时Android运行时使用的文件。 它包含在构建过​​程中生成的Dalvik字节码。

经过反汇编此文件,您能够得到有关应用程序中使用的Java类的信息。 为此,您可使用一个名为dexdump的工具。 使用如下命令,您能够将dexdump的输出重定向到能够由任何文本编辑器打开的文件。

dexdump -d /tmp/classes.dex > /tmp/classes.dasm

若是打开classes.dasm ,您将看到它包含数百行低级代码,以下所示:

拆解的底层指令

不用说,很难理解。 幸运的是,您可使用-l选项将dexdump的输出格式dexdump为XML。 使用如下命令,能够将其输出重定向到能够在浏览器中打开的文件。

dexdump -d -l xml /tmp/classes.dex > /tmp/classes.xml

XML格式的可用信息量较少,但可使您对应用程序中存在的Java类,方法和字段有一个清晰的了解。

XML反汇编代码

结论

在本教程中,您学习了APK的建立方式及其包含的内容。 您还学习了如何使用Android SDK中提供的工具来解密APK文件的内容。 关于这些工具的文档并很少,可是,因为它们是开源的,所以您能够尝试阅读其注释普遍的源代码以了解有关它们的更多信息。

若是您正在寻找更易于使用的工具,则能够尝试使用流行的第三方工具,例如dex2jar (能够生成可读性更高的反汇编代码)或JADX (能够生成Java代码的反编译器)。

翻译自: https://code.tutsplus.com/tutorials/how-to-dissect-an-android-application--cms-26178