Android 上静态链接的 OpenSSL 库始终按 BoringSSL 处理,选中错误的偏移文件且不报错
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
internal/probe/openssl/config_ecandroid.go的detectOS()直接置c.IsBoringSSL = true,并合成SslVersion = "boringssl_a_<ver>"internal/probe/openssl/config.go(约 335 行)在isAndroid为真时,把刚从 ELF 读出的 版本改写为boringssl_a_<ver>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
Source: gojue/ecapture