没有 addService() 的 C++ Binder

Posted

技术标签:

【中文标题】没有 addService() 的 C++ Binder【英文标题】:C++ Binder without addService() 【发布时间】:2014-03-17 16:37:49 【问题描述】:

是否可以使用 C++ Binder API 在两个非特权进程之间进行通信?

我发现的所有示例(例如https://github.com/mcr/android-HelloWorldService)都依赖于通过ServiceManager->addService() 注册服务,这在非root 手机上执行时会引发以下错误:

E/ServiceManager﹕ add_service('my.test.service',0x48) uid=2000 - PERMISSION DENIED

【问题讨论】:

【参考方案1】:

在文件frameworks/native/cmds/servicemanager/service_manager.c中的AOSP(Android Open Source Project)里面 你可以找到以下方法:

int svc_can_register(uid_t uid, const uint16_t *name)

    size_t n;

    if ((uid == 0) || (uid == AID_SYSTEM))
        return 1;

    for (n = 0; n < sizeof(allowed) / sizeof(allowed[0]); n++)
        if ((uid == allowed[n].uid) && str16eq(name, allowed[n].name))
            return 1;

    return 0;

还有一点:

/* TODO:
 * These should come from a config file or perhaps be
 * based on some namespace rules of some sort (media
 * uid can register media.*, etc)
 */
static struct 
    uid_t uid;
    const char *name;
 allowed[] = 
     AID_MEDIA, "media.audio_flinger" ,
     AID_MEDIA, "media.log" ,
     AID_MEDIA, "media.player" ,
     AID_MEDIA, "media.camera" ,
     AID_MEDIA, "media.audio_policy" ,
     AID_DRM,   "drm.drmManager" ,
     AID_NFC,   "nfc" ,
     AID_BLUETOOTH, "bluetooth" ,
     AID_RADIO, "radio.phone" ,
     AID_RADIO, "radio.sms" ,
     AID_RADIO, "radio.phonesubinfo" ,
     AID_RADIO, "radio.simphonebook" ,
/* TODO: remove after phone services are updated: */
     AID_RADIO, "phone" ,
     AID_RADIO, "sip" ,
     AID_RADIO, "isms" ,
     AID_RADIO, "iphonesubinfo" ,
     AID_RADIO, "simphonebook" ,
     AID_MEDIA, "common_time.clock" ,
     AID_MEDIA, "common_time.config" ,
     AID_KEYSTORE, "android.security.keystore" ,
;

再往下:

if (!svc_can_register(uid, s)) 
    ALOGE("add_service('%s',%x) uid=%d - PERMISSION DENIED\n",
         str8(s), handle, uid);
    return -1;

结论:/system/bin/servicemanager 中的系统二进制文件不允许。 (出于安全原因) 可能的解决方案:

杀死并重用列出的 PID 和服务名称 重新编译你自己的 servicemanager 二进制文件并使用这个 在这个二进制文件中注入你的代码,让每个人都可以 更改 servicemanager 读取的 PID(更改 ioctl 响应 servicemanager 在 binder.h(同一目录)中获取) 或者只是在具有 root 权限的二进制文件中启动您的服务器。客户端无需 root 即可连接,但服务器需要它。

【讨论】:

以上是关于没有 addService() 的 C++ Binder的主要内容,如果未能解决你的问题,请参考以下文章

自定义配置集合 - 无法识别的元素“addService”

CBPeripheralManager AddService 上的 iOS 崩溃断言失败:

Binder学习笔记—— ServiceManager如何响应addService请求 ?

Binder学习笔记—— ServiceManager如何响应addService请求 ?

Binder学习笔记—— binder服务端是如何组织addService数据的?

错误(mingw32/bin/ld.exe 最终链接失败:设备上没有剩余空间)构建 C++ 项目