#1037·ecapture

Android 上静态链接的 OpenSSL 库始终按 BoringSSL 处理,选中错误的偏移文件且不报错

Author: YuYuKunKunCreated Sep 30, 2026Updated Sep 30, 2026

Android 上静态链接的 OpenSSL 库始终按 BoringSSL 处理,选中错误的偏移文件,且不报错

现象

Android 下 OpenSSL 探针强制走 BoringSSL 配置,从不进入共享的 OpenSSL 版本探测。静态链接 OpenSSL 的原生库(游戏等引擎类应用的常见做法)因此用错误的结构体偏移挂载,运行不报任何 错误,只产出零数据。

$ ecapture tls -m text --libssl=/data/app/.../lib/arm64/<库>.so
INF OpenSSL probe initialized is_boringssl=true ssl_version=boringssl_a_16
INF OpenSSL probe started Android=16 BoringSSL=true SslBpfFile=boringssl_a_16_kern.o

该库中是 OpenSSL 1.1.1q,而 kern/openssl_1_1_1j_kern.c 已覆盖该版本(sslVersionBpfMap 把 openssl 1.1.1j~1.1.1s 映射到 openssl_1_1_1j_kern.o),但这张表根本没被查到。

根因:三处按平台假定 BoringSSL

  1. internal/probe/openssl/config_ecandroid.go 的 detectOS() 直接置 c.IsBoringSSL = true,并合成 SslVersion = "boringssl_a_<ver>"
  2. internal/probe/openssl/config.go(约 335 行)在 isAndroid 为真时,把刚从 ELF 读出的 版本改写为 boringssl_a_<ver>
  3. internal/probe/openssl/config.go 的 autoDetectBytecode() 在 isAndroid 为真时走 BoringSSL 默认分支

第 2 条是关键:它丢掉了唯一能选出正确目标文件的信息。

建议的修法:按内容判断,不要按文件名

看起来显然的修法 ——「路径里含 boringssl 就当 BoringSSL,否则当 OpenSSL」—— 是错的。 我按这个思路改过一版,实测把原本正常的情况改坏了,因为 Android 自己的 BoringSSL 路径里 根本没有这个词:

/apex/com.android.conscrypt/lib64/libssl.so
/apex/com.android.tethering/lib64/stable_cronet_libssl.so

实测对照(同一台设备,Android 16 / aarch64 / GKI 6.6):

库 2.6.0 按文件名判断 按内容判断
静态链接的 OpenSSL 1.1.1q boringssl_a_16(错) openssl_1_1_1j openssl_1_1_1j
/apex/.../conscrypt/lib64/libssl.so boringssl_a_16 linux_default_1_1_1(错) boringssl_a_16
/apex/.../cronet/libssl.so boringssl_a_16 openssl_1_1_1j(错) boringssl_a_16
某厂商改名后的 BoringSSL boringssl_a_16 boringssl_a_16 boringssl_a_16

OpenSSL 库会报出版本字符串,BoringSSL 不会,所以问库本身即可判定,不需要任何命名约定。 三处改动最终都归结为一句:只有在读不到 OpenSSL 版本时才使用 BoringSSL 配置。 IsAndroid 保持不变,因为 openssl_probe.go 另有用途。

相关的另一类阻塞(非本 issue,供排查参考)

--libssl 指向 extractNativeLibs=false 的 APK 时会失败:

FTL probe start failed. error="[401] failed to attach eBPF probe 'openssl manager start':
  * error:opening uprobe: lazy load symbols: parse ELF file:
    bad magic number '[80 75 3 4]' in record at byte 0x0

[80 75 3 4] 即 PK\x03\x04,是 ZIP 头。这类应用的原生库直接从 APK 内映射,磁盘上不存在 独立文件,把库解压出来再指向副本也不行(uprobe 按 inode+offset 匹配)。

复现环境

ecapture tls -m text --libssl=<库路径>
构建:CROSS_ARCH=arm64 ANDROID=1 make nocore

我有一份可用的改动与构建工作流(基于 master,保留完整历史): https://github.com/YuYuKunKun/ecapture-openssl-android