• 【Android安全】Binder解析


    参考: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对象serviceConnection

      intent.setAction("com.baronzhang.ipc.server");
      bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
      
      • 1
      • 2
    • 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() {…………}
      
      • 1

      Client端 调用Stub类的静态方法asInterface,将Server端传递来的IBinder对象转换为Proxy对象

      private ServiceConnection serviceConnection = new ServiceConnection() {
              @Override
              public void onServiceConnected(ComponentName name, IBinder service) {
              ……
      		bookManager = Stub.asInterface(service);
              ……
      		}
      ……
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9

      其实,Proxy类只有两个成员变量:IBinder类对象remote,String类对象DESCRIPTOR(用于让Binder驱动 区分这个Proxy对象对应于哪个Binder Server)

      private static final String DESCRIPTOR = "com.baronzhang.ipc.server.BookManager";
      private IBinder remote;
      
      • 1
      • 2

      所以只用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() {…………}
    
    • 1

    Client端 调用Stub类的静态方法asInterface,将Server端传递来的IBinder对象转换为Proxy对象

    private ServiceConnection serviceConnection = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
            ……
    		bookManager = Stub.asInterface(service);
            ……
    		}
    ……
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    其实,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;
    
    • 1
    • 2

    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
    在这里插入图片描述

    在这里插入图片描述

  • 相关阅读:
    (一)Amira入门实例
    windows7中安装docker
    Fe3O4纳米粒子/氧化锌纳米粒子/纳米氧化铈/纳米聚乙烯修饰二氧化硅微球表征探究
    【文件输入输出流】Inputstream和Outputstream
    《致新来的你》
    vue学习-10vue整合SpringBoot跨域请求
    007 怎么修改win7电脑系统显示时间
    软件测试周刊(第83期):当你感觉忙得没时间休息,就是你最需要找时间休息的时候。 ​​​
    开启防火墙iptable规则后,系统网络变慢
    【iPad已停用】解锁教程
  • 原文地址:https://blog.csdn.net/qq_39441603/article/details/126006535