IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android Binder getCallingUid() getCallingPid() -> 正文阅读

[移动开发]Android Binder getCallingUid() getCallingPid()

Binder getCallingUid() getCallingPid() 返回?

??Android在进程间交互的时候,会使用Binder机制。在Binder交互过程中,通过Binder.getCallingUid()、Binder.getCallingPid()得到调用方的UID和进程PID。

    /**
     * Return the ID of the process that sent you the current transaction
     * that is being processed.  This pid can be used with higher-level
     * system services to determine its identity and check permissions.
     * If the current thread is not currently executing an incoming transaction,
     * then its own pid is returned.
     *
     * Warning: oneway transactions do not receive PID.
     */
    @CriticalNative
    public static final native int getCallingPid();

    /**
     * Return the Linux uid assigned to the process that sent you the
     * current transaction that is being processed.  This uid can be used with
     * higher-level system services to determine its identity and check
     * permissions.  If the current thread is not currently executing an
     * incoming transaction, then its own uid is returned.
     */
    @CriticalNative
    public static final native int getCallingUid();

??这俩函数的实现在android_util_Binder.cpp中

static jint android_os_Binder_getCallingPid()
{
    return IPCThreadState::self()->getCallingPid();
}

static jint android_os_Binder_getCallingUid()
{
    return IPCThreadState::self()->getCallingUid();
}

??IPCThreadState这个类对应着线程,

pid_t IPCThreadState::getCallingPid() const
{
    checkContextIsBinderForUse(__func__);
    return mCallingPid;
}
uid_t IPCThreadState::getCallingUid() const
{
    checkContextIsBinderForUse(__func__);
    return mCallingUid;
}

??所以现在就知道Binder.getCallingUid()、Binder.getCallingPid()得到的值了,就是对应的线程对应的IPCThreadState类对象的成员mCallingUid、mCallingPid的值。

mCallingUid mCallingPid在哪块赋值

Binder交互过程中协议命令

Binder交互过程中协议命令

??要知道mCallingUid mCallingPid在哪块赋值,需要知道Binder交互过程。在这块只需要知道有关mCallingUid、mCallingPid相关的代码。
??在BC_TRANSACTION命令中如下代码:

static void binder_transaction(struct binder_proc *proc,
			       struct binder_thread *thread,
			       struct binder_transaction_data *tr, int reply,
			       binder_size_t extra_buffers_size)
{
…………
	t->sender_euid = task_euid(proc->tsk);
…………
}

??其中t是binder_transaction指针,在这里将成员变量sender_euid 设置为调用进程的uid。在BC_TRANSACTION将事务数据设置完毕之后,会唤醒目标进程的线程进行处理相应事务,这块相关代码在binder_thread_read()中。

static int binder_thread_read(struct binder_proc *proc,
			      struct binder_thread *thread,
			      binder_uintptr_t binder_buffer, size_t size,
			      binder_size_t *consumed, int non_block)
{
…………
		trd->code = t->code;
		trd->flags = t->flags;
		trd->sender_euid = from_kuid(current_user_ns(), t->sender_euid);

		t_from = binder_get_txn_from(t);
		if (t_from) {
			struct task_struct *sender = t_from->proc->tsk;

			trd->sender_pid =
				task_tgid_nr_ns(sender,
						task_active_pid_ns(current));
			trace_android_vh_sync_txn_recvd(thread->task, t_from->task);
		} else {
			trd->sender_pid = 0;
		}
…………
}

??在这里是在目标线程里执行代码的,trd是binder_transaction_data类指针,将它的成员变量sender_euid设置为t->sender_euid,这块的t->sender_euid就是上面赋值的调用方进程的uid。sender是调用方的进程描述符,trd->sender_pid在这块设置成调用方进程的pid。然后设置完事务数据之后,将cmd设置为BR_TRANSACTION或者BR_TRANSACTION_SEC_CTX之后,返回到用户态进行处理。
??用户态进程处理的代码如下:

status_t IPCThreadState::executeCommand(int32_t cmd)
{
…………
	case BR_TRANSACTION_SEC_CTX:
    case BR_TRANSACTION:
        {
        	…………
			const pid_t origPid = mCallingPid;
            const char* origSid = mCallingSid;
            const uid_t origUid = mCallingUid;
            …………
            mCallingPid = tr.sender_pid;
            mCallingSid = reinterpret_cast<const char*>(tr_secctx.secctx);
            mCallingUid = tr.sender_euid;
            …………
            error = reinterpret_cast<BBinder*>(tr.cookie)->transact(tr.code, buffer,
                            &reply, tr.flags);
            …………
            mCallingPid = origPid;
            mCallingSid = origSid;
            mCallingUid = origUid;
            …………
					break;
				}
…………
}

??tr是binder_transaction_data对象,里面的数据就是在binder_thread_read()中设置的。在这里可以看到,在这里看到mCallingPid、mCallingUid被设置之后,就调用被调用对象的transact()方法。等到整个Bind处理完毕之后,就会将mCallingPid、mCallingUid设置为它们原来的值。

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章           查看所有文章
加:2022-03-03 16:26:11  更:2022-03-03 16:31:13 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 17:17:30-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码