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

本文涉及的产品
阿里云百炼推荐规格 ADB PostgreSQL,4核16GB 100GB 1个月
简介: 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操作,也可以通过修改应用白名单数组来指定哪些应用的文件可以传输。这样可以提高系统的安全性和灵活性。

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

相关实践学习
阿里云百炼xAnalyticDB PostgreSQL构建AIGC应用
通过该实验体验在阿里云百炼中构建企业专属知识库构建及应用全流程。同时体验使用ADB-PG向量检索引擎提供专属安全存储,保障企业数据隐私安全。
AnalyticDB PostgreSQL 企业智能数据中台:一站式管理数据服务资产
企业在数据仓库之上可构建丰富的数据服务用以支持数据应用及业务场景;ADB PG推出全新企业智能数据平台,用以帮助用户一站式的管理企业数据服务资产,包括创建, 管理,探索, 监控等; 助力企业在现有平台之上快速构建起数据服务资产体系
相关文章
|
2月前
|
Shell
Shell 文件包含
10月更文挑战第5天
35 4
|
27天前
|
人工智能 搜索推荐 物联网
Android系统版本演进与未来展望####
本文深入探讨了Android操作系统从诞生至今的发展历程,详细阐述了其关键版本迭代带来的创新特性、用户体验提升及对全球移动生态系统的影响。通过对Android历史版本的回顾与分析,本文旨在揭示其成功背后的驱动力,并展望未来Android可能的发展趋势与面临的挑战,为读者呈现一个既全面又具深度的技术视角。 ####
|
2月前
|
ARouter Android开发
Android不同module布局文件重名被覆盖
Android不同module布局文件重名被覆盖
|
25天前
|
IDE Java 开发工具
移动应用与系统:探索Android开发之旅
在这篇文章中,我们将深入探讨Android开发的各个方面,从基础知识到高级技术。我们将通过代码示例和案例分析,帮助读者更好地理解和掌握Android开发。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的信息和技巧。让我们一起开启Android开发的旅程吧!
|
12天前
|
监控 Java Android开发
深入探索Android系统的内存管理机制
本文旨在全面解析Android系统的内存管理机制,包括其工作原理、常见问题及其解决方案。通过对Android内存模型的深入分析,本文将帮助开发者更好地理解内存分配、回收以及优化策略,从而提高应用性能和用户体验。
|
14天前
|
存储 安全 Android开发
探索Android系统的最新安全特性
在数字时代,智能手机已成为我们生活中不可或缺的一部分。随着技术的不断进步,手机操作系统的安全性也越来越受到重视。本文将深入探讨Android系统最新的安全特性,包括其设计理念、实施方式以及对用户的影响。通过分析这些安全措施如何保护用户免受恶意软件和网络攻击的威胁,我们希望为读者提供对Android安全性的全面了解。
|
2月前
|
缓存 Java Shell
Android 系统缓存扫描与清理方法分析
Android 系统缓存从原理探索到实现。
74 15
Android 系统缓存扫描与清理方法分析
|
27天前
|
监控 Java Android开发
深入探讨Android系统的内存管理机制
本文将深入分析Android系统的内存管理机制,包括其内存分配、回收策略以及常见的内存泄漏问题。通过对这些方面的详细讨论,读者可以更好地理解Android系统如何高效地管理内存资源,从而提高应用程序的性能和稳定性。
61 16
|
19天前
|
安全 Android开发 iOS开发
深入探讨Android与iOS系统的差异及未来发展趋势
本文旨在深入分析Android和iOS两大移动操作系统的核心技术差异、用户体验以及各自的市场表现,进一步探讨它们在未来技术革新中可能的发展方向。通过对比两者的开放性、安全性、生态系统等方面,本文揭示了两大系统在移动设备市场中的竞争态势和潜在变革。
|
1月前
|
算法 JavaScript Android开发