执行共享库

执行共享库

某些共享库在从命令行调用时提供输出,就好像它们是可执行文件一样。例如:

$ /lib/libc.so.6 
GNU C Library stable release version 2.13, by Roland McGrath et al.
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 4.5.2.
Compiled on a Linux 2.6.37 system on 2011-01-18.
[...]

在我自己用 C 编写的共享库中,如何提供此输出?我现在已经执行了一个刚刚创建的库,并且得到了一个segment fault.

答案1

尝试定义 avoid __libc_main()void _init()

答案2

我刚刚基本上回答了同样的问题堆栈溢出。我解决这个问题的动机是为了实现支持libcappam_cap.so

答案的关键成分是:.interpELF 部分内容,其中包括对动态库加载器的引用;运行时入口点的规范。

步骤(缩写为堆栈溢出答案)你这样做:

  • 找出您的系统上使用的动态加载程序:
$ ldd $(which awk)|grep ld-linux|awk '{print $1}'
/lib64/ld-linux-x86-64.so.2
  • 构建共享库源代码以包含对该二进制文件的引用,并进行一些强制堆栈对齐以避免 SSE 相关的段错误(称为foo.c):
#include <stdio.h>
#include <stdlib.h>

void multi(const char *caller) {
    printf("called from %s\n", caller);
}

__attribute__((force_align_arg_pointer))
void multi_main(void) {
    multi(__FILE__);
    exit(42);
}

const char dl_loader[] __attribute__((section(".interp"))) =
    "/lib64/ld-linux-x86-64.so.2";
  • 编译/链接库及其可运行定义的入口点:
$ gcc -fPIC -shared -o foo.so foo.c --entry=multi_main
$ ldd foo.so 
    linux-vdso.so.1 (0x00007fff345d7000)
    libc.so.6 => /lib64/libc.so.6 (0x00007f5bd69f6000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f5bd6be9000)
$ file foo.so 
foo.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=94ffcc60e66b21021ad564882c8e39ebeccd477e, not stripped
$ ./foo.so 
called from foo.c

这是一个相当小的例子。您可以在我之前的回答或链接的提交中找到更多详细信息libcap

相关内容