找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 3578|回复: 0

adb root/adb reboot/adb remount实现简易剖析

[复制链接]
发表于 2016-5-10 20:01:43 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有账号?立即注册→加入我们

×
本帖最后由 元始天尊 于 2016-5-10 20:07 编辑

/system/core/adb/commandline.c

  1. int adb_commandline(int argc, char **argv){
  2. ...............//总分支
  3.     if(!strcmp(argv[0], "remount") || !strcmp(argv[0], "reboot")
  4.             || !strcmp(argv[0], "reboot-bootloader")
  5.             || !strcmp(argv[0], "tcpip") || !strcmp(argv[0], "usb")
  6.             || !strcmp(argv[0], "root")) {
  7.         char command[100];
  8.         if (!strcmp(argv[0], "reboot-bootloader"))
  9.             snprintf(command, sizeof(command), "reboot:bootloader");
  10.         else if (argc > 1)
  11.             snprintf(command, sizeof(command), "%s:%s", argv[0], argv[1]);
  12.         else
  13.             snprintf(command, sizeof(command), "%s:", argv[0]);
  14.         int fd = adb_connect(command);
  15.         if(fd >= 0) {
  16.             read_and_dump(fd);
  17.             adb_close(fd);
  18.             return 0;
  19.         }
  20.         fprintf(stderr,"error: %s\n", adb_error());
  21.         return 1;
  22.     }
  23. }

  24. //service.c
  25. int service_to_fd(const char *name)
  26. else if(!strncmp(name, "remount:", 8)) {
  27.         ret = create_service_thread(remount_service, NULL);
  28.     } else if(!strncmp(name, "reboot:", 7)) {
  29.         void* arg = strdup(name + 7);
  30.         if(arg == 0) return -1;
  31.         ret = create_service_thread(reboot_service, arg);
  32.     } else if(!strncmp(name, "root:", 5)) {
  33.         ret = create_service_thread(restart_root_service, NULL);
  34.     }

复制代码


/remount_service.c

  1. static int remount_system()
  2. {
  3.     char *dev;

  4.     if (system_ro == 0) {
  5.         return 0;
  6.     }

  7.     dev = find_mount("/system");

  8.     if (!dev)
  9.         return -1;

  10.     system_ro = mount(dev, "/system", "none", MS_REMOUNT, NULL);

  11.     free(dev);

  12.     return system_ro;
  13. }
复制代码


/reboot_service

  1. void reboot_service(int fd, void *arg)
  2. {
  3.     char buf[100];
  4.     int pid, ret;

  5.     sync();

  6.     /* Attempt to unmount the SD card first.
  7.      * No need to bother checking for errors.
  8.      */
  9.     pid = fork();
  10.     if (pid == 0) {
  11.         /* ask vdc to unmount it */
  12.         execl("/system/bin/vdc", "/system/bin/vdc", "volume", "unmount",
  13.                 getenv("EXTERNAL_STORAGE"), "force", NULL);
  14.     } else if (pid > 0) {
  15.         /* wait until vdc succeeds or fails */
  16.         waitpid(pid, &ret, 0);
  17.     }

  18.     ret = android_reboot(ANDROID_RB_RESTART2, 0, (char *) arg);
  19.     if (ret < 0) {
  20.         snprintf(buf, sizeof(buf), "reboot failed: %s\n", strerror(errno));
  21.         writex(fd, buf, strlen(buf));
  22.     }
  23.     free(arg);
  24.     adb_close(fd);
  25. }

  26. //system/core/libcutils/android_reboot.c
  27. int android_reboot(int cmd, int flags, char *arg)
  28. {
  29.     int ret;

  30.     if (!(flags & ANDROID_RB_FLAG_NO_SYNC))
  31.         sync();

  32.     if (!(flags & ANDROID_RB_FLAG_NO_REMOUNT_RO))
  33.         remount_ro();

  34.     switch (cmd) {
  35.         case ANDROID_RB_RESTART:
  36.             ret = reboot(RB_AUTOBOOT);
  37.             break;

  38.         case ANDROID_RB_POWEROFF:
  39.             ret = reboot(RB_POWER_OFF);
  40.             break;

  41.         case ANDROID_RB_RESTART2:
  42.             ret = __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
  43.                            LINUX_REBOOT_CMD_RESTART2, arg);
  44.             break;

  45.         default:
  46.             ret = -1;
  47.     }

  48.     return ret;
  49. }
  50. //bionic/libc/arch-arm/syscalls/__reboot.S
  51. ENTRY(__reboot)
  52.     mov     ip, r7
  53.     ldr     r7, =__NR_reboot
  54.     swi     #0
  55.     mov     r7, ip
  56.     cmn     r0, #(MAX_ERRNO + 1)
  57.     bxls    lr
  58.     neg     r0, r0
  59.     b       __set_errno_internal
  60. END(__reboot)

复制代码


/root

  1. void restart_root_service(int fd, void *cookie)
  2. {
  3.     char buf[100];
  4.     char value[PROPERTY_VALUE_MAX];

  5.     if (getuid() == 0) {
  6.         snprintf(buf, sizeof(buf), "adbd is already running as root\n");
  7.         writex(fd, buf, strlen(buf));
  8.         adb_close(fd);
  9.     } else {
  10.         property_get("ro.debuggable", value, "");
  11.         if (strcmp(value, "1") != 0) {
  12.             snprintf(buf, sizeof(buf), "adbd cannot run as root in production builds\n");
  13.             writex(fd, buf, strlen(buf));
  14.             adb_close(fd);
  15.             return;
  16.         }

  17.         property_set("service.adb.root", "1");
  18.         snprintf(buf, sizeof(buf), "restarting adbd as root\n");
  19.         writex(fd, buf, strlen(buf));
  20.         adb_close(fd);
  21.     }
  22. }
  23. static int should_drop_privileges() {
  24. #ifndef ALLOW_ADBD_ROOT
  25.     return 1;
  26. #else /* ALLOW_ADBD_ROOT */
  27.     int secure = 0;
  28.     char value[PROPERTY_VALUE_MAX];

  29.    /* run adbd in secure mode if ro.secure is set and
  30.     ** we are not in the emulator
  31.     */
  32.     property_get("ro.kernel.qemu", value, "");
  33.     if (strcmp(value, "1") != 0) {
  34.         property_get("ro.secure", value, "1");
  35.         if (strcmp(value, "1") == 0) {
  36.             // don't run as root if ro.secure is set...
  37.             secure = 1;

  38.             // ... except we allow running as root in userdebug builds if the
  39.             // service.adb.root property has been set by the "adb root" command
  40.             property_get("ro.debuggable", value, "");
  41.             if (strcmp(value, "1") == 0) {
  42.                 property_get("service.adb.root", value, "");
  43.                 if (strcmp(value, "1") == 0) {
  44.                     secure = 0;
  45.                 }
  46.             }
  47.         }
  48.     }
  49.     return secure;
  50. #endif /* ALLOW_ADBD_ROOT */
  51. }
  52. int adb_main(int is_daemon, int server_port){
  53. .....................
  54.     if (should_drop_privileges()) {
  55.         struct __user_cap_header_struct header;
  56.         struct __user_cap_data_struct cap;

  57.         if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) != 0) {
  58.             exit(1);
  59.         }

  60.         /* add extra groups:
  61.         ** AID_ADB to access the USB driver
  62.         ** AID_LOG to read system logs (adb logcat)
  63.         ** AID_INPUT to diagnose input issues (getevent)
  64.         ** AID_INET to diagnose network issues (netcfg, ping)
  65.         ** AID_GRAPHICS to access the frame buffer
  66.         ** AID_NET_BT and AID_NET_BT_ADMIN to diagnose bluetooth (hcidump)
  67.         ** AID_SDCARD_R to allow reading from the SD card
  68.         ** AID_SDCARD_RW to allow writing to the SD card
  69.         ** AID_MOUNT to allow unmounting the SD card before rebooting
  70.         ** AID_NET_BW_STATS to read out qtaguid statistics
  71.         */
  72.         gid_t groups[] = { AID_ADB, AID_LOG, AID_INPUT, AID_INET, AID_GRAPHICS,
  73.                            AID_NET_BT, AID_NET_BT_ADMIN, AID_SDCARD_R, AID_SDCARD_RW,
  74.                            AID_MOUNT, AID_NET_BW_STATS };
  75.         if (setgroups(sizeof(groups)/sizeof(groups[0]), groups) != 0) {
  76.             exit(1);
  77.         }

  78.         /* then switch user and group to "shell" */
  79.         if (setgid(AID_SHELL) != 0) {
  80.             exit(1);
  81.         }
  82.         if (setuid(AID_SHELL) != 0) {
  83.             exit(1);
  84.         }

  85.         /* set CAP_SYS_BOOT capability, so "adb reboot" will succeed */
  86.         header.version = _LINUX_CAPABILITY_VERSION;
  87.         header.pid = 0;
  88.         cap.effective = cap.permitted = (1 << CAP_SYS_BOOT);
  89.         cap.inheritable = 0;
  90.         capset(&header, &cap);

  91.         D("Local port disabled\n");
  92.     } else {
  93.         char local_name[30];
  94.         build_local_name(local_name, sizeof(local_name), server_port);
  95.         if(install_listener(local_name, "*smartsocket*", NULL)) {
  96.             exit(1);
  97.         }
  98.     }

  99. }


复制代码
回复

使用道具 举报

本版积分规则

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2024-12-22 21:01 , Processed in 0.037655 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表