zoukankan      html  css  js  c++  java
  • 系统进程 zygote(三)—— app_process 的 main 函数

    ilocker:关注 Android 安全(新入行,0基础) QQ: 2597294287

    首先:

    1 if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) {
    2     // Older kernels don't understand PR_SET_NO_NEW_PRIVS and return
    3     // EINVAL. Don't die on such kernels.
    4     if (errno != EINVAL) {
    5         LOG_ALWAYS_FATAL("PR_SET_NO_NEW_PRIVS failed: %s", strerror(errno));
    6         return 12;
    7     }
    8 }

    这段代码与系统安全机制有关,prctl(PR_SET_NO_NEW_PRIVS) 貌似是禁止动态改变权限,相关内容需要去了解 SEAndroid。

    SEAndroid 是在 Android 4.4 上正式推出的基于 SELinux 的系统安全机制。

    然后创建 AppRuntime 对象,类 AppRuntime 继承自 AndroidRuntime。

    1 AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));

    接着从命令行参数中找到虚拟机相关的参数 (argv[0] 肯定不是,直接忽略),添加到 runtime 对象:

     1 argc--;
     2 argv++;
     3 
     4 int i;
     5 for (i = 0; i < argc; i++) {
     6     if (argv[i][0] != '-') {
     7         break;
     8     }
     9     if (argv[i][1] == '-' && argv[i][2] == 0) {
    10         ++i; // Skip --.
    11         break;
    12     }
    13     runtime.addOption(strdup(argv[i]));
    14 }

    假设传入的命令行参数是这样:

    -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote

    -Xzygote 是传递给虚拟机的参数,/system/bin 是 parent dir (程序的运行目录)。后面接着一些 internal 参数,其中 --zygote 表示以 zygote 模式启动。

    如果是上面这段命令行参数,藉由 for 循环中的两个 if,最终添加到 runtime 对象的参数是 -Xzygote。

    接着处理 parent dir 后面的那些 internal 参数:

     1 ++i;  // Skip unused "parent dir" argument.
     2 while (i < argc) {
     3     const char* arg = argv[i++];
     4     if (strcmp(arg, "--zygote") == 0) {
     5         zygote = true;
     6         niceName = ZYGOTE_NICE_NAME;
     7     } else if (strcmp(arg, "--start-system-server") == 0) {
     8         startSystemServer = true;
     9     } else if (strcmp(arg, "--application") == 0) {
    10         application = true;
    11     } else if (strncmp(arg, "--nice-name=", 12) == 0) {
    12         niceName.setTo(arg + 12);
    13     } else if (strncmp(arg, "--", 2) != 0) {
    14         className.setTo(arg);
    15         break;
    16     } else {
    17         --i;
    18         break;
    19     }
    20 }

    结果是:变量 zygote 为 true,niceName 为 zygote 或 zygote64 (ZYGOTE_NICE_NAME),startSystemServer 为 true。

    接着准备启动 ZygoteInit 类 (或 RuntimeInit 类) 的参数:

     1 Vector<String8> args;
     2 if (!className.isEmpty()) {
     3     // We're not in zygote mode, the only argument we need to pass
     4     // to RuntimeInit is the application argument.
     5     args.add(application ? String8("application") : String8("tool"));
     6     runtime.setClassNameAndArgs(className, argc - i, argv + i);
     7 } else {
     8     // We're in zygote mode.
     9     maybeCreateDalvikCache();
    10 
    11     if (startSystemServer) {
    12         args.add(String8("start-system-server"));
    13     }
    14 
    15     char prop[PROP_VALUE_MAX];
    16     if (property_get(ABI_LIST_PROPERTY, prop, NULL) == 0) {
    17         LOG_ALWAYS_FATAL("app_process: Unable to determine ABI list from property %s.",
    18             ABI_LIST_PROPERTY);
    19         return 11;
    20     }
    21 
    22     String8 abiFlag("--abi-list=");
    23     abiFlag.append(prop);
    24     args.add(abiFlag);
    25 
    26     // In zygote mode, pass all remaining arguments to the zygote
    27     // main() method.
    28     for (; i < argc; ++i) {
    29         args.add(String8(argv[i]));
    30     }
    31 }

    然后将传给 runtime 对象的启动参数的 argv[0] (应该为 app_processxx) 替换为 niceName。并将本进程的进程名也修改为 niceName。

    1 if (!niceName.isEmpty()) {
    2     runtime.setArgv0(niceName.string());
    3     set_process_name(niceName.string());
    4 }

    最后启动 Java 类 ZygoteInit (如果是 zygote 模式),并传入启动参数。

     1 if (zygote) {
     2     runtime.start("com.android.internal.os.ZygoteInit", args);
     3 } else if (className) {
     4     runtime.start("com.android.internal.os.RuntimeInit", args);
     5 } else {
     6     fprintf(stderr, "Error: no class name or --zygote supplied.
    ");
     7     app_usage();
     8     LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
     9     return 10;
    10 }

    app_process 除了能启动 Zygote 进程,也可以执行某个系统的 Java 类。Android 手机中常用的工具 “am” 是一个通过发送 Intent 来启动应用程序的工具。但是,“am” 实际上只是一个包含几行代码的脚本文件,它的功能就是调用 app_process 来完成。

    学习资料: 《深入解析 Android 5.0 系统》

  • 相关阅读:
    NIO学习
    XML(二)
    IO和NIO
    Log4j
    异常处理机制
    XML
    数据交互
    分页实现的三种方式
    Idea破解
    数据库连接池
  • 原文地址:https://www.cnblogs.com/ilocker/p/4718547.html
Copyright © 2011-2022 走看看