我们现在日常生活中都使用手机,它们的使用已经发展到了一个至关重要的水平,以至于人们经常将手机列为除了食物和水之外不可或缺的三样东西之一。手机几乎处理了所有任务,从管理银行账户和投资到旅行预订、购物和健康预约。
为了执行这些任务,手机拥有移动应用程序。这些应用程序处理了大部分您的数据,并帮助您执行任务。
由于这些现代移动应用程序处理敏感用户信息,执行关键任务,并提供对互联网上大量资源的访问,因此处理的数据安全性和执行的操作也需要得到改善。
移动应用程序渗透测试人员测试移动应用程序的安全性以发现漏洞。为了找到漏洞,测试人员需要理解应用程序的内部工作原理和逻辑。这些细节可以在应用程序的源代码中找到。然而,在黑盒渗透测试的情况下,渗透测试人员并不总是能够得到源代码。在黑盒渗透测试期间,渗透测试人员所拥有的只是应用程序包,即Android应用程序包(APK)或iOS应用商店包(IPA)文件。在这种情况下,为了理解应用程序的工作原理,他们需要解压应用程序包并获得源代码。
逆向工程是拆解物体以研究其内部设计、代码、逻辑等的技术。逆向工程移动应用程序是指拆解/解构应用程序以揭示其代码和内部逻辑、组件等的过程。
在本章中,我们将涵盖以下主要内容:
- 逆向工程基础知识
- Android应用程序基础知识
- iOS应用程序基础知识
我们将学习逆向工程的基础知识以及移动应用程序是如何构建的。在我们深入了解现代应用程序的逆向工程任务之前,理解这些基础知识是很重要的。
技术要求:
完成相关的实践练习需要使用 Android Studio 和 Xcode。Xcode 是苹果公司的集成开发环境(IDE),用于开发 macOS、iOS、iPadOS、watchOS 和 tvOS 的软件。Android Studio 是谷歌的 Android 操作系统的官方集成开发环境。苹果笔记本电脑/台式机(Mac)可以安装并运行 Xcode 和 Android Studio,而运行 Windows 或 Linux 的其他笔记本电脑/台式机只能支持 Android Studio。
更多信息,请参阅以下链接:
- Android Studio: developer.android.com/studio
- Xcode: developer.apple.com/xcode/
逆向工程基础知识
首先让我们了解逆向工程的基本原理,为什么需要逆向工程以及涉及的步骤。
正如本章前面提到的,逆向工程是拆解一个对象以研究其内部设计、代码和逻辑的技术。 当开发人员构建一个移动应用时,他们会选择一种编程语言(根据目标平台 - Android、iOS 或两者都有),编写他们想要的功能的代码,并添加资源,如图像、证书等。然后将代码编译以创建应用程序包。
在逆向工程相同的应用程序时,逆向工程师将应用程序包拆解为组件和代码。 在逆向工程中经常使用的一些术语如下:
- 反编译:这是将文件从低级语言翻译为高级语言的过程。执行反编译的工具称为反编译器。反编译器接收一个二进制程序文件,并将该程序转换为更高级别的结构化语言。下图说明了反编译过程:
- 拆解:这是将机器码(在目标代码二进制文件中)转换为人类可读的助记符表示称为汇编语言的过程。执行拆解的工具称为反汇编器,因为它执行的是与汇编器相反的操作。下图说明了拆解过程:
一个简单的二进制文件在反汇编工具 Hopper 中进行反汇编后如下所示:
- 调试:这是一种技术,允许用户在运行时查看和修改程序的状态。下图说明了调试过程:
了解逆向工程中使用的不同方法和方法论非常重要。我们将在本书的后续章节中运用所有这些概念。 现在我们已经了解了逆向工程的基础知识,让我们探索一下移动应用程序,也就是 Android 和 iOS 应用程序是如何开发的。我们现在将深入研究移动应用程序基础知识背后的组件、结构和概念。
Android应用程序基础知识
原生Android应用主要使用Java或Kotlin编写。Android SDK工具将代码与任何数据和资源文件编译成APK或Android应用程序包。编译后的应用程序以特定格式存储,其扩展名为.apk。换句话说,Android包是一个包含多个应用程序文件和元数据的存档文件。
趣味小知识 :将APK文件的文件扩展名改为.zip,并使用unzip打开。您将能够查看其内容。
以下是APK的主要组成部分:
-
AndroidManifest.xml:应用程序清单文件,包含应用程序详细信息,如名称、版本、引用的库以及XML格式中的组件详细信息。Android操作系统依赖于该文件的存在,以识别与应用程序和相关文件有关的相关信息。
-
Dalvik可执行文件(classes.dex文件)。
-
META-INF:
- MANIFEST.MF(清单文件)
- CERT.RSA(应用程序的证书)
- CERT.SF(带有MANIFEST.MF文件中相应行的SHA-1摘要的资源列表)
-
lib:包含特定于一系列处理器的编译代码,如下所示:
- armeabi:所有基于ARM的处理器的编译代码
- armeabi-v7a:所有基于ARMv7及以上的处理器的编译代码
- x86:x86处理器的编译代码
- mips:MIPS处理器的编译代码
-
res:未编译为resources.arsc的资源。
-
assets:包含应用程序资产。
-
resources.arsc:预编译资源。
重要提示 :Android设备中的Java代码不在Java虚拟机(JVM)中运行。相反,它以Dalvik可执行(DEX)字节码格式编译。DEX文件包含最终由Android Runtime执行的代码。
让我们看看如何为Android创建一个简单的"Hello World"应用程序,然后解压缩它以查看其组件:
- Android应用程序使用Android Studio开发。请从developer.android.com/studio下载并安装最新版本的Android Studio。
- 让我们选择"新项目"选项,然后选择"空活动"选项:
- 在接下来的屏幕上,按照以下截图中显示的方式填写所有细节。您可以随意选择名称:
-
点击"完成"后,将为默认的活动/屏幕应用程序创建一个新项目。
-
您现在可以尝试在任何连接的Android设备上或虚拟Android模拟器上运行该应用程序。对于后者,请从AVD菜单创建一个虚拟Android设备。
-
一旦应用程序成功运行,我们将尝试从Android Studio中提取此应用程序的应用程序包。
-
要从Android Studio获取APK,请转到"构建|构建Bundle(s)/APK(s)|构建APK(s)"菜单选项。生成后,导航到"定位"选项中提到的文件夹,并复制APK。
-
复制APK后,将文件的扩展名更改为.zip:
- 使用任何存档工具解压文件并提取其内容:
arduino
# unzip MARE-Chapter-1.zip
供参考,结果如下:
- 让我们分析APK内部的组件,并与此处的列表进行比较(Android应用程序基础知识)。
以下图示显示了对Android应用程序进行正向和逆向工程的过程:
Android 应用主要使用 Java 和 Kotlin 进行开发。无论基于 Java 还是 Kotlin,Android 包的内部结构都是相同的。因此,逆向工程应用程序的方法也是相同的。
我们现在已经了解了 Android 应用程序的基础知识。iOS 应用程序也被打包成特定的格式,并具有特定的结构。现在让我们来了解 iOS 应用程序的基础知识。
iOS 应用程序基础知识
类似于 Android,iOS 应用程序也以特定的压缩格式称为 IPA,或者 iOS 应用商店包。iOS 应用程序包也可以通过将扩展名更改为 ZIP 来重命名,然后可以提取组件,尽管 iOS 应用程序包的组件与 Android 应用程序包的不同。
iOS 应用主要使用 Objective-C 和 Swift 构建,这两种语言都可以使用诸如 Hopper 或 Ghidra 的反汇编器进行反汇编。在 Objective-C 应用中,方法通过动态函数指针调用,在运行时通过名称解析。这些名称完整地存储在二进制文件中,使得反汇编代码更易读。与 Android 不同的是,在 iOS 中,应用程序代码被编译为可以使用反汇编器进行分析的机器代码。
以下是 iOS 应用程序包的主要组件:
- Info.plist:类似于 APK 中的 Android 清单文件,此信息属性列表文件包含键值对,用于指定应用程序的关键运行时配置信息。iOS 操作系统依赖于此文件的存在,以识别有关应用程序及其相关文件的相关信息。
- 可执行文件:在设备上运行的文件,包含应用程序的主入口点和静态链接到应用程序目标的代码。
- 资源文件:可执行文件所需的文件,对于应用程序正确运行是必需的。这可能包含图像、nib 文件、字符串文件和配置文件。
以下图示说明了 iOS 架构概览:
让我们看看如何为iOS创建一个简单的"Hello World"应用程序,然后解压它并查看其组件:
-
iOS 应用程序是使用 Xcode 开发的。在 Mac 上通过 App Store 下载最新版本的 Xcode。
-
在接下来的屏幕上,选择默认的应用程序模板作为您的新项目:
-
在接下来的屏幕上,提供一个产品名称(您喜欢的任何名称),选择一个团队,并提供一个组织标识符。要从 Xcode 创建和导出 IPA,您需要拥有苹果开发者许可证。
-
选择在您的计算机上保存项目的位置。 Xcode 现在将创建一个简单的"Hello World"应用程序,并且您将在 Xcode 窗口中看到以下默认代码:
-
现在您可以尝试在内置的 iOS 模拟器上运行此应用程序。为此,请选择一个可用的模拟器(只需点击顶部栏中的模拟器名称,列表将打开),如下图所示:
应用程序应在所选模拟器上运行:
-
现在,让我们从这个 Xcode 项目中导出 IPA。为此,请从模拟器选项中选择"任何 iOS 设备(arm64)"选项。
-
然后,转到"产品|存档",并选择"分发应用程序"选项:
-
在接下来的屏幕上,选择"开发",并在随后的屏幕上将选项保持默认设置。
-
最后,您将能够将 IPA 与其他一些编译的项目文件一起导出:
- 一旦导出 IPA 文件,只需将文件的扩展名更改为 .zip 即可:
- 使用任何工具解压文件并提取其内容:
arduino
# unzip MARE-Chapter-1.zip
以下截图显示了供参考的结果:
- 进入 Payload 目录,然后进入 MobileAppReverseEngg-App-1.app 文件:
shell
# cd Payload
# cd MobileAppReverseEngg-App-1.app
- 让我们分析 IPA 内部的组件,并将其与此处的列表(iOS 应用程序基础知识)进行比较:
以下图示说明了逆向工程 iOS 应用程序的过程:
看一下图 1.3,了解在 Hopper 反汇编器中,一个反汇编二进制文件的样子。