1. 程式人生 > >為Android應用程式讀取/dev下裝置而提權(一)

為Android應用程式讀取/dev下裝置而提權(一)

//分別遍歷/sys/class /sys/block /sys/devices
device_init()
{
  coldboot(fd,"/sys/class");
  coldboot(fd,"/sys/block");
  coldboot(fd,"/sys/devices");
}
   
//後面有個遞迴 /sys下是核心生成的裝置,這就相當於udev的作用
do_coldboot()
{
  if(fd>= 0) {
  write(fd,"add\n", 4);
  close(fd);
  handle_device_fd(event_fd);
  }
}

//從socket裡讀出add處理
handle_device_fd() 
{
  if(!strcmp(uevent->action,"add")) {
  make_device(devpath,block, uevent->major, uevent->minor);
  return;
  }
}

//得到裝置的相關資訊建立裝置節點
make_device() 
{
  mode= get_device_perm(path,&uid, &gid) | (block ? S_IFBLK : S_IFCHR);
  dev= (major << 8) | minor;
  mknod(path,mode, dev);
  chown(path,uid, gid);
}

get_device_perm()
{
  if(get_device_perm_inner(qemu_perms, path, uid, gid, &perm) == 0) {
  returnperm;
  }elseif(get_device_perm_inner(devperms,path, uid, gid, &perm) == 0){
   returnperm;
  }else{
                …….
}

//得到devperms結構體的資訊
get_device_perm_inner
{
 for(i= 0; perms[i].name; i++) {

 if(perms[i].prefix){
 if(strncmp(path,perms[i].name, strlen(perms[i].name)))
 continue;
 }else{
 if(strcmp(path,perms[i].name))
 continue;
 }
 *uid= perms[i].uid;
 *gid= perms[i].gid;
 *perm= perms[i].perm; //許可權位
 return0;
 }
}

這是devperms的具體內容
structperms_ {
   char*name;
   mode_tperm;
   unsignedintuid;
   unsignedintgid;
   unsignedshortprefix;
};
staticstructperms_ devperms[] = {
{"/dev/null", 0666, AID_ROOT, AID_ROOT, 0 },
{"/dev/zero", 0666, AID_ROOT, AID_ROOT, 0 },
{"/dev/full", 0666, AID_ROOT, AID_ROOT, 0 },
{"/dev/ptmx", 0666, AID_ROOT, AID_ROOT, 0 },
{"/dev/tty", 0666, AID_ROOT, AID_ROOT, 0 },
{"/dev/random", 0666, AID_ROOT, AID_ROOT, 0 },
{"/dev/urandom", 0666, AID_ROOT, AID_ROOT, 0 },
{"/dev/ashmem", 0666, AID_ROOT, AID_ROOT, 0 },
{"/dev/binder", 0666, AID_ROOT, AID_ROOT, 0 },

/* logger should be world writable (for logging) but not readable*/
{"/dev/log/", 0662, AID_ROOT, AID_LOG, 1 },

/*these should not be world writable */
{"/dev/android_adb", 0660, AID_ADB, AID_ADB, 0 },
{"/dev/android_adb_enable", 0660, AID_ADB, AID_ADB, 0 },
{"/dev/ttyMSM0", 0660, AID_BLUETOOTH, AID_BLUETOOTH, 0 },
{"/dev/alarm", 0664, AID_SYSTEM, AID_RADIO, 0 },
{"/dev/tty0", 0666, AID_ROOT, AID_SYSTEM, 0 },
{"/dev/graphics/", 0660, AID_ROOT, AID_GRAPHICS, 1 },
{"/dev/hw3d", 0660, AID_SYSTEM, AID_GRAPHICS, 0 },
{"/dev/input/", 0660, AID_ROOT, AID_INPUT, 1 },
{"/dev/eac", 0660, AID_ROOT, AID_AUDIO, 0 },
{"/dev/cam", 0660, AID_ROOT, AID_CAMERA, 0 },
{"/dev/pmem", 0660, AID_SYSTEM, AID_GRAPHICS, 0 },
{"/dev/pmem_gpu", 0660, AID_SYSTEM, AID_GRAPHICS, 1 },
{"/dev/pmem_adsp", 0660, AID_SYSTEM, AID_AUDIO, 1 },
{"/dev/pmem_camera", 0660, AID_SYSTEM, AID_CAMERA, 1 },
{"/dev/oncrpc/", 0660, AID_ROOT, AID_SYSTEM, 1 },
{"/dev/adsp/", 0660, AID_SYSTEM, AID_AUDIO, 1 },
{"/dev/mt9t013", 0660, AID_SYSTEM, AID_SYSTEM, 0 },
{"/dev/akm8976_daemon",0640, AID_COMPASS, AID_SYSTEM, 0 },
{"/dev/akm8976_aot", 0640, AID_COMPASS, AID_SYSTEM, 0 },
{"/dev/akm8976_pffd", 0640, AID_COMPASS, AID_SYSTEM, 0 },
{"/dev/msm_pcm_out", 0660, AID_SYSTEM, AID_AUDIO, 1 },
{"/dev/msm_pcm_in", 0660, AID_SYSTEM, AID_AUDIO, 1 },
{"/dev/msm_pcm_ctl", 0660, AID_SYSTEM, AID_AUDIO, 1 },
{"/dev/msm_mp3", 0660, AID_SYSTEM, AID_AUDIO, 1 },
{"/dev/smd0", 0640, AID_RADIO, AID_RADIO, 0 },
{"/dev/qmi", 0640, AID_RADIO, AID_RADIO, 0 },
{"/dev/qmi0", 0640, AID_RADIO, AID_RADIO, 0 },
{"/dev/qmi1", 0640, AID_RADIO, AID_RADIO, 0 },
{"/dev/qmi2", 0640, AID_RADIO, AID_RADIO, 0 },
{"/dev/htc-acoustic", 0640, AID_RADIO, AID_RADIO, 0 },
{NULL, 0, 0, 0, 0 },
};

✿ init.c

       init.rc指令碼和老版本android中的init.goldfish.rc指令碼很早就被parse_config_file()函式解析將指令碼內容分為幾個段,early-init,init,early-boot,boot,和各個服務。然後在不同的時間點上執行各個段得命令或者開啟各種服務。