使用dlopen动态加载x86 android .so文件,出现未定义符号错误
using dlopen to dynamically load x86 android .so file, error with undefined symbol
我正在尝试使用以下代码动态加载 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;
}
我在 运行 我的程序中首先得到以下错误:
Cannot Load Library. Error: /usr/lib/i386-linux-gnu/libc.so
这是因为我的 libc.so 文件是一个链接描述文件,它正试图将其作为实际的 SO 文件读取。
如果我使用以下命令手动复制 libc.so:sudo cp /lib/i386-linux-gnu/ld-linux.so.2 libc.so 它有效。然后我不得不找到我所做的 liblog.so 的 x86 版本,还有 libstdc++.so
现在我终于得到了所有这些库我在调用 dlopen 时收到以下错误:
Cannot Load Library Error: /libmonodroid_bundle.app.so undefined
symbol: __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 table,您可以看到 __sF 没有指向任何奇怪的东西。
您似乎正在尝试在使用 glibc 的 GNU/Linux 系统上使用针对 Bionic libc(针对 Android)编译的二进制文件。这两个 C 库不兼容。
我不会说你尝试的事情是不可能的,但实现你的目标并不像复制几个文件那么简单。您需要一个自定义动态链接器和一个将 Bionic libc 调用转换为 glibc 调用(或原始系统调用)的填充程序。
我正在尝试使用以下代码动态加载 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;
}
我在 运行 我的程序中首先得到以下错误:
Cannot Load Library. Error: /usr/lib/i386-linux-gnu/libc.so
这是因为我的 libc.so 文件是一个链接描述文件,它正试图将其作为实际的 SO 文件读取。
如果我使用以下命令手动复制 libc.so:sudo cp /lib/i386-linux-gnu/ld-linux.so.2 libc.so 它有效。然后我不得不找到我所做的 liblog.so 的 x86 版本,还有 libstdc++.so
现在我终于得到了所有这些库我在调用 dlopen 时收到以下错误:
Cannot Load Library Error: /libmonodroid_bundle.app.so undefined symbol: __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 table,您可以看到 __sF 没有指向任何奇怪的东西。
您似乎正在尝试在使用 glibc 的 GNU/Linux 系统上使用针对 Bionic libc(针对 Android)编译的二进制文件。这两个 C 库不兼容。
我不会说你尝试的事情是不可能的,但实现你的目标并不像复制几个文件那么简单。您需要一个自定义动态链接器和一个将 Bionic libc 调用转换为 glibc 调用(或原始系统调用)的填充程序。