为Android应用程序读取/dev下设备而提权(二)
为Android应用程序读取/dev下设备而提权(一) 中,简单总结了提权的两种方法: device_init init.rc 。在此篇文章中,我将详细总结的是稍一不留神,就容易把人弄晕乎的 init.c device_initinit.rc 三者之间的关系,TA们到底是如何工作的。

目录结构

ls一下system/core/init/ devices.c、devices.h、init.c、init.h、keywords.h、parser.c、property_service.c.... 另外system/core/rootdir/init.rc ,当然init.rc的位置可以另行指定。


init流程

init过程的起点是init.c *注释中的序号表示执行顺序 [cpp] view plain copy
  1. intmain(intargc,char**argv)
  2. {
  3. ……
  4. mkdir("/dev",0755);//建立基本文件系统节点
  5. mkdir("/proc",0755);
  6. mkdir("/sys",0755);
  7. mount("tmpfs","/dev","tmpfs",0,"mode=0755");
  8. mkdir("/dev/pts",0755);
  9. mkdir("/dev/socket",0755);
  10. mount("devpts","/dev/pts","devpts",0,NULL);
  11. mount("proc","/proc","proc",0,NULL);
  12. mount("sysfs","/sys","sysfs",0,NULL);
  13. ……
  14. INFO("readingconfigfile\n");
  15. parse_config_file("/init.rc");//1、调用parse_config函数解析init.rc脚本
  16. //11、经过解析,init.rc的内容就被分为多少个段,被串在action_list链表中。on开头的都是action类型的段,比如init段,init段用一个结构体structaction表示,其中name是init,所有这个段内的命令,都被串在commands链表中。
  17. action_for_each_trigger("early-init",action_add_queue_tail);//12、遍历action_list链表,查找name是early-init的那个action,将这个节点放在action_queue的尾部。
  18. drain_action_queue();//13、将action_queue尾部的节点遍历,然后删除。就相当于遍历name是early-init的action节点内的commands链表。就是在执行init.rc脚本中onearly-init段内的所有命令。
  19. ……
  20. INFO("deviceinit\n");
  21. device_fd=device_init();//常见必要的设备节点
  22. property_init();//init以后的任务就是proper_service
  23. action_for_each_trigger("init",action_add_queue_tail);//14、将init段,加入action_queue
  24. drain_action_queue();//执行init段得命令
  25. ……
  26. }

system/core/init/parser.c:

[cpp] view plain copy
  1. staticvoidparse_config(constchar*fn,char*s)
  2. {
  3. structparse_statestate;
  4. char*args[MAXARGS];
  5. intnargs;
  6. nargs=0;
  7. state.filename=fn;
  8. state.line=1;
  9. state.ptr=s;
  10. state.nexttoken=0;
  11. state.parse_line=parse_line_no_op;//这个函数是空的,就是什么都不做
  12. for(;;){
  13. switch(next_token(&state)){//2、和T_TEXT状态配合,先把把每一行的参数都放在args数组里
  14. caseT_EOF:
  15. state.parse_line(&state,0,0);//最后看这,到此文件解析完成,也是上一段的完成,需要写个NULL表示末尾。
  16. return;
  17. caseT_NEWLINE:
  18. if(nargs){
  19. intkw=lookup_keyword(args[0]);//3、得到新的一行,开始解析,判断一下拿到的第一个参数是什么关键字,这里面有几种情,命令COMMAND,段SECTION,和选项OPTION,这个选项是针对服务的,开启,关闭等操作。
  20. if(kw_is(kw,SECTION)){//4、判断得到的关键字是不是段,keywords.h里定义了各种能解析的关键字分别是什么属性。
  21. state.parse_line(&state,0,0);//表示上一段解析结束,因为使用的是双向链表,这样就给链表最后一个元素写NULL,表示到末尾了。
  22. parse_new_section(&state,kw,nargs,args);//5、创建一个新段的链表,比如init段,先跳到这个函数看,然后再回来。
  23. }else{
  24. state.parse_line(&state,nargs,args);//10、得到新的一行,通过上面的操作已经知道现在是在什么段中,是on还是service,行解析函数也做了相应变化,开始解析这一行,加入action的commands链表中。
  25. }
  26. nargs=0;
  27. }
  28. break;
  29. caseT_TEXT:
  30. if(nargs<MAXARGS){
  31. args[nargs++]=state.text;
  32. }
  33. break;
  34. }
  35. }
  36. }
  37. voidparse_new_section(structparse_state*state,intkw,
  38. intnargs,char**args)
  39. {
  40. printf("[%s%s]\n",args[0],
  41. nargs>1?args[1]:"");
  42. switch(kw){//6、这里判断是什么类型的段,不同类型的段使用的解析函数不同,说白了就是分命令还是服务。
  43. caseK_service:
  44. state->context=parse_service(state,nargs,args);
  45. if(state->context){
  46. state->parse_line=parse_line_service;
  47. return;
  48. }
  49. break;
  50. caseK_on:
  51. state->context=parse_action(state,nargs,args);//7、创建一个action链表,把这个链表加入到action_list中
  52. if(state->context){
  53. state->parse_line=parse_line_action;//8、把行解析函数换掉,原来是parse_no_op什么都不做,再在要把每行都解析成一个命令动作。把这个命令动作加入到action中的commands链表内
  54. return;
  55. }
  56. break;
  57. }
  58. state->parse_line=parse_line_no_op;//9、走到这就是出错了,段的名字没写或者写多了
  59. }


本章小结


经过上面的分析,对/dev/设备权限的修改放在不同的位置会有覆盖的效果,device.c内的修改会覆盖early-init段内的命令,init 段内的命令会覆盖device.c中的修改,如果3个位置都有对用一个设备权限的修改,那init段的修改会最终生效。

更多相关文章

  1. Android的ADB工具使用
  2. adb shell 命令详解
  3. 【转官方】Android(安卓)ADB调试命令、支持的命令、ADB文档
  4. webview中的javascript调用android命令实现android latex显示
  5. Android学习系列(29)--App调试的几个命令实践
  6. adb logcat命令查看并过滤android输出log
  7. Android系统源码目录解析
  8. Android系统架构解析
  9. Android控件之TextView全解析

随机推荐

  1. android 的一些小知识
  2. android所有控件
  3. Android(安卓)启动栈管理方式 (二)
  4. Android(安卓)单选队列 RadioGroup与Radi
  5. android:textAppearance是什么意思
  6. Android界面开发
  7. android Toast大全(五种情形)建立属于你自
  8. 设置TextView文字居中
  9. android 备忘
  10. Android(安卓)音视频汇总