Android系统 adb shell push/pull 禁止特定文件

简介: Android系统 adb shell push/pull 禁止特定文件

在Android系统中,adb shell是一个强大的工具,可以让我们在电脑上通过命令行操作Android设备上的文件和程序。其中,push和pull命令可以实现电脑和手机之间的文件传输,非常方便。但是,有时候(客制化需求或者防止某些内容被盗取)我们可能不希望某些文件被随意传输,比如系统敏感文件或者应用白名单文件。那么,我们该如何实现adb shell push/pull的禁止特定文件功能呢?

android11源码 push/pull的流程

为了解决这个问题,需要先了解android11源码system/core/adb/daemon/file_sync_service.cpp中push/pull命令的实现流程。我们以adb pull为例,简单介绍一下主要步骤:

  1. 在电脑端,adb客户端程序接收到用户输入的adb pull命令后,会解析出要传输的源文件路径和目标文件路径,并向adb服务端程序发送一个SYNC服务请求。
  2. 在Android端,adb服务端程序收到SYNC服务请求后,会启动一个file_sync_service线程来处理文件传输相关的操作。
  3. file_sync_service线程会从adb客户端程序读取一个SyncRequest结构体,其中包含了请求的ID和路径长度。然后根据路径长度再读取相应的路径字符串。
  4. file_sync_service线程会根据请求的ID判断是push还是pull操作,并调用相应的函数来处理。对于pull操作,会调用do_recv_v1或do_recv_v2函数(根据协议版本不同而不同, 测试发现是do_recv_v1)。
static bool handle_sync_command(int fd, std::vector<char>& buffer) {
    D("sync: waiting for request");
    SyncRequest request;
    if (!ReadFdExactly(fd, &request, sizeof(request))) {
        SendSyncFail(fd, "command read failure");
        return false;
    }
    size_t path_length = request.path_length;
    if (path_length > 1024) {
        SendSyncFail(fd, "path too long11");
        return false;
    }
    char name[1025];
    if (!ReadFdExactly(fd, name, path_length)) {
        SendSyncFail(fd, "filename read failure");
        return false;
    }
    name[path_length] = 0;
    std::string id_name = sync_id_to_name(request.id);
    D("sync: %s('%s')", id_name.c_str(), name);
    // 在处理每个命令之前,检查是否禁止了pull或push操作
    std::string path(name);
    switch (request.id) {
    .............
  1. do_recv_v1或do_recv_v2函数会根据路径字符串打开手机上对应的文件,并将文件内容按照一定的格式和大小分块发送给adb客户端程序。
  2. 在电脑端,adb客户端程序收到file_sync_service线程发送的文件内容后,会根据目标文件路径创建或覆盖相应的文件,并将收到的内容写入文件中。
  3. 当file_sync_service线程发送完所有的文件内容后,会发送一个ID_DONE消息表示传输结束。adb客户端程序收到ID_DONE消息后,会关闭目标文件,并显示传输结果。

isOperationAllowed函数的作用

在android11源码中,有一个新添加的函数isOperationAllowed,它的作用是判断是否允许进行push或pull操作。它的原型如下:

// 通过属性判断是否允许操作
static bool isOperationAllowed(const char* filePath, const char* operationProperty);
static const char* appWhitelist[] = {
    "system/bin/candump",
    "system/bin/cansend",
    // Add more paths here as needed
};
// 通过属性判断是否允许操作
static bool isOperationAllowed(const char* filePath, const char* operationProperty) {
    char operationDisabledValue[PROP_VALUE_MAX];
    __system_property_get(operationProperty, operationDisabledValue);
    LOG(INFO) << operationProperty << "-filePath(" << operationDisabledValue << "," << filePath << ")";
    if (strcmp(operationDisabledValue, "1") == 0){
        LOG(INFO) << operationProperty << " = true!!!!!";
        for (const char* path : appWhitelist) {
            if (strstr(filePath, path) != nullptr){
                return false;
            }
        }
        LOG(INFO) << operationProperty << "22";
    } else {
        LOG(INFO) << operationProperty << "33";
    }
    return true;
}

它接受两个参数:filePath是要传输的文件路径,operationProperty是一个系统属性名,表示是否禁止某种操作。例如,persist.adb.push_disabled表示是否禁止push操作,persist.adb.pull_disabled表示是否禁止pull操作。

这个函数的实现逻辑如下:

  1. 从系统属性中读取operationProperty对应的值,如果值为"1",表示禁止该操作;如果值为其他或者没有设置该属性,则表示允许该操作。
  2. 如果禁止该操作,则遍历一个预定义的应用白名单数组appWhitelist,检查filePath是否包含数组中的任何一个路径。如果包含,则表示该文件属于白名单中的应用,允许该操作;如果不包含,则表示该文件不属于白名单中的应用,禁止该操作。
  3. 返回最终的判断结果,true表示允许,false表示禁止。
// 在处理每个命令之前,检查是否禁止了pull或push操作
    std::string path(name);
    switch (request.id) {
        case ID_LSTAT_V1:
            if (!do_lstat_v1(fd, name)) return false;
            break;
        case ID_LSTAT_V2:
        case ID_STAT_V2:
            if (!do_stat_v2(fd, request.id, name)) return false;
            break;
        case ID_LIST_V1:
            if (!do_list_v1(fd, name)) return false;
            break;
        case ID_LIST_V2:
            if (!do_list_v2(fd, name)) return false;
            break;
        case ID_SEND_V1:
            // 检查是否允许push操作
            if (!isOperationAllowed(name, "persist.adb.push_disabled")){
                LOG(ERROR) << "forbid_push_file";
                return false;
            }
            if (!do_send_v1(fd, name, buffer)) return false;
            break;
        case ID_SEND_V2:
            // 检查是否允许push操作
            if (!isOperationAllowed(name, "persist.adb.push_disabled")){
                LOG(ERROR) << "forbid_push_file";
                return false;
            }
            if (!do_send_v2(fd, name, buffer)) return false;
            break;
        case ID_RECV_V1:
            // 检查是否允许pull操作
            if (!isOperationAllowed(name, "persist.adb.pull_disabled")){
                LOG(ERROR) << "forbid_pull_file";
                return false;
            }
            if (!do_recv_v1(fd, name, buffer)) return false;
            break;
        case ID_RECV_V2:
            // 检查是否允许pull操作
            if (!isOperationAllowed(name, "persist.adb.pull_disabled")){
                LOG(ERROR) << "forbid_pull_file";
                return false;
            }
            if (!do_recv_v2(fd, name, buffer)) return false;
            break;
        case ID_QUIT:
            return false;
        default:
            SendSyncFail(fd, StringPrintf("unknown command %08x", request.id));
            return false;
    }
    return true;
}

这个函数被调用的地方有两个:一个是在handle_send_file函数中,用于判断是否允许push操作;另一个是在do_recv_v1或do_recv_v2函数中,用于判断是否允许pull操作。如果判断结果为false,则会向adb客户端程序发送一个ID_FAIL消息,并终止传输。

总结

通过上面的分析,android11源码中实现了adb shell push/pull禁止特定文件的功能,主要是通过新增一个isOperationAllowed函数来判断是否允许传输某个文件。这个函数的优点是可以通过设置系统属性来动态控制是否禁止push或pull操作,也可以通过修改应用白名单数组来指定哪些应用的文件可以传输。这样可以提高系统的安全性和灵活性。

希望我的博客文章对你有所帮助。如果你有任何问题或建议,请随时与我联系。谢谢!

相关实践学习
AnalyticDB PostgreSQL 企业智能数据中台:一站式管理数据服务资产
企业在数据仓库之上可构建丰富的数据服务用以支持数据应用及业务场景;ADB PG推出全新企业智能数据平台,用以帮助用户一站式的管理企业数据服务资产,包括创建, 管理,探索, 监控等; 助力企业在现有平台之上快速构建起数据服务资产体系
相关文章
|
8月前
|
开发工具 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)-优雅草卓伊凡
824 11
X Android SDK file not found: adb.安卓开发常见问题-Android SDK 缺少 `adb`(Android Debug Bridge)-优雅草卓伊凡
|
12月前
|
Android开发 开发者
Android自定义View之不得不知道的文件attrs.xml(自定义属性)
本文详细介绍了如何通过自定义 `attrs.xml` 文件实现 Android 自定义 View 的属性配置。以一个包含 TextView 和 ImageView 的 DemoView 为例,讲解了如何使用自定义属性动态改变文字内容和控制图片显示隐藏。同时,通过设置布尔值和点击事件,实现了图片状态的切换功能。代码中展示了如何在构造函数中解析自定义属性,并通过方法 `setSetting0n` 和 `setbackeguang` 实现功能逻辑的优化与封装。此示例帮助开发者更好地理解自定义 View 的开发流程与 attrs.xml 的实际应用。
339 2
Android自定义View之不得不知道的文件attrs.xml(自定义属性)
|
移动开发 安全 Java
Android历史版本与APK文件结构
通过以上内容,您可以全面了解Android的历史版本及其主要特性,同时掌握APK文件的结构和各部分的作用。这些知识对于理解Android应用的开发和发布过程非常重要,也有助于在实际开发中进行高效的应用管理和优化。希望这些内容对您的学习和工作有所帮助。
1611 83
|
12月前
|
Java Android开发
Android studio中build.gradle文件简单介绍
本文解析了Android项目中build.gradle文件的作用,包括jcenter仓库配置、模块类型定义、包名设置及依赖管理,涵盖本地、库和远程依赖的区别。
970 19
|
12月前
|
存储 XML Java
Android 文件数据储存之内部储存 + 外部储存
简介:本文详细介绍了Android内部存储与外部存储的使用方法及核心原理。内部存储位于手机内存中,默认私有,适合存储SharedPreferences、SQLite数据库等重要数据,应用卸载后数据会被清除。外部存储包括公共文件和私有文件,支持SD卡或内部不可移除存储,需申请权限访问。文章通过代码示例展示了如何保存、读取、追加、删除文件以及将图片保存到系统相册的操作,帮助开发者理解存储机制并实现相关功能。
2732 2
|
ARouter Android开发
Android不同module布局文件重名被覆盖
Android不同module布局文件重名被覆盖
|
监控 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) 系统信息获取如屏幕截图和录屏。通过这些功能,用户可高效调试和管理安卓设备。
|
ARouter Android开发
Android不同module布局文件重名被覆盖
Android不同module布局文件重名被覆盖
1109 0
|
Shell Linux Android开发
Android强大的原生调试工具adb的常用命令
Android强大的原生调试工具adb的常用命令
|
Android开发 Shell
android adb常用命令
命令通用格式 adb [-d|-e|-s] 命令通用格式,adb是必须的,接下来方括号[]里面的内容不是必须的,最后才是我们需要执行的命令操作,例如 adb -s emulator-5554 install xxxer.
1283 0