Android源码定制(4)——Xposed源码定制

一、前言

在上篇文章源码编译(2)——Xopsed源码编译详解中详细介绍了Xposed源码编译的完整过程,本文将从Android编译过程到Xposed运行机制,最后进行Xposed框架的详细定制。其中Xposed的定制主要参考世界美景大佬的定制Xposed框架和肉丝大佬的来自高纬的对抗:魔改XPOSED过框架检测(下)

致谢:

首先感谢世界美景大佬的定制Xposed框架,从里面学习到对Xposed框架特征的修改,但是由于个人水平有限,大佬的贴子不够详细,不能完整复现,经过搜索发现肉丝大佬的基于此的两篇详细的贴子讲解:来自高纬的对抗:魔改XPOSED过框架检测(上)来自高纬的对抗:魔改XPOSED过框架检测(下),本文的Android系统运行参考老罗的博客

二、Android运行机制

我们在了解Xposed的运行机制前,不得不需要了解Android系统的基本结构和运行机制,这样我们才能进一步学习如何进行Xposed定制,才能减少更多的错误

1. Android平台架构

Android的平台架构如下图所示:

image-20211002145934512

下面我们依次介绍各层之间的功能和作用:

(1)Linux内核

Android平台的基础是linux内核,Android Runtime(ART)依靠Linux内核来执行底层功能,使用Linux内核可让Android利用主要安全功能,并且运行设备制造商为著名的内核开发硬件驱动程序,可以理解基于linux内核让Android更安全并且可以拥有很多设备驱动

(2)硬件抽象层(HAL)

HAL提供标准界面,向更高级别Java API框架显示设备硬件功能,HAL包含多个模块,其中每个模块都为特定类型的硬件组件实现一个界面,例如相机和蓝牙模块,当框架API要访问设备硬件时,Android系统为该硬件组件加载库模块。

(3)Android Runtime

Android 5.0之前Android Runtime为Dalvik,Android 5.0之后Android Runtime为ART

首先我们先了解一些文件的含义:

(1)dex文件:Android将所有的class文件打包形成一个dex文件,是Dalvik运行的程序
(2)odex文件:优化过的dex文件,Apk在安装时会进行验证和优化,通过dexopt生成odex文件,加快Apk的响应时间
(3)oat文件:Android私有ELF文件格式,有dex2oat处理生成,包含(原dex文件+dex翻译的本地机器指令),是ART虚拟机使用的文件,可以直接加载
(4)vdex文件:Android 8.0引入,包含APK的未压缩DEX代码,以及一些旨在加快验证速度的元数据

下面我们从Android系统的发展过程中详细介绍二者的区别:

版本 虚拟机类型 特性
2.1-4.4 Dalvik JIT+解释器
5.0-7.0 ART AOT
7.0-11 ART AOT+JIT+解释器

下面部分参考博客:博客地址

Android 2.2

Dalvik

    支持已转换成dex格式的android应用,基于寄存器,指令执行更快,加载的是odex文件,采用JIT运行时编译

JIT:

    JIT即运行时编译策略,可以理解成一种运行时编译器,此时Android的虚拟机使用的是Dalvik,为了加快Dalvik虚拟机解释dex速度,运行时动态地将执行频率很高的dex字节码翻译成本地机器码
缺点:
    (1)每次启动应用都需要重新编译
    (2)运行时比较耗电,造成电池额外的开销

image-20211002145934512

image-20211003100041210

    基于Dalvik的虚拟机,在APK安装时会对dex文件进行优化,产生odex文件,然后在启动APP后,运行时会利用JIT即时编译,处理执行频率高的一部分dex,将其翻译成机器码,这样在再次调用的时候就可以直接运行机器码,从而提高了Dalvik翻译的速率,提高运行速度
缺点:
    (1)由于在Dex加载时会触发dexopt , 导致Multidex加载的时候会非常慢
    (2)由于热点代码的Monitor一直在运行 , 解释器解释的字节码会带来CPU和时间的消耗, 会带来电量的损耗

Android 4.4——ART和AOT

此时引入全新的虚拟机运行环境ART和全新的编译策略AOT,此时ART和Dalvik是共存的,用户可以在两者之间选择

Android 5.0——ART全面取代Dalvik

AOT:

AOT是一种运行前编译的策略
缺点:
(1)应用安装和系统升级之后的应用优化比较耗时
(2)优化后的文件会占用额外的存储空间

AOT与JIT区别:

JIT 是在运行时进行编译,是动态编译,并且每次运行程序的时候都需要对 odex 重新进行编译
AOT 是静态编译,应用在安装的时候会启动 dex2oat 过程把 dex 预编译成 ELF 文件,每次运行程序的时候不用重新编译,是真正意义上的本地应用

JVM、Dalvik和ART区别:

JVM:传统的Java虚拟机、基于栈、运行class文件
Dalvik:支持已转换成dex格式的android应用,基于寄存器,指令执行更快,加载的是odex(优化的dex)
ART:第一次安装时,将dex进行Aot(预编译),字节码预先编译成机器码,生成可执行oat文件(ELF文件)

image-20211002154534641

image-20211003101124310

    基于ART的虚拟机,会在APK第一次安装时,将dex进行AOT(预编译),通过dex2oat生成oat文件,即Android可执行ELF文件,包括原dex文件和翻译后的机器码,然后启动程序后,直接运行
缺点:
    (1)由于安装APK时触发dex2oat , 需要编译成native code , 导致安装时间过长
    (2)由于dex2oat生成的文件较大 , 会占用较多的空间

Android 7.0——JIT回归

考虑上面AOT的缺点,dex2oat过程比较耗时且会占用额外的存储空间,Android 7.0 再次加入JIT形成AOT+JIT+解释器模式

特点:

(1)应用在安装的时候 dex 不会被编译
(2)应用在运行时 dex 文件先通过解析器(Interpreter)后会被直接执行,与此同时,热点函数(Hot Code)会被识别并被 JIT 编译后存储在 jit code cache 中并生成 profile 文件以记录热点函数的信息
(3)手机进入 IDLE(空闲) 或者 Charging(充电) 状态的时候,系统会扫描 App 目录下的 profile 文件并执行 AOT 过程进行编译

混合编译模式综合了 AOT 和 JIT 的各种优点,使得应用在安装速度加快的同时,运行速度、存储空间和耗电量等指标都得到了优化

image-20211003102555392

最后我们可以看下Android各版本ClassLoader加载dex时的dexopt过程:

image-20211003102844820

(4)原生C/C++库

许多核心 Android 系统组件和服务(例如 ART 和 HAL)构建自原生代码,需要以 C 和 C++ 编写的原生库。Android 平台提供 Java 框架 API 以向应用显示其中部分原生库的功能,我们可以通过NDK开发Android中的C/C++库

(5)Java API框架

通过以 Java 语言编写的 API 使用 Android OS 的整个功能集。这些 API 形成创建 Android 应用所需的构建块,它们可简化核心模块化系统组件和服务的重复使用,包括以下组件和服务

2. Android启动流程

Android启动流程如下图所示:

image-20211003102844820

(1)Loader
Boot ROM: 当手机处于关机状态时,长按Power键开机,引导芯片开始从固化在ROM里的预设代码开始执行,然后加载引导程序到RAM
Boot Loader:这是启动Android系统之前的引导程序,主要是检查RAM,初始化硬件参数,拉起Android OS

我们长按电源键后,手机就会在Loader层加载引导程序,并启动引导程序,初始化参数

(2)Linux内核
(1)启动Kernel的swapper进程(pid=0):该进程又称为idle进程, 系统初始化过程Kernel由无到有开创的第一个进程, 用于初始化进程管理、内存管理,加载Display,Camera Driver,Binder Driver等相关工作,这些模块驱动都会封装到对应的HAL层中
(2)启动 init 进程(用户进程的祖宗)。pid = 1,用来孵化用户空间的守护进程、HAL、开机动画等
(3)启动kthreadd进程(pid=2)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值