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

首先:

 if (prctl(PR_SET_NO_NEW_PRIVS, , , , ) < ) {
// 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 ;
}
}

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

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

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

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

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

 argc--;
argv++; int i;
for (i = ; i < argc; i++) {
if (argv[i][] != '-') {
break;
}
if (argv[i][] == '-' && argv[i][] == ) {
++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") == ) {
zygote = true;
niceName = ZYGOTE_NICE_NAME;
} else if (strcmp(arg, "--start-system-server") == ) {
startSystemServer = true;
} else if (strcmp(arg, "--application") == ) {
application = true;
} else if (strncmp(arg, "--nice-name=", ) == ) {
niceName.setTo(arg + );
} else if (strncmp(arg, "--", ) != ) {
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) == ) {
LOG_ALWAYS_FATAL("app_process: Unable to determine ABI list from property %s.",
ABI_LIST_PROPERTY);
return ;
} 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 ;
}

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

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

系统进程 zygote(三)—— app_process 的 main 函数的更多相关文章

  1. 系统进程 zygote(一)—— 概述

    和蔼的春光,充满鸳鸯的池塘:快辞别寂寞的梦乡,来和我摸一会鱼儿,折一枝海棠.—— 徐志摩·醒!醒! ilocker:关注 Android 安全(新入行,0基础) QQ: 2597294287 先看一张 ...

  2. Zygote(app_process)相关分析1

    首先我们从Init.c中来看,当Init中解析完init.rc文件时会得到一系列的action,通过action去调用一些函数. Zygote是在init.rc中service section中 se ...

  3. x264代码剖析(三):主函数main()、解析函数parse()与编码函数encode()

    x264代码剖析(三):主函数main().解析函数parse()与编码函数encode() x264的入口函数为main().main()函数首先调用parse()解析输入的參数,然后调用encod ...

  4. 三种方法打印 main函数的返回地址的值(old EIP)(用途,你懂得!)

    这里能够简单的改动随意函数的返回地址.能够做到自己定义EIP的指向,就可以运行当前进程空间的随意指令,这里仅仅是让大家更清楚栈帧结构,没有涉及跨进程的inline HOOK 等,后面会陆续讲下读取随意 ...

  5. Android系统进程Zygote启动过程的源代码分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6768304 在Android系统中,所有的应用 ...

  6. 系统进程 zygote(二)—— zygote.rc 脚本

    夕阳已在沉沉的淡化,这黄昏的美,有谁能描画?莽莽的天涯,哪里是我的家,哪里是我的家?爱人呀,我这般的想着你,你那里可也有丝毫的牵挂?—— 徐志摩·海边的梦 ilocker:关注 Android 安全( ...

  7. Zygote(app_process)相关分析2

    在前一篇文章中已经分析了从init.c到Zygote(app_process)的启动流程. 今天开始分析frameworks/base/cmds/app_process/app_main.cpp. s ...

  8. [汇编与C语言关系]2. main函数与启动例程

    为什么汇编程序的入口是_start,而C程序的入口是main函数呢?以下就来解释这个问题 在<x86汇编程序基础(AT&T语法)>一文中我们汇编和链接的步骤是: $ as hell ...

  9. 【Go入门教程3】流程(if、goto、for、switch)和函数(多个返回值、变参、传值与传指针、defer、函数作为值/类型、Panic和Recover、main函数和init函数、import)

    这小节我们要介绍Go里面的流程控制以及函数操作. 流程控制 流程控制在编程语言中是最伟大的发明了,因为有了它,你可以通过很简单的流程描述来表达很复杂的逻辑.Go中流程控制分三大类:条件判断,循环控制和 ...

随机推荐

  1. servletcontext监听器的启动位置以及tomcat和eclipse的目录结构

    情景: 想在应用启动的时候就加载spring容器 在ServletContextListener.contextInitialized()中加载spring容器 ApplicationContext ...

  2. Properties+重温Map+本地计数器

    昨天想写一个记账本,发现并不能把项目名称与内容关联起来,于是乎我想到了map,可是又不知道map储存到文件中又怎么读出来,幸好今天遇到了properties Properties是Hashtable的 ...

  3. Ubuntu 12.10 配置MyEclipes 10.7环境(加破解)

    下周要在Ubuntu中调试程序,所以今天抽空先配置好Myeclipse环境. 准备: JDK  下载地址: http://www.oracle.com/technetwork/java/javase/ ...

  4. css知多少(7)——盒子模型

    1. 引言 从这一节开始,我们就进入本系列的第三部分——css呈现.本部分将描述css在页面的几种布局和呈现的特性.包括两类:文字.块. 第一类——文字.这部分相对比较简单一些,例如设置字号.字体.颜 ...

  5. PhotoSwipe - 移动开发必备的 iOS 风格相册

    PhotoSwipe 是一个专门针对移动设备的图像画廊,它的灵感来自 iOS 的图片浏览器和谷歌移动端图像. PhotoSwipe 提供您的访客熟悉和直观的界面,使他们能够与您的移动网站上的图像进行交 ...

  6. 带给您灵感的25个最新鲜的 HTML5 网站

    感谢 HTML5 带来的惊人的先进特性,在未来几年,HTML5 将会继续发挥巨大的推动作用,不仅是在 Web 应用中,网页设计领域也会有新的变革.今天,我们在这里集合了能够带给您灵感的25个最新鲜的 ...

  7. CSS3动画处理浏览器内核时候前缀(兼容性)

    Gecko内核   css前缀为"-moz-" 火狐浏览器 WebKit内核 css前缀为"-webkit-"    Comodo Drangon(科摩多龙), ...

  8. CSS3 学习笔记

    border-radius 圆角是做网页永远绕不过的话题,以前基本是通过背景图片做的,有了 CSS3 以后通过属性就 能够搞定,我们可以通过 border-radius 设置元素的圆角半径. bord ...

  9. canvas画布在主流浏览器中的尺寸限制

    通过测试发现,canvas在不同浏览器下面有不同的最大尺寸限制. 大家都知道,canvas有自身的width,height属性来控制尺寸,用css的width,height,控制显示的大小.可以理解为 ...

  10. Android Animation学习(三) ApiDemos解析:XML动画文件的使用

    Android Animation学习(三) ApiDemos解析:XML动画文件的使用 可以用XML文件来定义Animation. 文件必须有一个唯一的根节点: <set>, <o ...