2009-09-20 22 views
43

所以大家可能知道的glibc的/lib/libc.so.6可以像在情况下,它打印其版本信息并退出正常的可执行文件的shell执行。这是通过在.so中定义一个入口点完成的。对于某些情况,也可以将其用于其他项目。不幸的是,你可以通过ld的-e选项设置的低级入口点有点太低级:动态加载器不可用,所以你不能调用任何合适的库函数。出于这个原因,glibc通过在这个入口点的裸体系统调用来实现write()系统调用。现在建设。所以,这也是一个可执行

我的问题是,谁能想到一个很好的方式,一个如何从该入口点引导全动态连接器这样就可以从其他的.so的访问功能?

+5

'/ lib目录/ LD-linux.so.2'只是另一个例子:) – 2010-07-11 22:21:51

回答

43

构建共享库-pie选项似乎给你你想要的一切:

/* pie.c */ 
#include <stdio.h> 
int foo() 
{ 
    printf("in %s %s:%d\n", __func__, __FILE__, __LINE__); 
    return 42; 
} 
int main() 
{ 
    printf("in %s %s:%d\n", __func__, __FILE__, __LINE__); 
    return foo(); 
} 


/* main.c */ 
#include <stdio.h> 

extern int foo(void); 
int main() 
{ 
    printf("in %s %s:%d\n", __func__, __FILE__, __LINE__); 
    return foo(); 
} 


$ gcc -fPIC -pie -o pie.so pie.c -Wl,-E 
$ gcc main.c ./pie.so 


$ ./pie.so 
in main pie.c:9 
in foo pie.c:4 
$ ./a.out 
in main main.c:6 
in foo pie.c:4 
$ 

p.S. glibc的通过系统调用实现write(3),因为它没有其他地方调用(这是最低水平的话)。这与能够执行libc.so.6无关。

+0

我发现'-shared'选项可能会阻止这样做,并给你一个分段错误。你必须确保'-shared'选项不存在或者放在'-pie'之前,这样它就会被忽略。 – 2015-07-06 05:11:16

1

不是一个很好的方式,但我会围绕该调用入口点函数我要运行的。所以一个小小的包装可执行。

0

我想你会让你的ld -e指向一个入口点,然后使用dlopen()函数系列来查找和引导动态链接器的其余部分。当然,你必须确保dlopen()本身无论是静态链接,或者您可能必须实施足够自己连接残端的它(获得使用系统调用接口,如mmap()一样的libc本身在做什么。

这些都不听起来“不错”给我。其实刚够评估作业的大小的阅读glibc的来源思想(与ld-linux源代码,作为一个例子)听起来很苍老的我。这也可能是一个可移植性的噩梦,Linux实现ld-linux的方式与OpenSolaris,FreeBSD等链接方式之间可能存在很大的差异(我不知道)

相关问题