android 读取其他应用程序,为Android应用程序读取/dev下设备而提权(二)

int main(int argc, char **argv)

{

… …

mkdir("/dev", 0755); //建立基本文件系统节点

mkdir("/proc", 0755);

mkdir("/sys", 0755);

mount("tmpfs", "/dev", "tmpfs", 0, "mode=0755");

mkdir("/dev/pts", 0755);

mkdir("/dev/socket", 0755);

mount("devpts", "/dev/pts", "devpts", 0, NULL);

mount("proc", "/proc", "proc", 0, NULL);

mount("sysfs", "/sys", "sysfs", 0, NULL);

… …

INFO("reading config file\n");

parse_config_file("/init.rc"); // 1、 调用parse_config 函数解析init.rc脚本

//11、经过解析,init.rc的内容就被分为多少个段,被串在action_list链表中。on 开头的都是action类型的段,比如init段,init段用一个结构体struct action表示, 其中name是init,所有这个段内的命令,都被串在commands链表中。

action_for_each_trigger("early-init", action_add_queue_tail); //12、 遍历action_list链表,查找name是early-init的那个action,将这个节点放在action_queu e的尾部。

drain_action_queue(); // 13、将action_queue尾部的节点遍历,然后删除。就相当于遍历name是early-init的action节点内的commands链表。就是在执行init.rc脚本中 on early-init段内的所有命令。

… …

INFO("device init\n");

device_fd = device_init(); //常见必要的设备节点

property_init(); //init 以后的任务就是proper_service

action_for_each_trigger("init", action_add_queue_tail); //14、将init 段,加入action_queue

drain_action_queue(); // 执行init段得命令

… …

}

system/core/init/parser.c:

static void parse_config(const char *fn, char *s)

{

struct parse_state state;

char *args[MAXARGS];

int nargs;

nargs = 0;

state.filename = fn;

state.line = 1;

state.ptr = s;

state.nexttoken = 0;

state.parse_line = parse_line_no_op; //这个函数是空的,就是什么都不做

for (;;) {

switch (next_token(&state)) { // 2、 和T_TEXT状态配合,先把把每一行的参数都放在args数组里

case T_EOF:

state.parse_line(&state, 0, 0); // 最后看这,到此文件解析完成,也是上一段的完成,需要写个NULL表示末尾。

return;

case T_NEWLINE:

if (nargs) {

int kw = lookup_keyword(args[0]); // 3、得到新的一行,开始解析,判断一下拿到的第一个参数是什么关键字,这里面有几种情,命令COMMAND,段SECTION,和选项OPTION,这个选项是针对服务的,开启,关闭等操作。

if (kw_is(kw, SECTION)) { // 4、判断得到的关键字是不是段,keywords.h里定义了各种能解析的关键字分别是什么属性。

state.parse_line(&state, 0, 0); // 表示上一段解析结束,因为使用的是双向链表,这样就给链表最后一个元素写NULL,表示到末尾了。

parse_new_section(&state, kw, nargs, args); // 5、创建一个新段的链表,比如init段,先跳到这个函数看,然后再回来。

} else {

state.parse_line(&state, nargs, args); //10、 得到新的一行,通过上面的操作已经知道现在是在什么段中,是on 还是service,行解析函数也做了相应变化,开始解析这一行,加入action的commands链表中。

}

nargs = 0;

}

break;

case T_TEXT:

if (nargs < MAXARGS) {

args[nargs++] = state.text;

}

break;

}

}

}

void parse_new_section(struct parse_state *state, int kw,

int nargs, char **args)

{

printf("[ %s %s ]\n", args[0],

nargs > 1 ? args[1] : "");

switch(kw) { // 6、这里判断 是什么类型的段,不同类型的段使用的解析函数不同,说白了就是分命令还是服务。

case K_service:

state->context = parse_service(state, nargs, args);

if (state->context) {

state->parse_line = parse_line_service;

return;

}

break;

case K_on:

state->context = parse_action(state, nargs, args); // 7、创建一个action 链表,把这个链表加入到action_list中

if (state->context) {

state->parse_line = parse_line_action; // 8、把行解析函数换掉,原来是parse_no_op 什么都不做,再在要把每行都解析成一个命令动作。把这个命令动作加入到action中的commands链表内

return;

}

break;

}

state->parse_line = parse_line_no_op; // 9、走到这就是出错了,段的名字没写或者写多了

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值