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

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;
        }
    }
}

从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 <stdio.h>
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;
}

在上述的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功能

10-03 06:04