使用dlopen动态加载x86 android .so文件,错误与未定义的符号

时间:2017-10-08 07:57:24

标签: android c++ shared-libraries cross-compiling glibc

我正在尝试使用以下代码动态加载SO文件。 SO文件是从apk中提取的,其中包含x86和这个SO库的arm版本(带有单声道C#dlls的打包文件)。

void * mono = dlopen("./libmonodroid_bundle_app.so", RTLD_LAZY);
if(!mono){
    cerr << "Cannot Load Library. Error: " << dlerror() << '\n';
    return -1;
}

我在运行程序时首先遇到以下错误:

  

无法加载库。错误:/usr/lib/i386-linux-gnu/libc.so

这是因为我的libc.so文件是一个链接描述文件,它试图将其作为一个实际的SO文件读取。

如果我使用以下方法手动复制libc.so:sudo cp /lib/i386-linux-gnu/ld-linux.so.2 libc.so它可以工作。然后我必须找到我所做的lib86.so的x86版本,也是libstdc ++。所以

现在我终于得到了所有这些库,在调用dlopen时出现以下错误:

  

无法加载库错误:/libmonodroid_bundle.app.so undefined   符号:__sF

未定义的符号在哪里?我可以编辑.so文件以通过IDA将其删除但我怀疑它无法正常运行。

我试图在下面调用的.so文件的LDD输出如果有帮助:

ldd -r -v libmonodroid_bundle_app.so 
    linux-gate.so.1 =>  (0xb77fd000)
    libc.so => /usr/lib/i386-linux-gnu/libc.so (0xb6de2000)
    libm.so => /usr/lib/i386-linux-gnu/libm.so (0xb6d8c000)
    libdl.so => /usr/lib/i386-linux-gnu/libdl.so (0xb6d85000)
    liblog.so => /usr/lib/i386-linux-gnu/liblog.so (0xb6d83000)
    libz.so => /usr/lib/i386-linux-gnu/libz.so (0xb6d66000)
    libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb6bac000)
    /lib/ld-linux.so.2 (0x80009000)
undefined symbol: __sF  (./libmonodroid_bundle_app.so)

    Version information:
    /usr/lib/i386-linux-gnu/libm.so:
        ld-linux.so.2 (GLIBC_PRIVATE) => /lib/ld-linux.so.2
        libc.so.6 (GLIBC_2.1.3) => /lib/i386-linux-gnu/libc.so.6
        libc.so.6 (GLIBC_2.0) => /lib/i386-linux-gnu/libc.so.6
        libc.so.6 (GLIBC_PRIVATE) => /lib/i386-linux-gnu/libc.so.6
    /usr/lib/i386-linux-gnu/libdl.so:
        ld-linux.so.2 (GLIBC_PRIVATE) => /lib/ld-linux.so.2
        libc.so.6 (GLIBC_PRIVATE) => /lib/i386-linux-gnu/libc.so.6
        libc.so.6 (GLIBC_2.1.3) => /lib/i386-linux-gnu/libc.so.6
        libc.so.6 (GLIBC_2.1) => /lib/i386-linux-gnu/libc.so.6
        libc.so.6 (GLIBC_2.0) => /lib/i386-linux-gnu/libc.so.6
    /usr/lib/i386-linux-gnu/libz.so:
        libc.so.6 (GLIBC_2.1) => /lib/i386-linux-gnu/libc.so.6
        libc.so.6 (GLIBC_2.1.3) => /lib/i386-linux-gnu/libc.so.6
        libc.so.6 (GLIBC_2.4) => /lib/i386-linux-gnu/libc.so.6
        libc.so.6 (GLIBC_2.0) => /lib/i386-linux-gnu/libc.so.6
        libc.so.6 (GLIBC_2.3.4) => /lib/i386-linux-gnu/libc.so.6
    /lib/i386-linux-gnu/libc.so.6:
        ld-linux.so.2 (GLIBC_2.3) => /lib/ld-linux.so.2
        ld-linux.so.2 (GLIBC_PRIVATE) => /lib/ld-linux.so.2
        ld-linux.so.2 (GLIBC_2.1) => /lib/ld-linux.so.2

编辑:这是IDA的extern表,你可以看到__sF没有指向任何奇怪的东西。

https://i.imgur.com/spI9Lu3.png

1 个答案:

答案 0 :(得分:1)

似乎您正在尝试使用在GNU / Linux系统上使用glibc对Bionic libc(针对Android)编译的二进制文件。这两个C库是不兼容的。

我不会说你不可能做你正在尝试的事情,但实现你的目标并不像复制几个文件那么简单。您需要一个自定义动态链接器和一个垫片,它将Bionic libc调用转换为glibc调用(或原始系统调用)。