当前位置:网站首页>【Android安全】Binder解析
【Android安全】Binder解析
2022-08-08 06:27:00 【Jouzzy】
参考:https://zhuanlan.zhihu.com/p/35519585
Binder一次copy的原理

相比于其他IPC机制
相比于其他IPC机制(Socket、共享内存):
相比于Socket(以及管道、信号量等),Binder少了一个copy(少了copy_to_user),因此更快
相比于共享内存,无需实现复杂的访问控制策略(锁)
Binder代理机制
当 A 进程想要获取 B 进程中的 object 时,驱动并不会真的把 object 返回给 A,而是返回了一个跟 object 看起来一模一样的代理对象Proxy,这个 Proxy 具有和 object 一摸一样的方法,但是这些方法并没有 B 进程中 object 对象那些方法的能力,这些方法只需要把把请求参数交给驱动即可。对于 A 进程(client)来说和直接调用 object 中的方法是一样的。
当 Binder 驱动接收到 A 进程的消息后,发现这是个 Proxy 就去查询自己维护的表单,一查发现这是 B 进程 object 的代理对象。于是就会去通知 B 进程调用 object 的方法,并要求 B 进程把返回结果发给自己。当驱动拿到 B 进程的返回结果后就会转发给 A 进程,一次通信就完成了。
Java层Binder的各个类和接口
IBinder : 是一个接口。只要类实现了这个接口,类的对象就能跨进程传输。下文简称IBinder接口的实现类的对象 为 IBinder对象
客户端调用bindService方法,接收服务端传递来的IBinder对象,存为IBinder对象serviceConnectionintent.setAction("com.baronzhang.ipc.server"); bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
IInterface : 是一个接口,代表Server 提供给Client的方法的集合
Binder : 一个类,实现了 IBinder 接口,Binder类对象应该出现在Server端
BookManager:Server端定义的接口,继承IInterface接口;定义Server端提供的功能,但不实现功能
其中功能方法的实现,在Server端新建的Stub对象中Stub:AIDL生成的类,实现BookManager接口,继承Binder类
客户端和服务端均可调用Stub类的方法
Server端 在新建的Stub对象中,实现提供给Client端的功能方法
private final Stub bookManager = new Stub() { …………}
Client端 调用Stub类的静态方法asInterface,将Server端传递来的IBinder对象转换为Proxy对象
private ServiceConnection serviceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { …… bookManager = Stub.asInterface(service); …… } …… }
其实,Proxy类只有两个成员变量:IBinder类对象remote,String类对象DESCRIPTOR(用于让Binder驱动 区分这个Proxy对象对应于哪个Binder Server)
private static final String DESCRIPTOR = "com.baronzhang.ipc.server.BookManager"; private IBinder remote;
所以只用IBinder对象service,就能初始化一个Proxy对象了
此外,服务端的Stub对象的onTransact()方法,会根据方法编号调用BookManager中的相关方法
Proxy:Server端定义的类,实现了BookManager接口
Server端将一个 IBinder的实现类的对象 (下文简称IBinder对象)传递给客户端,客户端利用此IBinder对象,创建Proxy对象类的实例出现在Client端,代表Server端的 Stub对象的代理
Proxy中实现的方法体,不实际处理任务,而是负责从客户端接收参数,交给服务端;再从服务端获取返回值,交给客户端
Binder、IBinder 和 IInterface 的关系:
参考https://blog.csdn.net/caoshen2014/article/details/99782563
关于AIDL
参考:https://juejin.cn/post/6844903496882323464
AIDL:Android Interface Define Language
AIDL代码遵循Java语法
AIDL代码存放在AIDLmodule中的.aidl文件里,需要经过AS的编译,才能转换为Java代码
Java层Binder实例代码分析
完整代码在:https://link.zhihu.com/?target=https%3A//github.com/BaronZ88/HelloBinder
IInterface : 是一个接口,代表Server 提供给Client的方法的集合
Binder : 一个类,实现了 IBinder 接口,Binder类对象应该出现在Server端
BookManager:Server端定义的接口,继承IInterface接口;定义Server端提供的功能,但不实现功能;
具体功能方法的实现,在Server端新建的Stub对象中
Stub:AIDL生成的类,实现BookManager接口,继承Binder类
客户端和服务端均可调用Stub类的方法。
Server端 在新建的Stub对象中,实现提供给Client端的功能方法
private final Stub bookManager = new Stub() {
…………}
Client端 调用Stub类的静态方法asInterface,将Server端传递来的IBinder对象转换为Proxy对象
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
……
bookManager = Stub.asInterface(service);
……
}
……
}
其实,Proxy类只有两个成员变量:IBinder类对象remote,String类对象DESCRIPTOR(用于让Binder驱动 区分这个Proxy对象对应于哪个Binder Server)
所以只用IBinder对象service,就能初始化一个Proxy对象了
private static final String DESCRIPTOR = "com.baronzhang.ipc.server.BookManager";
private IBinder remote;
Proxy:Server端定义的类,实现了BookManager接口
Server端将一个 IBinder的实现类的对象 (下文简称IBinder对象)传递给客户端,客户端利用此IBinder对象,通过Stub.asInterface,创建Proxy对象:
类的实例出现在Client端,代表Server端的 Stub对象的代理
关于asInterface函数:
Proxy中实现的方法体,不实际处理任务,而是负责从客户端接收参数,交给服务端;再从服务端获取返回值,交给客户端
Stub类中,会对BookManager中的方法进行编号:
Proxy中调用transact进行分配:
private IBinder remote;
remote.transact(Stub.TRANSAVTION_getBooks, data, reply, 0);
最终调用到Stub的onTransact函数:
Native层Binder实现
参考:https://blog.csdn.net/a372048518/article/details/75020240
鸡生蛋问题
参考https://www.jianshu.com/p/062a6e4f5cbe
ServiceManager和Binder驱动属于两个不同的进程,它们是为Client和Server之间的进程间通信服务的,也就是说Client和Server之间的进程间通信依赖ServiceManager和Binder驱动之间的进程间通信,这就像是:“蛋生鸡,鸡生蛋,但第一个蛋得通过一只鸡孵出来”。Binder机制是如何创造第一只下蛋的鸡呢?
当Android系统启动后,会创建一个名称为servicemanager的进程,这个进程通过一个约定的命令BINDERSETCONTEXT_MGR向Binder驱动注册,申请成为ServiceManager,Binder驱动会自动为ServiceManager创建一个Binder实体(第一只下蛋的鸡);
并且这个Binder实体的引用在所有的Client中都为0,也就说各个Client通过这个0号引用就可以和ServiceManager进行通信。Server通过0号引用向ServiceManager进行注册,Client通过0号引用就可以获取到要通信的Server的Binder引用。
边栏推荐
猜你喜欢
随机推荐
【图形学】02 数学部分(二、向量和坐标系)
P19 美颜相机的实现——基础铺垫1
模块知识点补充
C language judges the problem of big and small endian storage
NVIDIA CUDA 高度并行处理器编程(四):性能优化习题
NVIDIA CUDA 高度并行处理器编程(七):并行模式:前缀和
网络安全笔记第三天day3(kali2021系统的安装)
leetcode每日一题8.6(持续更新)
文件IO实现图片的加密操作
【图形学】四元数(二)
golang 服务大量 CLOSE_WAIT 故障排查
模块及模块导入
CSDN21天学习挑战赛之顺序查找
有符号数和无符号数参与运算时的问题
Implementation of bubble sort in C language and optimization of bubble sort
C# Unicode (Universal Code) text conversion
带头双向循环链表的增删查改
Stack queue OJ question sharing and explanation
Makefile文件的编写(实例详解)
Unity—ParticleSystem(粒子系统)与Animator(动画状态机)批量管理器