加载可执行文件或执行库

2023-12-02

有一个large number of 问题关于如何执行库或动态加载可执行文件的SO。据我所知,所有答案都归结为:将可执行文件编译为位置无关代码并使用dlopen。这非常有效,并且在 macOS 上仍然有效,直到glibc 最近的变化,明确禁用dlopenPIE。例如,此更改现在存在于 ArchLinux 上的当前版本的 glibc (2.30) 中,并试图dlopen位置无关的可执行文件给出错误:“无法动态加载位置无关的可执行文件”。

很难猜测是什么促使了如此彻底的改变,破坏了如此多的代码和有用的用例。 (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);
}

}

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

我有两个问题:

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

很难猜测是什么促使了如此彻底的改变

事实并非如此:它从来没有正常工作过。

破坏了这么多代码

该代码已经以微妙的方式被破解。现在你会得到一个明确的指示,表明它不起作用。

还有其他选择吗?

不这样做吗?

有什么问题dlopening 一个可执行的解决方案?

如果这是一个真正的问题,请打开 GLIBC bugzilla 功能请求,解释该问题并请求支持的机制以实现所需的结果。

Update:

至少说一下为什么“它从来没有正常工作过”。是一些琐碎的事情,比如可执行文件之间可能发生全局冲突,还是真实的事情?

线程局部变量就是一个不能正常工作的例子。不管你认为它们是“真实的”还是假的,我不知道。

这是代码:

// foo.c
#include <stdio.h>

__thread int var;

__attribute__((constructor))
static void init()
{
  var = 42;
  printf("foo.c init: %d %p\n", var, &var);
}

int bar() {
  printf("foo.c bar:  %d %p\n", var, &var);
  return var;
}

int main()
{
  printf("foo.c main: %d %p bar()=%d\n", var, &var, bar());
  return 0;
}
gcc -g foo.c -o foo -Wl,-E -fpie -pie && ./foo
foo.c init: 42 0x7fb5dfd7d4fc
foo.c bar:  42 0x7fb5dfd7d4fc
foo.c main: 42 0x7fb5dfd7d4fc bar()=42
// main.c
// Error checking omitted for brevity
#include <dlfcn.h>
#include <stdio.h>

int main()
{
  void *h1 = dlopen("./foo", RTLD_LOCAL|RTLD_LAZY);
  int (*bar)(void) = dlsym(h1, "bar");

  printf("main.c: %d\n", bar());
  return 0;
}
gcc -g main.c -ldl && ./a.out
foo.c init: 42 0x7fb7305da73c
foo.c bar:  0 0x7fb7305da73c    <<< what?
main.c: 0                       <<< what?

这是使用GNU C Library (Debian GLIBC 2.28-10) stable release version 2.28.

底线:这从来都不是为了工作而设计的,而你只是碰巧没有踩到许多地雷,所以你认为它正在工作,而事实上你正在练习未定义的行为。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

加载可执行文件或执行库 的相关文章

  • 如何在 Linux 中显示进程状态(阻塞、非阻塞)

    有没有办法查询 Linux 进程表中进程的状态 以便能够演示执行查询时进程是正在运行还是被阻止 我的目标是从进程或程序的 外部 执行此操作 因为我希望从操作系统进程的角度来理解这一点 但欢迎任何想法 这是Python代码阻塞的过程 impo
  • Tk 初始化失败:无显示名称且无 $DISPLAY 环境变量

    我试图从 Ubuntu 终端调用 Centos 服务器上的工具 我收到以下错误 Tk 初始化失败 没有显示名称 也没有 DISPLAY 环境变量 请帮我解决这个问题 提前致谢 连接到你的 CentOS 机器ssh Y其中 每man ssh
  • 如何从powershell获取主机名?

    我如何获得hostname https stackoverflow com q 42014215 262852 for dur来自 powershell PS home thufir powershell gt PS home thufir
  • C 标准库函数与系统调用。哪个是“open()”?

    I know fopen 在C标准库中 所以我绝对可以调用fopen C 程序中的函数 我感到困惑的是为什么我可以打电话给open 功能也一样 open 应该是系统调用 所以它不是标准库中的C函数 因为我能够成功地调用open 函数 我调用
  • 如何搭建qtwayland?

    我花了一整天的时间尝试使用QtWayland Compositor 1 0在 Qt 创建者中 我已经遵循了从那里开始的所有步骤https wiki qt io QtWayland https wiki qt io QtWayland但我收到
  • 带有接收器的 boost_log 示例无法编译

    我正在考虑将 boost log 用于一个项目 一开始我就遇到了以下问题 我在以下位置找到的升压日志示例 http www boost org doc libs 1 54 0 libs log example doc tutorial fi
  • 多线程进程的线程ID可以与另一个正在运行的进程的进程ID相同吗?

    我正在尝试找到一种方法来唯一标识多进程环境中的线程 我有一个服务器 它跟踪连接到它的不同进程 其中一些是多线程的 一些不是 为了识别多线程连接中的线程 我使用线程 ID 作为唯一标识符 在任何给定时间最多有 1 个多线程进程连接 我的问题是
  • 导出多个 LD_LIBRARY_PATH 的正确方法

    对于linux的使用 我是一个新手 根据有关我的项目的指南 我必须多次导出 LD LIBRARY PATH 并且我不确定是否不覆盖它们 Cupti Tensorflow CUDAit export LD LIBRARY PATH LD LI
  • 如何像C99一样使用make和编译?

    我正在尝试使用 Makefile 编译 Linux 内核模块 obj m main o all make C lib modules shell uname r build M PWD modules clean make C lib mo
  • Docker容器内的动态监听端口

    我有一个应用程序 在使用其默认端口建立一些连接后 开始打开 侦听 新的随机端口来处理现有连接 然后删除它们 视频通话 它还在通信协议内交换其IP地址和端口 我能够解决IP地址问题 但仍然无法找到一种方法来动态告诉主机的IPTABLES在Do
  • 在 Bash 中使用“$RANDOM”生成随机字符串

    我正在尝试使用 Bash 变量 RANDOM创建一个由包含整数和字母数字的变量中的 8 个字符组成的随机字符串 例如 var abcd1234ABCD 我怎样才能做到这一点 使用参数扩展 chars 是可能的字符数 是模运算符 chars
  • 如何在Linux中获取带有图标的活动应用程序

    我想找到一种方法获取活动应用程序的列表及其名称和图标 实际上 我正在使用此命令来获取所有活动进程 wmctrl lp 示例输出 0x03800002 0 3293 user notebook XdndCollectionWindowImp
  • 使用多个 NIC 广播 UDP 数据包

    我正在 Linux 中为相机控制器构建嵌入式系统 非实时 我在让网络做我想做的事情时遇到问题 该系统有 3 个 NIC 1 个 100base T 和 2 个千兆端口 我将较慢的连接到相机 这就是它支持的全部 而较快的连接是与其他机器的点对
  • 超立方体错误。非法的最小或最大规格

    尝试从这里运行示例代码http tess4j sourceforge net codesample html http tess4j sourceforge net codesample html我收到一条错误消息 Error Illega
  • Java 内存错误:无法创建新的本机线程

    运行 java 服务器时 我在 UNIX 服务器上收到此错误 Exception in thread Thread 0 java lang OutOfMemoryError unable to create new native threa
  • 为什么 ls -l 中的“总计”加起来不等于列出的总文件大小? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 为什么是total在输出中ls l打印为64并不是26078列出的所有文件的总数是多少 ls l test ls total 64 rw
  • 如何使用 sed 交换两行?

    有谁知道如何更换line a with line b and line b with line a使用 sed 编辑器在文本文件中 我可以看到如何用保留空间中的一行替换模式空间中的一行 即 Paco x or Paco g 但是如果我想采取
  • 未找到 DEADLINE 调度策略

    我想在 C 中实现 DEADLINE 调度策略 我知道该功能已实现Linux 3 14 10我正在使用 Ubuntu 14 04Linux 3 17 0 031700 lowlatency 201410060605 SMP PREEMPT这
  • 为什么存在系统调用

    我一直在阅读有关系统调用及其在 Linux 中如何工作的内容 我还有更多的阅读要做 但我读过的一件事都没有回答 那就是 为什么我们需要系统调用 我知道系统调用是用户空间程序要求内核执行某些操作的请求 但我的问题基本上是 为什么用户空间程序本
  • Google Apps 脚本自动生成的库文档

    我目前正在开发一个 Google Apps 脚本库 它基本上将电子表格视为数据库对象 目前 该库有两个相同的功能 例如 Opens and creates a query object for a spreadsheet with the

随机推荐

  • 替换 Javascript 中正则表达式匹配的第 n 个实例

    我正在尝试编写一个正则表达式函数 该函数将识别并替换字符串中匹配的单个实例 而不影响其他实例 例如 我有这个字符串 12 34 56 我想用 符号替换第二组管道以获得此字符串 12 34 56 正则表达式函数需要能够处理 x 数量的管道并允
  • 我们能想到的最简单的垂直对齐

    总而言之 在容器中垂直对齐内容的方法很少 这些是主要方法 如果您现在采用一些完全不同的方法来做到这一点 那么您将非常慷慨地提供示例 我将在此处将其合并 using position and transform特性 http jsfiddle
  • 对一系列线段进行曲线拟合

    SO 有很多曲线拟合问题 但我似乎找不到一个可以解决我正在寻找的问题 场景很简单 我在平板电脑屏幕上捕获 X Y 点 我想将生成的线段绘制为平滑曲线而不是一系列线段 许多应用程序都会这样做 例如 倒数第二个 草图演示 0 36 or 欧特克
  • 如何通过一笔交易在 Firebase 上创建用户并上传数据

    我正在制作一个 Web 应用程序 它使用电子邮件和密码在 Firebase 上创建用户firebase auth createUserUsingEmailAndPassowrd 创建帐户后 我立即根据 firebase 数据库上的表单值上传
  • 修改WebApi的ActionFilterAttribute的OnActionExecuted方法中的HttpContent(actionExecutedContext.Response.Content)

    我的 WebApi 操作方法返回一个 IQueryable 我想通过 Asp Net WebApi 不是 MVC 中的 ActionFilterAttribute 修改它 应用分页和过滤 以下线程我了解了如何访问传递的模型 Net Web
  • 删除序列中的重复数字

    我有一个类型的向量 c 3 3 9 9 2 2 3 3 7 7 我想删除序列中重复的数字 而不破坏顺序 这是 我想获得类似的东西 c 3 9 2 3 7 我怎样才能在 R 中做到这一点 我们还可以观察到序列中的重复项与相邻项的差异为 0 因
  • UIPageControl - 单击按钮更改页面

    我在用UIPageControl随着UISwipeGestureRecognizer在视图控制器之间切换 使用滑动即可更改页面 我还需要更改页面UIButton在视图控制器之一上按下 以下是如何使用滑动来更改视图 void swipeRig
  • 如何将扩展运算符与“this”一起使用?

    我正在 TypeScript 中定义一个类 因此 使用展开运算符 我可以发出这样的命令 class Foo constructor data IDataStructure const k data and then k has taken
  • 如何获取小时时间?

    我正在编写 python 脚本以获得 12 小时的时间 我想要得到7小时而不是07 self getControl 4203 setLabel time strftime I 30 time strftime p print time st
  • Oracle 中的复杂左外连接,转换为 PostgreSQL

    我有一个来自 Oracle SAS 环境的巨大 SQL 语句 我明白了大部分内容 但最让我困惑的是 WHERE 子句中的左外连接 加号 我需要将其转换为 Postgres 我可以处理代码的第一部分 这是让我困惑的连接 SELECT A bu
  • 如何将项目左对齐同时将它们保留在一列中?

    我试图将项目左对齐 同时将它们保留在列中 但是 当我将项目放入列中时 它默认将页面上的项目重新居中 这是我所拥有的 HTML div div post title div div post author div div CSS postHe
  • Ionic 2 Facebook 登录 - “应用程序未设置”和“未登录”和“不允许给定 URL”错误

    我正在尝试从 Ionic Native 库实现 Facebook 登录 API 并在我的应用程序中有一个用于打开 Facebook 登录窗口的按钮 但是 当该窗口在我的 iOS 设备上打开时 首先出现以下错误 然后 在终端中执行以下命令后
  • 嵌套元组列表的高级排序标准

    我有一个以下形式的嵌套元组列表 a b c 现在我想选择最大化的元素a同时最小化b and c同时 例如在 7 5 1 7 4 1 6 3 1 获胜者应该是 7 4 1 任何帮助表示赞赏 根据我的理解 您希望按 a 降序排序 按 b 升序排
  • 只删除c#上的一些html标签

    我有一个字符串 string hmtl div b xpto b div 并需要删除标签 div and div 结果是 b xpto b Just div and div 没有去掉很多html标签 而是保存了 b xpto b Use h
  • 在 Windows Phone 8.1 上使用 Sharepoint REST API 时,HttpClient 无法通过 NTLM 对第二个请求进行身份验证

    很抱歉标题很长 但这似乎是迄今为止我所知道的最好的总结 我们目前正在开发一个通用应用程序 该应用程序需要使用 NTLM 身份验证通过 REST API 访问 Sharepoint 服务器上的一些文档 事实证明这比应有的要困难 虽然我们能够找
  • React Native adb 反向 ENOENT

    我正在尝试使用 React NativeAndroid V4 2 2 Genymotion 但我无法在模拟器上测试该应用程序 当我跑的时候react native run android 我收到此错误Could not run adb re
  • 涉及数值 (0) 的加法

    假设 x 是实数或向量 i 的值为 False 那么 x i 将返回 numeric 0 我想将其视为实数 0 或整数 0 它们都适合加法 numeric 0 添加到任何实数将返回 numeric 0 而我希望获得添加的实数作为结果 如何转
  • 在struts2阿拉伯语国际化中如何自动将文本框中的光标更改为rtl?

    我已经在我的 Struts2 应用程序中实现了国际化 并且工作正常 但是当我选择阿拉伯语作为语言时 如何将所有 jsp 中的所有文本框中的光标位置自动更改为 RTL 如果你能给我一个简单的例子 那将会非常有帮助 添加怎么样dir归因于JSP
  • “UseTaskFriendlySynchronizationContext”是什么意思?

    asp net 4 5 中有一个新的应用程序设置
  • 加载可执行文件或执行库

    有一个large number of 问题关于如何执行库或动态加载可执行文件的SO 据我所知 所有答案都归结为 将可执行文件编译为位置无关代码并使用dlopen 这非常有效 并且在 macOS 上仍然有效 直到glibc 最近的变化 明确禁