你真的了解Android权限机制吗?@2

栏目: IOS · Android · 发布时间: 5年前

内容简介:接上文https://www.epubit.com/selfpublish/article/6093 @1未完编辑,有敏感词(代码里小写的ID居然是敏感词)。。。。那么第二个问题,当我们安装应用完成,启动应用,应用的进程是如何启动并被赋予进程属性的呢?

接上文https://www.epubit.com/selfpublish/article/6093 @1

未完编辑,有敏感词(代码里小写的ID居然是敏感词)。。。。

那么第二个问题,当我们安装应用完成,启动应用,应用的进程是如何启动并被赋予进程属性的呢?

每个应用都会运行在自己的 Dalvik 虚拟机进程中,但是为了提高启动效率,Android 不会为每个应用都新建一个 Dalvik 进程,而是采用 fork 的形式。每个进程都 fork form zygote 进程。那么 fork 比起 new ,效率提高在哪里?

因为 zygote 进程已经预加载了大部分核心和 Java 应用框架库,fork 的子进程会继承 zygote 的进程空间,也就是说,fork 的子进程,可以共享这些预加载的副本(记住,是副本,不是直接共享。fork 时,会 copy-on-write 预加载的内容),减少了重新加载核心库的时间。

当 zygote 收到启动新进程的请求时,它会 fork 自身出一个子进程,并对该子进程做特殊化处理。其源代码位于 dalvik/vm/native/dalvik_system_Zygote.c 中。forkAndSpecializeCommon() 的主要代码如下:

staticp_tforkAndSpecializeCommon(constu4

args, boolisSystemServer)

{

...

pID = fork();//创建新进程

if(pID ==0)//判断是否是root,有没有权限修改自己的进程属性

{

setgroupsIntarray(gIDs);//设置进程的所有组

setrlimitsFromArray(rlimits);

setgid(gID);//设置进程的组ID

setuid(uID);//设置进程的用户ID

}

...

}

args, boolisSystemServer)

{

...

pid = fork();//创建新进程

if(pid ==0)//判断是否是root,有没有权限修改自己的进程属性

{

setgroupsIntarray(gids);//设置进程的所有组

setrlimitsFromArray(rlimits);

setgid(gid);//设置进程的组ID

setuid(uid);//设置进程的用户ID

}

...

}

如上所示:这里设置进程的组 ID 和用户 ID,通过 fork 创建的子进程调用 setgroups Intarray 设置该进程所属的组,这样应用程序就拥有了该组的权限,并且可以通过 setgid() 及 setuid() 确定应用程序的 GID 及 UID 值。刚刚开始 fork 时,子进程是以 root 执行的,所以它可以更改自己的进程属性,当属性都设置完成,子进程就以分配的 GID 和 UID 执行,此时,子进程无法再更改自己的进程属性了,因为用户 ID 已经不是 root 即 ! = 0 了,没有修改自己进程属性的权限了。

adb shell ps,看下进程列表:

USERPIDPPIDVSZRSSWCHANADDRSNAME

root1 0 10456 2352SyS_epoll_wait0Sinit

...

root1620 1 1614572 20312poll_schedule_timeout0Szygote

...

u0_a883468 1620 1929916 112340SyS_epoll_wait0Scom.feelschaotic.demo

u0_a903574 1620 1696012 24176SyS_epoll_wait0Scom.demo.pushdemo

u0_a903607 1620 1708844 26748SyS_epoll_wait0Scom.demo.pushdemo:mult

u0_i03741 1879 1557800 11720SyS_epoll_wait0Scom.android.chrome:sandboxed

u0_a153774 1620 1690604 22056SyS_epoll_wait0Scom.google.android.ext.services

system3805 1620 1687840 19688SyS_epoll_wait0Scom.android.keychain

u0_a423831 1620 1834408 45660SyS_epoll_wait0Scom.android.chrome

...

PID 表示应用的进程 ID,PPID 表示父进程 ID,NAME 表示进程名称(一般情况下 NAME 是应用包名)。可以看到 zygote 进程是由 init 进程启动,所有的应用进程的父进程都是 zygote。USER 表示的是进程的专有用户,这个我们下次再详细讲讲 Android 的用户管理机制。

好了,既然如此,每个应用进程都分配好自己的 GID、UID和补充 GID,系统内核和守护进程就可以用这些标识来决定,是否要赋予进程权限。

权限的检查

1. 系统内核层权限检查

思考一下:如果我们的应用没有在 AndroidManifest.xml 中申请 android.permission.INTERNET 权限就进行网络请求,是不是会报 Permission denied 错误。这个权限,是谁来检查?其他进程来检查吗?明显不是,网络访问权限是由低层来进行控制的。

Android 的访问控制,和 Linux 是一样的,但 Android 增加了个特有的网络访问安全控制机制,也就是说,创建网络套接字的进程,必须属于 inet 组。

你真的了解Android权限机制吗?@2 如上内核代码,current_has_network(void) 方法检查了进程的所在组。如果不在 inet 组,则直接返回错误。所以为了使我们的应用具有访问网络的能力,我们需要在 AndroidManifest.xml 中申请 INTERNET 权限,经过解析,逐步映射到内核层的组 ID 和用户 ID,最终才能通过内核层的检查。

你可能会有疑问,那非内核层的其他 C/C++ 层,要怎么拿到进程的所在组信息呢?在 PMS 初始化所有包信息之后,就会调用 mSettings.writeLPr()。

你真的了解Android权限机制吗?@2 你真的了解Android权限机制吗?@2

这段代码的任务就是将mPackages 中保存的所有包的信息保存到 /data/system/packages.list。所以,packages.list中保存了所有应用申请的权限,C代码只要读这个文件就能判断某个应用是否申请了我们要求的权限。

你真的了解Android权限机制吗?@2

以上所述就是小编给大家介绍的《你真的了解Android权限机制吗?@2》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

马化腾自述-我的互联网思维

马化腾自述-我的互联网思维

赵黎 / 石油工业出版社 / 2014-8-1 / 35

马化腾自述:我的互联网思维》讲述了些人说移动互联网就是加了“移动”两个字,互联网十几年了,移动互联网应该是个延伸。我的感受是,移动互联网远远不只是一个延伸,甚至是一个颠覆。互联网是一个开放交融、瞬息万变的大生态,企业作为互联网生态里面的物种,需要像自然界的生物一样,各个方面都具有与生态系统汇接、和谐、共生的特性。开放和分享并不是一个宣传口号,也不是一个简单的概念。开放很多时候被看作一种姿态,但是我......一起来看看 《马化腾自述-我的互联网思维》 这本书的介绍吧!

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

html转js在线工具
html转js在线工具

html转js在线工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换