惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
WordPress大学
WordPress大学
宝玉的分享
宝玉的分享
人人都是产品经理
人人都是产品经理
博客园 - 聂微东
IT之家
IT之家
V
V2EX
Jina AI
Jina AI
V
Visual Studio Blog
有赞技术团队
有赞技术团队
博客园 - 司徒正美
博客园 - 叶小钗
The Cloudflare Blog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
小众软件
小众软件
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
博客园 - 三生石上(FineUI控件)
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Google DeepMind News
Google DeepMind News
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
腾讯CDC
Google Online Security Blog
Google Online Security Blog
博客园 - 【当耐特】
Apple Machine Learning Research
Apple Machine Learning Research
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
N
News and Events Feed by Topic
N
News and Events Feed by Topic
The Last Watchdog
The Last Watchdog
W
WeLiveSecurity
月光博客
月光博客
Security Archives - TechRepublic
Security Archives - TechRepublic
Webroot Blog
Webroot Blog
SecWiki News
SecWiki News
博客园_首页
罗磊的独立博客
量子位
Latest news
Latest news
I
Intezer
V
Vulnerabilities – Threatpost
A
Arctic Wolf
Last Week in AI
Last Week in AI
Recent Commits to openclaw:main
Recent Commits to openclaw:main
S
SegmentFault 最新的问题
S
Security Affairs
阮一峰的网络日志
阮一峰的网络日志
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
酷 壳 – CoolShell
酷 壳 – CoolShell
P
Palo Alto Networks Blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
N
News | PayPal Newsroom

博客园 - GKLBB

软件研发 --- AI模型 之 图片转xlsx 软件神器 --- ctf靶场 之 pwn.college 术语俗话 --- 什么是加密狗 软件神器 --- 自动电脑锁屏软件 软件研发 --- 网络安全 之 putty生成无密码登录密钥 软件神器 --- 视频剪辑 之 Avidemux MP4Joiner Shotcut 软件神器 --- 视频格式转化 之 handbrake 软件研发 --- 经验之谈 这个是什么图标,经常看到 软件研发 --- 术语俗话 之 多模态 术语俗话 --- 什么是大数据开发 软件研发 --- 术语俗话 之 什么是边缘计算 软件研发 --- 应知应会 之 什么是云计算开发 应知应会 --- 如何不装软件查看网速 常见问题解决 --- 360拦截接触 常见问题解决 --- 加入会议摄像头无法打开 网络安全 --- CTF打靶 之 ZIP伪加密 → Robot36慢扫电视 → 二维码补齐 → DeepSound隐写 → GPG解密 → Base64图片 → SilentEye隐写 软件研发 --- 应知应会 之 无错误的闪退如何解决 软件研发 --- 应知应会 之 为什么别人的软件如此复杂我的如此简单 网络安全 --- 应知应会 之 什么是旁站 应知应会 --- 如何查询备案 软件神器 --- 格式转化 之 jpg 2 svg 网络安全 --- CTF打靶 之 flag搜索 软件神器 --- 互联网测速 之 软件神器 --- 局域网测速 之 iperf 常见问题解决 --- 模拟器USG6000打开后,启动设备失败,错误40 软件研发 --- AI网络 之 ensp配置生成 软件研发 --- AI编程 之 极简流程 软件研发 --- AI生图产品比较 常见问题解答 --- 为什么我的服务一直被人DDOS 软件研发 --- 开发万能格式转化工具 网站神器 --- 在线格式转化 之 文档转md 术语俗话 --- 什么是云电脑 常见问题解决 --- 如何在没有安装杀毒软件的情况下知道这个文件是不是牧马 常见问题解决 --- Win10下VMware 17安装VMware Tools选项灰色/失效解决办法 常见问题解决 --- 云电脑报错 :PAGE FAULT IN NONPAGED AREA 记一次牧马的发现 人生感悟 --- 为什么我们生活中同一件事有多个品牌,他们到底有什么区别 软件运维 --- 云电脑安装打印机 常见问题解决 --- 网络打印默认端口 常见问题解决 --- 京瓷打印云电脑无法设置双面打印 软件研发 --- 网络安全 之 brupsuite如何设置上游袋里 术语俗话 --- 什么是同步和异步 我的目标 软件研发 --- dify配置 之 markword转word带有简单样式的方法 软件研发 --- 接口文档格式 常见问题 --- dify 的 deepseek是旧模型版本 OWASP 非营利性开源社区 计算机标准化组织 术语俗话 --- POSIX 就是 Unix 世界的"普通话",大家说同一种语言就能互相理解。 我的数字生活唯一选择 术语俗话 --- 页面对齐、 跨页 计算机的哪些人 --- 社交之王 马克·扎克伯格 计算机的哪些人 --- 重新定义新能源 之 埃隆·马斯克 软件研发 --- AI生成ppt word excel pdf的开发关键 软件研发 --- AI应用开发 之 AI生成Word 人生感悟 --- 致可悲的人 软件研发 --- pdf 表格图片 转 excel 常见问题解决 --- 装有系统的固态硬盘错误 人生感悟 --- 什么是行业黑话 术语俗话 --- Kubernetes 术语俗话 --- 什么是DBI,和hook什么区别 答疑解惑 --- 为什么苹果手机电池不允许拆卸 代码可视化技术 术语俗话 --- Wrap 函数 人生感悟 --- 逆向工程为什么十分枯燥且无聊 --- 这里引用一句逆向工程核心原理的话 人生感悟 --- 为什么干活时不见同事,活干完了就来了 软件研发 --- AI应用研发 之 提炼提示词 软件研发 --- AI应用开发 之 AI生成PPT最佳方案 基于屏幕-摄像头的单向数据传输方案设计 俗语俗话 --- 纯虚函数 硬件研发 --- 产品介绍 之 AX6 硬件研发 --- 产品大全 之 SUMAVISION CM50X 应知应会 --- 为什么U盘不识别但是还是可以数据恢复回来 应知应会 --- 为什么我删除了一个文件但是还是可以恢复回来 软件研发 --- AI UI设计 之 PC端效果比对 常见问题修复 --- chrome浏览器白屏 应用安全 --- 逆向工程 之 C++类的本质 软件研发 --- AI提示词开发 之 代码注释提示词 dobby反编译 https://www.cnblogs.com/Un1corn/p/18615567 应知应会 --- 手机作为热点,windows电脑临时作为网关,给其他电脑上网 应知应会 --- 大量小文件如何快速迁移 常见问题解决 --- apk安装过程中闪退 应用安全 --- 安卓逆向 之 dobby框架 在线生成 APK 图标工具推荐 一个开源库 术语俗话 --- 什么是软件即服务 软件神器 --- 常用谷歌插件 应用安全 --- 逆向技巧 之 识别未知函数 人生感悟 --- 为什么两句话可以说明白的事情要500字说明 软件研发 --- Dify 生成 PPT 方案分析 应用安全 --- 逆向技巧 之 IDA未知函数如何识别 https://yuuki.cool/ 应用安全 --- 逆向技巧 之 ELF节(Section) 与 段(Segment) 硬件研发 --- 接口 人生感悟 --- 为什么ld一直爱开会 应用安全 --- 逆向技巧 之 IDA和claude反编译缺陷 应用安全 --- 逆向技巧 之 ida反编译yahfa的so和源码的差异化比对
软件开发 --- 安卓开发 之 命名空间隔离
GKLBB · 2026-05-02 · via 博客园 - GKLBB

打个比方

text

把 Android 系统想象成一栋大楼

┌─────────────────────────────────────┐
│              大楼(Android系统)      │
│                                     │
│  ┌─────────┐      ┌─────────────┐  │
│  │ 系统层   │      │  厂商层      │  │
│  │ /system │      │  /vendor    │  │
│  └─────────┘      └─────────────┘  │
│                                     │
│  ┌─────────────────────────────┐   │
│  │         你的 App             │   │
│  └─────────────────────────────┘   │
└─────────────────────────────────────┘

命名空间隔离 = 给每层楼装上门禁
不同区域的人只能用自己区域的工具

具体是什么问题

Android 7.0 之前(没有门禁)

text

App 开发者发现:
"哇,系统里有个 libcrypto.so 可以直接用!"
"还有 libcutils.so,真方便!"

于是直接调用系统私有库 ↓

App ──dlopen()──▶ /system/lib/libcrypto.so  ✅ 成功


结果:

Android 升级后系统库改了
App 直接崩溃 💥

或者:

不同厂商的系统库符号不一样
App 在某些手机上崩溃 💥

Android 7.0 之后(装了门禁)

text

App 再想直接用系统私有库

App ──dlopen()──▶ /system/lib/libcrypto.so  ❌ 拒绝!

错误信息:
"libcrypto.so is not accessible 
 for the namespace classloader-namespace"

你只能用官方开放给你的库(NDK 公开库)

命名空间是什么

text

命名空间 = 每个进程/区域 能看到的库的范围

就像:
┌──────────────────────────────────────┐
│  你的 App(classloader-namespace)    │
│                                      │
│  能用的库:                           │
│  ✅ libc.so      (基础C库)          │
│  ✅ libm.so      (数学库)           │
│  ✅ liblog.so    (日志库)           │
│  ✅ libOpenGL.so (图形库)           │
│                                      │
│  看不到:                             │
│  ❌ libcrypto.so  (系统加密库)      │
│  ❌ libcutils.so  (系统工具库)      │
│  ❌ libbinder.so  (IPC库)          │
└──────────────────────────────────────┘

换一个区域,能看到的库就不一样

为什么要隔离 System 和 Vendor

text

没隔离之前的痛点(Android 8.0 之前):

手机厂商(高通/MTK)
修改了 /system 里的库
Google 想升级 Android 系统
升级会破坏厂商的修改
厂商需要重新适配,耗时1~2年
用户迟迟收不到系统更新 😭


隔离之后(Treble 架构):

/system  ←→  /vendor  严格隔离
  ↑                ↑
Google 负责      厂商负责
可以独立升级    可以独立适配

Google 升级系统 → 不影响厂商的 vendor 库
厂商适配硬件   → 不影响系统层
用户更快收到更新 🎉

回退链接是什么

text

命名空间之间不是完全封闭的
可以配置"走后门"的通道

例如:
SP-HAL 命名空间(厂商图形库)
    │ 找不到 libc.so?
回退到 default 命名空间找 ✅
    │ 找不到 libbase.so?
回退到 vndk 命名空间找 ✅
    │ 还找不到?
报错 ❌

这个"走后门的通道"就是回退链接
但只有白名单里的库才能走这个通道

配置文件通俗理解

ini

# 门卫规则手册(ld.config.txt)

# 从 /system/bin 启动的程序 → 用 [system] 这套规则
dir.system = /system/bin

# 从 /vendor/bin 启动的程序 → 用 [vendor] 这套规则  
dir.vendor = /vendor/bin

[system]
# 系统进程有3个命名空间(3个房间)
additional.namespaces = sphal,vndk

# 默认房间(framework 住这里)
namespace.default.isolated = true          # 开启门禁
namespace.default.search.paths = /system/${LIB}  # 只能找这里的库

# SP-HAL 房间(厂商图形驱动住这里)
namespace.sphal.isolated = true
namespace.sphal.search.paths = /vendor/${LIB}
namespace.sphal.links = default,vndk       # 找不到可以去这两个房间借
namespace.sphal.link.default.shared_libs = libc.so:libm.so  # 但只能借这些

[vendor]
# 厂商进程
namespace.default.isolated = false        # 不开门禁(历史遗留,比较宽松)

总结:三句话

text

① 隔离是什么?
  每个进程/区域只能使用被允许的共享库
  就像每个部门只能用自己的工具库

② 为什么要隔离?
  防止 App 乱用私有系统库导致崩溃
  让 System 和 Vendor 可以独立升级

③ 怎么实现的?
  动态链接器读取 ld.config.txt 里的规则
  加载库之前先检查"这个库在我的命名空间里吗"
  不在就拒绝,或者按规则去回退命名空间找

Android 命名空间隔离了哪些系统库

一句话理解

text

公开的 NDK 库 → 随便用
私有系统库   → 禁止用

公开可用(NDK 公开库)

text

这些库任何 App 都可以链接:

基础类
  libc.so          C 标准库
  libm.so          数学库
  libdl.so         动态链接库
  libz.so          压缩库
  libc++.so        C++ 标准库

图形类
  libEGL.so        OpenGL 窗口系统接口
  libGLESv1_CM.so  OpenGL ES 1.x
  libGLESv2.so     OpenGL ES 2.0
  libGLESv3.so     OpenGL ES 3.0
  libvulkan.so     Vulkan 图形 API

Android 功能类
  libandroid.so        Android 原生API(传感器/窗口等)
  liblog.so            日志
  libnativewindow.so   原生窗口
  libsync.so           同步原语
  libneuralnetworks.so NNAPI 神经网络
  libandroid_net.so    网络
  libvndksupport.so    VNDK 支持
  libmediandk.so       媒体 NDK
  libcamera2ndk.so     Camera2 NDK
  libOpenMAXAL.so      OpenMAX 音频
  libOpenSLES.so       OpenSL 音频
  libjnigraphics.so    Bitmap 操作

禁止使用(私有系统库)

运行时/框架内部

text

libandroid_runtime.so   ← Android 运行时
libdvm.so               ← Dalvik 虚拟机(已废弃)
libart.so               ← ART 虚拟机
libjavacrypto.so        ← Java 加密实现
libjavacore.so          ← Java 核心库实现

系统工具

text

libcutils.so            ← 系统工具函数
libutils.so             ← Android 通用工具
libbase.so              ← Android base 库
liblog_system.so        ← 系统日志内部
libprocessgroup.so      ← 进程组管理
libcgrouprc.so          ← cgroup 控制

通信/IPC

text

libbinder.so            ← Binder IPC 核心
libhwbinder.so          ← HW Binder
libhidlbase.so          ← HIDL 基础
libhidltransport.so     ← HIDL 传输层
libhidlmemory.so        ← HIDL 内存

加密/网络

text

libcrypto.so            ← BoringSSL 加密(系统版本)
libssl.so               ← SSL/TLS(系统版本)
libnetd_client.so       ← 网络守护进程客户端

图形内部

text

libskia.so              ← Skia 图形引擎
libhardware.so          ← HAL 硬件抽象
libion.so               ← ION 内存分配器
libui.so                ← UI 核心库
libgui.so               ← Surface/BufferQueue
libsurfaceflinger.so    ← SurfaceFlinger 合成器

媒体内部

text

libmedia.so             ← 媒体框架
libmediacodec.so        ← 媒体编解码
libstagefright.so       ← Stagefright 媒体引擎
libstagefright_foundation.so
libsoundpool.so         ← 音效池

数据库

text

libsqlite.so            ← SQLite(系统版本)

特殊情况:暂时豁免库

text

targetSdkVersion ≤ 23 的老应用
可以临时访问以下库(但会有警告):

libandroid_runtime.so
libcutils.so
libcrypto.so
libssl.so

警告日志长这样:
W linker: library "libcutils.so" is not accessible
for the namespace "classloader-namespace"
- the access is temporarily granted as a workaround

⚠️ 未来版本会彻底禁止,现在只是过渡期

VNDK-SP(特殊区域的库)

text

这些库比较特殊:
  不给普通 App 用
  专门给 SP-HAL(厂商图形/相机驱动)在框架进程里用

libbase.so
libc++.so
libcutils.so          ← 注意!这是 vndk-sp 版本,不是系统版本
libutils.so           ← 同上,是专门的副本
libhardware.so
libhidlbase.so
libhidltransport.so
libhwbinder.so
libion.so
libz.so
android.hardware.graphics.common@1.0.so
android.hardware.graphics.mapper@2.0.so
android.hardware.renderscript@1.0.so
android.hidl.memory@1.0.so

位置在:/system/lib/vndk-sp-${VER}/
而不是:/system/lib/

直观对比图

text

/system/lib/
├── libc.so              ✅ 公开,App 可用
├── libm.so              ✅ 公开,App 可用
├── liblog.so            ✅ 公开,App 可用
├── libEGL.so            ✅ 公开,App 可用
├── libvulkan.so         ✅ 公开,App 可用
├── libandroid_runtime.so ❌ 私有,禁止使用
├── libbinder.so          ❌ 私有,禁止使用
├── libskia.so            ❌ 私有,禁止使用
├── libsqlite.so          ❌ 私有,禁止使用
├── libcrypto.so          ❌ 私有,禁止使用(用自己的)
├── libssl.so             ❌ 私有,禁止使用(用自己的)
└── vndk-sp-34/
    ├── libcutils.so      ⚠️  仅 SP-HAL 可用
    ├── libutils.so       ⚠️  仅 SP-HAL 可用
    └── libbase.so        ⚠️  仅 SP-HAL 可用

怎么检查自己用了哪些私有库

Bash

# 方法1:readelf 查看依赖
aarch64-linux-android-readelf -dW libMyLib.so | grep NEEDED

# 输出示例:
0x0000000000000001 (NEEDED) Shared library: [libc.so]        ✅
0x0000000000000001 (NEEDED) Shared library: [libm.so]        ✅
0x0000000000000001 (NEEDED) Shared library: [libcutils.so]   ❌ 危险!

# 方法2:运行时看 logcat
adb logcat | grep "not accessible for the namespace"

# 方法3:Android Studio
Build → Analyze APK → 查看 .so 文件的依赖

被禁了怎么办

text

原来用的私有库          官方替代方案
──────────────────────────────────────────────
libcrypto.so/libssl.so  自己打包 BoringSSL 或 conscrypt
libsqlite.so            使用 Room 数据库 或 自带 SQLite
libandroid_runtime.so   使用标准 JNI <jni.h>
  getJavaVM()      →    GetJavaVM()
  getJNIEnv()      →    JavaVM::GetEnv()
libcutils.so            
  property_get()   →    __system_property_get()
                        #include <sys/system_properties.h>
libui.so/libgui.so      使用 ANativeWindow API
libmedia.so             使用 NDK Media API (libmediandk.so)
libhardware.so          通过 HAL HIDL/AIDL 接口访问

Android N+ 命名空间隔离 官方文档总结

一、问题背景(为什么需要隔离)

text

两个核心难题:

1. 符号冲突问题
   SP-HAL 共享库加载到框架进程时
   可能与系统库产生符号冲突

2. 运行时依赖不可见问题
   dlopen() 引入的依赖在构建时无法静态分析检测

二、核心机制

基本原理

text

┌─────────────────────────────────────────────────────────┐
│                   动态链接器 (linker)                     │
│                                                          │
│  命名空间 A                    命名空间 B                 │
│  /system/lib/libcutils.so     /system/lib/vndk-sp/       │
│                               libcutils.so               │
│                                                          │
│  ← 框架模块依赖                ← SP-HAL 依赖 →           │
│                                                          │
│  同名库,不同符号,互相隔离,不冲突                        │
└─────────────────────────────────────────────────────────┘

公共库示例:/system/lib/libc.so
  → 由一个命名空间导出
  → 被导入到多个命名空间
  → 其依赖项(libnetd_client.so)对其他命名空间不可见

加载逻辑流程

text

dlopen() / DT_NEEDED 触发加载
  找出调用方所在的命名空间
  尝试在同一命名空间中加载依赖
    ┌────┴────┐
   成功      失败
    │         │
    ▼         ▼
  完成    向关联命名空间
        索取导出的共享库
         ┌────┴────┐
        找到      找不到
         │         │
         ▼         ▼
       完成      报错

三、配置文件详解

配置文件位置

Bash

Android 8/9:   /system/etc/ld.config.txt
Android 11+:   /linkerconfig/ld.config.txt  # 运行时动态生成

配置文件结构

ini

# ① 目录-区段映射(决定哪个可执行文件用哪套配置)
dir.system = /system/bin
dir.system = /system/xbin
dir.vendor = /vendor/bin

# ② system 进程的命名空间配置
[system]
additional.namespaces = sphal,vndk   # 除default外还有2个命名空间

# default 命名空间
namespace.default.isolated = true
namespace.default.search.paths = /system/${LIB}
namespace.default.permitted.paths = /system/${LIB}/hw

# sphal 命名空间(SP-HAL)
namespace.sphal.isolated = true
namespace.sphal.visible = true
namespace.sphal.search.paths = /odm/${LIB}:/vendor/${LIB}
namespace.sphal.permitted.paths = /odm/${LIB}:/vendor/${LIB}
namespace.sphal.links = default,vndk              # 回退顺序
namespace.sphal.link.default.shared_libs = libc.so:libm.so
namespace.sphal.link.vndk.shared_libs = libbase.so:libcutils.so

# vndk 命名空间
namespace.vndk.isolated = true
namespace.vndk.search.paths = /system/${LIB}/vndk-sp-29
namespace.vndk.links = default
namespace.vndk.link.default.shared_libs = libc.so:libm.so

# ③ vendor 进程的命名空间配置
[vendor]
namespace.default.isolated = false   # vendor不隔离
namespace.default.search.paths = /vendor/${LIB}:/system/${LIB}

关键属性一览

text

属性                                    含义
─────────────────────────────────────────────────────────
isolated = true/false                  是否启用路径隔离检查
search.paths                           库搜索目录(不含子目录)
permitted.paths                        允许加载的目录(含子目录)
asan.search.paths                      ASan模式下的搜索路径
links                                  回退命名空间列表(有序)
link.X.shared_libs                     回退时允许的库名白名单
link.X.allow_all_shared_libs = true    回退时允许所有库(与上互斥)
visible = true/false                   是否可被android_get_exported_namespace()获取

注意:${LIB} 占位符
  32位进程 → lib
  64位进程 → lib64

四、三种隔离配置对比

text

PRODUCT_TREBLE_        BOARD_VNDK_
LINKER_NAMESPACES      VERSION        配置类型      适用场景
─────────────────────────────────────────────────────────
true                   current        VNDK          Android 9+ 必须
true                   空             VNDK Lite     Android 8.x 必须
false                  空             Legacy        不支持Treble的设备

VNDK 配置(最严格,Android 9+)

text

框架进程命名空间:
  default  ← 系统共享库
  vndk     ← VNDK-SP 库
  sphal    ← SP-HAL 库
  rs       ← RenderScript

供应商进程命名空间:
  default  ← 供应商共享库
  vndk     ← VNDK/VNDK-SP 库
  system   ← LL-NDK 及依赖

核心保证:system分区模块不依赖vendor库,反之亦然

VNDK Lite 配置(Android 8.0)

text

只隔离 SP-HAL 和 VNDK-SP 共享库
符号不与其他框架共享库冲突

五、Android 7.0 对应用的直接影响

限制行为

text

Android 7.0 之前:
  dlopen("/system/lib/libandroid_runtime.so") ✅ 成功

Android 7.0 之后:
  dlopen("/system/lib/libandroid_runtime.so") ❌ 失败

按 targetSdkVersion 的不同行为

text

库类型              targetSdkVersion    Android 7.0 行为
─────────────────────────────────────────────────────
公开 NDK 库         任何                ✅ 正常运行
私有暂时可访问库     ≤ 23               ⚠️ 可访问但有 logcat 警告
私有暂时可访问库     ≥ 24               ❌ 运行时错误,崩溃
其他私有库          任何                ❌ 运行时错误,崩溃

暂时可访问的私有库(targetSdk≤23 有警告)

text

libandroid_runtime.so
libcutils.so
libcrypto.so
libssl.so

典型错误日志

text

# 警告(targetSdk ≤ 23)
W linker: library "libandroid_runtime.so" needed or dlopened by
"/data/app/com.example/lib/arm/libapp.so" is not accessible
for the namespace "classloader-namespace" - the access is
temporarily granted as a workaround for http://b/26394120

# 崩溃(targetSdk ≥ 24)
java.lang.UnsatisfiedLinkError: dlopen failed:
library "libcutils.so" is not accessible
for the namespace "classloader-namespace"

六、LL-NDK 与 VNDK-SP 库清单

LL-NDK(所有进程可访问)

text

libEGL.so          libGLESv1_CM.so    libGLESv2.so
libGLESv3.so       libc.so            libdl.so
liblog.so          libm.so            libvulkan.so
libnativewindow.so libsync.so         libvndksupport.so
libandroid_net.so  libneuralnetworks.so

VNDK-SP(框架进程内 SP-HAL 可访问)

text

libbase.so         libc++.so          libcutils.so
libhidlbase.so     libhidltransport.so libhwbinder.so
libutils.so        libz.so            libion.so
libhardware.so     libhidlmemory.so
android.hardware.graphics.common@1.0.so
android.hardware.graphics.mapper@2.0.so
...

七、Android 版本演进

text

Android 7.0 (N)
  └─ 首次引入命名空间隔离
  └─ 禁止应用访问私有平台库
  └─ 使用静态 ld.config.txt 文件

Android 8.0 (O)
  └─ 引入 VNDK Lite 配置
  └─ SP-HAL / VNDK-SP 隔离

Android 8.1 (O MR1)
  └─ VNDK 完整配置成为默认
  └─ system ↔ vendor 完全隔离

Android 9 (P)
  └─ vendor 进程增加 vndk 命名空间
  └─ VNDK 库与默认命名空间隔离
  └─ 重命名配置文件
  └─ 添加 product / odm 分区支持

Android 11 (R)
  └─ 移除静态 ld.config.*.txt
  └─ LinkerConfig 在启动时动态生成
  └─ 根据运行时环境(APEX等)自动适配

八、应用修复方案

text

问题                          解决方案
──────────────────────────────────────────────────────
使用私有平台库                 ① 使用公开 NDK API 替代
                              ② 将库副本打包进 APK

使用访问私有符号的第三方库      联系库作者更新

libandroid_runtime.so         使用 <jni.h> 标准函数:
的 getJavaVM/getJNIEnv         GetJavaVM / JavaVM::GetEnv

libcutils.so 的               使用 __system_property_get
property_get                  #include <sys/system_properties.h>

libcrypto.so 的 SSL_ctrl      静态链接 libcrypto.a
                              或打包 BoringSSL/OpenSSL

检测是否使用私有库             aarch64-linux-android-readelf
                              -dW libMyLibrary.so

九、一句话核心总结

text

命名空间隔离 = 动态链接器强制执行的库访问边界

目的:
  防止符号冲突 + 强制 System/Vendor 分区解耦

实现:
  ld.config.txt 定义命名空间 → 
  每个进程只能访问其命名空间内或被显式导出的库

结果:
  应用/vendor 无法随意使用私有系统库
  system 和 vendor 分区可以独立更新(Treble 基础)

免责声明 本文档所有内容仅供安全研究、学术交流与技术学习使用,严禁用于任何未经授权的逆向破解、网络攻击、隐私窃取、恶意软件开发及其他违反《中华人民共和国网络安全法》《数据安全法》等法律法规的行为,使用者应确保已获得目标软件权利人的合法授权并自行承担因使用本文档内容所产生的一切法律责任与后果,作者不对任何直接或间接损害承担任何责任,继续阅读即视为您已知悉并同意上述全部条款。