Android ndk 仿生与libc’;s存根实现
我想在一台非android linux机器上运行一个从apk获取的x86共享库 它与android libc相关联,所以我从android ndk中获取了Android ndk 仿生与libc’;s存根实现,android-ndk,shared-libraries,ld,libc,bionic,Android Ndk,Shared Libraries,Ld,Libc,Bionic,我想在一台非android linux机器上运行一个从apk获取的x86共享库 它与android libc相关联,所以我从android ndk中获取了libc.so。 在调试segfaults一段时间后,我认为libc.so是“欺骗”,只包含许多库函数的nop实现: $ objdump -d libc.so | grep memalign -A 8 0000bf82 <memalign>: bf82: 55 push
libc.so
。
在调试segfaults一段时间后,我认为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
$objdump-d libc.so | grep memalign-A 8
0000bf82:
bf82:55推力%ebp
bf83:89 e5 mov%esp,%ebp
bf85:5d pop%ebp
bf86:c3 ret
现在ndk还包含一个libc.a
,其中包含这些函数的实际实现,但是如何让我的进程加载这些函数并覆盖libc.so的nop函数呢?
我还想了解更多关于android为什么要做这个把戏以及重写如何在那里工作的上下文。正如您所看到的
libc。所以取自NDK的只包含存根,因为它的目的是在创建您自己的共享库或可执行文件期间向链接器提供必要的信息。下面是我们需要存根库的原因
因此,如果您需要一个实libc.So
binary,有两种选择:
直接从Android设备获取:
$ adb pull /system/lib/libc.so <local_destination>
(解释器是一个执行二进制文件实际加载并由内核加载的小程序)显然,Linux系统没有/system/bin/linker
,内核将拒绝加载此类二进制文件。因此,您必须以某种方式正确加载节,并自行解决所有依赖项
Android内核与桌面内核不一样,它有一些额外的特性,这是libc所依赖的,因此,即使你加载ELF,它仍然与你的内核不兼容,你肯定会在某个时候遇到问题
最重要的是:在桌面GNU/Linux上重用android二进制文件几乎是不可能的,即使它们的目标是相同的硬件架构
$ 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]