你真的了解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》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

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

免费

免费

[美] 克里斯·安德森 / 蒋旭峰、冯斌、璩静 / 中信出版社 / 2009-9 / 39.00

在《免费:商业的未来 》这本书,克里斯·安德森认为,新型的“免费”并不是一种左口袋出、右口袋进的营销策略,而是一种把货物和服务的成本压低到零的新型卓越能力。在上世纪“免费”是一种强有力的推销手段,而在21世纪它已经成为一种全新的经济模式。 究竟什么是免费商业模式?根据克里斯·安德森的说法,这种新型的“免费”商业模式是一种建立在以电脑字节为基础上的经济学,而非过去建立在物理原子基础上的经济学。......一起来看看 《免费》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

URL 编码/解码
URL 编码/解码

URL 编码/解码