百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 热门文章 > 正文

Android Native禁止使用系统私有库详解

bigegpt 2024-08-10 12:05 11 浏览

系统私有库指的是,存放在android系统/system/lib/和/vendor/lib下面,但是Android NDK中没有公开API的lib库。

从Android N开始(SDK >= 24),通过dlopen打开系统私有库,或者lib库中依赖系统私有库,都会产生异常,甚至可能导致app崩溃。具体可以阅读官方文档说明。

这个变更会有怎样的影响呢?

曾经的美好

在以前,在ndk层面,我们是可以使用一些hack的手段得到系统的私有api的。

比如,你想使用虚拟机中的一些内部符号,在N以下版本,你可以这么搞

    void *handle = dlopen("libart.so", RTLD_NOW);
    
    void *originFunc = dlsym(handle, "_ZNK3art6Thread13DumpJavaStackERNSt3__113basic_ostreamIcNS1_11char_traitsIcEEEE");

这样你就能得到art::Thread::DumpJavaStack的函数指针,然后愉快地调用它了。

晴天霹雳

但是到了N以后,

void *handle = dlopen("libart.so", RTLD_NOW);
//  没问题,返回了handle指针。

void *originFunc = dlsym(handle, "_ZNK3art6Thread13DumpJavaStackERNSt3__113basic_ostreamIcNS1_11char_traitsIcEEEE");
// 失败!得到的originFunc为空!

这就很奇怪了,我们能够得到handle指针,就说明libart.so是找到了。但是为什么libart.so中却没有找到art::Thread::DumpJavaStack的符号呢?

看一下内存映射表,我们发现了一个有趣的东西

7de5d4d000-7de5d4e000 r-xp 00000000 fe:00 774                            /system/fake-libs64/libart.so
7de5d4e000-7de5d4f000 r--p 00000000 fe:00 774                            /system/fake-libs64/libart.so
7de5d4f000-7de5d50000 rw-p 00001000 fe:00 774                            /system/fake-libs64/libart.so
... ...
7de6a04000-7de6feb000 r-xp 00000000 fe:00 1414                           /system/lib64/libart.so
7de6feb000-7de6ffa000 r--p 005e6000 fe:00 1414                           /system/lib64/libart.so
7de6ffa000-7de6ffd000 rw-p 005f5000 fe:00 1414                           /system/lib64/libart.so

难怪,我们知道dlopen参数为libart.so的话,系统会先找到/system/fake-libs64/libart.so,而不是/system/lib64/libart.so。

而/system/fake-libs64/libart.so又是什么鬼?从名字上看,就知道他是个假的libart。在系统源码文件art/libart_fake/README.md中,我们找到了对他的解释,

A fake libart made to satisfy some misbehaving apps that will attempt to link
against libart.so.

这就是为了以防你们这些图谋不轨(misbehaving)的APP们做一些奇怪的事而专门设的套啊!

只要你自己的lib库依赖了libart.so或者试图打开libart.so,在linker查找libart.so时,因为fake-libs路径被设置在了查找路径表的靠前处,就会先找到/system/fake-libs64/libart.so,而不是真正的/system/lib64/libart.so。

设置fake-libs代码:

@ frameworks/base/core/java/android/app/LoadedApk.java

public static void makePaths(...) {
...
    // Add fake libs into the library search path if we target prior to N.
    if (aInfo.targetSdkVersion <= 23) {
        outLibPaths.add("/system/fake-libs" +
            (VMRuntime.is64BitAbi(aInfo.primaryCpuAbi) ? "64" : ""));
    }
...
}

而这个/system/fake-libs64/libart.so的内容基本上的空的(art/libart_fake/fake.cc),所以在它里面当然什么符号都找不到啦~

霸王硬上弓

既然如此,那我们在dlopen中直接指定lib的绝对路径总行了吧?像这样:

void *handle = dlopen("/system/lib64/libart.so", RTLD_NOW);

可是很遗憾,它报了一个错:

01-11 13:16:10.413 19869-19869/com.patch.demo E/linker: library "/system/lib64/libart.so" ("/system/lib64/libart.so")
needed or dlopened by "/data/app/com.patch.demo-1/lib/arm64/libbcpatch.so"
is not accessible for the namespace:
[name="classloader-namespace", ld_library_paths="",
default_library_paths="/data/app/com.patch.demo-1/lib/arm64:/system/fake-libs64:/data/app/com.patch.demo-1/base.apk!/lib/arm64-v8a",
permitted_paths="/data:/mnt/expand:/data/data/com.patch.demo"]

也就是说,你被允许访问的路径(包含ld_library_paths、default_library_paths、permitted_paths)只有

/data/app/com.patch.demo-1/lib/arm64
/system/fake-libs64
/data/app/com.patch.demo-1/base.apk!/lib/arm64-v8a
/data
/mnt/expand
/data/data/com.patch.demo

所以,试图访问/system/lib64/下的libart.so当然是不行的啦。

真是魔高一尺道高一丈啊。

至此,我们算是知道了Google封杀在ndk中访问系统私有库的方法。本质是在linker中加入一系列校验机制来做限制。linker作为最基础的lib库链接器,所有链接行为都会被限制住。

缓兵之计

不过,在Android N,你可以指定APP的sdk为API级别23或更低。那么,对于以下灰名单中的lib,仍然可以正常使用:

// TODO(dimitry): The grey-list is a workaround for http://b/26394120 ---
// gradually remove libraries from this list until it is gone.
static bool is_greylisted(const char* name, const soinfo* needed_by) {
  static const char* const kLibraryGreyList[] = {
    "libandroid_runtime.so",
    "libbinder.so",
    "libcrypto.so",
    "libcutils.so",
    "libexpat.so",
    "libgui.so",
    "libmedia.so",
    "libnativehelper.so",
    "libskia.so",
    "libssl.so",
    "libstagefright.so",
    "libsqlite.so",
    "libui.so",
    "libutils.so",
    "libvorbisidec.so",
    nullptr
  };

这样的话,每次使用dlopen或者链接以上lib都会打印出一个警告,然后仍然正常执行原有功能。

同时Google也声明了,在将来的版本会将这些lib的支持也一并移除。因此,这只是提供了一个让你尽快在代码中去除相关依赖的过渡期。

可见,不久的将来就无法愉快地使用系统的非公开符号了。

突出重围

那我们真的就没办法了吗?

也不是绝对的,Android限制的只是dlopen这个途径,而我们访问内存是随心所欲的:)

方法就是,通过内存映射表找到libart.so的真实起始位置:

7de6a04000-7de6feb000 r-xp 00000000 fe:00 1414                           /system/lib64/libart.so
7de6feb000-7de6ffa000 r--p 005e6000 fe:00 1414                           /system/lib64/libart.so
7de6ffa000-7de6ffd000 rw-p 005f5000 fe:00 1414                           /system/lib64/libart.so

然后在加载地址起始位置手动解析libart.so的elf格式,提取出所需符号的位置信息。相当于你自己实现linker原本的查找逻辑。

当然,这种遍历内存解析elf的实现是比较复杂的。因此,这一次Google算是封死了一大波底层hack的手段。

不过,网上仍然有很多绕过这个限制的方式,大家有兴趣的可以自己发掘一下。


查看更多:https://yqh.aliyun.com/detail/6896?utm_content=g_1000107051

上云就看云栖号:更多云资讯,上云案例,最佳实践,产品入门,访问:https://yqh.aliyun.com/

相关推荐

5分钟调色大片的方法(5分钟调色大片的方法有哪些)

哈喽大家好。在大家印象中一定觉得ps非常难学非常难。大家不要着急,小编的教学都是针对ps零基础的同学的,而且非常实用哦。只要大家跟着图文练习一两遍,保证大家立马学会~!好了,废话少说,下面开始我们今天...

闪白特效原来是这么用的(闪白特效怎么使用)

作者|高艳侠订阅|010-86092062闪白特效是影视作品中应用比较多的效果之一,那么具体该在哪些场景使用闪白特效?具体该如何操作?下面就以AdobePremiere(以下简称PR)为例,...

ppt常用小图标去哪里找?3个矢量素材网站推荐!

ppt是一个注重可视化表达的演示载体,除了高清图片,ppt中另一类常用的素材是各种小图标,也叫矢量图标,巧妙运用小图标能提升整体美观度和表现力,那么ppt常用小图标去哪里找呢?为方便各位快速找到合适的...

有什么好用的截图录屏工具?试试这9款

经常有朋友反馈苦于缺乏截屏和录屏的趁手工具,本期我们分享几个相当好用的截屏和录屏工具,希望能帮到大家。ScreenToGifScreenToGif是一款免费且开源的录屏工具。此款工具最大的特点是可以...

配色苦手福音!专业快速色环配色PS插件

今天橘子老师给的大家介绍的是一款快速配色的插件,非常强大配色苦手福音来啦!(获取方式见文末)【插件介绍】配色在后期设计中占有主导地位,好的配色能让作品更加抢眼Coolorus这款专业的配色插件,能够...

如何用PS抠主体?(ps怎么抠主体)

1.主体法抠图-抠花苞和花梗导入一张荷花苞的照片,点击上图中顶部“选择”菜单栏,下拉单击“主体”。可以看到,只有花苞被选中,但是花梗并没有被选中。接下来单击上图中左侧工具栏的“快速选择工具”,上图中顶...

2799元的4K电视,有保障吗?(买4k电视机哪个品牌好)

在上一期《电脑报》的3·15专题报道中,我们揭露了一款不靠谱的42英寸4K智能电视——TCLD42A561U。这款售价2699元的4K智能电视不仅4K画质方面存在严重问题,而且各种功能和应用体验也不理...

苹果电脑的Touch Bar推出一段时间了 这款工具可以帮你开发适用于它的APP

距离苹果推出带有TouchBar的MacBookPro已经有一段时间了,除了那些像Adobe、Google和Microsoft大公司在开发适用于TouchBar的应用之外,其实还有很多独立的开...

如魔法般吸取颜色的桌灯(如魔法般吸取颜色的桌灯叫什么)

色彩为生活带来的感官刺激,逐渐被视为理所当然。一盏桌灯运用它的神奇力量,将隐藏于物件中的颜色逐一释放,成为装点环境的空间魔法师。ColorUp是一款可以改变颜色的吸色台灯,沿用传统灯泡的造型,融入了拾...

一篇文章带你用jquery mobile设计颜色拾取器

【一、项目背景】现实生活中,我们经常会遇到配色的问题,这个时候去百度一下RGB表。而RGB表只提供相对于的颜色的RGB值而没有可以验证的模块。我们可以通过jquerymobile去设计颜色的拾取器...

ps拾色器快捷键是什么?(ps2019拾色器快捷键)

ps拾色器快捷键是什么?文章末尾有获取方式,按照以下步骤就能自动获得!学会制作PS特效需要一定程度的耐心和毅力。初学者可以从基本的工具和技术开始学习,逐渐提高他们的技能水平。同时,观看更多优秀的特效作...

免费开源的 Windows 截图录屏工具,支持 OCR 识别和滚动截图等

功能很强大、安装很小巧的免费截图、录屏工具,提供很多使用的工具来帮我么能解决问题,推荐给大家。关于ShareXShareX是一款免费的windows工具,起初是一个小巧的截图工具,经过多年的迭...

入门到精通系列PS教程:第13篇 · 拾色器、颜色问题说明及补充

入门到精通系列PS教程:第13篇·拾色器、颜色问题说明及补充作者|侯潇问题说明我的第12篇教程里,有个小问题没有说清楚。要说是错误,又不算是错误,只是没有说准确。写完那篇教程后,因为已经到了深...

PS冷知识:用吸管工具吸取屏幕上的任意颜色

今天,我们给大家介绍PS中的一个冷知识:用吸管工具可以吸取屏幕上的任意颜色。其实,操作起来是非常简单的。大多数情况下,我们认为,PS的吸管工具只能吸取PS软件作图区域范围内的颜色,最多加上画布四周的...

Windows 11 将提供内置颜色选择器工具

Windows11内置了颜色选择器,可以扫描并识别屏幕上的颜色并生成颜色代码。此外,微软还利用人工智能技术,让屏幕上的文本扫描和选择变得更加便捷。这两项功能均已在SnippingToolv1...