对于术语和可能出现的愚蠢问题,我深表歉意,我是 C++ 和操作系统架构方面的新手。
我有一个为 x86 32 位编译的library.so 文件,我需要使用其中的函数。在IDA的帮助下,我知道了函数的符号和名称及其参数。
我使用 dlopen()
调用创建了一个 .cpp 文件来导入库,然后通过函数名称获取指向函数的指针,最后使用两个参数从库中调用该函数: “4d”
,“13a7330873d6e062”
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
int main(int argc, char **argv) {
void *handle;
char * (*cipher)(const char *,const char *);
char *error;
handle = dlopen ("/path/to/library.so", RTLD_LAZY);
if (!handle) {
fprintf (stderr, "%s\n", dlerror());
exit(1);
}
dlerror(); /* Clear any existing error */
cipher = (char * (*)(const char *,const char *)) dlsym(handle, "known_function_name");
if ((error = dlerror()) != NULL) {
fprintf (stderr, "%s\n", error);
exit(1);
}
printf ("%s\n", (*cipher)("4d","13a7330873d6e062"));
dlclose(handle);
return 0;
}
然后我尝试使用 g++-4.6 编译它(因为正如我在 lib 内容中看到的那样,它是使用 gcc 4.6 编译的),并使用以下选项:
g++-4.6 -o test test.cpp -ldl
它编译时没有任何警告/错误,但是当我启动 ./test 时,我得到:
/usr/lib/i386-linux-gnu/libc.so: invalid ELF header
如果我尝试执行 readelf -h/usr/lib/i386-linux-gnu/libc.so,我会收到类似“无法读取 0x2074 字节的节头...不是 ELF 文件”的信息。好的,如果我对/lib/i386-linux-gnu/libc.so.6 进行符号链接(symbolic link),那么它读起来很好,但是当我再次启动该文件时:
/path/to/library.so: undefined symbol: __stack_chk_guard
如果我尝试将 .so 文件导入到 Java 测试类代码中,我会收到完全相同的消息。
问题是:在知道函数签名的情况下,如何正确地将 .so lib 导入到我的 proram 中。我没有该库的头文件。
谢谢
更新:我尝试添加
void *__stack_chk_guard;
进入我的 test.cpp 文件(如果我理解正确的话)并使用 -fstack-protector
选项重新编译它,但它没有帮助,我仍然得到
/path/to/library.so: undefined symbol: __stack_chk_guard
另外:它针对我当前的/usr/lib/i386-linux-gnu/libc.so 编译得很好,但是当我启动它时,它会提示它,正如我之前所说的:
/usr/lib/i386-linux-gnu/libc.so: invalid ELF header
如果我备份它并创建符号链接(symbolic link)/usr/lib/i386-linux-gnu/libc.so ->/lib/i386-linux-gnu/libc.so.6 ,那么它将无法编译:
/usr/lib/gcc/i686-linux-gnu/4.6/../../../i386-linux-gnu/crt1.o: In function `_start':
(.text+0xc): undefined reference to `__libc_csu_fini'
/usr/lib/gcc/i686-linux-gnu/4.6/../../../i386-linux-gnu/crt1.o: In function `_start':
(.text+0x11): undefined reference to `__libc_csu_init'
collect2: ld returned 1 exit status
但随后它运行
/path/to/library.so: undefined symbol: __stack_chk_guard
最佳答案
验证library.so 是否已正确加载所有依赖项。如果您使用不同的库,其中可能没有 __stack_chk_guard 。使用 ldd 和其他工具检查。
顺便说一句,__stack_chk_guard 在 x86 架构上并不是很流行...
关于c++ - 使用 .so 库中的函数而不使用头文件,知道函数签名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23930656/