编写仿supersu的权限管理工具(aosp11 root、实现aosp系统内置wifi、root管理apk)

一、题目介绍

项目所有内容均需基于AOSP原版代码实现,版本可选择10或者11,测试设备建议使用Pixel3.
1、修改su代码,并实现root管理APK,功能至少包括APP申请root权限管理、root权限请求记录;
2、实现USB调试功能一键开关,WiFi一键开关;
3、实现AOSP系统内置指定WiFi名称与密码,刷机后可自动连接指定WiFi;
4、(可选)为AOSP11版本系统添加OpenSSH Server;

二、环境介绍

pixel3测试机一台
aosp11源代码(android-11.0.0_r1)
Android studio

三、操作步骤与程序设计

aosp源码下载

我们将Google的镜像地址替换为清华的地址https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/platform/manifest之后,下载的速度会更快一些。
首先找到一个空目录

mkdir android11
cd android11
repo init -u https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/platform/manifest #初始化repo仓库
repo init --depth 1 -u https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/platform/manifest -b android-11.0.1_r1  #这里加入--depth 1 控制git的深度可以节省磁盘空间
repo sync -j20 #这一步执行时开始下载源码

接着我们就进入漫长的下载等待时间,如果速度能达到10m/s的话,估计要等待3-5个小时。

pixel3 硬件库下载

Android11刷机不能缺乏硬件库,否则刷机后会不断重启,首先我们要查看对应的BUILD_ID和pixel3的代号,查看源码中的build/core/build_id.mk文件,其中BUILD_ID=RP1A.200720.009,pixel3的代号是blueline,对应的硬件库下载地址是:
https://developers.google.cn/android/drivers?hl=zh-cn#bluelinerp1a.200720.009
将两个文件下载到源码根目录,然后执行,会自动生成vendor文件

~/code/android11$ tar zxvf google_devices-blueline-rp1a.200720.009-6cd41940.tgz
~/code/android11$ tar zxvf qcom-blueline-rp1a.200720.009-f772c38c.tgz
~/code/android11$ ./extract-google_devices-blueline.sh
~/code/android11$ ./extract-qcom-blueline.sh

这里补充一下,Google的每一代手机都有一个对应的代号,具体如下图:
在这里插入图片描述

编译aosp11源码

首先我们需要安装openjdk8

sudo apt-get update
sudo apt-get install openjdk-8-jdk

之后开始编译

~/code/android11$ source build/envsetup.sh
~/code/android11$ lunch aosp_blueline-userdebug
~/code/android11$ make -j16

编译的过程时间也是非常的长,大约三个小时,不过第一次编译之后,下一次再进行编译就不用整体编译一遍了,只需要编译修改的源码部分。

为pixel3烧录aosp11

首先我们解锁OEM,开发者选项里面解开就行
之后bootloader解锁,手机连接上电脑后,打开命令行

adb reboot bootloader
fastboot deivces #查看机器
fastboot flashing unlock
fastboot reboot

烧录,由于我使用的是linux服务器,本地机子是Windows,所以每次编译完成后给将编译好的系统进行打包下载到本地再烧录。
打包命令

tar -zcvf blueline.tar.gz blueline/  #此时要切换到/out/target/product/blueline路径下
#直接用linux烧录的话
~/code/android11$ export ANDROID_PRODUCT_OUT=./out/target/product/blueline
set ANDROID_PRODUCT_OUT=这里是blueline的路径  #如果是windows系统,也就是我的机器,则就用set命令
~/code/android11$ fastboot flashall -w
aosp11 root过程

在源码里面总共修改11个文件

system/core/init/selinux.cpp
frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
build/make/target/product/base_system.mk
/system/core/libcutils/fs_config.cpp
/frameworks/base/core/jni/com_android_internal_os_Zygote.cpp
system/core/adb/Android.bp
system/core/adb/daemon/main.cpp
system/core/fs_mgr/Android.bp
system/sepolicy/Android.mk
systen/sepolicy/definitions.mk
frameworks/base/services/usb/java/com/android/server/usb/UsbDeviceManager.java
1、修改SELinux权限为Permissive

system/core/init/selinux.cpp

bool IsEnforcing() {
   
    //改了这里
+    return false;
    //改了这里
    if (ALLOW_PERMISSIVE_SELINUX) {
   
        return StatusFromCmdline() == SELINUX_ENFORCING;
    }
    return true;
}

frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java

                if (!Build.isBuildConsistent()) {
   
                    Slog.e(TAG, "Build fingerprint is not consistent, warning user");
                    mUiHandler.post(() -> {
   
                        if (mShowDialogs) {
   
                            AlertDialog d = new BaseErrorDialog(mUiContext);
                            d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
                            d.setCancelable(false);
                            d.setTitle(mUiContext.getText(R.string.android_system_label));
                            d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
                            d.setButton(DialogInterface.BUTTON_POSITIVE,
                                    mUiContext.getText(R.string.ok),
                                    mUiHandler.obtainMessage(DISMISS_DIALOG_UI_MSG, d));
                            //改了这里
-                            d.show();
                            //改了这里
                        }
                    });
                }
            }
        }
2、增加su相关,确保apk root权限

需要编译su.cpp到system/bin目录下,为adb添加remount命令
build/make/target/product/base_system.mk

PRODUCT_PACKAGES += \
    remout \
    su \

注册用户组权限检测
system/extras/su/su.cpp

int main(int argc, char** argv) {
   
    // uid_t current_uid = getuid();
    // if (current_uid != AID_ROOT && current_uid != AID_SHELL) error(1, 0, "not allowed");

    // Handle -h and --help.
    ++argv;
    if (*argv && (strcmp(*argv, "--help") == 0 || strcmp(*argv, "-h") == 0)) {
   
        fprintf(stderr,
                "usage: su [WHO [COMMAND...]]\n"
                "\n"
                "Switch to WHO (default 'root') and run the given COMMAND (default sh).\n"
                "\n"
                "WHO is a comma-separated list of user, group, and supplementary groups\n"
                "in that order.\n"
                "\n");
        return 0;
    }

给su文件默认授予root权限
/system/core/libcutils/fs_config.cpp

    // the following two files are INTENTIONALLY set-uid, but they
    // are NOT included on user builds.
    {
    06755, AID_ROOT,      AID_ROOT,      0, "system/xbin/procmem" },
    {
    06755, AID_ROOT,      AID_SHELL,     0, "system/bin/su" },
    {
    06755, AID_ROOT,      AID_SHELL,     0, "system/xbin/su" },

/frameworks/base/core/jni/com_android_internal_os_Zygote.cpp

static void DropCapabilitiesBoundingSet(fail_fn_t fail_fn) {
   
  // for (int i = 0; prctl(PR_CAPBSET_READ, i, 0, 0, 0) >= 0; i++) {
   ;
  //   if (prctl(PR_CAPBSET_DROP, i, 0, 0, 0) == -1) {
   
  //     if (errno == EINVAL) {
   
  //       ALOGE("prctl(PR_CAPBSET_DROP) failed with EINVAL. Please verify "
  //             "your kernel is compiled with file capabilities support");
  //     } else {
   
  //       fail_fn(CREATE_ERROR("prctl(PR_CAPBSET_DROP, %d) failed: %s", i, strerror(errno)));
  //     }
  //   }
  // }
}
5、解锁fastboot,并关闭verity按需操作

system/core/adb/Android.bp

cc_defaults {
   
    name: "adbd_defaults",
    defaults: ["adb_defaults"],
//改了这里
-   cflags: ["-UADB_HOST", "-DADB_HOST=0"],
+    //cflags: ["-UADB_HOST", "-DADB_HOST=0"],
+    cflags: [
+        "-UADB_HOST",
+        "-DADB_HOST=0",
+        "-UALLOW_ADBD_ROOT",
+        "-DALLOW_ADBD_ROOT=1",
+        "-DALLOW_ADBD_DISABLE_VERITY",
+        "-DALLOW_ADBD_NO_AUTH",
    ],
}


cc_library {
   
    name: "libadbd_services",
    defaults: ["adbd_defaults", "host_adbd_supported"],
    recovery_available: true,
    compile_multilib: "both",

	....

//改了这里
+	required: [ "remount",],
    
    target: {
   
        android: {
   
            srcs: [
                "daemon/abb_service.cpp",

system/core/adb/daemon/main.cpp

static void drop_privileges(int server_port) {
   
    ScopedMinijail jail(minijail_new());

    // Add extra groups:
    // AID_ADB to access the USB driver
    // AID_LOG to read system logs (adb logcat)
    // AID_INPUT to diagnose input issues (getevent)
    // AID_INET to diagnose network issues (ping)
    // AID_NET_BT and AID_NET_BT_ADMIN to diagnose bluetooth (hcidump)
    // AID_SDCARD_R to allow reading from the SD card
    // AID_SDCARD_RW to allow writing to the SD card
    // AID_NET_BW_STATS to read out qtaguid statistics
    // AID_READPROC for reading /proc entries across UID boundaries
    // AID_UHID for using 'hid' command to read/write to /dev/uhid
    gid_t groups[] = {
   AID_ADB,          AID_LOG,          AID_INPUT,    AID_INET,
                      AID_NET_BT,       AID_NET_BT_ADMIN, AID_SDCARD_R, AID_SDCARD_RW,
                      AID_NET_BW_STATS, AID_READPROC,     AID_UHID};
    minijail_set_supplementary_gids(jail.get(), arraysize(groups), groups);

    // Don't listen on a port (default 5037) if running in secure mode.
    // Don't run as root if running in secure mode.
    if (should_drop_privileges()) {
   
        //改了这里
-       //const bool should_drop_caps = !__android_log_is_debuggable();
+       const bool should_drop_caps = false;
        if (should_drop_caps) {
   
            minijail_use_caps(jail.get(), CAP_TO_MASK(CAP_SETUID) | CAP_TO_MASK(CAP_SETGID));
        }

system/core/fs_mgr/Android.bp

    whole_static_libs: [
        "liblogwrap",
        "libdm",
        "libext2_uuid",
        "libfscrypt",
        "libfstab",
    ],
    cppflags: [
-       "-DALLOW_ADBD_DISABLE_VERITY=0"
+       "-UALLOW_ADBD_DISABLE_VERITY",
+       "-DALLOW_ADBD_DISABLE_VERITY=1",
    ],
    product_variables: {
   
        debuggable: {
   
            cppflags: [
                "-UALLOW_ADBD_DISABLE_VERITY",
                "-DALLOW_ADBD_DISABLE_VERITY=1",
            ],
        },
    },



    srcs: [
        "fs_mgr_remount.cpp",
    ],
    cppflags: [
-       "-DALLOW_ADBD_DISABLE_VERITY=0",
+       "-UALLOW_ADBD_DISABLE_VERITY",
+       "-DALLOW_ADBD_DISABLE_VERITY=1",
    ],
    product_variables: {
   
        debuggable: {
   
            cppflags: [
                "-UALLOW_ADBD_DISABLE_VERITY",
                "-DALLOW_ADBD_DISABLE_VERITY=1",
            ],
        },
    },

user版本启动overlayfs来装载remount对应分区
system/sepolicy/Android.mk

 ifneq ($(filter address,$(SANITIZE_TARGET)),)
   local_fc_files += $(wildcard $(addsuffix /file_contexts_asan, $(PLAT_PRIVATE_POLICY)))
 endif
-ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
+ifneq (,$(filter user userdebug eng,$(TARGET_BUILD_VARIANT)))
   local_fc_files += $(wildcard $(addsuffix /file_contexts_overlayfs, $(PLAT_PRIVATE_POLICY)))
 endif
 ifeq ($(TARGET_FLATTEN_APEX),true)

file_contexts.device.tmp :=
file_contexts.local.tmp :=

systen/sepolicy/definitions.mk

# Command to turn collection of policy files into a policy.conf file to be
# processed by checkpolicy
define transform-policy-to-conf
@mkdir -p $(dir $@)
$(hide) $(M4) --fatal-warnings $(PRIVATE_ADDITIONAL_M4DEFS) \
	-D mls_num_sens=$(PRIVATE_MLS_SENS) -D mls_num_cats=$(PRIVATE_MLS_CATS) \
-   -D target_build_variant=$(PRIVATE_TARGET_BUILD_VARIANT)
+   -D target_build_variant=eng \
	-D target_with_dexpreopt=$(WITH_DEXPREOPT) \
	-D target_arch=$(PRIVATE_TGT_ARCH) \
	-D target_with_asan=$(PRIVATE_TGT_WITH_ASAN) \
	-D target_with_native_coverage=$(PRIVATE_TGT_WITH_NATIVE_COVERAGE) \
	-D target_full_treble=$(PRIVATE_SEPOLICY_SPLIT) \
	-D target_compatible_property=$(PRIVATE_COMPATIBLE_PROPERTY) \
	-D target_treble_sysprop_neverallow=$(PRIVATE_TREBLE_SYSPROP_NEVERALLOW) \
	-D target_exclude_build_test=$(PRIVATE_EXCLUDE_BUILD_TEST) \
	-D target_requires_insecure_execmem_for_swiftshader=$(PRODUCT_REQUIRES_INSECURE_EXECMEM_FOR_SWIFTSHADER) \
	$(PRIVATE_TGT_RECOVERY) \
	-s $(PRIVATE_POLICY_FILES) > $@
endef
.KATI_READONLY := transform-policy-to-conf
6、默认开启OEM和去除OEM解锁警告提示

默认开启OEM解锁选项
frameworks/base/services/usb/java/com/android/server/usb/UsbDeviceManager.java

         protected void finishBoot() {
   
+            android.service.oemlock.OemLockManager mOemLockManager 
+            = (android.service.oemlock.OemLockManager) mContext.getSystemService(Context.OEM_LOCK_SERVICE);
+            mOemLockManager.setOemUnlockAllowedByUser(true);
+
             if (mBootCompleted && mCurrentUsbFunctionsReceived && mSystemReady) {
   
                 if (mPendingBootBroadcast) {
   
                     updateUsbStateBroadcastIfNeeded(getAppliedFunctions(mCurrentFunctions));
su代码修改,实现root权限管理APK,功能包括APP申请root权限管理,root权限请求记录。

首先我们来分析一下app应用如何执行root权限的命令,可以看出,应用先要执行su命令,然后再执行想要执行的命令,那我们在管理应用root权限的时候,首先我们需要知道是哪个应用需要执行root命令,还需要获取本机所有的应用,并控制这些应用app执行root命令的权限。

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;

public class RootCommand {
   
    public static String runCommand(String command){
   
        Process process = null;
        String result = "";
        DataOutputStream os = null;
        DataInputStream is 
  • 5
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值