第三节-Android10.0 Binder通信原理(三)-ServiceManager篇

news2025/1/11 18:36:21

1、概述

        在Android中,系统提供的服务被包装成一个个系统级service,这些service往往会在设备启动之时添加进Android系统,当某个应用想要调用系统某个服务的功能时,往往是向系统发出请求,调用该服务的外部接口。在上一节我们了解到,这种外部接口,我们通常称之为代理接口,也就是我们要拿到目标服务对应的代理对象。
    //TODO

    在Android8.0后,谷歌引入Treble机制,binder机制增加了hwbinder和vndbinder,其中vndbinder的守护进程为vndservicemanager。
    vndservicemanager和service共用同一份代码,只是传入的参数和宏控制的流程有部分差异。
    vndservicemanager会传入参数“/dev/vndbinder”,servicemanager使用默认的“/dev/binder”。
    servicemanager主要做了以下几件事:
    1、打开binder驱动,申请了128k的内存空间
    2、然后调用binder_become_context_manager()让自己成为整个系统中唯一的上下文管理器,其实也就是service管理器
    3、调用binder_loop()进入无限循环,不断监听并解析binder驱动发来的命令


2、Binder架构

//TODO

3、servicemanager的启动

//TODO

4、service_manager调用栈:

//TODO

5、源码分析

    5.1 主程序启动main()

         //TODO

    5.2 binder_open()

        servicemanager启动后,先通过binder_open()来打开“/dev/binder”,代码如下:
        

binder_open()的工作也比较简单,分为以下几步:

1、通过系统调用open()来打开“/dev/binder”,获得一个句柄信息,在Binder驱动重对应的是函数binder_open()

2、通过ioctl获取binder的版本信息,比较binder协议版本是否相同,不同则跳出,在Binder驱动重对应的是函数binder_ioctl()

3、通过mmap内存映射128k的内存空间,即把binder驱动文件的128K字节映射到了内存空间,这128K内存空间的servicemanager使用,在Binder驱动重对应的是函数binder_mmap()。

其他的binder服务进程会映射BINDER_VM_SIZE((1*1024*1024)-sysconf(SC_PAGE_SIZE)*2)的内存空间,SC_PAGE_SIZE表示一个page页的大小,通常情况下为4K,即(1M-4K*2)=(1M-7K)

这个page的大小,不同厂家有时候也会调整大小,一般有1M,64K,4K,1KB,通常为4K。

ServiceManager进程mmap的内存大小可以通过adb shell命令得出:

其中0x7457b61000 -0x745d41000=0x20000,转成10进制,即为128K

ARM32内存映射:

虚拟空间的低3GB部分从0-0XBFFFFFFF的虚拟线性地址,用户态和内核态都可以寻址,这部分也是每个进程的独立空间。

虚拟空间的高1G部分从0XC00000000到0XFFFFFFFF的虚拟地址,只有内核态的进程才能访问,这种限制由页目录和页眉描述符的权限标示位决定,通过MML启动控制

ARM64内存映射:

默认情况下,32位系统默认只能支持4G的内存,在打开PAE后,最大可以扩展到64G的内存,随着物理硬件的不断升级,现在的内存越来越大,因此基本上都切换到了64位系统。

理论上讲,64位的地址总线可以支持高达16EB(2^64)的内存。

2^64次方太大了,Linux内核只采用了64bits的一部分(开启CONFIG_ARM64_64K_PAGES时使用42bits,页大小是4K时使用39bits),该文假设使用的页大小是4K(VA_BITS=39)

ARM64有足够的虚拟地址,用户空间和内核空间可以有各自的2^39=512GB的虚拟地址。

需要注意到,32位应用仍然拥有512GB的内核虚拟地址空间,并且不与内核共享自己的4GB空间,但在ARM32上,32位应用只有3GB的地址空间。

ARM32和ARM64内存地址比较:


    5.3 binder_become_context_manager()

binder_become_context_manager()的作用是让servicemanager成为整个系统中唯一的上下文管理器,其实也就是service管理器,这样我们就可以把ServiceManager称之为守护进程。

对应的binder驱动中操作如下:

从用户空间拷贝ioctl的参数,调用binder_ioctl_set_ctx_mgr()进行设置

BINDER_SET_CONTEXT_MGR_EXT带参数,BINDER_SET_CONTEXT_MGR不带参数

binder_ioctl_set_ctx_mgr()的流程也比较简单

1、先检查当前进程是否具有注册Context Manager的SEAndroid安全权限

2、如果具有SELinux权限,会为整个系统的上下管理器专门生成一个binder_node节点,便该节点的强弱应用加1

3、新创建的binder_node节点,记入context->binder_context_mgr_node,即ServiceManager进程的context binder节点,使之成为serviceManager的binder管理实体


    5.4 binder_loop()

        下一步进行守护进程的循环处理,binder_loop()会先向binder驱动发出了BC_ENTER_LOOPER命令,告诉binder驱动“本线程要进入循环状态了”,接着进入一个for循环不断调用ioctl()读取发来的数据,接着解析这些数据

其中最重要的一个结构体是binder_write_read,它用来记录Binder buffer中读和写的数据信息结构体如下:

    5.5 binder_parse()

        在binder_loop()进入for循环之后,核心处理流程就是ioctl和binder_parse(),即不停的从Binder驱动接收读写数据,进行binder解析后,进行处理。

在binder_loop()中声明了一个128字节的栈内存-readbuf,用BINDER_WRITE_READ命令从驱动读取一些内容,并传入binder_parse(),binder_parse()根据binder驱动传来的“BR_XXX”协议码,进行相关的逻辑处理,最重要的有三个“BR_XXX”协议:

BR_TRANSACTION:事务处理,解析binder_transaction_data的数据,调用回调函数svcmgr_handler()进行服务的注册,获取等操作

BR_REPLY:消息回复

BR_DEAD_BINDER:死亡通知

只要binder_parse()解析正常,binder_loop()就会一直执行下去,ServiceManager进程不退出。

binder_parse()解析binder驱动传来的readbuf的内存,readbuf拥有128字节的栈内存,每次可以只处理一个cmd,也可以有多个cmd,所以存在一个while循环,可以同时解析多个cmd,多个cmd的结构体如下图所示:

        5.5.1 BR_XXX 协议码分析

        BR_XXX码,也称为Binder响应码,这里介绍了ServiceManager处理的一些响应码的作用:

        5.5.2 BR_TRANSACTION解析

        我们这里单独分析下BR_TRANSACTION的流程,这也是我们常用的一个流程,这是Binder驱动向Server端发送请求数据。

从readbuf中解析出binder_transaction_data的数据,最后对接收和发送数据进行了封装,传递给svcmgr_handler()做详细处理

从上main的逻辑看,我们重点关注的是binder_transaction_data这个结构,binder_transaction_data说明了transaction到底在传输什么语义,而语义码就记录在其code成员中,不同语义码需要携带的数据也是不同的,这些数据由data指定。

结构体说明如下:

从上面binder_transaction_data的结构可以看出,data可存入的数据很少,主要采用了数据其实地址和数据偏移量,根据代码上下文可知,调用了bio_init_from_txn(),从txn.transaction_data解析出binder_io的信息,存入msg

        5.5.2.1 bio_init_from_txn()

bio_init_from_txn()的作用就是把binder_transaction_data的“数据起始地址”,“偏移量”,“data数据的总大小”和“偏移数组中可用的条目”:

binder_transaction_data和binder_io的关联

初始化完binder_io的replay,并把transaction_data转换成了binder_io的msg后,调用回调函数svcmgr_handler()进行最终逻辑处理

    5.6 svcmgr_handler()

        在BR_TRANSACTION的命令解析后,就把binder_transaction_data_secctx的数据传给回调函数svcmgr_handler()进行处理。

根据不同的传输语义码(txn->code)来进行相应的操作:查询服务,注册服务,以及列举所服务

源码如下:

    5.7 ServiceManager是如何管理service信息的?

        //TODO

    5.8 注册服务

        根据传入的code:SVC_MGR_ADD_SERVICE得知,本次binder流程想要进行服务注册。

步骤:

从binder_io msg中获取服务名称和长度

从binder_io msg中获取handle

检查该服务是否有注册的selinx权限

查询服务列表svclist是否存在该handle,如果有handle,就更新该服务的handle信息,通过这个handle我们最终就能找到远端的service实体

如果svclist不存在该服务,申请一个svcinfo的空间,把服务名,长度,handle等信息存入其中

把svcinfo进入svclist的链表中

再以BC_ACQUIRE命令,handle为目标的信息,通过ioctl发送给binder驱动

最后以BC_REQEST_DEATH_NOTIFICATION命令的信息,通过ioctl发送给binder驱动,主要用于清理内存等收尾工作        

    5.9 查找服务

        //TODO

6、总结

        //TODO

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1240773.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vue批量全局处理undefined和null转为““ 空字符串

我们在处理后台返回的信息,有的时候返回的是undefined或者null,这种字符串容易引起用户的误解,所以需要我们把这些字符串处理一下。 如果每个页面都单独处理,那么页面会很冗余,并且后期如果有修改容易遗漏&#xff0c…

生成式AI与大语言模型,东软已经准备就绪

伴随着ChatGPT的火爆全球,数以百计的大语言模型也争先恐后地加入了这一战局,掀起了一场轰轰烈烈的“百模大战”。毋庸置疑的是,继方兴未艾的人工智能普及大潮之后,生成式AI与大语言模型正在全球开启新一轮生产力革新的科技浪潮。 …

PostgreSQL (Hologres) 日期生成

PostgreSQL 生成指定日期下一个月的日期 (在Hologres中,不支持递归查询) SELECTto_char(T, YYYYMMDD)::int4 AS date_int,date(T) AS date_str,date_part(year, T)::int4 AS year_int,date_part(month, T)::int4 AS month_int,date_part(da…

中职组网络安全B模块-渗透提权2

任务五:渗透提权2 任务环境说明: 仅能获取xxx的IP地址 用户名:test,密码:123456 访问服务器主机,找到主机中管理员名称,将管理员名称作为Flag值提交; Flag:doyoudoyoudo 访问服…

使用Pytorch从零开始构建DCGAN

在本文中,我们将深入研究生成建模的世界,并使用流行的 PyTorch 框架探索 DCGAN(生成对抗网络 (GAN) 的一种变体)的实现。具体来说,我们将使用 CelebA 数据集(名人面部图像的集合)来生成逼真的合…

微服务学习|初识Docker、使用Docker、自定义镜像、DockerCompose、Docker镜像仓库

初识Docker 项目部署的问题 大型项目组件较多,运行环境也较为复杂,部署时会碰到一些问题 依赖关系复杂,容易出现兼容性问题 开发、测试、生产环境有差异 Docker如何解决依赖的兼容问题的? 将应用的Libs (函数库)、Deps (依赖)配置与应用…

c语言:用迭代法解决递归问题

题目&#xff1a; 解释&#xff1a;题目的意思就是用迭代法的空间和时间复杂的太高了&#xff0c;需要我们减小空间与时间的复杂度&#xff0c;我就想到了迭代法&#xff0c;思路和代码如下&#xff1a; #include <stdio.h> //这里是递归法转迭代法 int main() {int x,i…

Spark---转换算子、行动算子、持久化算子

一、转换算子和行动算子 1、Transformations转换算子 1&#xff09;、概念 Transformations类算子是一类算子&#xff08;函数&#xff09;叫做转换算子&#xff0c;如map、flatMap、reduceByKey等。Transformations算子是延迟执行&#xff0c;也叫懒加载执行。 2)、Transf…

Leetcode——121 买卖股票的最佳时机

(超时。。。。。。&#xff09;除了暴力法我是真的。。。。。。 class Solution {public int maxProfit(int[] prices) {int len prices.length;int max0;for(int i0;i<len-1;i){for(int ji1;j<len;j){int income prices[j] - prices[i];if(income>max){maxincome;…

路由的控制与转发原理

场景1&#xff1a;路由器收到数据包后&#xff0c;会根据数据包的目标IP地址&#xff0c;计算出目标网段&#xff0c;再确定终端设备的具体位置。这个过程中&#xff0c;还需要计算出接口&#xff0c;或数据包下一跳的地址。最终会生成一条路由&#xff0c;即路径&#xff0c;存…

外部中断为什么会误触发?

今天在写外部中断的程序的时候&#xff0c;发现中断特别容易受到干扰&#xff0c;我把手放在对应的中断引脚上&#xff0c;中断就一直触发&#xff0c;没有停过。经过一天的学习&#xff0c;找到了几个解决方法&#xff0c;所以写了这篇笔记。如果你的中断也时不时会误触发&…

基于JavaWeb+SSM+Vue教学辅助微信小程序系统的设计和实现

基于JavaWebSSMVue教学辅助微信小程序系统的设计和实现 源码获取入口前言主要技术系统设计功能截图Lun文目录订阅经典源码专栏Java项目精品实战案例《500套》 源码获取 源码获取入口 前言 1.1 概述 随着信息时代的快速发展&#xff0c;互联网的优势和普及&#xff0c;人们生活…

二、防火墙-安全策略

学习防火墙之前&#xff0c;对路由交换应要有一定的认识 1、安全策略基本概念2、匹配顺序3、缺省包过滤4、安全策略发展史4.1.基于ACL包过滤4.2.融合UTM安全策略4.3.一体化安全策略 5、Local区域安全策略5.1.针对OSPF协议配置Local区域安全策略5.2.其他协议 6、ASPF6.1.帮助FTP…

PCIE链路训练-状态跳转1

A&#xff1a;12ms超时&#xff0c;或者再任何lane上检测到Electrical Idle Exit&#xff1b; B&#xff1a; 1.发送“receiver detection”之后没有一个lane的接收逻辑被rx检测到 2.不满足条件c&#xff0c;比如两次detection出现差别&#xff1b; C&#xff1a;发送端在没…

文本分析:NLP 魔法!

一、说明 这是一个关于 NLP 和分类项目的博客。NLP 是自然语言处理&#xff0c;目前需求量很大。让我们了解如何利用 NLP。我们将通过编码来理解流程和概念。我将在本博客中介绍 BagOfWords 和 n-gram 以及朴素贝叶斯分类模型。这个博客的独特之处&#xff08;这使得它很长&…

竞赛选题 车道线检测(自动驾驶 机器视觉)

0 前言 无人驾驶技术是机器学习为主的一门前沿领域&#xff0c;在无人驾驶领域中机器学习的各种算法随处可见&#xff0c;今天学长给大家介绍无人驾驶技术中的车道线检测。 1 车道线检测 在无人驾驶领域每一个任务都是相当复杂&#xff0c;看上去无从下手。那么面对这样极其…

Oracle 的 Java SE、OpenJDK、Database 链接

1 访问主站 Oracle | Cloud Applications and Cloud Platform 2 开发者 2.1 OpenJDK (这里的不用登录&#xff0c;就可以下载) JDK Builds from Oracle 2.2 JavaSE (需要登录&#xff0c;才可以下载) Java Downloads | Oracle 2.3 DataBase (MySQL为例) MySQL :: MySQL Dow…

排序算法--快速排序

实现逻辑 ① 从数列中挑出一个元素&#xff0c;称为 “基准”&#xff08;pivot&#xff09;&#xff0c; ② 重新排序数列&#xff0c;所有元素比基准值小的摆放在基准前面&#xff0c;所有元素比基准值大的摆在基准的后面&#xff08;相同的数可以到任一边&#xff09;。在这…

DataFunSummit:2023年OLAP引擎架构峰会-核心PPT资料下载

一、峰会简介 OLAP技术是当前大数据领域的热门方向&#xff0c;该领域在各个行业都有广泛的使用场景&#xff0c;对OLAP引擎的功能有丰富多样的需求。同时&#xff0c;在性能、稳定性和成本方面&#xff0c;也有诸多挑战。目前&#xff0c;OLAP技术没有形成统一的事实标准&…

系统移植-交叉编译工具链

不同架构的机器码 与 汇编语言 都不可移植&#xff0c; 且二者一一对应 c语言中三种成分&#xff1a; 1.分号结尾的叫做语句 语句可以让CPU执行&#xff0c;可以进行预处理&#xff0c;编译等生成机器码 2.#开头的为预处理指令 不带分号 CPU无法执行 3.注释&#xff0c;…