在之前的几篇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版本上就实现了。