Android系统 adb shell auth授权使用

简介: Android系统 adb shell auth授权使用

前言

adb shell是Android开发者常用的一个工具,它可以让我们在电脑上通过USB或网络连接到Android设备,并执行一些命令或操作。但是,有时候我们可能不想让任何人都能随意使用adb shell,而是需要一些授权或验证的机制,以保护我们的设备和数据。本文将介绍如何在基于rockchip rk3568 android11的系统上实现自定义的adb shell授权功能。

1.实现原理

要实现自定义的adb shell授权功能,我们需要修改adb daemon的代码(),让它在接收到shell服务请求时,先检查是否已经通过了授权,如果没有,就返回一个错误信息,并提示用户输入一个随机生成的授权码。用户可以通过adb shell auth 命令来输入授权码,如果正确,就可以正常使用adb shell,否则就会被拒绝。

system/core/adb/client/commandline.cpp 这里是adb client端的,改这里没有 最开始走弯路.

system/core/adb/daemon/file_sync_service.cpp 这里是adb push/pull 逻辑,后面再研究

1.1 ADB 授权流程

  • 开始
  • 生成随机授权码
  • 检查授权状态
  • 如果已经授权,执行 ADB 命令,然后结束
  • 如果未授权,检查命令是否以 “auth” 开头
  • 如果命令以 “auth” 开头,检查授权码是否与预期授权码匹配
  • 如果授权码匹配,设置已授权标志为真,返回 “authorization ok”,执行 ADB 命令,然后结束
  • 如果授权码不匹配,返回 “authorization code:预期授权码”,然后结束
  • 如果命令不以 “auth” 开头,返回 “authorization code:预期授权码”,然后结束
1.2 ADB 命令执行流程

  • 接收 ADB 命令。
  • 如果命令以 “shell” 开头,执行 ShellService。
  • 在 ShellService 中,如果已经授权,执行 ADB 命令并返回执行结果。
  • 如果未授权,检查命令是否以 “auth” 开头。
  • 如果命令以 “auth” 开头,检查授权码是否与预期的授权码匹配。
  • 如果授权码匹配,设置授权标志为真,并返回 “authorization ok”。
  • 如果授权码不匹配,返回 “authorization code:预期授权码”。
  • 如果命令不以 “auth” 开头,返回 “authorization code:预期授权码”。
  • 如果命令不以 “shell” 开头,根据命令的不同执行不同的服务,如 “exec:”, “sync:”, “reverse:”, “reconnect”, “spin” 等,并返回执行结果。

2.修改adb daemon源码

需要修改system/core/adb/daemon/services.cpp文件中的ShellService函数,增加一个CheckAuthorization函数来检查授权状态和处理授权码输入。CheckAuthorization函数的实现如下:

bool authorized = false;
std::string GenerateRandomCode() {
    static std::string expected_code; // 在启动时生成随机码。
    if (!expected_code.empty()) {
        return expected_code;
    }
    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_int_distribution<> dis(0, 35);
    for (int i = 0; i < 6; ++i) {
        int random = dis(gen);
        if (random < 10) {
            expected_code += '0' + random;
        } else {
            expected_code += 'a' + random - 10;
        }
    }
    return expected_code;
}
unique_fd CheckAuthorization(std::string_view command, SubprocessProtocol protocol) {
    std::string expected_code = GenerateRandomCode();
    if (command.starts_with("auth")) {
        std::string auth_code = std::string(command.substr(strlen("auth")));
        auth_code = android::base::Trim(auth_code); // remove leading/trailing whitespace
        if (auth_code == expected_code) {
            authorized = true;
            std::string message = "authorization ok";
            return ReportError(protocol, message);
        } else {
            std::string message = android::base::StringPrintf("authorization code:%s", expected_code.c_str());
            return ReportError(protocol, message);
        }
    }
    if (!authorized) {
        std::string message = android::base::StringPrintf("authorization code:%s", expected_code.c_str());
        return ReportError(protocol, message);
    }
    return unique_fd{}; // Return an invalid fd if authorized
}

在ShellService函数中,在解析服务参数和命令之后,调用CheckAuthorization函数,并根据返回值判断是否继续执行shell服务:

unique_fd ShellService(std::string_view args, const atransport* transport) {
    size_t delimiter_index = args.find(':');
    if (delimiter_index == std::string::npos) {
        LOG(ERROR) << "Invalid shell service arguments: " << args;
        return unique_fd{};
    }
    // TODO: android::base::Split(const std::string_view&, ...)
    std::string service_args(args.substr(0, delimiter_index));
    std::string command(args.substr(delimiter_index + 1));
    // Defaults:
    //   PTY for interactive, raw for non-interactive.
    //   No protocol.
    //   $TERM set to "dumb".
    SubprocessType type(command.empty() ? SubprocessType::kPty : SubprocessType::kRaw);
    SubprocessProtocol protocol = SubprocessProtocol::kNone;
    std::string terminal_type = "dumb";
    for (const auto& arg : android::base::Split(service_args, ",")) {
        if (arg == "raw") {
            type = SubprocessType::kRaw;
        } else if (arg == "pty") {
            type = SubprocessType::kPty;
        } else if (arg == "v2") {
            protocol = SubprocessProtocol::kV2;
        } else if (arg.starts_with("TERM=")) {
            terminal_type = arg.substr(strlen("TERM="));
        } else if (!arg.empty()) {
            // This is not an error to allow for future expansion.
            LOG(WARNING) << "Ignoring unknown shell service argument: " << arg;
        }
    }
  
    unique_fd auth_fd = CheckAuthorization(command, protocol);
    if (auth_fd.get() != -1) {
        return auth_fd;
    }
    return StartSubprocess(command, terminal_type.c_str(), type, protocol);
}

还需要修改system/core/adb/Android.bp文件,去掉-Wexit-time-destructors的编译选项,因为我们使用了一个静态变量来存储授权码,它会在程序退出时触发析构函数,导致编译报错:

cc_defaults {
    name: "adb_defaults",
    cflags: [
        "-Wall",
        "-Wextra",
        "-Werror",
-        "-Wexit-time-destructors",
+        "-Wno-exit-time-destructors",
        "-Wno-unused-parameter",
        "-Wno-missing-field-initializers",
        "-Wthread-safety",

修改完代码后,我们重新编译并刷入系统,然后连接设备并尝试使用adb shell。我们可以看到,如果没有输入正确的授权码,就会收到一个错误信息,并提示我们输入授权码。如果输入正确的授权码,就可以正常使用adb shell。测试结果如下:

总结

本文介绍了如何在基于rockchip rk3568 android11的系统上实现自定义的adb shell授权功能,主要是通过修改adb daemon的代码,增加一个CheckAuthorization函数来检查授权状态和处理授权码输入。这样可以提高设备的安全性,防止未经授权的人员使用adb shell。

这只是一个简单的示例,实际应用中可能需要更复杂的逻辑和更安全的机制。希望本文对你有所帮助。

相关实践学习
AnalyticDB PostgreSQL 企业智能数据中台:一站式管理数据服务资产
企业在数据仓库之上可构建丰富的数据服务用以支持数据应用及业务场景;ADB PG推出全新企业智能数据平台,用以帮助用户一站式的管理企业数据服务资产,包括创建, 管理,探索, 监控等; 助力企业在现有平台之上快速构建起数据服务资产体系
相关文章
|
9月前
|
开发工具 Android开发
X Android SDK file not found: adb.安卓开发常见问题-Android SDK 缺少 `adb`(Android Debug Bridge)-优雅草卓伊凡
X Android SDK file not found: adb.安卓开发常见问题-Android SDK 缺少 `adb`(Android Debug Bridge)-优雅草卓伊凡
902 11
X Android SDK file not found: adb.安卓开发常见问题-Android SDK 缺少 `adb`(Android Debug Bridge)-优雅草卓伊凡
|
Shell Linux 开发工具
"开发者的救星:揭秘如何用adb神器征服Android设备,开启高效调试之旅!"
【8月更文挑战第20天】Android Debug Bridge (adb) 是 Android 开发者必备工具,用于实现计算机与 Android 设备间通讯,执行调试及命令操作。adb 提供了丰富的命令行接口,覆盖从基础设备管理到复杂系统操作的需求。本文详细介绍 adb 的安装配置流程,并列举实用命令示例,包括设备连接管理、应用安装调试、文件系统访问等基础功能,以及端口转发、日志查看等高级技巧。此外,还提供了常见问题的故障排除指南,帮助开发者快速解决问题。掌握 adb 将极大提升 Android 开发效率,助力项目顺利推进。
825 0
|
监控 数据处理 索引
整合LlamaIndex与LangChain构建高级的查询处理系统
该文阐述了如何结合LlamaIndex和LangChain构建一个扩展性和定制性强的代理RAG应用。LlamaIndex擅长智能搜索,LangChain提供跨平台兼容性。代理RAG允许大型语言模型访问多个查询引擎,增强决策能力和多样化回答。文章通过示例代码展示了如何设置LLM、嵌入模型、LlamaIndex索引及查询引擎,并将它们转换为LangChain兼容的工具,实现高效、精准的问题解答。通过多代理协作,系统能处理复杂查询,提高答案质量和相关性。
1433 0
|
监控 Shell Linux
Android调试终极指南:ADB安装+多设备连接+ANR日志抓取全流程解析,覆盖环境变量配置/多设备调试/ANR日志分析全流程,附Win/Mac/Linux三平台解决方案
ADB(Android Debug Bridge)是安卓开发中的重要工具,用于连接电脑与安卓设备,实现文件传输、应用管理、日志抓取等功能。本文介绍了 ADB 的基本概念、安装配置及常用命令。包括:1) 基本命令如 `adb version` 和 `adb devices`;2) 权限操作如 `adb root` 和 `adb shell`;3) APK 操作如安装、卸载应用;4) 文件传输如 `adb push` 和 `adb pull`;5) 日志记录如 `adb logcat`;6) 系统信息获取如屏幕截图和录屏。通过这些功能,用户可高效调试和管理安卓设备。
10433 2
|
监控 网络协议 Shell
ip和ip网段攻击拦截系统-绿叶结界防火墙系统shell脚本
这是一个名为“小绿叶技术博客扫段攻击拦截系统”的Bash脚本,用于监控和拦截TCP攻击。通过抓取网络数据包监控可疑IP,并利用iptables和firewalld防火墙规则对这些IP进行拦截。同时,该系统能够查询数据库中的白名单,确保合法IP不受影响。此外,它还具备日志记录功能,以便于后续分析和审计。
396 6
|
运维 监控 Shell
深入理解Linux系统下的Shell脚本编程
【10月更文挑战第24天】本文将深入浅出地介绍Linux系统中Shell脚本的基础知识和实用技巧,帮助读者从零开始学习编写Shell脚本。通过本文的学习,你将能够掌握Shell脚本的基本语法、变量使用、流程控制以及函数定义等核心概念,并学会如何将这些知识应用于实际问题解决中。文章还将展示几个实用的Shell脚本例子,以加深对知识点的理解和应用。无论你是运维人员还是软件开发者,这篇文章都将为你提供强大的Linux自动化工具。
|
Shell
5.Electron之shell(使用系统默认浏览器打开网页)
5.Electron之shell(使用系统默认浏览器打开网页)
731 1
|
Shell Android开发
ADB更改Android设备屏幕显示方向
ADB更改Android设备屏幕显示方向
1870 5
|
开发框架 Unix Linux
LangChain 构建问题之在Unix/Linux系统上设置OpenAI API密钥如何解决
LangChain 构建问题之在Unix/Linux系统上设置OpenAI API密钥如何解决
423 0
|
索引 Cloud Native
云原生数据仓库问题之精确匹配查询如何解决
云原生数据仓库问题之精确匹配查询如何解决
237 0