相关疑难解决方法(0)

构建一个也是可执行文件的.so

所以每个人都可能知道glibc /lib/libc.so.6可以在shell中执行,就像普通的可执行文件一样,在这种情况下它可以打印出版本信息并退出.这是通过在.so中定义入口点来完成的.对于某些情况,将其用于其他项目可能会很有趣.不幸的是,您可以通过ld的-e选项设置的低级入口点有点太低级:动态加载器不可用,因此您无法调用任何正确的库函数.因此,glibc通过此入口点中的裸系统调用实现write()系统调用.

我现在的问题是,任何人都可以想到一个很好的方法,如何从该入口点引导一个完整的动态链接器,以便可以访问其他.so的函数?

c linux glibc shared-libraries dlopen

48
推荐指数
2
解决办法
4467
查看次数

在可执行文件上使用dlopen()

我需要从另一个程序调用一个函数.如果其他程序是库,我可以简单地使用dlopen和dlsym来获取函数的句柄.不幸的是,其他程序是Unix可执行程序,并且将其构建为库不是一种选择.在可执行文件上尝试dlopen()会显示以下错误消息:

dlopen([...]/testprogram, 1): no suitable image found. Did find: [...]/testprogram: can't map

这并不奇怪,因为dlopen用于库,而不是可执行文件.有没有办法让dlopen和dlsym使用可执行文件?如果没有,是否有另一种方法可以达到同样的目的?

unix executable dlopen

13
推荐指数
2
解决办法
5902
查看次数

加载可执行文件或执行库

SO有大量 关于如何执行库或动态加载可执行文件的问题据我所知,所有答案都归结为:将可执行文件编译为位置无关代码并使用. 这非常有效,并且在 macOS 上仍然有效,直到glibc 最近发生更改,明确禁用了PIE。例如,此更改现在出现在 ArchLinux 上当前版本的 glibc (2.30) 中,并且尝试位置无关的可执行文件会出现错误:“无法动态加载位置无关的可执行文件”。dlopendlopendlopen

很难猜测是什么促使了如此彻底的改变,破坏了如此多的代码和有用的用例。(Patchwork 和 Bugzilla 的解释对我来说没有多大意义。)但是现在有一个问题:如果你想创建一个同时也是动态库的可执行文件该怎么办,反之亦然?

其中一条评论链接了一个解决方案。在这里为后代复制它:

#include <stdio.h>
#include <unistd.h>

const char service_interp[] __attribute__((section(".interp"))) = "/lib/ld-linux-x86-64.so.2";

extern "C" {

void lib_entry(void)
{
  printf("Entry point of the service library\n");    
  _exit(0);
}

}
Run Code Online (Sandbox Code Playgroud)

编译生成g++ -shared test-no-pie.cpp -o test-no-pie -Wl,-e,lib_entry一个也可以在 Linux 上执行的共享对象(动态库)。

我有两个问题:

  1. 如果我想传递命令行参数怎么办?如何修改此解决方案以使其接受arc,argv
  2. 还有其他选择吗?

linux executable glibc shared-libraries dlopen

9
推荐指数
1
解决办法
5865
查看次数

使用dlopen编译C程序,使用-fPIC编译dlsym

我遇到了错误的符号解析问题.我的主程序用dlopen加载一个带dlopen的共享库和一个符号.程序和库都是用C语言库代码编写的

int a(int b)
{
  return b+1;
}

int c(int d)
{
  return a(d)+1;
}
Run Code Online (Sandbox Code Playgroud)

为了使它在64位机器上运行,-fPIC在编译时传递给gcc.

该计划是:

#include <dlfcn.h>
#include <stdio.h>

int (*a)(int b);
int (*c)(int d);

int main()
{
  void* lib=dlopen("./libtest.so",RTLD_LAZY);
  a=dlsym(lib,"a");
  c=dlsym(lib,"c");
  int d = c(6);
  int b = a(5);
  printf("b is %d d is %d\n",b,d);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

如果程序未使用-fPIC编译,则一切运行正常,但在使用-fPIC编译程序时,它会因分段错误而崩溃.调查导致发现崩溃是由于符号a的错误解决.无论是从库还是主程序(后者是通过在主程序中注释掉调用c()的行获得的),都会在调用a时发生崩溃.

调用c()本身时没有问题,可能是因为c()不是由库本身在内部调用,而a()既是库内部使用的函数,也是库的API函数.

编译程序时,一个简单的解决方法是不使用-fPIC.但这并不总是可行的,例如当主程序的代码必须在共享库本身时.另一种解决方法是将指针重命名为其他功能.但我找不到任何真正的解决方案.

用RTLD_NOW替换RTLD_LAZY没有帮助.

c linux gcc elf dlopen

5
推荐指数
1
解决办法
1万
查看次数

标签 统计

dlopen ×4

linux ×3

c ×2

executable ×2

glibc ×2

shared-libraries ×2

elf ×1

gcc ×1

unix ×1