因此,每个人都可能知道glibc /lib/libc.so.6可以像普通可执行文件一样在shell中执行,在这种情况下,它会打印其版本信息并退出。这是通过在.so中定义一个入口点来完成的。在某些情况下,将其用于其他项目也可能很有趣。不幸的是,您可以通过ld的- e选项设置的低级入口点太低级:动态加载程序不可用,因此您无法调用任何适当的库函数。因此,glibc在此入口点通过裸系统调用实现write()系统调用。
/lib/libc.so.6
我现在的问题是,没有人能想到一种好方法如何从该入口点引导一个完整的动态链接器,以便一个人可以访问其他.so的函数?
使用-pieoption 构建共享库似乎可以为您提供所需的一切:
-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 $
PS glibc write(3)通过系统调用实现,因为它没有别的地方可以调用(它已经是 最低 级别了)。这与能够执行无关libc.so.6。
write(3)
libc.so.6