博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
为Android应用程序读取/dev下设备而提权(一)
阅读量:4208 次
发布时间:2019-05-26

本文共 5310 字,大约阅读时间需要 17 分钟。

为Android应用程序读取/dev下设备而提权(一)
         倘若应用程序需要对/dev/xxx进行读写操作,就需要提升其权限。提权方法不唯一,需要根据具体需求情况而选择。归根结底,终究都落到chmod 777 /dev/xxx 上,不同的是,chmod操作被执行在何时何地,在此做个分析总结。
        内核启动后会执行/system/init,传说中的系统1号进程,init程序起初的任务是初始化,包括各种mkdir来构建文件系统,得到硬件信息建立设备节点,安装SIGCHLD信号来回收僵尸进程的资源,解析init.rc启动脚本等等,然后init程序变身为property_service来管理系统的权限。我们可以下手的地方有两处: device_init和init.rc 

✿ init.rc

 
  这个方案是大家用的比较多的,在其中添加chmod操作很简单不多说。

✿ device.c

   这个方案用的比较少,先了解下device.c。
   device_init在/system/core/init/device.c中,详细分析如下:
  1. //分别遍历/sys/class /sys/block /sys/devices  
  2. device_init()  
  3. {  
  4.   coldboot(fd,"/sys/class");  
  5.   coldboot(fd,"/sys/block");  
  6.   coldboot(fd,"/sys/devices");  
  7. }  
  8.      
  9. //后面有个递归 /sys下是内核生成的设备,这就相当于udev的作用  
  10. do_coldboot()  
  11. {  
  12.   if(fd>= 0) {  
  13.   write(fd,"add\n", 4);  
  14.   close(fd);  
  15.   handle_device_fd(event_fd);  
  16.   }  
  17. }  
  18.   
  19. //从socket里读出add处理  
  20. handle_device_fd()   
  21. {  
  22.   if(!strcmp(uevent->action,"add")) {  
  23.   make_device(devpath,block, uevent->major, uevent->minor);  
  24.   return;  
  25.   }  
  26. }  
  27.   
  28. //得到设备的相关信息创建设备节点  
  29. make_device()   
  30. {  
  31.   mode= get_device_perm(path,&uid, &gid) | (block ? S_IFBLK : S_IFCHR);  
  32.   dev= (major << 8) | minor;  
  33.   mknod(path,mode, dev);  
  34.   chown(path,uid, gid);  
  35. }  
  36.   
  37. get_device_perm()  
  38. {  
  39.   if(get_device_perm_inner(qemu_perms, path, uid, gid, &perm) == 0) {  
  40.   returnperm;  
  41.   }elseif(get_device_perm_inner(devperms,path, uid, gid, &perm) == 0){  
  42.    returnperm;  
  43.   }else{  
  44.                 …….  
  45. }  
  46.   
  47. //得到devperms结构体的信息  
  48. get_device_perm_inner  
  49. {  
  50.  for(i= 0; perms[i].name; i++) {  
  51.   
  52.  if(perms[i].prefix){  
  53.  if(strncmp(path,perms[i].name, strlen(perms[i].name)))  
  54.  continue;  
  55.  }else{  
  56.  if(strcmp(path,perms[i].name))  
  57.  continue;  
  58.  }  
  59.  *uid= perms[i].uid;  
  60.  *gid= perms[i].gid;  
  61.  *perm= perms[i].perm; //权限位  
  62.  return0;  
  63.  }  
  64. }  
  65.   
  66. 这是devperms的具体内容  
  67. structperms_ {  
  68.    char*name;  
  69.    mode_tperm;  
  70.    unsignedintuid;  
  71.    unsignedintgid;  
  72.    unsignedshortprefix;  
  73. };  
  74. staticstructperms_ devperms[] = {  
  75. {
    "/dev/null", 0666, AID_ROOT, AID_ROOT, 0 },  
  76. {
    "/dev/zero", 0666, AID_ROOT, AID_ROOT, 0 },  
  77. {
    "/dev/full", 0666, AID_ROOT, AID_ROOT, 0 },  
  78. {
    "/dev/ptmx", 0666, AID_ROOT, AID_ROOT, 0 },  
  79. {
    "/dev/tty", 0666, AID_ROOT, AID_ROOT, 0 },  
  80. {
    "/dev/random", 0666, AID_ROOT, AID_ROOT, 0 },  
  81. {
    "/dev/urandom", 0666, AID_ROOT, AID_ROOT, 0 },  
  82. {
    "/dev/ashmem", 0666, AID_ROOT, AID_ROOT, 0 },  
  83. {
    "/dev/binder", 0666, AID_ROOT, AID_ROOT, 0 },  
  84.   
  85. /* logger should be world writable (for logging) but not readable*/  
  86. {
    "/dev/log/", 0662, AID_ROOT, AID_LOG, 1 },  
  87.   
  88. /*these should not be world writable */  
  89. {
    "/dev/android_adb", 0660, AID_ADB, AID_ADB, 0 },  
  90. {
    "/dev/android_adb_enable", 0660, AID_ADB, AID_ADB, 0 },  
  91. {
    "/dev/ttyMSM0", 0660, AID_BLUETOOTH, AID_BLUETOOTH, 0 },  
  92. {
    "/dev/alarm", 0664, AID_SYSTEM, AID_RADIO, 0 },  
  93. {
    "/dev/tty0", 0666, AID_ROOT, AID_SYSTEM, 0 },  
  94. {
    "/dev/graphics/", 0660, AID_ROOT, AID_GRAPHICS, 1 },  
  95. {
    "/dev/hw3d", 0660, AID_SYSTEM, AID_GRAPHICS, 0 },  
  96. {
    "/dev/input/", 0660, AID_ROOT, AID_INPUT, 1 },  
  97. {
    "/dev/eac", 0660, AID_ROOT, AID_AUDIO, 0 },  
  98. {
    "/dev/cam", 0660, AID_ROOT, AID_CAMERA, 0 },  
  99. {
    "/dev/pmem", 0660, AID_SYSTEM, AID_GRAPHICS, 0 },  
  100. {
    "/dev/pmem_gpu", 0660, AID_SYSTEM, AID_GRAPHICS, 1 },  
  101. {
    "/dev/pmem_adsp", 0660, AID_SYSTEM, AID_AUDIO, 1 },  
  102. {
    "/dev/pmem_camera", 0660, AID_SYSTEM, AID_CAMERA, 1 },  
  103. {
    "/dev/oncrpc/", 0660, AID_ROOT, AID_SYSTEM, 1 },  
  104. {
    "/dev/adsp/", 0660, AID_SYSTEM, AID_AUDIO, 1 },  
  105. {
    "/dev/mt9t013", 0660, AID_SYSTEM, AID_SYSTEM, 0 },  
  106. {
    "/dev/akm8976_daemon",0640, AID_COMPASS, AID_SYSTEM, 0 },  
  107. {
    "/dev/akm8976_aot", 0640, AID_COMPASS, AID_SYSTEM, 0 },  
  108. {
    "/dev/akm8976_pffd", 0640, AID_COMPASS, AID_SYSTEM, 0 },  
  109. {
    "/dev/msm_pcm_out", 0660, AID_SYSTEM, AID_AUDIO, 1 },  
  110. {
    "/dev/msm_pcm_in", 0660, AID_SYSTEM, AID_AUDIO, 1 },  
  111. {
    "/dev/msm_pcm_ctl", 0660, AID_SYSTEM, AID_AUDIO, 1 },  
  112. {
    "/dev/msm_mp3", 0660, AID_SYSTEM, AID_AUDIO, 1 },  
  113. {
    "/dev/smd0", 0640, AID_RADIO, AID_RADIO, 0 },  
  114. {
    "/dev/qmi", 0640, AID_RADIO, AID_RADIO, 0 },  
  115. {
    "/dev/qmi0", 0640, AID_RADIO, AID_RADIO, 0 },  
  116. {
    "/dev/qmi1", 0640, AID_RADIO, AID_RADIO, 0 },  
  117. {
    "/dev/qmi2", 0640, AID_RADIO, AID_RADIO, 0 },  
  118. {
    "/dev/htc-acoustic", 0640, AID_RADIO, AID_RADIO, 0 },  
  119. {NULL, 0, 0, 0, 0 },  
  120. };  

✿ init.c

       init.rc脚本和老版本android中的init.goldfish.rc脚本很早就被parse_config_file()函数解析将脚本内容分为几个段,early-init,init,early-boot,boot,和各个服务。然后在不同的时间点上执行各个段得命令或者开启各种服务。
   
init.c的一段节选:
   
  1. int main(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("readingconfig file\n");  
  15.   parse_config_file("/init.rc");   
  16. //调用parse_config解析init.rc脚本  
  17. //经过解析,init.rc的内容就被分为多少个段,被串在action_list链表中。  
  18. //on开头的都是action类型的段,比如init段,init段用一个结构体struct action表示,其中name是init,  
  19. //所有这个段内的命令,都被串在commands链表中。  
  20.   
  21.   action_for_each_trigger("early-init",action_add_queue_tail);   
  22. //遍历action_list链表,查找name是early-init的那个action,将这个节点放在action_queue的尾部。  
  23.   drain_action_queue();  
  24. //将action_queue尾部的节点遍历,然后删除。  
  25. //就相当于遍历name是early-init的action节点内的commands链表。  
  26. //就是在执行init.rc脚本中onearly-init段内的所有命令。  
  27.   
  28. ……  
  29.   INFO("deviceinit\n");  
  30.   device_fd= device_init(); //常见必要的设备节点  
  31.   
  32.   property_init();//init 以后的任务就是proper_service  
  33.   
  34.   action_for_each_trigger("init",action_add_queue_tail); //将init段,加入action_queue  
  35.   drain_action_queue();// 执行init段得命令  
  36.   
  37. … …  
  38. }  

✿ 本节小结

      
 device_init其实就是linux中的udev的一个简单的替代。把/sys/下的所有内核提供的设备都安排在/dev下创建设备节点。如果要改动/dev/一些设备的权限,可以把chmod 777写在init.rc中,但是要注意写的位置,不能太早执行,不能写在early-init段内,因为那时/dev/下的设备节点还没有被创建。
      在devices.c中修改的方法隐藏的较深不容易被发现,但是如果init.rc内再次修改就可能把之前的修改覆盖掉。

转载地址:http://aqlli.baihongyu.com/

你可能感兴趣的文章
Informatica Powercenter调优
查看>>
增量聚集
查看>>
INCREMENTAL AGGREGATION IN INFORMATICA
查看>>
INFORMATICA1
查看>>
INFORMATICA2
查看>>
GENERATE DATE / TIME DIMENSION IN INFORMATICA
查看>>
日期维表数据生成方法(Oracle方式)
查看>>
2013年中国城市及省份GDP排名
查看>>
2013年欧洲穆斯林人口达5638万(转载)
查看>>
中国将在2014年成为十万亿级的超级大国
查看>>
月球可能曾是火星卫星
查看>>
华为u8818如何刷机
查看>>
少不读水浒——揭秘水浒传
查看>>
华为——让华盛顿感到恐慌的中国公司(转载)
查看>>
VMware虚拟机磁盘分区图文教程
查看>>
从CSV文件转换为Excel的多个Sheet
查看>>
ThinkPad E40如何安装W7Ghost
查看>>
Win7旗舰版 安装步骤
查看>>
Windows 7 SP1相关资源下载
查看>>
win7下直接安装win10
查看>>