getCallingUid/getCallingPid 在 Handler.handleMessage 中返回当前的 uid 和 pid

Posted

技术标签:

【中文标题】getCallingUid/getCallingPid 在 Handler.handleMessage 中返回当前的 uid 和 pid【英文标题】:getCallingUid/getCallingPid return current uid and pid in Handler.handleMessage 【发布时间】:2011-09-05 15:19:23 【问题描述】:

我有一个扩展android.os.Handler 的课程。此处理程序的一个实例被传递给Messenger 的构造函数。来自getBinderMessengerIBinder 作为我服务中onBind 事件的结果传递。从远程应用程序通过活页夹发送的消息确实会转到处理程序的handleMessage 方法,但是在handleMessage 中调用Binder.getCallingUidBinder.getCallingPid 总是返回服务进程的uid 和pid(这绝对不是同一个进程作为远程应用程序)。 handleMessage 绝对是 IPC 事务的一部分,不是吗?那么我哪里出错了?我需要它来对连接的应用程序进行身份验证。

提前致谢。

编辑

好的。我有一种可怕的感觉,handleMessage 不是 IPC 事务的一部分,因为这发生在 AIDL 的单独线程中,它将消息放入Messenger 的队列中。有没有其他方法可以获取调用者的 User ID 和 Process ID?

【问题讨论】:

【参考方案1】:

创建一个自定义的Handler 类并覆盖sendMessageAtTime(这是Handler 类中唯一可覆盖的发布方法),然后使用它创建一个从onBind 返回的Messenger

sendMessageAtTime方法中,可以通过getCallingPidgetCallingUid获取调用远程应用的pid/uid。

但是,在使用Messenger 的IPC 中,与使用AIDL 不同,getCallingPid 将始终返回0,因为远程应用程序发送的消息是异步的;与IBinder.FLAG_ONEWAY 的交易。 因此,uid 是唯一可用的信息。

【讨论】:

非常感谢!事实上,看起来 sendMessageAtTime 在 getCallingPid 上给出了正确的响应【参考方案2】:

我想出了一个我觉得很巧妙的方法来解决这个问题。所有通过 IPC 的消息都使用 Message.CREATOR.createFromParcel 从包裹中重建。因此,我创建了一个 Java 动态代理类(直接从 docs 提取的代码),它检测对 createFromParcel 的调用,并在返回结果之前将进程 ID 和用户 ID 作为附加项添加到消息包中。该消息保证在事务中创建,查看Messenger 的来源,因此ID 是正确的。然后我使用反射将静态最终变量Message.CREATOR 替换为自身的代理。当需要身份验证时,稍后会在事务之外从消息中提取 ID。

到目前为止,这完全符合预期。

之前我试图创建Messenger 的替代版本,并使用反射来访问IMessenger,但即使Messenger 在事务结束之前也无法处理Messages。代理的工作量要少得多,而且在转换 IMessenger 的不同实现时更不容易出错。

【讨论】:

这在当前的 Android 中不起作用。就像在 sendMessageAtTime 中一样,您得到的是 UID,而不是 PID。无论如何,这确实不是一个好主意,因为它取决于可以(并且显然确实)随时更改的未记录的系统内部结构。【参考方案3】:

处理消息的代码不涉及任何 IPC,您应该查看将消息发布到处理程序的代码。

【讨论】:

那不是android本身的一部分吗?我正在研究围绕MessengerIBinder 包装一个代理。我会看看是否可以从transact 中添加 pid 和 uid 作为消息包的附加内容。 看起来不可能围绕IBinder 实现一个简单的包装器。那么有什么方法可以将IBinder 包装在Binder 的子类中? 好的。我想我可以使用与 Messenger 行为非常相似的相同 AIDL 创建一个类,但会在收到的每条消息中添加 pid 和 uid。我会发回结果。

以上是关于getCallingUid/getCallingPid 在 Handler.handleMessage 中返回当前的 uid 和 pid的主要内容,如果未能解决你的问题,请参考以下文章