- 对本书的赞誉
- 前言
- 基础篇
- 第 1 章 Android 中锁屏密码加密算法分析
- 第 2 章 Android 中 NDK 开发
- 第 3 章 Android 中开发与逆向常用命令总结
- 第 4 章 so 文件格式解析
- 第 5 章 AndroidManifest.xml 文件格式解析
- 第 6 章 resource.arsc 文件格式解析
- 第 7 章 dex 文件格式解析
- 防护篇
- 第 8 章 Android 应用安全防护的基本策略
- 第 9 章 Android 中常用权限分析
- 第 10 章 Android 中的 run-as 命令
- 第 11 章 Android 中的 allowBackup 属性
- 第 12 章 Android 中的签名机制
- 第 13 章 Android 应用加固原理
- 第 14 章 Android 中的 so 加固原理
- 工具篇
- 第 15 章 Android 逆向分析基础
- 第 16 章 反编译神器 apktool 和 Jadx
- 第 17 章 Hook 神器 Xposed
- 第 18 章 脱壳神器 ZjDroid
- 第 19 章 Native 层 Hook 神器 Cydia Substrate
- 操作篇
- 第 20 章 静态方式逆向应用
- 第 21 章 动态调试 smali 源码
- 第 22 章 IDA 工具调试 so 源码
- 第 23 章 逆向加固应用
- 第 24 章 逆向应用经典案例分析
- 第 25 章 Android 中常见漏洞分析
- 第 26 章 文件加密病毒 Wannacry 样本分析
10.1 命令分析和使用
以前想看一个应用的沙盒数据(/data/data/xxx/目录内容),一般都是选择 root 之后去查看对应的数据库、XML 等数据。但是如果没有 root 了也想看这些数据,怎么办呢?Android 中提供了一个命令,那就是 run-as,不过这个命令有一个缺陷,就是只有 debug 模式应用才能被查看。
命令的用法很简单:run-as[packagename]。其中 packagename 就是想查看的应用的包名,运行命令之后,就直接进入指定应用的目录:/data/data/packagename/。
现在稍微了解了 Android 中有这个命令可以查看 debug 应用的沙盒数据,但直接运行会遇到问题,运行结果如下所示:
为什么这个命令会报错呢?遇到这个情况有两种方式解决:一种是网上查资料,一种是自己去看源代码。为了问题解决的高效性,就去看源码吧。Android 中的命令一般都在/system/bin 和/system/xbin 目录下,这些命令的源码都是放在 Android 源码目录/system/core/下,如图 10-1 所示。
图 10-1 run-as 命令源码的位置
run-as 的源码如图 10-2 所示。
图 10-2 run-as 源码分析(一)
看到这里,原来 run-as 命令运行是有很多限制的。下面分别介绍。
第一个限制:运行的 uid 限制
运行命令的用户 id 只能是 shell 和 root 用户。下面可以验证一下,使用 system 的 uid 运行命令:
这里用于测试的设备已经 root 了。看到使用 su 可以随意设定 uid,这里将 uid 变成了 system,再运行 run-as 发现报错了,符合预期吧?
第二个限制:应用的安装必须合法
这里再仔细看看 get_package_info 这个函数的源码,它位于 run-as.c 同目录下的 package.c,如图 10-3 所示。
这里通过 map_file 函数来获取 PACKAGES_LIST_FILE 文件的 buffer 内容,再来看一下 PACKAGES_LIST_FILE 的定义:
图 10-3 run-as 源码分析(二)
导出这个文件,查看内容:
这个文件记录所有安装应用的信息:包名,用户 id(uid),是否为 debug 模式,对应的数据目录,是否是 release 版,组 id(gid)。这里发现 demo.systemapi 应用是 debug 模式的。一般正式 App 都是非 debug 模式。
通过读取这些信息就可以构造出一个 PackageInfo 了,如图 10-4 所示。
图 10-4 run-as 源码分析(三)
注意,这里看到了 packages.list 文件是存储安装包的简略信息,和它同一目录下还有一个重要文件 packages.xml,可以导出来看看,如下所示:
这里记录了安装应用的详细信息,还有一个重要信息就是应用的安装来源,有些 App 可以做到这点就是通过这个信息来获取的,还有签名信息、权限等。
当然可以使用 Android 中的 dumpsys packageinfo 命令来查看指定应用的详细信息,如下所示:
第三个限制:应用的 uid 必须合法
对于查看的应用的 uid 也是有相应限制的,如下所示:
这里 AID_APP 的定义在 Android 源码目录\system\core\include\private\android_filesystem_config.h 下。
定义了一些 uid 信息,例如:
·AID_ROOT 对应的是 root 用户,uid=0。
·AID_SYSTEM 对应的是 system 用户,uid=1000。
·AID_SHELL 对应的是 shell 用户,uid=2000。
可以看到,root 用户的权限>system 用户的权限>shell 用户的权限>第三方应用的权限。
不过这里所说的权限只是针对一些情况,不是全部。Android 中有些 API 会做 uid 限制,即使用反射机制也是访问失败的,比如,一个 API 限制只能 uid=1000 的用户即 system 用户才能调用,那么这时你是 root 用户也是没办法的,不过可以使用 su 进行降权。
这三个用户的 id 最好记住,算是常识,如下代码有详细定义:
再往下看,第三方应用 uid 的定义如下所示:
这里的 AID_APP 是 10000,安装的应用的 uid 都是从 10000 开始的,所以 uid 都是大于 10000 的,代码中做了一层 uid 的合法性判断限制。
注意:一般查看应用的 uid 时,得到最后的整数+10000 就是应用的 uid,比如 demo.systemapi 的 uid 就是:10000+100=10100。
如下代码可以获取到应用的 uid:
这可以验证,查看上面提到的 packages.list 文件中的信息,如下所示:
第四个限制:应用是否为 debug 模式
之前说过,run-as 有一个最大的限制就是查看应用的数据时,应用必须是 debug 模式的,所以在开发程序的时候千万要保证一点,就是 debug 包不能外泄,不然数据就等于外泄了。
言归正传,源码看得差不多了,看一下问题,在运行 run-as 的时候遇到的问题如下所示:
问题就出在如下代码上:
再看 get_package_info 函数:
再看 map_file 函数:
终于找到原因了,原来是/data/system/packages.list 文件的读取权限是 AID_SYSTEM,查看一下如下代码:
问题找到了,尝试使用 su 升级权限再查看一下,如下所示:
可惜的是,这样明显是不行的,原因很简单,run-as 有限制,本身这个命令只能是 root 和 shell 用户才可以访问。这里也可以看到,shell 用户也不比 system 用户权限低,所以要视情况而定来看 root、system、shell 这三个用户的权限范围。
那么再使用 root 用户去尝试一下,如下所示:
这是可以的,因为 run-as 的权限验证通过了。
从上面的几个限制可以看到,首先 root 的 uid 限制可以放行,然后是 debug 模式可以放行,packages.list 文件的访问权限是 system,但是这对于 root 用户来说没有限制,因为在文件的读取权限上 root 可以操作任何文件,demo.systemapi 的 uid 可以放行。
注意:这里运行完 run-as 命令之后,进入/data/data/demo.systemapi 目录下,看到变成了 sh 命令,#变成$了,这其实是 run-as 在启动一个 shell 程序,可以查看 run-as 的源码:
到这里就分析完了为什么运行 run-as 命令失败,失败的原因也找到了,解决的办法也有了,但是还是需要 root,这貌似和开始说的有点出入,因为本身 run-as 命令就是可以在非 root 设备上查看 debug 模式下应用的沙盒数据,那现在 root 了,还有什么意义呢?其实不是的,run-as 命令很特殊。找到一个没有 root 的设备,然后运行 run-as 命令,结果如下所示:
也是可以运行成功的,而且这个设备没有 root。但是在上面已经 root 的设备上运行 run-as 却报错,为什么呢?下面就开始本章的主要内容,即为何没有 root,run-as 命令还能运行成功,进入指定的应用目录下。
是这样的:开始的时候为了讲解 run-as 源码和一些前提知识,做了一件事,就是修改了 run-as 命令的权限,如下所示:
查看 run-as 命令的本来权限是:
然后修改了它的权限 chmod 0755 run-as,变成
这个操作是为了开始本章内容。
下面把 run-as 权限改回原来的值,然后再运行 run-as,如下所示:
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论