【发布时间】:2014-05-29 09:59:58
【问题描述】:
我想为术语和可能的愚蠢问题道歉,我是 C++ 和操作系统架构的新手。
我有一个为 x86 32 位编译的 library.so 文件,我需要使用其中的一个函数。在 IDA 的帮助下,我知道函数及其参数的符号和名称。
我创建了一个 .cpp 文件,调用 dlopen() 来导入库,然后通过函数名获取指向函数的指针,最后使用两个参数从库中调用函数:"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 进行符号链接,那么它读取正常,但是当我再次启动文件时:
/path/to/library.so: undefined symbol: __stack_chk_guard
如果我尝试将 .so 文件导入 Java 测试类代码,我会收到完全相同的消息。
问题是:如何在知道函数签名的情况下将 .so 库正确导入我的 proram。我没有库的头文件。
谢谢
更新:我试着把
void *__stack_chk_guard;
进入我的 test.cpp 文件(如果我理解正确的话)并使用 -fstack-protector 选项重新编译它,但它没有帮助,我仍然得到 p>
/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
如果我备份它并创建一个符号链接 /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
【问题讨论】:
-
您的 'glibc' 版本是在没有 'glibc stack guard support' 但 'library.so' 的情况下编译的。这就是 '__stack_chk_guard' 未定义的原因。
-
hmm,我可以通过堆栈保护从包 repo 安装 glibc 吗?还是我只需要手动重新编译?我在Ubuntu saucy
-
Ubuntu 13.10 应该具有开箱即用的功能。正确的方法是为ubuntu重新编译'library.so'。解决方法 - 只需将该行放在源代码中的某个位置:'void *__stack_chk_guard;' (或'uintptr_t stack_chk_guard')并用随机值初始化它。
-
如果您使用选项
-fstack-protector编译 test.cpp,错误可能会消失。重要的一点是您必须使用-fstack-protector或-fno-stack-protector编译每个源代码。 -
@alexander 非常感谢您的 cmets,见上文,我更新了我的问题。实际上,我有两个 libc.so ,第一个编译没有错误,但不想启动,第二个无法编译(请参阅更新部分中的错误),但至少尝试过运行和抱怨堆栈保护