PackageManagerService及APK安装流程剖析

PackageManagerService及APK安装流程剖析

 

目录

PackageManagerService及APK安装流程剖析

1 概述

1.1 PMS介绍

1.2 PMS启动

2 APK分析

2.1 Apk包组成

2.2  Apk文件分析

3 PMS安装流程

3.1介绍

3.2 流程分析


 

1 概述

1.1 PMS介绍

PMS是PackageManagerService服务简称,常驻在SystemServer进程内,负责Android系统安装包信息,安装全流程管理。其在SystemServer中被启动,代码如下,是Android系统核心服务之一。

1.2 PMS启动

PMS作为Android系统的核心服务之一,负责的核心功能包括但不限于:包信息管理,包解析,权限管理,多包统一管理,Apk安装全流程管理,其它系统服务交互管理。可见其功能复杂,需要精心的架构设计才能完成其功能。

首先来看下基于Android4.4的PMS静态架构图,帮助我们理解后面的内容:

 

接下来重点来分析下PMS的启动方法,简要来看下其在启动时操作的业务,如下

继续来看它的新建方法,这个方法较长,我们分解来看,主要做了几个事情

  1. 新建mSettings对象,辅助Package管理
  2. 已安装程序扫描分析
  3. 安装包APk路径扫描机安装
  4. 通过mSettings回写系统app现状,创建packages.xml文件。

这里来看下,mSettings的新建

这个对象负责package包的日常管理,是及其重要的,其类为Settings,这里先不展开。

接下来PMS分析已安装APK的现状,如下:‘

这一步主要负责已安装APP现状分析(基于持久化文件),构建内存对象,核心是PMS中的mPackages对象。

PMS新建方法中的第三部是非常核心的,负责APK包的扫描分析,包括系统预装路径下APK及应用目录下的APK,其中还涉及到APK解析及安装,如下

跟踪进入方法scanDirLI方法来看如下:

List目录,并对apk文件执行scanPackageLI方法,继续深入此方法,关注核心点如下:

到此为止调用scanPackageLI方法完成apk解析及信息提取,有兴趣的可以深入进去。通过这步PMS的mPackages方法已经填充完毕,接下来来看PMS构建方法的第四步,更新持久化信息packages.xml。

PMS通过mSettings.writeLPr()达到目标,如下

继续跟踪,如下

可以看到通过fs最终更新packages.xml文件。

至此PMS的初始化方法,完成了Android系统APP包信息的统一,安装,权限收集等,以待其它系统服务的调用。

2 APK分析

2.1 Apk包组成

我们在分析安装流程前,先显示来看下android安装包即APK的组成。APK是AndroidPackage的缩写,即Android安装包(apk)。APK是类似Symbian Sis或Sisx的文件格式。通过将APK文件直接传到Android模拟器或Android手机中执行即可安装。

apk文件和sis一样,把android sdk编译的工程打包成一个安装程序文件,格式为apk APK文件其实是zip格式,但后缀名被修改为apk,通过UnZip解压后,可以看到Dex文件,DexDalvikVM executes的简称,即Android Dalvik执行程序,并非Java ME字节码而是Dalvik字节码。Android在运行一个程序时首先需要UnZip,然后类似Symbian那样直接,和Windows Mobile中的PE文件有区别。

我们通过分析一个举列子,来看下具体的APK文件。

得到结果如下

剩下的META-INF主要是对此apk文件的加密信息。

2.2  Apk文件分析

 了解了APK文件的实质以及内容后,可以更进一步,上文提到classes.dex是apk可执行文件的二进制码,被davilk解析执行,这里可以通过一些开源的反编译工具查看内容,但受限于混淆技术,可看到的东西其实不多。

  此时直接打开AndroidMannifest.XML文件,发现无法查看,这其实是Android在apk打包过程中对xml进行了压缩导致,可以通过源代码下的aapt工具来查看,执行如下命令../prebuilts/sdk/tools/linux/aapt d xmlstrings pmcszj.apk AndroidManifest.xml

同理,我们还可以查看此apk归档文件申请的权限,通过执行下面命令../prebuilts/sdk/tools/linux/aapt d permissions pmcszj.apk

可以看到此示列程序申请了wifi,读写rom磁盘权限等。看过1.2PMS启动的分析就会明白,此apk安装后,其权限信息已经被提取记录到PMS中。

下面来看下apk归档文件的加密信息,METE_INFO下面有三个文件

1  MENIFEST.MF :保存对所有文件的sha(安全哈希)的base24编码 (可以直接打开,我用的notepad++)

2  CERT.SF : 对MENIFEST.MF中的每一项进行sha(安全哈希) 并且通过apk签名的私钥进行运算后的base64编码 (可以直接打开,我用的notepad++)

3 CERT.RSA : 证书文件,封装对apk数字签名对应公钥信息,采用RSA算法。

简单点来说其原理是MENIFEST.MF对普通的类和资源文件进行校验,CERT.SF 加上 CERT.RSA 校验MENIFEST.MF . 这样就保证不能伪造他人来发布apk。

可以通过keytool -printcert -file test/META-INF/SCREENTE.RSA查看示列程序的公钥信息,如下

 

至此初步完成了对apk文件的分析,其本质只是一个符合Android平台开发规范的协议归档文件。

3 PMS安装流程

3.1介绍

Android平台下安装apk程序,有多重途径,这里以adb shell install开始做入口来分析,其它方式大同小异,查看frameworks/base/cmds/pm/src/com/android/commands/pm/Pm.java

文件,存在入口如下:

这里可以看到通过Binder转接,实质是通过PMS来实现安装,其调用时序如下参考如下:

 

3.2 流程分析

下面,逐步来分析apk安装流程

1 首先分析installPackageWithVerificationAndEncryption方法

在这里做了基本的检查,原封不动对参数构建InstallParams对象,并发送INIT_COPY信息来处理。

这里关注下类InstallParams,如下:

 

可以看出,此类可抽象理解为对安装参数处理,其内部封装了一些核心方法来触发安装,是PMS中重要的辅助类。

2 基于第一点分析,通过内部handler发送INIT_COPY命令处理封装信息:

这里添加param参数到list中,接着触发MCS_BOUND命令,如下

由上面知道mPendingInstalls内至少有一个对象,接着执行params的startCopy方法,接着来看

 

这里可以看到,此方法基本主要分两步:

  • handleStartCopy:处理apk的拷贝
  • handleReturnCode:处理拷贝后的后续安装

下面基于这两个方法,分段来分析。

3 接着上面分析,这里分析handleStartCopy方法,其过程较长,这里关注核心的几个点

通过params传入的参数,来新建packagefile,笔者这里测试信息参考如下:

/data/app/vmdl-734788364.tmp

然后通过mContainerService服务来获取package的基本信息,这里可以看到:

这主要是对位置以及packagename的解析。这里重点是location参数的解析。Android系统接下来还要对location进行核实(通过自定义策略支持),如下

这里不展开,在新安装的app,不会改变packagelite中的取值。

接下来基于InstallParams来构建FileInstallArgs对象,如下

 

之前在上文提到了InstallParams类的作用,其主要负责安装参数封装及安装触发,这里也来看下FileInstallArgs的抽象意义

 

可以看到FileInstallArgs主要负责文件的复制,以及安装生命周期回调。持有Apk相关核心参数。

继续来看handleStartCopy方法

这里有个if else分支,对于新安装程序(不许要VerifierPackag),直接调用args的copyapk来处理,而次args对象就是刚刚提到的FileInstallArgs对象,接着来看

 

这里主要是创建temp文件及确定路径,笔者测试时列子中,其codefilename:path=/data/app/vmdl-734788364.tmp

接下来看

可以看到这里主要做了两件事,就是从adb临时目录(file:///data/local/tmp/da021051-c596-4422-903a-0c6600320e2d.apk)下拷贝资源到刚刚创建的temp文件主要是code及lib拷贝

至此已经完成了从adb临时文件到temp拷贝,并确定了基本的一些路径参数

 

4下面接着第三步来分析handleReturnCode函数

这里可以看到,直接调用PMS下的processPendingInstall 方法来处理,其中入参包括mArgs(InstallParams)

这里可以看到在PMS中post的了一个线程来处理接下来工作,可以预见其比较耗时,这里忽略安装前的参数检查,直接来看installPackageLI方法

这里面画箭头的地方,主要做了两件事,基于传递进入的InstallArgs参数

1 通过PackageParser解析apk信息,提取出PackageParser.Package对象,后面有机会介绍这个是apk类在内存中对应的重要的对象。

2 通过package及flags参数来提取mete-inf中的rsa信息,这个在第二章节中已经提到,这在后面权限验证会用到。

接下来继续分析

可以看到这里直接调用到了installNewPackageLI方法,这里继续来看

此方法中主要做了两件事情,调用scanPackageLI来浏览梳理apk信息,之后调用updateSettingsLI方法,根据方法名我猜应该是更新本地化配置(package.xml),这个在第一章分析过。

 

5 接下来重点分析下scanPackageLI方法

这里分段来看。首先,打开之前拷贝的temp文件

接下来更新共享库

这里基于传入的pkg来更新msetting中的对象(会新建,传入其list中,这里不展开)

解析最新的pkg信息后,就是检查rsa文件等,如下

下面,创建app的安装目录,如下

其实还有一些列资源文件lib文件拷贝的。

分析到这里即便是解析及拷贝,下面就是基于全新的pkg来更新内存中的对象,针对apk中声明的Andorid四大组件,这为AMS管理组件声明周期提供了基础,这里代码太多,只给出activity的提取及示列

笔者做测试的列子,提取到的信息日志如下


V/PackageManager( 7148):   activity com.waps.OffersWebView:
V/PackageManager( 7148):     Class=com.waps.OffersWebView
V/PackageManager( 7148):   activity ps.wb.music20130822001587.MyAdView:
V/PackageManager( 7148):     Class=ps.wb.music20130822001587.MyAdView
V/PackageManager( 7148):   activity ps.wb.music20130822001587.MusicSet:
V/PackageManager( 7148):     Class=ps.wb.music20130822001587.MusicSet
V/PackageManager( 7148):   activity ps.wb.music20130822001587.Index:
V/PackageManager( 7148):     Class=ps.wb.music20130822001587.Index
V/PackageManager( 7148):     IntentFilter:
V/PackageManager( 7148):       Action: "android.intent.action.MAIN"
V/PackageManager( 7148):       Category: "android.intent.category.LAUNCHER"
V/PackageManager( 7148):   activity ps.md.music.InputFile:
V/PackageManager( 7148):     Class=ps.md.music.InputFile

至此基本分析完了scanPackageLI方法,可以看到其实安装最核心的方法,涉及到temp文件解析,权限检查,安装目录新建及复制,以及内存对象构建等。

6 接下来继续分析,我们在第四步分析时提到过最终还会执行updateSettingsLI方法,这里来简单看下

其实这个方法很简单,就是针对上面安装apk后的信息,执行mSettings.writeLPr()方法来更新package.xml配置文件,以便于下次Android系统启动,从此文件恢复核心的内存对象。

至此基本分析完了apk的安装流程,由于涉及到信息量太多,这里采用抓主干方式,后期有时间可以针对一些细节来展开。

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
`adb install`和`pm install`命令都用于在Android设备上安装应用程序,它们的安装流程如下: 1. `adb install`安装流程: - 通过USB连接将Android设备与计算机相连。 - 打开终端或命令提示符,并导航到ADB工具的目录(通常是Android SDK的`platform-tools`目录)。 - 运行命令`adb devices`,确保设备已经被检测到。 - 使用命令`adb install <path_to_apk>`,其中`<path_to_apk>`指向要安装APK文件的路径。 - ADB客户端将APK文件发送到设备,并启动设备上的ADB守护进程。 - ADB守护进程将APK文件传递给`pm install`命令进行处理。 2. `pm install`安装流程: - 接收到安装请求的`pm install`命令会调用PackageManagerService中的相应方法来处理安装操作。 - 首先,会进行签名验证,确保APK文件的签名与设备上已安装应用程序的签名匹配或者具备系统签名。 - 然后,会检查应用程序的权限列表,并与设备的权限进行比对。 - 如果验证通过,PackageManagerService会解析APK文件,提取应用程序的信息(包名、版本号等)。 - 接下来,会为应用程序分配用户ID,并在系统中创建应用程序的数据目录。 - 最后,会将应用程序的APK文件复制到设备的数据分区,并注册应用程序的信息到PackageManagerService中,使其成为已安装应用。 需要注意的是,`pm install`命令可以在设备上直接运行,而`adb install`命令需要通过ADB客户端与设备进行通信。这两个命令都是通过PackageManagerService来处理应用程序的安装,但`adb install`命令会先将APK文件传递给设备上运行的ADB守护进程,再由守护进程调用`pm install`命令进行处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值