2016-08-23 64 views
1

我想运行一个x86共享库,我从一个非android的linux机器上的apk抓取。仿生和libc的存根实现

它与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为什么要这样做,以及重写如何在那里工作。

回答

1

正如你所看到的libc.so所取自NDK的内容仅包含存根,因为它的目的是在创建自己的共享库或可执行文件时为链接器提供必要的信息。这里是我们需要存根库的nice explanation

所以,如果你需要一个真正的libc.so二进制 - 有两种选择:

  1. 抓住它直接从Android设备:为您的设备

    $ adb pull /system/lib/libc.so <local_destination> 
    
  2. 下载工厂ROM映像,其解压,将system.img安装到您的本地文件系统,然后再从该安装的分区的/system/lib中复制它。

但即使你得到正确的二进制文件,这是一个非常痛苦的exersize - 使它在你的桌面Linux上工作。至少有两方面的原因:

  1. Android和桌面Linux的ELFs需要不同的解释。你可以用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重用二进制代码,即使他们的目标是相同的硬件架构。