Android8.0 user版本使用adb root(且不用授权adb key)

在之前的几篇adb文章中,我们清楚了adb root和adb key授权的流程。这篇文章我们我们主要分析下android8.0 上如何在user版本上adb root以及不用adb key的授权。

首先我们在adbd_main函数中将auth_required置为false,这个变量的用处我们在这篇博客中详细分析过了https://blog.csdn.net/kc58236582/article/details/53502177。这样我们在user版本就不用通过界面上的授权了,可以直接和pc的adb client通信。

int adbd_main(int server_port) {
    umask(0);

    signal(SIGPIPE, SIG_IGN);

    init_transport_registration();

    // We need to call this even if auth isn't enabled because the file
    // descriptor will always be open.
    adbd_cloexec_auth_socket();

    // Respect ro.adb.secure in userdebug/eng builds (ALLOW_ADBD_NO_AUTH), or when the
    // device is unlocked.
    if ((ALLOW_ADBD_NO_AUTH || is_device_unlocked()) &&
        !android::base::GetBoolProperty("ro.adb.secure", false)) {
        auth_required = false;
    }

    auth_required = false;

然后就是处理adb root的service,我们将版本不是debuggable的处理去除。

void restart_root_service(int fd, void *cookie) {
    if (getuid() == 0) {
        WriteFdExactly(fd, "adbd is already running as root\n");
        adb_close(fd);
    } else {
        /*if (!__android_log_is_debuggable()) {
            WriteFdExactly(fd, "adbd cannot run as root in production builds\n");
            adb_close(fd);
            return;
        }*/

        android::base::SetProperty("service.adb.root", "1");
        WriteFdExactly(fd, "restarting adbd as root\n");
        adb_close(fd);
    }
}

接着我们来看drop_privileges函数,这个函数如果adb不用root权限会给她降级到shell。而就是通过should_drop_privileges这个函数来判断是否要降级,返回false就是使用root权限。

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()) {
        drop_capabilities_bounding_set_if_needed(jail.get());

        minijail_change_gid(jail.get(), AID_SHELL);
        minijail_change_uid(jail.get(), AID_SHELL);
        // minijail_enter() will abort if any priv-dropping step fails.
        minijail_enter(jail.get());

        D("Local port disabled");
    } else {
        // minijail_enter() will abort if any priv-dropping step fails.
        minijail_enter(jail.get());

        if (root_seclabel != nullptr) {
            if (selinux_android_setcon(root_seclabel) < 0) {
                LOG(FATAL) << "Could not set SELinux context";
            }
        }
        std::string error;
        std::string local_name =
            android::base::StringPrintf("tcp:%d", server_port);
        if (install_listener(local_name, "*smartsocket*", nullptr, 0, nullptr, &error)) {
            LOG(FATAL) << "Could not install *smartsocket* listener: " << error;
        }
    }
}

因此我们在should_drop_privileges函数最上面直接判断处理,当service.adb.root(adb root会设置这个权限)是1就返回false

static bool should_drop_privileges() {
    // "adb root" not allowed, always drop privileges.
    //return false;
    std::string prop1 = android::base::GetProperty("service.adb.root", "");
    if (prop1 == "1") {
        return false;
    }

这样adbd的流程就差不多处理完了,但是发现adbd在输入adb root的时候会crash最后定位到是selinux问题。

这里我们提供一个在init中关闭selinux的简单方法。init初始化的时候会调用selinux_initialize函数,这个函数又会调用selinux_is_enforcing函数,我们确保这个函数返回false就可以了。

static selinux_enforcing_status selinux_status_from_cmdline() {
    /*selinux_enforcing_status status = SELINUX_ENFORCING;

    import_kernel_cmdline(false, [&](const std::string& key, const std::string& value, bool in_qemu) {
        if (key == "androidboot.selinux" && value == "permissive") {
            status = SELINUX_PERMISSIVE;
        }
    });*/

    return SELINUX_PERMISSIVE;
}

static bool selinux_is_enforcing(void)
{
    if (ALLOW_PERMISSIVE_SELINUX) {
        return selinux_status_from_cmdline() == SELINUX_ENFORCING;
    }
    return false;
    //return true;
}

这样adb root以及不用授权问题在user版本上就实现了。

你可能感兴趣的:(android,adb)