Xposed 实现原理分析

前言

Xposed 是 Android 平台上著名的 Java 层 Hook 框架,通过在 Android 设备上安装 Xposed 框架,编写 Xposed 模块,可实现对任意 Android 应用的 Java 方法的 Hook,以及应用资源的替换。

(Hook 是一种函数钩子技术,能够对函数进行接管,从而修改函数的返回值,改变函数的原始意图)

本文将基于 Xposed 最新的开源代码对 Xposed 的实现原理进行分析。Xposed 有两种实现版本,一个是基于 Dalvik 虚拟机的实现,它是针对早期的 Android 4.4 之前的 Android 设备设计的;另一个是基于 ART 虚拟机的实现,自 Android 5.0 系统开始,Android 系统正式采用了 ART 虚拟机模式运行,Dalvik 就成了历史,目前市面上几乎所有的手机都是以 ART 模式运行的,下面将主要对于 ART 上的 Xposed 实现进行详细分析,对于 Dalvik 上的 Xposed 的实现,进行必要性的分析。

通过了解 Xposed 的实现原理可以学到在 Android 平台上对于 Java 层代码的一种 Hook 机制的实现,同时复习 Android 系统的启动原理以及增加对于 Android ART 虚拟机运行原理的了解。

阅读更多

Android Dex 文件解析

前言

Java 代码文件在经过 javac 编译器编译后会产出 .class 格式的 Java 虚拟机可执行的字节码文件,而 Dex 文件则是 Android SDK 编译 Java 代码后的产物(Android SDK 使用 dx 或 d8 编译器将 .class 文件编译为 .dex 文件),了解 Dex 文件结构是理解 Android 虚拟机原理的基础,同时也是学习 Android 逆向工程的基础。

Dex 文件的文件后缀为 .dex,是 Android 虚拟机的可执行文件。

阅读更多

Xposed 框架的使用

Xposed 简介

Xposed 框架是 Android 平台上一个非常著名且强大的开源框架,使用它能够对系统进程内运行的方法进行 hook,所以可以用它来做一些系统层面的工作,它拥有无限可能的灵活性,目前市面上基于 Xposed 框架下开发 Xposed 子模块已经数不胜数了。

原理简析

Android 系统运行的核心和起点是 Zygote 进程,所有应用都是从它 fork 子进程产生的,当系统开始运行时由 init.rc 脚本启动, 使用 /system/bin/app_process 程序完成启动,它加载所需的类并调用初始化方法。

Xposed 框架将在这个地方发挥作用,当 Xposed 框架被安装时,一个被扩展的 app_process 程序将被复制到 /system/bin/ 中,这个扩展的 app_process 将向类的路径附加一个 jar 文件,并在某些位置调用其方法,可能是虚拟机创建之后,或者在 Zygote 进程的 main 方法之前。在这个方法里,我们可以在其上下文中做插桩。

阅读更多

Android 二进制 XML 文件解析

前言

Android SDK 在编译 Android 工程时,将会把诸如资源文件和清单文件之类的相关 XML 文件编译为特定的二进制格式,目的是为了压缩其容量以及优化其在运行时的解析效率。

将 XML 文件编译为二进制的 XML 文件是 Android 编译资源时的一个子步骤,Android 在完整的资源编译过程结束后将会生成一个 resources.arsc 文件,它是一个资源文件表,应用在运行时会将它映射在内存中,为了资源的查询和引用。编译 Xml 文件为生成 arsc 文件的一个子步骤,如果 Xml 文件中引用了资源,例如字符串资源,那么 Xml 文件中引用字符串的位置将会包含一个全局字串池的索引,通过索引在 arsc 文件中的全局字符串池中即可查询到引用的具体字符串。

有关 arsc 文件的结构和解析方法可参考:Android arsc 文件解析

阅读更多

Android arsc 文件解析

apk 文件结构

在使用 Android SDK 编译 Android 工程时,它会将工程的源代码和资源打包为一个 apk 文件,apk 文件实质为一个压缩包,一个未签名的 apk 文件典型结构如下:

1
2
3
4
5
6
7
apk file:
assets/ - assets 原始资源文件
lib/ - so 库文件
res/ - 资源文件
classes.dex - 编译后的代码
resources.arsc - 资源信息文件
AndroidManifest.xml - 二进制的清单文件

在 Android 项目的编译过程中,Java 代码将会被编译为 classes.dex 文件,JNI 代码被编译为 .so 文件存放在 lib 目录下,assets 目录和 res/raw 目录中文件的将不会发生变化,对于资源文件中 xml 形式的资源将会被编译为优化过的特定的二进制 xml 格式,而类似于图片这种本身为二进制的类型也不会发生变化,AndroidManifest.xml 清单文件被编译为优化过的二进制格式。

阅读更多