乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      為Android應用程序讀取/dev下設備而提權(quán)(二)

       herowuking 2015-01-14
      為Android應用程序讀取/dev下設備而提權(quán)(二)
              
                在為Android應用程序讀取/dev下設備而提權(quán)(一)中,簡單總結(jié)了提權(quán)的兩種方法: device_initinit.rc 。在此篇文章中,我將詳細總結(jié)的是稍一不留神,就容易把人弄暈乎的init.cdevice_initinit.rc 三者之間的關(guān)系,TA們到底是如何工作的。


      目錄結(jié)構(gòu) 

               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 :        *注釋中的序號表示執(zhí)行順序    
      1. int main(int argc, char **argv)  
      2. {  
      3.     … …  
      4.     mkdir("/dev", 0755); //建立基本文件系統(tǒng)節(jié)點  
      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("reading config file\n");  
      15.     parse_config_file("/init.rc");   // 1、 調(diào)用parse_config 函數(shù)解析init.rc腳本   
      16.     //11、經(jīng)過解析,init.rc的內(nèi)容就被分為多少個段,被串在action_list鏈表中。on 開頭的都是action類型的段,比如init段,init段用一個結(jié)構(gòu)體struct action表示,    其中name是init,所有這個段內(nèi)的命令,都被串在commands鏈表中。  
      17.     action_for_each_trigger("early-init", action_add_queue_tail);  //12、 遍歷action_list鏈表,查找name是early-init的那個action,將這個節(jié)點放在action_queu    e的尾部。  
      18.     drain_action_queue(); // 13、將action_queue尾部的節(jié)點遍歷,然后刪除。就相當于遍歷name是early-init的action節(jié)點內(nèi)的commands鏈表。就是在執(zhí)行init.rc腳本中    on early-init段內(nèi)的所有命令。  
      19.     … …  
      20.     INFO("device init\n");  
      21.     device_fd = device_init();  //常見必要的設備節(jié)點  
      22.     property_init(); //init 以后的任務就是proper_service  
      23.   
      24.     action_for_each_trigger("init", action_add_queue_tail);  //14、將init 段,加入action_queue  
      25.     drain_action_queue(); // 執(zhí)行init段得命令  
      26.     … …  
      27. }  

      system/core/init/parser.c:

      1. static void parse_config(const char *fn, char *s)  
      2. {  
      3.     struct parse_state state;  
      4.     char *args[MAXARGS];  
      5.     int nargs;  
      6.   
      7.     nargs = 0;  
      8.     state.filename = fn;  
      9.     state.line = 1;  
      10.     state.ptr = s;  
      11.     state.nexttoken = 0;  
      12.     state.parse_line = parse_line_no_op;  //這個函數(shù)是空的,就是什么都不做  
      13.     for (;;) {  
      14.         switch (next_token(&state)) {  // 2、 和T_TEXT狀態(tài)配合,先把把每一行的參數(shù)都放在args數(shù)組里  
      15.         case T_EOF:  
      16.             state.parse_line(&state, 0, 0); // 最后看這,到此文件解析完成,也是上一段的完成,需要寫個NULL表示末尾。  
      17.             return;  
      18.         case T_NEWLINE:  
      19.             if (nargs) {  
      20.                 int kw = lookup_keyword(args[0]);  // 3、得到新的一行,開始解析,判斷一下拿到的第一個參數(shù)是什么關(guān)鍵字,這里面有幾種情,命令COMMAND,段SECTION,和選項OPTION,這個選項是針對服務的,開啟,關(guān)閉等操作。  
      21.                 if (kw_is(kw, SECTION)) {   // 4、判斷得到的關(guān)鍵字是不是段,keywords.h里定義了各種能解析的關(guān)鍵字分別是什么屬性。  
      22.                     state.parse_line(&state, 0, 0); // 表示上一段解析結(jié)束,因為使用的是雙向鏈表,這樣就給鏈表最后一個元素寫NULL,表示到末尾了。  
      23.                     parse_new_section(&state, kw, nargs, args);  // 5、創(chuàng)建一個新段的鏈表,比如init段,先跳到這個函數(shù)看,然后再回來。  
      24.                 } else {  
      25.                     state.parse_line(&state, nargs, args); //10、 得到新的一行,通過上面的操作已經(jīng)知道現(xiàn)在是在什么段中,是on 還是service,行解析函數(shù)也做了相應變化,開始解析這一行,加入action的commands鏈表中。  
      26.                 }  
      27.                 nargs = 0;  
      28.             }  
      29.             break;  
      30.         case T_TEXT:  
      31.             if (nargs < MAXARGS) {  
      32.                 args[nargs++] = state.text;  
      33.             }  
      34.             break;  
      35.         }  
      36.     }  
      37. }  
      38.   
      39.   
      40. void parse_new_section(struct parse_state *state, int kw,  
      41.                        int nargs, char **args)  
      42. {  
      43.     printf("[ %s %s ]\n", args[0],  
      44.            nargs > 1 ? args[1] : "");  
      45.     switch(kw) {  // 6、這里判斷 是什么類型的段,不同類型的段使用的解析函數(shù)不同,說白了就是分命令還是服務。  
      46.     case K_service:  
      47.         state->context = parse_service(state, nargs, args);  
      48.         if (state->context) {  
      49.             state->parse_line = parse_line_service;  
      50.             return;  
      51.         }  
      52.         break;  
      53.     case K_on:  
      54.         state->context = parse_action(state, nargs, args); // 7、創(chuàng)建一個action 鏈表,把這個鏈表加入到action_list中  
      55.         if (state->context) {  
      56.             state->parse_line = parse_line_action; // 8、把行解析函數(shù)換掉,原來是parse_no_op 什么都不做,再在要把每行都解析成一個命令動作。把這個命令動作加入到action中的commands鏈表內(nèi)  
      57.             return;  
      58.         }  
      59.         break;  
      60.     }  
      61.     state->parse_line = parse_line_no_op; // 9、走到這就是出錯了,段的名字沒寫或者寫多了  
      62. }  


      本章小結(jié)


              經(jīng)過上面的分析,對/dev/設備權(quán)限的修改放在不同的位置會有覆蓋的效果,device.c內(nèi)的修改會覆蓋early-init段內(nèi)的命令,init 段內(nèi)的命令會覆蓋device.c中的修改,如果3個位置都有對用一個設備權(quán)限的修改,那init段的修改會最終生效。




        本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多