【问题标题】:Bionic and libc’s stub implementationsBionic 和 libc 的存根实现
【发布时间】:2016-08-23 18:57:54
【问题描述】:

我想在非 android linux 机器上运行我从 apk 中获取的 x86 共享库。

它与 android libc 相关联,所以我从 android ndk 中获取了libc.so。 在调试了一段时间的段错误之后,我发现libc.so 是“作弊”,并且只包含许多库函数的 nop 实现:

$ objdump -d libc.so | grep memalign -A 8
0000bf82 <memalign>:
    bf82:       55                      push   %ebp
    bf83:       89 e5                   mov    %esp,%ebp
    bf85:       5d                      pop    %ebp
    bf86:       c3                      ret    

现在 ndk 还包含一个 libc.a,其中包含这些函数的实际实现,但我如何让我的进程加载这些并覆盖 libc.so 的 nop 函数? 还想了解更多有关 android 为何使用此技巧以及覆盖如何在那里工作的上下文。

【问题讨论】:

    标签: android-ndk shared-libraries ld libc bionic


    【解决方案1】:

    如您所见,取自 NDK 的 libc.so 仅包含存根,因为它的目的是在创建您自己的共享库或可执行文件期间向链接器提供必要的信息。这是nice explanation 为什么我们需要存根库。

    因此,如果您需要真正的 libc.so 二进制文件 - 有两种选择:

    1. 直接从 Android 设备获取:

      $ adb pull /system/lib/libc.so <local_destination>
      
    2. 为您的设备下载出厂 ROM 映像,解压缩,将system.img 挂载到本地文件系统,然后再次从该挂载分区的/system/lib 复制它。

    但是,即使你得到了正确的二进制文件,它也是一个非常痛苦的练习——让它在你的桌面 Linux 上运行。至少有两个原因:

    1. Android 和桌面 Linux ELF 需要不同的解释器。可以通过readelf查看:

      $ readelf --all <android_binary> | grep interpreter
      [Requesting program interpreter: /system/bin/linker]
      $ readelf --all <linux_x64_binary> | grep interpreter
      [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
      

      (解释器是一个小程序,执行实际加载二进制文件并由内核加载)显然你的Linux系统没有/system/bin/linker,内核将拒绝加载此类二进制文件。因此,您必须以某种方式正确加载部分并自行解决所有依赖关系。

    2. Android 内核与桌面内核不同,它有一些libc.so 依赖的额外功能,所以即使你以某种方式加载 ELF,它仍然与你的内核不兼容,你肯定会遇到问题一会儿。

    最重要的是:几乎不可能在桌面 GNU/Linux 上重用 android 二进制文件,即使它们的目标硬件架构相同。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-17
      • 2011-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-09
      • 1970-01-01
      • 2012-09-15
      相关资源
      最近更新 更多