像极客一样提取Android的Root权限_busybox require superuser privileges (root)

进入到bootloader模式后就可以随心所欲地刷机了。在本文只介绍如何刷Recovery,后续的文章会深入讲解如何刷各种镜像文件。假设下载的Recovery镜像文件是recovery-clockwork-touch-6.0.2.3-grouper.img。在bootloader模式下刷Recovery镜像文件的命令如下:

fastboot flash recovery recovery-clockwork-touch-6.0.2.3-grouper.img

如果刷机成功,会显示如图1所示的信息。

图1  成功刷Recovery

在bootloader模式下通过音量上下键切换到“Recovery mode”选择项(在屏幕右上角显示),然后按电源键,大概等5秒,Nexus 7就会进入Clockwork Recovery。如果想重新启动Nexus 7,并进入正常的模式,可以选择Recovery的“reboot system now”菜单项,然后按电源键即可。如果读者刷的是带触摸功能的Recovery,只要点击“reboot system now”菜单项即可重新启动Nexus 7。如果读者目前处于正常模式下,并且Nexus 7已通过USB线与PC连接,可以使用下面的命令进入Recovery模式。

adb reboot recovery

  1. su命令源代码分析

刷完了Recovery后,就需要将su文件放到Android设备中的/system/bin或/system/xbin目录中,然后直接执行su命令即可使当前的Shell获得root权限(Shell提示符从$变成了#),以前很多不能做的事也可以做了,例如,普通用户不能查看/data/data目录中的内容,使用su命令提取root权限后也可以使用ls命令查看/data/data目录的内容了。

读者可以从网上下载合适的su文件,或直接从Android源代码中获取su文件。如果Android源代码还没有编译,需要按着1.3.2节的步骤编译整个Android源代码。成功编译Android源代码后,就可以在如下的目录找到编译好的su文件。

<Android源代码本目录>/out/target/product/generic/system/xbin

实际上这个su命令完全可以满足目前的需求,也就是提取Android设备当前Shell的root权限。不过先别忙将su文件弄到Android设备上。接下来先看一下su文件的源代码,了解一下su文件的运行原理以及为什么能在Android设备上成功执行。

读者可以从如下的目录找到su命令的源代码。

<Android源代码根目录>/system/extras/su

su是用C语言编写的普通可执行文件,主文件是su.c。读者可以打开该文件看一下su的源代码。

su.c文件中除了引用的一些头文件外,就只有一个main函数,代码如下:

源代码文件:<Android源代码根目录>/system/extras/su/su.c

#define LOG_TAG “su”
… …
/* 此处省略了#include … 语句 */
int main(int argc, char **argv)
{
struct passwd pw;
int uid, gid, myuid;
/
获取用户ID,只有root和当前的Shell能执行su命令 */
myuid = getuid();
if (myuid != AID_ROOT && myuid != AID_SHELL) {
fprintf(stderr,“su: uid %d not allowed to su\n”, myuid);
return 1;
}

if(argc < 2) {
uid = gid = 0;
} else {
/* 根据参数指定的用户名获取用户属性,如果getpwnam函数返回0,表示参数指定的是用户ID
而不是用户名
*/
pw = getpwnam(argv[1]);

if(pw == 0) {
uid = gid = atoi(argv[1]);
} else {
uid = pw->pw_uid;
gid = pw->pw_gid;
}
}
/*
setgid函数要设置一个用户组ID,使用属于该用户组的用户执行任何文件时都拥有该文件所有者
的权限。setuid函数与setgid函数类似,需要设置一个用户ID。使用该用户执行任何可执行文件都
会拥有该文件所有者的权限。例如,sh命令的所有者是root用户,而当前登录用户是user,这时
使用setuid函数设置user的ID后,再执行sh命令,就相当于以root用户的身份执行sh命令,
所以进入新的Shell后就会拥有root权限
*/
if(setgid(gid) || setuid(uid)) {
fprintf(stderr,“su: permission denied\n”);
return 1;
}

/* 执行通过命令行参数指定的命令 /
if (argc == 3 ) {
if (execlp(argv[2], argv[2], NULL) < 0) {
fprintf(stderr, “su: exec failed for %s Error:%s\n”, argv[2],
strerror(errno));
return -errno;
}
} else if (argc > 3) {
/
Copy the rest of the args from main. */
char *exec_args[argc - 1];
memset(exec_args, 0, sizeof(exec_args));
memcpy(exec_args, &argv[2], sizeof(exec_args));
if (execvp(argv[2], exec_args) < 0) {
fprintf(stderr, “su: exec failed for %s Error:%s\n”, argv[2],
strerror(errno));
return -errno;
}
}

/* 执行sh命令进入新的Shell,如果成功执行,当前程序会立刻退出,如果执行失败,会继续
执行下面的语句
*/
execlp(“/system/bin/sh”, “sh”, NULL);

fprintf(stderr, “su: exec failed\n”);
return 1;
}

从su.c文件的代码可以看出,su命令支持多个命令行参数。这些命令行参数分为如下两类。

第1类:su的第一个参数,该参数指定了要提升权限的用户ID或用户名,如果不指定,就是当前的用户。

第2类:其余的参数。表示提升权限后要立刻执行的命令和该命令的参数。

下面都是合法的su命令调用形式。

su

su user

su user ls –al /data/data/

su提升权限的核心有如下两个。

  • 通过setgid和setuid函数提升权限,也就是使得任何用户在执行sh命令时都会拥有与sh命令拥有者同样的权限。由于sh命令的拥有者是root用户,所以自然就将新的Shell提升到了root权限。
  • 通过execlp函数执行sh命令。由于前面已经调用了setgid和setuid函数,所以执行sh命令会进入新的Shell,并且该Shell与sh命令文件的所有者(root用户)拥有同样的权限。执行exit命令会退出拥有root权限的Shell,并重新回到原来没有root权限的Shell。再次执行exit命令后,就会退出Android Shell,回到Ubuntu Linux的终端。
  1. 制作第一个Recovery刷机包(编写脚本文件)

Recovery使用的刷机包就是zip格式的压缩文件。根据不同的需求,刷机包中包含的文件不同,一个完整的刷机包非常复杂,不过本节的目的只是将su文件复制到/system/xbin目录中,所以暂时用不着那么复杂的刷机包。关于Recovery刷机包的详细制作过程将在后面跟的章节深入探讨。本文只做最基本的刷机包。

其实要做一个Recovery刷机包并不困难。制作Recovery刷机包之前通常要考虑使用的是哪个Recovery。例如,本书主要使用了Clockwork Recovery,所以可以利用Clockwork Recovery中的一些特性。

本文要制作的刷机包中只有两个目录:system和META-INF。其中system就是编译Android源代码后,在<Android源代码根目录>/out/target/product/generic目录中的system目录,也是进入Android设备的Shell后看到的“/system”目录,在该目录下包含了Android的系统文件,其中包括很多命令文件以及系统应用程序。不过本文制作的Recovery刷机包没这么复杂。由于只需要将su文件复制到/system/xbin目录,所以在system目录中只要有一个xbin子目录,并且在该目录中放一个在上一节获得的su文件即可。

可能很多读者会问,将su文件放到/system/xbin目录中,Recovery中刷机时就会将su文件复制到Android系统的/system/xbin目录中吗?答案很简单,Recovery当然不知道自己要做什么,具体要完成什么工作,如何来完成,玄机全在META-INF目录中。

在META-INF/com/google/android目录中有一个updater-script脚本文件(纯文本文件)和一个update-binary可执行文件。别看这两个文件一共不到200KB,它们却是整个Recovery刷机包中最核心的部分。尤其是update-binary,该文件通常在190KB上下,别看文件尺寸不大,这可是内嵌于Recovery的一种轻量级脚本语言的解析器,而updater-script脚本文件就是使用这种脚本语言写的。这种脚本语言就是edify。该语言除了定义一些简单的语句外,还定义了几十个用于各种操作的函数,例如,复制文件、删除文件、建立链接等。

Edify语言会在后面的章节介绍,在本文只介绍该语言的几个常用的函数。这些函数的原型、含义及其用法如下:

ui_print

原型:ui_print(msg1, …, msgN);

含义:该函数用于在Recovery界面输出字符串。其中msg1、…、msgN表示N个字符串参数,该函数至少需要指定一个参数。如果指定多个参数,会将这些参数值连接起来输出。

用法:ui_print(" hello world ");

run_program

原型:run_program(prog, arg1, …, argN);

含义:该函数用于执行程序,其中prog参数表示要执行的程序文件(要写完整路径),arg1、…、argN表示要执行程序的参数。prog参数是必须的,其他参数都是可选的。

用法:run_program(“/sbin/busybox”,“mount”, “/system”);

delete

原型:delete(file1, file2, …, fileN);

含义:该函数用于删除一个或多个文件。其中file1、file2、…、fileN表示要删除文件的路径,至少需要指定一个文件。

用法:delete(“/system/xbin/su”);

package_extract_dir

原型:package_extract_dir(package_path, destination_path);

含义:用于提取刷机包中package_path指定目录的所有文件到destination_path指定的目录。其中package_path参数表示刷机包中的目录,destination_path参数表示目标目录。

用法:package_extract_dir(“system”, “/system”);

set_perm

原型:set_perm(uid, gid, mode, file1, file2, …, fileN);

含义:用于设置一个或多个文件的权限。其中uid参数表示用户ID,gid参数表示用户组ID。如果想让文件的用户和用户组都是root,uid和gid需要都为0。mode参数表示设置的权限,这个权限与chmod命令设置的权限完全一样,例如,如果将一个文件设为任何用户都可以读写和执行的权限值是0777。file1、file2、…、fileN表示要设置权限的文件的路径。

用法:set_perm(0, 0, 0777, “/system/xbin/su”);

unmount

原型:unmount(mount_point);

含义:用于解除文件系统的挂载。其中mount_point参数表示文件系统。

用法:unmount(“/system”);

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数HarmonyOS鸿蒙开发工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年HarmonyOS鸿蒙开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上HarmonyOS鸿蒙开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新

如果你觉得这些内容对你有帮助,可以添加VX:vip204888 (备注鸿蒙获取)
img

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

知识点,真正体系化!**

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新

如果你觉得这些内容对你有帮助,可以添加VX:vip204888 (备注鸿蒙获取)
[外链图片转存中…(img-qs9RwKMc-1712745720156)]

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值