Adb的全称为Android Debug Bridge,起到通过PC对Android系统的调试桥的作用,是一个多用途的工具,它能够执行多种命令,还能提供一个shell。这儿简单介绍一下Adb的代码结构,并在某些情况下我们可以获取root权限。

Adb的代码在system/core/adb里,它的入口函数很直接了当:

int main(int argc, char **argv)
{
#if ADB_HOST            //代码被ADB_HOST宏分成两部分,一部分是宿主,即被ADB_HOST定义包括的部分,运行在Windows或Linux系统上。另一部分是目标,即Android系统上的deamon程序。adb_sysdeps_init();adb_trace_init();D("Handling commandline()\n");return adb_commandline(argc - 1, argv + 1);
#else/* If adbd runs inside the emulator this will enable adb tracing via* adb-debug qemud service in the emulator. */adb_qemu_trace_init();if((argc > 1) && (!strcmp(argv[1],"recovery"))) {adb_device_banner = "recovery";recovery_mode = 1;}start_device_log();D("Handling main()\n");return adb_main(0, DEFAULT_ADB_PORT);
#endif
}

先看宿主代码的路径,我们看到它进入了adb_commandline()函数,这里主要是负责解析参数并执行相应的命令,注意这儿在执行命令之前还有一个启动本地服务的动作:

    if (is_server) {if (no_daemon || is_daemon) {r = adb_main(is_daemon, server_port);  //Linux平台} else {r = launch_server(server_port);  //Windows平台}if(r) {fprintf(stderr,"* could not start server *\n");}return r;}

这儿会区分宿主平台是Linux还是Windows,他们的服务形态是不一样 的。我们可以使用adb start-server, adb kill-server这样的命令原因在此。

在本地服务启动前会有一些初始化工作,例如USB的初始化:

#if ADB_HOSTHOST = 1;usb_vendors_init();usb_init();local_init(DEFAULT_ADB_LOCAL_TRANSPORT_PORT);char local_name[30];build_local_name(local_name, sizeof(local_name), server_port);if(install_listener(local_name, "*smartsocket*", NULL)) {exit(1);}
#else

因为adb是通过USB 进行socket通信,以adb devices的命令执行过程分析如下:

1. 组织命令格式,

    if(!strcmp(argv[0], "devices")) {char *tmp;snprintf(buf, sizeof buf, "host:%s", argv[0]);  //命令格式为:host:devicestmp = adb_query(buf);                           //发送命令并返回命令执行结果if(tmp) {printf("List of devices attached \n");printf("%s\n", tmp);                        //打印结果return 0;} else {return 1;}}

2. 在adb_query()函数中调用adb_connect()函数发送socket数据,返回后再调用adb_close()关闭socket连接

下面再来分析目标机器即Android上的adbd守护进程,在刚才的入口函数中,它直接进入了adb_main()函数,并传入DEFAULT_ADB_PORT  5037作为默认端口。在adb_main()函数里进行了一系列初始化动作如,USB,端口监听,运行级别,权限设置等,最后进入到事件循环中等待连接(这儿使用epoll机制)。

fdevent_loop();

其中我们对运行级别比较感兴趣,一般情况下我们的adb都是运行在shell用户下,而事实上,adb.c中的代码都是以root权限运行的,以完成部分初始化工作,直到执行了下面的代码:

if (should_drop_privileges()) {......if (setgid(AID_SHELL) != 0) {exit(1);                        //这儿曾经是个漏洞,没有检查返回值,可以被某些恶意软件利用来破解root权限}if (setuid(AID_SHELL) != 0) {exit(1);}

它被强行将为shell用户,失去了root权限,那么它在什么情况下才被降级呢?我们看到是因为should_drop_privileges()函数,代码如下:

static int should_drop_privileges() {
#ifndef ALLOW_ADBD_ROOTreturn 1;
#else /* ALLOW_ADBD_ROOT */int secure = 0;char value[PROPERTY_VALUE_MAX];/* run adbd in secure mode if ro.secure is set and** we are not in the emulator*/property_get("ro.kernel.qemu", value, "");if (strcmp(value, "1") != 0) {property_get("ro.secure", value, "1");if (strcmp(value, "1") == 0) {// don't run as root if ro.secure is set...secure = 1;// ... except we allow running as root in userdebug builds if the// service.adb.root property has been set by the "adb root" commandproperty_get("ro.debuggable", value, "");if (strcmp(value, "1") == 0) {property_get("service.adb.root", value, "");if (strcmp(value, "1") == 0) {secure = 0;}}}}return secure;
#endif /* ALLOW_ADBD_ROOT */
}

首先考虑ALLOW_ADBD_ROOT宏,这是编译系统决定的,eng版本会打开该宏,其次我们看到变量secure初始值为0,但是在检查了一些属性之后,它变成了1,导致权限降级。而如果ro.debuggable激活,service.adb.root也为1的话,我们还是root权限。在userdebug版本中我们可以在shell下执行:

setprop service.adb.root 1

然后杀死并重启adbd守护进程,来提升root权限。

adb里面有个root命令,可以用来获取root权限。Android守护进程adbd启动时,会调用create_local_service_socket()创建socket套接字,

fd = service_to_fd(name);

在service_to_fd(name)函数里,有各种命令的处理方法,如root命令:

else if(!strncmp(name, "root:", 5)) {//ret = create_service_thread(restart_root_service, NULL);ret = create_service_thread(restart_root_service, (void *)(name + 5));} 

它在一个新线程里面执行restart_root_service()函数,原始的调用中参数为NULL,我们可以添加一个密码参数,使得该命令只有加上正确的密码才能执行。

void restart_root_service(int fd, void *cookie)
{char buf[100];char value[PROPERTY_VALUE_MAX];if (getuid() == 0) {                //本来就运行在root用户下snprintf(buf, sizeof(buf), "adbd is already running as root\n");writex(fd, buf, strlen(buf));adb_close(fd);} else {property_get("ro.debuggable", value, "");if (strcmp(value, "1") != 0) {              //始终绕不过的一个只读属性snprintf(buf, sizeof(buf), "adbd cannot run as root in production builds\n");writex(fd, buf, strlen(buf));adb_close(fd);return;}property_set("service.adb.root", "1");         //恭喜你拥有root了snprintf(buf, sizeof(buf), "restarting adbd as root\n");writex(fd, buf, strlen(buf));adb_close(fd);// quit, and init will restart us as rootsleep(1);exit(1);}
}

Adb分析及获取root权限相关推荐

  1. android 常用adb 和 adb shell 命令 获取root权限

    android 常用adb 和 adb shell 命令 ADB常用命令:   1. 查看设备 adb  devices 这个命令是查看当前连接的设备, 连接到计算机的android设备或者模拟器将会 ...

  2. 几乎万能的安卓root方法,需adb能获取root权限(小白教小白)

    此文章部分摘自 bingoCoder2013的博客 最近闲着没事,平常也喜欢搞搞机,搞机过程中遇到需要root权限是很麻烦的,各大root软件没有适配就无法root,现在有了一点收获,也是整理网上各大 ...

  3. 获取root权限及破解原理分析

    现在Android系统的root破解基本上成为大家的必备技能!网上也有很多中一键破解的软件,使root破解越来越容易.但是你思考过root破解的原理吗?root破解的本质是什么呢?难道是利用了Linu ...

  4. usb调试模式已打开,adb devices显示List of devices attached 解决办法!纽维K333一键ROOT,获取ROOT权限!...

    usb调试模式已打开,adb devices显示老显示List of devices attached .刚开始以为USB线问题,跟朋友借了一根,未果. 更换其他的机子测试就可以显示设备,但是这部纽维 ...

  5. 【Android 逆向】获取安装在手机中的应用的 APK 包 ( 进入 adb shell | 获取 root 权限 | 进入 /data/app/ 目录 | 拷贝 base.apk 到外置存储 )

    文章目录 一.获取 APK 包流程 二.获取 APK 包完整流程命令行输出 一.获取 APK 包流程 从应用市场中下载的应用 , 安装完毕后 , 自动删除 ; 如果想要获取安装应用的 APK 包 , ...

  6. 3 src 获取_CVE-2019-15846:Exim远程获取root权限漏洞分析

    报告编号:B6-2019-103101 报告来源:360-CERT 报告作者:360-CERT 更新日期:2019-10-31 0x00 漏洞背景 2019年9月6日18:00,exim发布exim- ...

  7. ADB工具 获取ROOT权限及复制文件方法

    adb push d:\tm3_sqlit.db data/zouhao/tm3_sqlit.db adb pull data/zouhao/tm3_sqlit.db d:\tm3_sqlit.db ...

  8. adb修改什么文件获取root权限_Android获取ROOT权限的通用方法

    背景 自从Android问世以后,给手机获取ROOT权限变成了玩机爱好者老生常谈的话题.拥有手机,却不能拥有操作手机的最高权限,这对于手机爱好者而言,这怎么可以忍?所以无论Android升到什么什么版 ...

  9. Android 学习之《第一行代码》第6章:adb调试:pemission denied以及模拟器不能获取root权限问题的解决

    问题描述: <第一行代码>第六章用ADB工具打开数据库过程中,cd 命令直接报 permission denied,想着应该是权限不够,于是尝试输入su .sudo.su root.adb ...

最新文章

  1. memcached基本操作和语法
  2. 单链表问题(反转、是否有环、删除结尾第N个节点、合并两个sortlist、找到交点)
  3. git学习------gt;写给 Git 初学者的7个建议
  4. 【Java从入门到头秃专栏 7】语法篇(六) :Lambda表达式(->) 方法引用(::) stream流
  5. kafka开源版本quota限流功能缺陷
  6. Unity3d开发IOS游戏 基础
  7. 系统安全工作笔记001---zigw挖矿病毒_没想到生产环境给整成矿鸡了_安全意识有待提升....
  8. 庆祝自己通过系分考试,分发资料
  9. java mockserver搭建_使用Moco搭建Mock Server教程
  10. 【U+】通用财务,附加数据库后,软件看不到账套。
  11. 疯狂java讲义第6版_疯狂java讲义第6版
  12. TMS320F28335之外部中断和自定义中断
  13. 关于机器人方面的sci论文_科学网-2014年SCI收录机器人期刊22种目录-万跃华的博文...
  14. 如何打造VUCA时代的敏捷型组织?
  15. Windows系统封装总结
  16. 博士五年,我在清华做时序数据库
  17. java shp文件_java发布shp数据
  18. 自动生成小程序的智能建站系统,项目分享
  19. Public Key Infrastructure
  20. 近端梯度下降法 (proximal gradient descent)

热门文章

  1. 极域语音教室的使用方法-设备管理方法又是什么?
  2. ubuntu如何让命令行支持中文?
  3. ST-link下载程序SWD配置步骤
  4. 最适合教育个体户的4种网校平台运营模式
  5. 逻辑题:假设河的同一侧有警察、强盗……
  6. 两难的选择 mobileme contacts vs google contacts
  7. xtwpro2编程器_XTW100编程器驱动-XTW100编程器驱动软件下载 --pc6下载站
  8. matlab 变量命名规则
  9. 【使用AI自动生成建筑立面】
  10. python怎么快速打括号_Python如何省略括号方法详解