• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >Android > android6.0 adbd深入分析(二)adb驱动数据的处理、写数据到adb驱动节点

android6.0 adbd深入分析(二)adb驱动数据的处理、写数据到adb驱动节点

作者:网友 字体:[增加 减小] 来源:互联网 时间:2017-05-26

网友通过本文主要向大家介绍了android6.0 adbd深入分析(二)adb驱动数据的处理、写数据到adb驱动节点等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

android6.0 adbd深入分析(二)adb驱动数据的处理、写数据到adb驱动节点


之前我们讲到在output_thread中,读取了adb驱动的数据后,就调用write_packet(t->fd, t->serial, &p)函数,把数据网socketpair的一侧写。</div>

这会导致socketpair的另一侧有数据,另一侧有数据会调用transport_socket_events函数来处理数据。

 

一、处理驱动读取的数据

我们现在来看看transport_socket_events函数:

static void transport_socket_events(int fd, unsigned events, void *_t)
{
    atransport *t = reinterpret_cast(_t);
    D("transport_socket_events(fd=%d, events=%04x,...)\n", fd, events);
    if(events & FDE_READ){
        apacket *p = 0;
        if(read_packet(fd, t->serial, &p)){
            D("%s: failed to read packet from transport socket on fd %d\n", t->serial, fd);
        } else {
            handle_packet(p, (atransport *) _t);
        }
    }
}

我们先把socketpair一端的数据读取出来,然后调用handle_packet来处理。

void handle_packet(apacket *p, atransport *t)
{
    asocket *s;

    switch(p->msg.command){//根据从驱动读取内容msg的命令
	......

    case A_OPEN: /* OPEN(local-id, 0, "destination") *
        if (t->online && p->msg.arg0 != 0 && p->msg.arg1 == 0) {
            char *name = (char*) p->data;
            name[p->msg.data_length > 0 ? p->msg.data_length - 1 : 0] = 0;
            s = create_local_service_socket(name);//创建一个本地的socket
            if(s == 0) {
                send_close(0, p->msg.arg0, t);
            } else {
                s->peer = create_remote_socket(p->msg.arg0, t);
                s->peer->peer = s;
                send_ready(s->id, s->peer->id, t);
                s->ready(s);
            }
        }
        break;
	......

    case A_WRTE: /* WRITE(local-id, remote-id, ) */
        if (t->online && p->msg.arg0 != 0 && p->msg.arg1 != 0) {
            if((s = find_local_socket(p->msg.arg1, p->msg.arg0))) {
                unsigned rid = p->msg.arg0;
                p->len = p->msg.data_length;

                if(s->enqueue(s, p) == 0) {
                    D("Enqueue the socket\n");
                    send_ready(s->id, rid, t);
                }
                return;
            }
        }
        break;

    default:
        printf("handle_packet: what is %08x?!\n", p->msg.command);
    }
    put_apacket(p);
}


上面是处理驱动的数据,我们先来看下处理open命令中一个create_local_service_socket函数

asocket *create_local_service_socket(const char *name)
{
#if !ADB_HOST
    if (!strcmp(name,"jdwp")) {
        return create_jdwp_service_socket();
    }
    if (!strcmp(name,"track-jdwp")) {
        return create_jdwp_tracker_service_socket();
    }
#endif
    int fd = service_to_fd(name);//获取fd
    if(fd < 0) return 0;

    asocket* s = create_local_socket(fd);//创建socket
    D("LS(%d): bound to '%s' via %d\n", s->id, name, fd);

#if !ADB_HOST
    char debug[PROPERTY_VALUE_MAX];
    if (!strncmp(name, "root:", 5))
        property_get("ro.debuggable", debug, "");

    if ((!strncmp(name, "root:", 5) && getuid() != 0 && strcmp(debug, "1") == 0)
        || (!strncmp(name, "unroot:", 7) && getuid() == 0)
        || !strncmp(name, "usb:", 4)
        || !strncmp(name, "tcpip:", 6)) {
        D("LS(%d): enabling exit_on_close\n", s->id);
        s->exit_on_close = 1;
    }
#endif

    return s;
}

我们先来看看service_to_fd函数:

 

int service_to_fd(const char *name)
{
    int ret = -1;

    if(!strncmp(name, "tcp:", 4)) {
        int port = atoi(name + 4);
        name = strchr(name + 4, ':');
        if(name == 0) {
            ret = socket_loopback_client(port, SOCK_STREAM);
            if (ret >= 0)
                disable_tcp_nagle(ret);
        } else {
#if ADB_HOST
            ret = socket_network_client(name + 1, port, SOCK_STREAM);
#else
            return -1;
#endif
        }
#ifndef HAVE_WINSOCK   /* winsock doesn't implement unix domain sockets */
    } else if(!strncmp(name, "local:", 6)) {
        ret = socket_local_client(name + 6,
                ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM);
    } else if(!strncmp(name, "localreserved:", 14)) {
        ret = socket_local_client(name + 14,
                ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM);
    } else if(!strncmp(name, "localabstract:", 14)) {
        ret = socket_local_client(name + 14,
                ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
    } else if(!strncmp(name, "localfilesystem:", 16)) {
        ret = socket_local_client(name + 16,
                ANDROID_SOCKET_NAMESPACE_FILESYSTEM, SOCK_STREAM);
#endif
#if !ADB_HOST
    } else if(!strncmp("dev:", name, 4)) {
        ret = unix_open(name + 4, O_RDWR | O_CLOEXEC);
    } else if(!strncmp(name, "framebuffer:", 12)) {
        ret = create_service_thread(framebuffer_service, 0);
    } else if (!strncmp(name, "jdwp:", 5)) {
        ret = create_jdwp_connection_fd(atoi(name+5));
    } else if(!HOST && !strncmp(name, "shell:", 6)) {//adb shell
        ret = create_subproc_thread(name + 6, SUBPROC_PTY);
    } else if(!HOST && !strncmp(name, "exec:", 5)) {
        ret = create_subproc_thread(name + 5, SUBPROC_RAW);
    } else if(!strncmp(name, "sync:", 5)) {
    	D("kangchen service_to_fd file_sync_service");
        ret = create_service_thread(file_sync_service, NULL);
    } else if(!strncmp(name, "remount:", 8)) {
        ret = create_service_thread(remount_service, NULL);
    } else if(!strncmp(name, "reboot:", 7)) {
        void* arg = strdup(name + 7);
        if (arg == NULL) return -1;
        ret = create_service_thread(reboot_service, arg);
    } else if(!strncmp(name, "root:", 5)) {//adb root
        ret = create_service_thread(restart_root_service, NULL);
这里我们主要看下adb root和adb shell,其他的以后自己慢慢研究:

 

1.2 adb root的处理过程

我们先来看下adb root的处理过程,serverice_to_fd函数先调用了create_service_thread函数:

static int create_service_thread(void (*func)(int, void *), void *cookie)
{
    int s[2];
    if (adb_socketpair(s)) {//建立一对socketpair
        printf("cannot create service socket pair\n");
        return -1;
    }
    D("socketpair: (%d,%d)", s[0], s[1]);

    stinfo* sti = reinterpret_cast(malloc(sizeof(stinfo)));
    if (sti == nullptr) {
        fatal("cannot allocate stinfo");
    }
    sti->func = func;
    sti->cookie = cookie;
    sti->fd = s[1];

    adb_thread_t t;
    if (adb_thread_create(&t, service_bootstrap_func, sti)) {
        free(sti);
        adb_close(s[0]);
        adb_close(s[1]);
        printf("cannot create service thread\n");
        return -1;
    }

    D("service thread started, %d:%d\n",s[0], s[1]);
    return s[0];//返回一端的socketpair
}

我们再来看看service_bootstrap_func函数:

void *service_bootstrap_func(void *x)
{
    stinfo* sti = reinterpret_cast(x);
    sti->func(sti->fd, sti->cookie);
    free(sti);
    return 0;
}

最终还是调用了create_service_thread传进来的func函数
而adb root传入的是restart_root_service函数:

void restart_root_service(int fd, void *cookie) {
    if (getuid() == 0) {//已经root
        WriteFdExactly(fd, "



 
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

相关文章

  • 2017-05-26RecyclerView 结合 CardView 使用(二),recyclerview使用
  • 2017-05-26Android 手机卫士11--窗体弹出PopupWindow,11--popupwindow
  • 2017-05-26Android Studio NDK开发
  • 2017-05-26Your project path contains non-ASCII characters,containsnon-ascii
  • 2017-05-26TabLayout和ViewPager简单实现页卡的滑动,tablayoutviewpager
  • 2017-05-26Handler造成的内存泄漏(一),handler泄漏
  • 2017-05-26《第一行代码》目录
  • 2017-08-23Glide中request的调用和管理
  • 2017-05-26集成websocket即时通讯 java聊天源码 代码下载 java后台框架源码 websocket源码 IM,websocket即时通讯
  • 2017-05-26Android提权漏洞CVE-2014-7920&amp;CVE-2014-7921分析,android提权漏洞

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • [Android] Activity间切换,传递数据,androidactivity
    • Android Studio发布到Jcenter
    • 使用Gradle动态配置资源,gradle动态资源
    • 在Android应用程序使用YouTube API来嵌入视频,
    • Android无线开发的几种常用技术综述
    • Java Web 开发填坑记- 如何正确的下载 Eclipse,javaeclipse
    • 独立开发者的个人经验之谈,独立开发者的
    • android studio我的习惯操作,androidstudio习惯
    • android_m2repository_rxx.zip下载地址以及MD5,androidm2repository
    • android列表停止滚动,加载图片,较为通用的一种办法,

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有