有时候我们会通过adb shell查看安装的debug的包一些资源信息,例如查看:
/proc/pid/fd
该目录下包含该进程运行是所有打开的fd相关信息。
如果我们直接adb shell,然后 cd /proc/pid/fd,你会发现会Permission denied
。
这个时候我们可以选择执行:
run-as 包名
cd /proc/pid/fd
就可以了。
问题来了:run-as背后做了什么?
以后至少每周更新一篇。
更多问答 >>
-
每日一问 | Service onStartCommand 返回STICKY是如何做到被拉活的?
2022-07-24 11:50 -
2022-05-27 20:55
-
2022-06-12 14:41
-
【大家提问】Android中的匿名binder与线程相关的一些问题
2022-07-03 10:48 -
每日一问 View.post 又来了与View.postOnAnimation 有什么区别?
2022-07-03 10:47 -
每日一问 | 可以不借助 bindService,实现跨进程 binder 通信吗?
2022-04-27 23:43 -
每日一问 | 被声明为private final 的内部类,能生成一个子类对象吗?逆天篡改~
2022-04-15 21:13 -
每日一问 .class vs Class.forName() vs loadClass() 类加载傻傻分不清楚?
2022-02-11 14:22 -
每日一问 | 脱糖对于Android 打包期间插桩的有什么影响?
2022-03-07 21:26
如果我们直接以 adb shell 执行这些命令,会这样子:
报错 Permission denied。使用
我们首先要搞清楚一个东西,报错是 permission denied ,这里的 permission 是什么?Android 是基于 Linux 的操作系统,它底层的权限机制直接复用了 Linux 的权限机制,Linux 里通过 uid 标记一个用户,当它为 0 时,即代表这个用户是超级权限用户也就是所谓的 root。而 Android 里为了实现每个应用的权限不同,给每个应用都分配了一个 uid(这里忽略 sharedUserId、多个应用跑在同一个进程等情况)。我们这里的 permission denied 会不会就是 uid 问题呢?stat 一下看看权限:run-as top.canyie.pine.examples
则可以正常执行。为什么?这个目录的权限是 500,如果不是目录的 owner 则没有任何权限。那么我们已知我们要调试的应用的 uid 是10063,我们
su 10063
切换 uid 再试一下:是的,成功了!不过等等,我们 su 之后 id 命令输出的 context 发生了变化,从 u:r🐚s0 变成了 u:r:su:s0。这个 context 是另一个安全机制 SELinux 的一部分,用于标识进程的“身份”。至于什么是 SELinux 这里就不展开说了,感兴趣的同学可以自行搜索。事实上,这个 context 的变化是 su 命令的副作用,如果保持原来的 shell context 去访问 /data/xxx 等 app 的私有目录,实际上还会失败,因为 /data/xxx 被标记为 app_data_file,shell 的 context 对这个 domain 没有访问权限。
我们可以看一下真正的 run-as 之后 id 有什么变化:由此我们可以得出结论:run-as 命令通过改变进程的 uid/gid/context 等属性来获得对 app 敏感目录的访问权限。(这里省略了 namespace 等繁琐内容)
扩展知识:capabilities
run-as 命令通过 setresuid 等系统调用改变进程的 uid,那么我们自己写一个东西用这个系统调用能够成功改变 uid 吗?显然是不行的,那么为什么 run-as 命令就有这个魔力改变 uid?
首先我们想到了文件的 s 属性,这个属性允许 exec 后进程更改 setuid,我们熟悉的 su 命令也是通过它才被允许 setuid 的。但是,我们 stat $(which run-as) 发现 run-as 的权限并没有 s ,那么是怎么做到的呢?我们 cat /proc/self/status 看看:这里就涉及到 Linux 的另一个权限机制,capabilities。这里简要介绍下最关键一点:我们 exec 一个文件时它拥有的 permitted capabilities 会和当前线程的 bounding capabilities 计算交集然后添加到执行进程的 permitted capabilities 中,它就拥有了特别的权限。run-as 也正是通过在文件上设置 CAP_SETUID 这些 capabilities 从而获得执行 setuid 的权限。更多细节可以查看 run-as.cpp 里的注释,写的很清楚了。
太强了,有推荐的书籍么~
我特喵看不懂
啊啦,是小白了,遇到问题都是现场 Google 的,也就是因为自己在给 Magisk (一套 Android Root 工具)提交代码还有做一些 Xposed 相关开发才了解一些。书籍的话我没看过,其 ...查看更多
啊啦,是小白了,遇到问题都是现场 Google 的,也就是因为自己在给 Magisk (一套 Android Root 工具)提交代码还有做一些 Xposed 相关开发才了解一些。书籍的话我没看过,其实都是 Linux 基础知识,建议直接网上搜 Linux 相关的书
牛逼,虽然没咋看懂但是也学习了;
UNIX环境高级编程,对stat的那个结构体还是说得很清楚的,exec系统调用也是。不过残页是实践起来了,更进一步