系统进程 zygote(三)—— app_process 的 main 函数
2015-08-10 17:10
633 查看
ilocker:关注 Android 安全(新入行,0基础) QQ: 2597294287
首先:
这段代码与系统安全机制有关,prctl(PR_SET_NO_NEW_PRIVS) 貌似是禁止动态改变权限,相关内容需要去了解 SEAndroid。
SEAndroid 是在 Android 4.4 上正式推出的基于 SELinux 的系统安全机制。
然后创建 AppRuntime 对象,类 AppRuntime 继承自 AndroidRuntime。
接着从命令行参数中找到虚拟机相关的参数 (argv[0] 肯定不是,直接忽略),添加到 runtime 对象:
假设传入的命令行参数是这样:
-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 参数:
结果是:变量 zygote 为 true,niceName 为 zygote 或 zygote64 (ZYGOTE_NICE_NAME),startSystemServer 为 true。
接着准备启动 ZygoteInit 类 (或 RuntimeInit 类) 的参数:
然后将传给 runtime 对象的启动参数的 argv[0] (应该为 app_processxx) 替换为 niceName。并将本进程的进程名也修改为 niceName。
最后启动 Java 类 ZygoteInit (如果是 zygote 模式),并传入启动参数。
app_process 除了能启动 Zygote 进程,也可以执行某个系统的 Java 类。Android 手机中常用的工具 “am” 是一个通过发送 Intent 来启动应用程序的工具。但是,“am” 实际上只是一个包含几行代码的脚本文件,它的功能就是调用 app_process 来完成。
学习资料: 《深入解析 Android 5.0 系统》
首先:
if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) { // Older kernels don't understand PR_SET_NO_NEW_PRIVS and return // EINVAL. Don't die on such kernels. if (errno != EINVAL) { LOG_ALWAYS_FATAL("PR_SET_NO_NEW_PRIVS failed: %s", strerror(errno)); return 12; } }
这段代码与系统安全机制有关,prctl(PR_SET_NO_NEW_PRIVS) 貌似是禁止动态改变权限,相关内容需要去了解 SEAndroid。
SEAndroid 是在 Android 4.4 上正式推出的基于 SELinux 的系统安全机制。
然后创建 AppRuntime 对象,类 AppRuntime 继承自 AndroidRuntime。
AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
接着从命令行参数中找到虚拟机相关的参数 (argv[0] 肯定不是,直接忽略),添加到 runtime 对象:
argc--; argv++; int i; for (i = 0; i < argc; i++) { if (argv[i][0] != '-') { break; } if (argv[i][1] == '-' && argv[i][2] == 0) { ++i; // Skip --. break; } runtime.addOption(strdup(argv[i])); }
假设传入的命令行参数是这样:
-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 参数:
++i; // Skip unused "parent dir" argument. while (i < argc) { const char* arg = argv[i++]; if (strcmp(arg, "--zygote") == 0) { zygote = true; niceName = ZYGOTE_NICE_NAME; } else if (strcmp(arg, "--start-system-server") == 0) { startSystemServer = true; } else if (strcmp(arg, "--application") == 0) { application = true; } else if (strncmp(arg, "--nice-name=", 12) == 0) { niceName.setTo(arg + 12); } else if (strncmp(arg, "--", 2) != 0) { className.setTo(arg); break; } else { --i; break; } }
结果是:变量 zygote 为 true,niceName 为 zygote 或 zygote64 (ZYGOTE_NICE_NAME),startSystemServer 为 true。
接着准备启动 ZygoteInit 类 (或 RuntimeInit 类) 的参数:
Vector<String8> args; if (!className.isEmpty()) { // We're not in zygote mode, the only argument we need to pass // to RuntimeInit is the application argument. args.add(application ? String8("application") : String8("tool")); runtime.setClassNameAndArgs(className, argc - i, argv + i); } else { // We're in zygote mode. maybeCreateDalvikCache(); if (startSystemServer) { args.add(String8("start-system-server")); } char prop[PROP_VALUE_MAX]; if (property_get(ABI_LIST_PROPERTY, prop, NULL) == 0) { LOG_ALWAYS_FATAL("app_process: Unable to determine ABI list from property %s.", ABI_LIST_PROPERTY); return 11; } String8 abiFlag("--abi-list="); abiFlag.append(prop); args.add(abiFlag); // In zygote mode, pass all remaining arguments to the zygote // main() method. for (; i < argc; ++i) { args.add(String8(argv[i])); } }
然后将传给 runtime 对象的启动参数的 argv[0] (应该为 app_processxx) 替换为 niceName。并将本进程的进程名也修改为 niceName。
if (!niceName.isEmpty()) { runtime.setArgv0(niceName.string()); set_process_name(niceName.string()); }
最后启动 Java 类 ZygoteInit (如果是 zygote 模式),并传入启动参数。
if (zygote) { runtime.start("com.android.internal.os.ZygoteInit", args); } else if (className) { runtime.start("com.android.internal.os.RuntimeInit", args); } else { fprintf(stderr, "Error: no class name or --zygote supplied.\n"); app_usage(); LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied."); return 10; }
app_process 除了能启动 Zygote 进程,也可以执行某个系统的 Java 类。Android 手机中常用的工具 “am” 是一个通过发送 Intent 来启动应用程序的工具。但是,“am” 实际上只是一个包含几行代码的脚本文件,它的功能就是调用 app_process 来完成。
学习资料: 《深入解析 Android 5.0 系统》
相关文章推荐
- [UVa 10780]Again Prime?No time.
- hdu 1151 Air Raid
- adb连接时出现如下错误CreateProcess failure, error 2
- Grails开源框架Note
- hdu1532Drainage Ditches 最大流模板水题
- Maven工程产生Jar时Main-Class和Class-Path的配置文件
- HOJ 13383 The Big Painting 二维字符串hash
- HN OJ 13375 Flowery Trails (spfa的路径遍历)
- Run-Time Check Failure #2 - Stack around the variable 'XX‘ was corrupted 解决方法
- 小米手机真机测试 waitingforDebugge 不动了
- hdu 1702 ACboy needs your help again!
- rails 2.3.8 对应的Gemfile内容
- 利用 gnuplot 绘制时间序列图 http://blog.csdn.net/liyuanbhu/article/details/8497582
- retain
- [单调栈] poj 3250 Bad Hair Day
- Gym - 100625J Jailbreak 最短路+搜索
- hyundai-wia
- grails中简单分页
- INSTALL_FAILED_MEDIA_UNAVAILABLE 错误解决
- hduoj 13375 Flowery Trails