某安卓系统8872端口打开原因分析

某安卓系统,我用netstat 查看正在监听的端口时,发现有127.0.0.1:8872打开着。

查找官方资料,关于这个端口是这样解释的。

某安卓系统8872端口打开原因分析_第1张图片

https://android.googlesource.com/platform/external/bluetooth/bluedroid/+/master/doc/btsnoop_net.md

下面来分析为什么有这样的端口存在。

1. 哪个文件会开8872端口?

在安卓系统全局搜索寻找是哪个文件开了这个8872端口侦听。费了一些周折终于找到了。

IDA pro逆向工具寻找socket server的IP和port_晓翔仔的博客-CSDN博客

逆向分析/system/lib/hw/bluetooth.default.so,可以发现bluetooth.default.so设置了socketserver(127.0.0.1:8872)。

2.bluetooth jni文件起到了关键的桥梁作用

既然这是蓝牙有关的文件,那查找资料了解"蓝牙进程与蓝牙堆栈通信"原理。

从一篇名为 “Android8.0 蓝牙进程与蓝牙堆栈通信源码分析” 的博客中查到:
Apps通过Binder IPC与蓝牙系统服务的通信,是由蓝牙服务AdapterService实现的。
AdapterService通过JNI接口调用蓝牙堆栈接口
JNI方法:/platform/packages/apps/bluetooth/jni/com_android_btservice_AdapterService.cpp

Android8.0 蓝牙进程与蓝牙堆栈通信源码分析_yurh的博客-CSDN博客_gabeldorsche功能堆栈

我从自己的安卓环境找到Bluetooth.apk,发现:
/system/app/Bluetooth/Bluetooth.apk的com_android_btservice_AdapterService里加载了/system/lib/libbluetooth_jni.so
代码:

    static {
        System.load("/system/lib/libbluetooth_jni.so");
        classInitNative();
    }


按照这里的目录,找到了libbluetooth_jni.so。那么libbluetooth_jni.so和bluetooth.default.so有什么关系呢?

3. libbluetooth_jni.so 和bluetooth.default.so的关系

 libbluetooth_jni.so 相关反编译出来的代码:

NAME= "bluetooth";
  if ( hw_get_module(NAME, &v9) )
  {
    _android_log_print(6, "BluetoothServiceJni", "No Bluetooth Library found");
  }

查看hw_get_module函数源码,并分析。

源码地址:
https://android.googlesource.com/platform/hardware/libhardware/+/master/hardware.c

源码中的hw_get_module函数执行逻辑:
1.用property_get查找ro.hardware.NAME,若变量的值是VALUE,则找BasePath/NAME.VALUE.so是否存在。(没有ro.hardware.bluetooth环境变量)

2.循环遍历variant_keys,若variant_keys数组里的变量的值是VALUE.则找BasePath/NAME.VALUE.so是否存在(都不存在)

3.如果上一步找不到,找BasePath/NAME.defaule.so是否存在(/system/lib/hw/bluetooth.default.so存在,目标module成功get到了)

附:

variant_keys数组:

static const char *variant_keys[] = {
    "ro.hardware",  /* This goes first so that it can pick up a different
                       file on the emulator. */
    "ro.product.board",
    "ro.board.platform",
    "ro.arch"
};

BasePath的定义

/** Base path of the hal modules */
#if defined(__LP64__)
#define HAL_LIBRARY_PATH1 "/system/lib64/hw"
#define HAL_LIBRARY_PATH2 "/vendor/lib64/hw"
#define HAL_LIBRARY_PATH3 "/odm/lib64/hw"
#else
#define HAL_LIBRARY_PATH1 "/system/lib/hw"
#define HAL_LIBRARY_PATH2 "/vendor/lib/hw"
#define HAL_LIBRARY_PATH3 "/odm/lib/hw"

可以发现libbluetooth_jni.so用hw_get_module的方式载入了/system/lib/hw/bluetooth.default.so。

4. 相关源码

从开源网站找到127.0.0.1:8872有关服务端代码

static void* listen_fn_(UNUSED_ATTR void* context) {
  int enable = 1;
  prctl(PR_SET_NAME, (unsigned long)LISTEN_THREAD_NAME_, 0, 0, 0);
  listen_socket_ = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  //......
  struct sockaddr_in addr;
  addr.sin_family = AF_INET;
  addr.sin_addr.s_addr = htonl(LOCALHOST_);
  addr.sin_port = htons(LISTEN_PORT_);
  if (bind(listen_socket_, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
    LOG_ERROR(LOG_TAG, "%s unable to bind listen socket: %s", __func__,
              strerror(errno));
    goto cleanup;
  }
  if (listen(listen_socket_, 10) == -1) {
    LOG_ERROR(LOG_TAG, "%s unable to listen: %s", __func__, strerror(errno));
    goto cleanup;
  }
  for (;;) {
    int client_socket;
    OSI_NO_INTR(client_socket = accept(listen_socket_, NULL, NULL));
    if (client_socket == -1) {
      if (errno == EINVAL || errno == EBADF) {
        break;
      }
      LOG_WARN(LOG_TAG, "%s error accepting socket: %s", __func__,
               strerror(errno));
      continue;
    }
    /* When a new client connects, we have to send the btsnoop file header. This
     * allows a decoder to treat the session as a new, valid btsnoop file. */
    std::lock_guard lock(client_socket_mutex_);
    safe_close_(&client_socket_);
    client_socket_ = client_socket;
    OSI_NO_INTR(send(client_socket_, "btsnoop\0\0\0\0\1\0\0\x3\xea", 16, 0));
  }
cleanup:
  safe_close_(&listen_socket_);
  return NULL;
}

发现 Server端的实现很简单,它在127.0.0.1:8872上监听前来连接的client。首次连接上,server会将16字节的header发送给client,这是HCI日志格式的一部分。后续一旦有数据在HCI层流动,server会将数据copy一份送给client。client无需发送给server任何消息,只要等待接收就行了。

总结:

这样,我们搞清楚了从Bluetooth.apk到bluetooth.default.so的关系,找到了127.0.0.1:8872打开的原因。

经过比较,上述分析和通用蓝牙模块框架是一致的。

某安卓系统8872端口打开原因分析_第2张图片

 图片摘自以下博客,感谢作者。

Android 蓝牙模块框架分析_Alex.Ke的博客-CSDN博客_bluetooth.default.so

如果你对打开该端口感兴趣,可以阅读以下博客了解安装系统中打开蓝牙HCI snoop文件的方法。

安卓系统中默认打开蓝牙 HCI snoop 文件的方法_坏小子VP的博客-CSDN博客

你可能感兴趣的:(tech,knowledge,android,java,蓝牙,bluetooth)