android系统架构

https://www.anquanke.com/post/id/273348

android系统

安卓(Android)是一种基于Linux内核(不包含GNU组件)的自由及开放源代码的操作系统。主要使用于移动设备,如智能手机和平板电脑,由美国Google公司和开放手机联盟领导及开发

android系统架构

image.png
左边的就是android系统框架了,右边我加了备注,这样更加明了,我们可以看到,android系统架构共分四层从下往上分别是:Linux内核层系统运行库层(程序库+android运行库)、应用程序框架层应用层
左边的就是android系统框架了,右边我加了备注,这样更加明了,我们可以看到,android系统架构共分四层从下往上分别是:Linux内核层系统运行库层(程序库+android运行库)、应用程序框架层应用层
大家重点关注下Android Runtime这一部分,其他的简单了解下就可以涉及到后面的讲解

  1. Llnux内核层: Android系统是基于Linux内核的,它提供了基本的系统功能及与硬件交互的驱动,像图中Display Driver(显示驱动)、Camera Driver(摄像头驱动)、WiFi Driver(WiFi驱动)等,简单了解下就可以
  2. 系统运行库层: 像图中内核的上一层就是系统运行库层,它由程序库(绿色部分)Android运行库(黄色部分) 组成。
  3. Librares(程序库): 由C、C++编写,一系列程序库的集合,供Android系统的各个组件使用。其中包括: | 系统类库名称 | 说明 | | —- | —- | | Surface Manager | 执行多个应用程序时,管理子系统的显示,另外也对2D和3D图形提供支持 | | Media Framework | 基PacketVideoOpenCore的多媒体库,支持多种常用的音频和视频格式的录制和回放,所支持的编码格式包括MPEG4,MP3,H264,AAC,ARM | | SQLite | 本地小型关系数据库,Android提供了一些新的SQLite数据库API,以替代传统的耗费资源的JDBC API | | OpenGL/ES | 基于OpenGL ES 1.0API标准实现的3D跨平台图形库 | | FreeType | 用于显示位图和矢量字体 | | WebKit | Web浏览器的软件引擎 | | SGL | 底层的2D图形引擎 | | Libc(bionic l ibc) | 继承自BSD的C函数库bionic libc,更适合基于嵌入式Linux的移动设备 | | SSL | 安全套接层,是为网络通信提供安全及数据完整性的一种安全协议 |

  4. Android runtime(Core Librares + Dalvik虚拟机): 翻译过来就是Android运行时,Android应用程序时采用Java语言编写,程序在Android运行时中执行,其运行时分为核心库Dalvik虚拟机两部分。

  5. Dalvik虚拟机(DVM):
  6. 而 Dalvik虚拟机又是什么鬼?

    Dalvik虚拟机与ART虚拟机

    Dalvik虚拟机

    Dalvik是google专门为Android操作系统设计的一个虚拟机,简称DVM在Android 4.4及以前的版本, 所有的Android程序都是在Dalvik虚拟机环境下去运行的。DVM的指令是基于寄存器的,运行的是经过转换的 .dex文件 (.dex是专为Dalvik设计的一种压缩格式,适合内存和处理器速度有限的系统),Dalvik虚拟机每次应用运行的时候,将代码编译成机器语言执行。
    DVM是基于寄存器的虚拟机 而JVM执行是基于虚拟栈的虚拟机。

  7. 寄存器存取速度比栈快的多,dvm可以根据硬件实现最大的优化,比较适合移动设备。

  8. 以下是同段代码经反编译形成的java字节码与Dalvik字节码对比

java字节码
image.png
Dalvik字节码
image.png
dvm执行的是.dex格式文件,jvm执行的是.class文件
.dex文件,是DVM独有的执行文件格式,体积更小,速度跟快,占用空间更少
运行环境的区别
Dalvik 经过优化,允许在有限的内存中同时运行多个虚拟机的实例,并且每一个Dalvik 应用作为一个独立的Linux 进程执行。独立的进程可以防止在虚拟机崩溃的时候所有程序都被关闭。

ART虚拟机

前面说到,当我们使用手机每运行一个程序,Dalvik虚拟机都会产生一个实例,互不影响,这就可能会出现占用资源过多等问题,随着人们日益增长的需求,dalvik无法满足人们对软件运行效率的需要。这是就诞生了ART虚拟机。
Android4.4及以上版本,应运而生的ART(Android Run Time)虚拟机替代了Dalvik虚拟机,其处理机制根本上的区别是它采用AOT(Ahead of TIme)技术,会在应用程序安装时就转换成机器语言,不再在执行时解释,从而优化了应用运行的速度。在内存管理方面,ART也有比较大的改进,对内存分配和回收都做了算法优化,降低了内存碎片化程度,回收时间也得以缩短。
DVM与ART的区别: 虽说ART替换了Dalvik虚拟机,并不意味着,其应用程序开发上也要发生改变,像android应用程序安装包(apk)中,仍然还是可执行的.dex文件。

  1. 执行方式:运行效率提高

DVM是在每当程序运行时,通过解释器来执行Davlik字节码,进而转化成快速运行的机器码;而ART是在程序安装时将字节码预先编译成机器码,这样运行程序就不用再次编译

  1. 预装时间:增加

ART安装程序的时间会长一些,但是每次运行程序会快一点;dvm相反

  1. 占用存储空间:增加

art由于预编译,所以所占的存储空间会大一些

  1. 支持64位 CPU

DVM是为32位CPU设计的,而ART是支持64位并且兼容32位CPU

Android应用程序架构

安卓应用程序使用JAVA语言编写。安卓的SDK工具负责将你编写的代码,用到的数据和资源文件编译进APK文件中,APK:android package(应用程序安装包)。apk文件包含了一个安卓应用程序的所有内容,并且被安卓设备用来安装应用程序。
而apk实际上就是一个标准的zip格式,修改后缀名,进行解压就可以看到内部结构
image.png
而每个文件夹都有各自不同的作用,大家可以了解下

  1. assets文件夹: 保存一些额外的资源文件,如游戏的声音文件,字体文件等等,在代码中可以用AssetManager获取assets文件夹的资源。
  2. lib文件夹: 存放用C/C++编写的,用NDK编译生成的so文件,供java端调用。
  3. META-INF文件夹: 存放apk签名信息,用来保证apk包的完整性和系统的安全。
  4. 在IDE编译生成一个apk包时,会对里面所有的文件做一个校验计算,并把计算结果存放在META-INF文件夹内,apk在安装的时候,系统会按照同样的算法对apk包里面的文件做校验,如果结果与META-INF里面的值不一样,系统就不会安装这个apk,这就保证了apk包里的文件不能被随意替换。比如拿到一个apk包后,如果想要替换里面的一幅图片,一段代码, 或一段版权信息,想直接解压缩、替换再重新打包,基本是不可能的。如此一来就给病毒感染和恶意修改增加了难度,有助于保护系 统的安全。
  5. res文件夹: 存放资源文件,包括icon,xml文件
  6. res/layout/: 存放被编译为屏幕布局(或屏幕的一部分)的XML文件
  7. res/values/: 存放可以被编译成很多类型的资源文件
  8. array.xml: 定义数组
  9. string.xml: 定义字符串(string)值
  10. AndroidManifest.xml文件: 应用程序配置文件,每个应用都必须定义和包含的,它描述了应用的名字、版本、权限、引用的库文件等信息。
  11. classes.dex文件: 传统 Class 文件是由一个 Java 源码文件生成的 .Class 文件,而 Android 是把所有 Class 文件进行合并优化,然后生成一个最终的 class.dex 文件。它包含 APK 的可执行代码,是分析 Android 软件时最常见的目标。由于dex文件很难看懂,可通过apktool反编译得到.smali文件,smali文件是对Dalvik虚拟机字节码的一种解释(也可以说是翻译),并非一种官方标准语言。通过对smali文件的解读可以获取源码的信息。
  12. resources.arsc文件: 二进制资源文件,包括字符串等。
  13. smali: smali是将Android字节码用可阅读的字符串形式表现出来的一种语言,可以称之为Android字节码的反汇编语言。利用apktool或者Android Killer,反编classes.dex文件,就可以得到以smali为后缀的文件,这些smali文件就是Dalvik的寄存器语言。

    Android应用编译流程

    image.png
    Android应用编译流程按图中的例子就是一个app应用的生成过程。在应用程序上架的时候都需要程序经过编译、签名 、生成一个后缀为apk的文件才能发布到应用市场。
    下面给大家简单讲解下:

  14. 第一步:打包资源文件,生成R.java文件

  15. 通过利用aapt资源打包工具,将文件目录中的Resource文件(就是工程中res中的文件)、Assets文件、AndroidManifest.xml文件、Android基础类库(Android.jar文件)进行打包,生成R.java
  16. 第二步:aidl生成Java文件
  17. AIDL是Android Interface Definition Language的简称, 是Android跨进程通讯的一种方式。 检索工程里所有的aidl文件,并转换为对应的Java文件
  18. 第三步:编译Java文件,生成对应的.class文件
  19. 将R.java、aidl生成的Java文件、Java源文件通过JDK携带的Javac编译生成.class文件
  20. 第四步:把.class文件转化成Davik VM支持的.dex文件
  21. 通过dx工具将.class文件生成为classes.dex
  22. 第五步:打包生成未签名的.apk文件
  23. 利用apkbuilder工具,将resources.arsc、res目录、AndroidManifest.xml、assets目录、dex文件打包成未签名的apk
  24. 第六步:对未签名.apk文件进行签名
  25. 使用apksigner为安装包添加签名信息。
  26. 第七步:对签名后的.apk文件进行对齐处理
  27. 使用zipalign工具对签名包进行内存对齐操作, 即优化安装包的结构。

    Android应用反编译流程及工具利用

    image.png

    https://www.freebuf.com/articles/terminal/189021.html

    x01 Xposed 模块编写简介

    Xposed 框架的原理就不多说了,它部署在ROOT后的安卓手机上,通过替换/system/bin/app_process程序控制zygote进程,使得app_process在启动过程中会加载XposedBridge.jar这个jar包,从而完成对Zygote进程及其创建的Dalvik虚拟机的劫持。可以让我们在不修改APK源码的情况下,通过自己编写的模块来影响程序运行的框架服务,实现类似于自动抢红包、微信消息自动回复等功能。
    其实,从本质上来讲,Xposed 模块也是一个 Android 程序。但与普通程序不同的是,想要让写出的Android程序成为一个Xposed 模块,要额外多完成以下四个硬性任务:
    1、让手机上的xposed框架知道我们安装的这个程序是个xposed模块。
    2、模块里要包含有xposed的API的jar包,以实现下一步的hook操作。
    3、这个模块里面要有对目标程序进行hook操作的方法。
    4、要让手机上的xposed框架知道,我们编写的xposed模块中,哪一个方法是实现hook操作的。
    这就引出我即将要介绍的四大件(与前四步一一对照):
    1、AndroidManifest.xml
    2、XposedBridgeApi-xx.jar 与 build.gradle
    3、实现hook操作的具体代码
    4、xposed_Init
    牢记以上四大件,按照顺序一个一个实现,就能完成我们的第一个Xposed模块编写。下面我们就开始吧!