• 禁用adb install 安装app功能


    1.前言

    android 的产品开发只中,在进行一些定制开发中,对于一些apo需要通过属性来控制禁上安装,adb nstl也不分许安装,所以就典熟悉adb install的安装流程,然后来禁用adb install安装功能,接下来分析下adb 下的安装流程

    2.禁用adb install 安装app功能的核心类

    system\core\adb\daemon\abb.cpp
    system\core\adb\daemon\shell_service.cpp
    
    • 1
    • 2

    3.禁用adb install 安装app功能的核心功能分析和实现

    在android 的产品中,在通过adb install 进入 adb install安装模式后正常可以进行安装app的相关操作,而adb 是pc端工具,adbd是服务端Q,运行在手机 adbd 读取 socket 解析由 adb 传过来的命令串,解析相关的命令执行相关功能,所以在pc端输入adb 相关命令就会在systemlcoreladb 模块解析相关命令所以说在abb.cpp中来作为服务端来执行相关功能

    3.1abb.cpp相关源码分析

    在system中的adb install 安装apk的时候会有下面的log,有install字样。会调用StartCommandlnProcess和execCmd执行命令abb.cpp里面的bin程序一直在读命令ReadProtocolString,abb这个程序开机就在后台运行

     
      std::vector<std::string_view> parseCmdArgs(std::string_view args) {
          std::vector<std::string_view> argv;
      
          char delim = ABB_ARG_DELIMETER;
          size_t size = args.size();
          size_t base = 0;
          while (base < size) {
              size_t found;
              for (found = base; found < size && args[found] && args[found] != delim; ++found)
                  ;
              if (found > base) {
                  argv.emplace_back(args.substr(base, found - base));
              }
              base = found + 1;
          }
      
          return argv;
      }
      
      }  // namespace
      
      static int execCmd(std::string_view args, int in, int out, int err) {
          AdbFdTextOutput oin(out);
          AdbFdTextOutput oerr(err);
          return cmdMain(parseCmdArgs(args), oin, oerr, in, out, err, RunMode::kLibrary);
      }
    int main(int argc, char* const argv[]) {
        signal(SIGPIPE, SIG_IGN);
     
        int fd = STDIN_FILENO;
        std::string data;
        while (true) {
            std::string error;
            if (!ReadProtocolString(fd, &data, &error)) {
                PLOG(ERROR) << "Failed to read message: " << error;
                break;
            }
     
            std::string_view name = data;
            auto protocol = SubprocessProtocol::kShell;
            if (android::base::ConsumePrefix(&name, "abb:")) {
                protocol = SubprocessProtocol::kShell;
            } else if (android::base::ConsumePrefix(&name, "abb_exec:")) {
                protocol = SubprocessProtocol::kNone;
            } else {
                LOG(FATAL) << "Unknown command prefix for abb: " << data;
            }
     
            unique_fd result = StartCommandInProcess(std::string(name), &execCmd, protocol);
            int max_buf = LINUX_MAX_SOCKET_SIZE;
            adb_setsockopt(result, SOL_SOCKET, SO_SNDBUF, &max_buf, sizeof(max_buf));
            if (android::base::SendFileDescriptors(fd, "", 1, result.get()) != 1) {
                PLOG(ERROR) << "Failed to send an inprocess fd for command: " << data;
                break;
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58

    从abb.cpp的上述的相关的源码中,可以知道abb.cpp里面的bin程席一直在读命令ReadProtocolStringabb这个程序开机就在后台运行,可以接收pc端的相关命令,在parseCmdArgs(std:string view args )中解析从adb的命令中解析命令
    接下来分析下shell service.cpp中的
    StartCommandInProcess相关命会分析

    3.2 shell service.cpp的相关源码分析

    在system/core/adb的模块中,在通过上述的分析得知,在这个shell service.cpp中负责在接收c端adb的相关命令中,负责解析,首先在StartCommand nProcess/std.sting name. Command command SubprocessProtocol prtoco 中fadb insta开t装app的相关
    功能的实现

     
      unique_fd StartSubprocess(std::string name, const char* terminal_type, SubprocessType type,
                                SubprocessProtocol protocol, bool make_pty_raw,
                                SubprocessProtocol error_protocol, unique_fd* error_fd) {
          D("starting %s subprocess (protocol=%s, TERM=%s): '%s'",
            type == SubprocessType::kRaw ? "raw" : "PTY",
            protocol == SubprocessProtocol::kNone ? "none" : "shell", terminal_type, name.c_str());
      
          auto subprocess = std::make_unique<Subprocess>(std::move(name), terminal_type, type, protocol,
                                                         make_pty_raw);
          if (!subprocess) {
              LOG(ERROR) << "failed to allocate new subprocess";
              *error_fd = ReportError(error_protocol, "failed to allocate new subprocess");
              return {};
          }
      
          std::string error;
          if (!subprocess->ForkAndExec(&error)) {
              LOG(ERROR) << "failed to start subprocess: " << error;
              *error_fd = ReportError(error_protocol, error);
              return {};
          }
      
          unique_fd local_socket(subprocess->ReleaseLocalSocket());
          D("subprocess creation successful: local_socket_fd=%d, pid=%d", local_socket.get(),
            subprocess->pid());
      
          if (!Subprocess::StartThread(std::move(subprocess), &error)) {
              LOG(ERROR) << "failed to start subprocess management thread: " << error;
              *error_fd = ReportError(error_protocol, error);
              return {};
          }
      
          return local_socket;
      }
    //add core start
    #include 
    bool isAllowInstall() {
    	std::string value = android::base::GetProperty("persist.sys.isallow", "true");
    	if (strcmp("true", value.c_str()) == 0)
          return true;
    	else
    	  return false;	
    }
    //add core end
     
    unique_fd StartCommandInProcess(std::string name, Command command, SubprocessProtocol protocol) {
        LOG(INFO) << "StartCommandInProcess(" << dump_hex(name.data(), name.size()) << ")";
     
    //add core start
    	std::string namestring = dump_hex(name.data(), name.size());
    	std::string install_flag="package.install";
    	std::string::size_type idx=namestring.find(install_flag);
    //add core end
     
        constexpr auto terminal_type = "";
        constexpr auto type = SubprocessType::kRaw;
        constexpr auto make_pty_raw = false;
     
        auto subprocess = std::make_unique<Subprocess>(std::move(name), terminal_type, type, protocol,
                                                       make_pty_raw);
    //add core start
    	if(idx == std::string::npos ){
    	     LOG(ERROR) << "the command do not include package.install string";
    	}else{
    	  if(!isAllowInstall()) {
    	     LOG(ERROR) << "can not allow to install app" ;
    	     return ReportError(protocol, "can not allow to install app by adb install command");
    	  }else 
    	     LOG(ERROR) << "Allow to install app";
    	}
    //add core end
     
    											   
        if (!subprocess) {
            LOG(ERROR) << "failed to allocate new subprocess";
            return ReportError(protocol, "failed to allocate new subprocess");
        }
     
        std::string error;
        if (!subprocess->ExecInProcess(std::move(command), &error)) {
            LOG(ERROR) << "failed to start subprocess: " << error;
            return ReportError(protocol, error);
        }
     
        unique_fd local_socket(subprocess->ReleaseLocalSocket());
        D("inprocess creation successful: local_socket_fd=%d, pid=%d", local_socket.get(),
          subprocess->pid());
     
        if (!Subprocess::StartThread(std::move(subprocess), &error)) {
            LOG(ERROR) << "failed to start inprocess management thread: " << error;
            return ReportError(protocol, error);
        }
     
        return local_socket;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96

    在上述的shell service.cpp的相关源码中分析得知,在通过判断dump hex(name.data(),name.size()中是否有package.install字符来判断是否执行adb install安装app的命令,然后在通过调用isAllowInstal()来判断系统属性persist.sys.isallow是否允许安装app,当为false就表示禁止安装第=方app,这时候就返回ReportError(protocol,“can not allow to install app by adb install command”).就实现禁止通过adb install来安装第三方app功能

  • 相关阅读:
    Missing Parts——Alpha 第 3 季NFT作品集来啦!
    网络安全笔记5——数字签名
    [CISCN2019 华北赛区 Day1 Web1]Dropbox 1
    ARM 汇编指令集1_2
    216. 组合总和 III
    2.ClickHouse系列之特点介绍
    MyBatis-Plus联表查询的短板,终于有一款工具补齐了
    unity的ui跟随鼠标移动
    HDLbits exercises 6 (MULTIPLEXERS节选题)
    李航老师《统计学习方法》第2章阅读笔记
  • 原文地址:https://blog.csdn.net/houxian1103/article/details/133500795