【问题标题】:using dlopen to dynamically load x86 android .so file, error with undefined symbol使用 dlopen 动态加载 x86 android .so 文件,带有未定义符号的错误
【发布时间】:2018-03-19 14:53:31
【问题描述】:

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

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 它可以工作。然后我必须找到我所做的 x86 版本的 liblog.so,还有 libstdc++.so

现在我终于得到了所有这些库我在调用 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 没有指向任何奇怪的东西。

【问题讨论】:

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


    【解决方案1】:

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

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

    【讨论】:

    • 谢谢。我最终反编译了文件并以另一种方式提取文件
    猜你喜欢
    • 2013-01-15
    • 1970-01-01
    • 2010-10-03
    • 2012-10-10
    • 2012-01-11
    • 1970-01-01
    • 2021-03-08
    • 1970-01-01
    相关资源
    最近更新 更多