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
的构造函数。来自getBinder
的Messenger
的IBinder
作为我服务中onBind
事件的结果传递。从远程应用程序通过活页夹发送的消息确实会转到处理程序的handleMessage
方法,但是在handleMessage
中调用Binder.getCallingUid
和Binder.getCallingPid
总是返回服务进程的uid 和pid(这绝对不是同一个进程作为远程应用程序)。 handleMessage
绝对是 IPC 事务的一部分,不是吗?那么我哪里出错了?我需要它来对连接的应用程序进行身份验证。
提前致谢。
编辑
好的。我有一种可怕的感觉,handleMessage
不是 IPC 事务的一部分,因为这发生在 AIDL 的单独线程中,它将消息放入Messenger
的队列中。有没有其他方法可以获取调用者的 User ID 和 Process ID?
【问题讨论】:
【参考方案1】:创建一个自定义的Handler
类并覆盖sendMessageAtTime
(这是Handler
类中唯一可覆盖的发布方法),然后使用它创建一个从onBind
返回的Messenger
。
在sendMessageAtTime
方法中,可以通过getCallingPid
和getCallingUid
获取调用远程应用的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
在事务结束之前也无法处理Message
s。代理的工作量要少得多,而且在转换 IMessenger
的不同实现时更不容易出错。
【讨论】:
这在当前的 Android 中不起作用。就像在 sendMessageAtTime 中一样,您得到的是 UID,而不是 PID。无论如何,这确实不是一个好主意,因为它取决于可以(并且显然确实)随时更改的未记录的系统内部结构。【参考方案3】:处理消息的代码不涉及任何 IPC,您应该查看将消息发布到处理程序的代码。
【讨论】:
那不是android本身的一部分吗?我正在研究围绕Messenger
的IBinder
包装一个代理。我会看看是否可以从transact
中添加 pid 和 uid 作为消息包的附加内容。
看起来不可能围绕IBinder
实现一个简单的包装器。那么有什么方法可以将IBinder
包装在Binder
的子类中?
好的。我想我可以使用与 Messenger 行为非常相似的相同 AIDL 创建一个类,但会在收到的每条消息中添加 pid 和 uid。我会发回结果。以上是关于getCallingUid/getCallingPid 在 Handler.handleMessage 中返回当前的 uid 和 pid的主要内容,如果未能解决你的问题,请参考以下文章