使用 glibc 而不是默认库编译的 C 程序:执行时权限被拒绝

2024-02-27

这是我在 stackoverflow 上的第一个问题,所以我会尽力做好。

Context:

我想提供一个可以在每个 Linux 发行版上运行的程序(例如,一个将使用 C++11 的程序,在没有 C++11 库的系统上运行)。 为此,我想复制我的程序使用的所有库,并将它们放入可执行文件的文件夹中,这样它就可以使用这些库而不是系统的库。

我有2个环境要测试: - Opensuse,带有(GNU libc)2.19 - Ubuntu,带有(Ubuntu EGLIBC 2.17-Oubuntu5.1)2.17

我在 Opensuse 下编译我的程序,并在 Ubuntu 下运行它。该程序在使用默认库时运行良好。

Project:

这里是main.c:

int main(int ac, char **av) {
printf("Hello World !\n");
}

这是 Opensuse 下我的文件夹树(在 Ubuntu 下相同,没有 main.c 和 exec.sh):

+ project
|
+---  main.c
+---  a.out
+---  exec.sh
+---+ lib
    |
    +--- libc.so.6
    +--- ld-linux-x86-64.so.2

最后,当我通过简单的编译启动程序时,这是 ldd 和 readelf:

> gcc main.c -o a.out
> ldd ./a.out
  linux-vdso.so.1 (0x00007fff85f57000)
  libc.so.6 => /lib64/libc.so.6 (0x00007f1fdaaaf000)
  /lib64/ld-linux-x86-64.so.2 (0x00007f1dae75000)
> readelf -d a.out | grep "library\|Library"
  0x0000000000000001 (NEEDED)            Shared library: [libc.so.6]

我做了一些研究,最后发现这个帖子 https://stackoverflow.com/questions/847179/multiple-glibc-libraries-on-a-single-host/851229#851229谁解释一下 ld-linux.so。

这是我用来编译的脚本:

#!/bin/bash

dir=`pwd`
execName="a.out"
libDir="/lib"
linker="ld-linux-x86-64.so.2"

gcc main.c -o ${execName} -Wl,--rpath=${dir}${libDir} -Wl,--dynamic-linker=${dir}${libDir}/${linker}

当我在 Opensuse 上启动 a.out 并使用脚本进行编译时,我得到以下信息:

> ./a.out
  Hello World !
> ldd ./a.out
  linux-vdso.so.1 (0x00007f3222e27000)
  libc.so.6 => /path/to/project/lib/libc.so.6 (0x00007f3222a7e000)
  /path/to/project/lib/ld-linux-x86-64.so.2 => /lib64/ld-linux-x86-64.so.2 (0x000073222e2b000)
> readelf -d a.out | grep "library\|Library"
  0x0000000000000001 (NEEDED)            Shared library: [libc.so.6]
  0x000000000000001d (RUNPATH)           Library runpath: [/path/to/project/lib]

Problem:

现在,当我在 Ubuntu 上启动这个可执行文件 a.out(在 Opensuse 下编译)时,我得到以下输出:

> ./a.out
  ./a.out: Permission denied.
> ldd ./a.out
  linux-vdso.so.1 (0x00007fff5b5fe000)
  libc.so.6 => /path/to/project/lib/libc.so.6 (0x00007f47df480000)
  /path/to/project/lib/ld-linux-x86-64.so.2 => /lib64/ld-linux-x86-64.so.2 (0x00007f47df82a000)
> readelf -d a.out | grep "library\|Library"
  0x0000000000000001 (NEEDED)            Shared library: [libc.so.6]
  0x000000000000001d (RUNPATH)           Library runpath: [/path/to/project/lib]

当我启动可执行文件时,此权限一直被拒绝,我不知道为什么。

我使用 Filezilla 将 a.out 和 lib 文件夹从 Opensuse 转移到 Ubuntu,并且 a.out 在转移后不是可执行文件,因此我需要执行以下操作:

chmod 755 a.out

我在 Opensuse 和 Ubuntu 下有相同的树 2个图书馆在lib文件夹是 Opensuse 的默认库

任何有关被拒绝的许可的帮助,或者以其他方式做我想做的事情都将受到欢迎。 在此先感谢您的帮助!

注意:我不能使用 LD_PRELOAD,因为你需要 root 才能使用它,所以它无法完成我想要做的事情。 另外我想避免静态编译,但如果这是唯一的解决方案我会考虑它


这可能有很多问题。这里有一些建议。

检查复制的库的文件权限

你已经提到过,无论你用什么来复制你的a.out更改该文件的权限。图书馆也需要特定的权限,因此请检查这些权限。

检查损坏的符号链接

其中许多库通常实际上是真正二进制文件的符号链接。如果您只复制了链接而不复制底层二进制文件,则它将无法工作。

检查不匹配的库

如你所知,libc不仅仅是一个文件。例如,在我的 Linux 机器上,如果我运行ldd /lib64/libc.so.6我得到这个结果:

/lib64/ld-linux-x86-64.so.2 (0x0000003531200000)
linux-vdso.so.1 =>  (0x00007ffe2c78c000)

除非你也抄袭all所需的库,它不会工作。

考虑使用-R对于链接器

The -L标志告诉链接器在哪里可以找到库,但还有一个-R告诉生成的可执行文件在运行时在哪里找到库的标志。我不清楚你是否需要它。

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

使用 glibc 而不是默认库编译的 C 程序:执行时权限被拒绝 的相关文章

  • 是否有可能在linux中找到包含特定文本的文件?

    考虑这种情况 我在文件夹 Example 下有很多文件 如果我需要找到一个包含特定短语 如 Class Example 的文件 我该如何使用 Linux shell 来做到这一点 linux中有类似 定位 的函数可以做到这一点吗 Thank
  • 我应该使用哪个 Linux 发行版作为 Xen 主机? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我为家庭办公室订购了一台服务器 我想用 Xen 对其进行分区 我认为这将使事情保持干净并且更容易维护 我将运行 MySQL PostgreSQL
  • Linux命令列出所有可用命令和别名

    是否有一个 Linux 命令可以列出该终端会话的所有可用命令和别名 就好像您输入 a 并按下 Tab 键一样 但针对的是字母表中的每个字母 或者运行 别名 但也返回命令 为什么 我想运行以下命令并查看命令是否可用 ListAllComman
  • perf stat中的cycles注释是什么意思

    8 014196 task clock 0 004 CPUs utilized 204 context switches 0 025 M sec 32 cpu migrations 0 004 M sec 0 page faults 0 0
  • 在 shell 脚本中查找和替换

    是否可以使用 shell 在文件中搜索然后替换值 当我安装服务时 我希望能够在配置文件中搜索变量 然后在该值中替换 插入我自己的设置 当然 您可以使用 sed 或 awk 来完成此操作 sed 示例 sed i s Andrew James
  • 是否从页面缓存中的脏页面进行文件读取?

    当字节写入文件时 内核不会立即将这些字节写入磁盘 而是将这些字节存储在页缓存中的脏页中 回写缓存 问题是 如果在脏页刷新到磁盘之前发出文件读取 则将从缓存中的脏页提供字节 还是首先将脏页刷新到磁盘 然后进行磁盘读取以提供字节 将它们存储在进
  • 如何从类似于 eclipse 的命令行创建可运行的 jar 文件

    我知道 eclipse 会生成一个可运行的 jar 文件 其中提取并包含在该 jar 文件中的所有库 jar 文件 从命令提示符手动创建 jar 文件时如何执行类似的操作 我需要将所有 lib jar 解压到类文件夹中吗 目前我正在使用 j
  • 使用 g++ 从 cpp 文件和静态库创建共享库 [重复]

    这个问题在这里已经有答案了 就像标题所说 我想从三个 cpp 文件和一些静态库创建共享库 基本上我想这样做 g libProject so file1 cpp file2 cpp file3 cpp I usr local include
  • Linux 上的 Python 3.6 tkinter 窗口图标错误

    我正在从 Python GUI 编程手册 学习 Python GUI 某项任务要求我通过将以下代码添加到我的配方中来更改窗口图标 Change the main windows icon win iconbitmap r C Python3
  • 为 Linux 安装 R 包时出错

    我试图在 R 3 3 上安装一个名为 rgeos 的包 但是当我输入 install packages rgeos 但它返回给我以下错误 其他包也会发生同样的情况 但不是所有包 gt installing source package rg
  • getaddrinfo在程序中调用assert

    我正在使用 libcurl 开发一个程序 该程序创建一个线程 该线程又使用 libcurl 发出 HTTP 请求 但有时程序会因错误而崩溃 netlink 描述符上出现意外错误 9 在curl中关闭AsynchDNS之后 但问题依然存在 据
  • 如何调用位于其他目录的Makefile?

    我正在尝试这样做 我想打电话给 make Makefile存在于其他目录中 abc可以使用位于不同目录中的 shell 脚本的路径 我该怎么做呢 由于 shell 脚本不允许我cd进入Makefile目录并执行make 我怎样才能编写she
  • 如何使用AWK脚本检查表的所有列数据类型? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 在这里 我正在检查表中第一列的数据类型 但我想知道AWK中表的所有列数据类型 我尝试过 但只能获得一列数据类型 例如 Column 1
  • InstaPy:“错误,无法确定 64 位 Linux 的正确文件名”

    有人知道如何解决或解决这个问题吗 来自控制台的堆栈跟踪 执行后报告错误 InstaPy Version 0 6 9 Workspace in use home zanettra InstaPy Error unable to determi
  • gentoo crontab:为什么这个简单的 crontab 不起作用?

    我使用 GENTOO 发行版 crontab e 35 12 root php5 home www cron php 当我手动运行时 php5 php5 home www cron php 这有效 它向我发送了一封电子邮件 然后我检查日期
  • 如何在Python中独立于语言安装(linux)获取用户桌面路径

    我找到了 如何找到用户桌面的路径 的几个问题和答案 但在我看来它们都已失效 至少我找到的那些 原因是 如果用户安装的 Linux 不是英语 他或她的桌面很可能位于除 Desktop 例如 对于瑞典语 我相信它是在 Skrivbord 谁知道
  • 在 Ubuntu 16.04 上找不到 printf.c

    我最近切换到Ubuntu 16 04 我在用vscode作为 Ubuntu 上的 IDE 我配置了其他语言 但我无法做到这一点C C 我创建c cpp properties json launch json tasks json 当我开始编
  • 每个进程每个线程的时间量

    我有一个关于 Windows 和 Linux 中进程和线程的时间量子的问题 我知道操作系统通常为每个线程提供固定的时间量 我知道时间量根据前台或后台线程而变化 也可能根据进程的优先级而变化 每个进程有固定的时间量吗 例如 如果操作系统为每个
  • Bash 方法的返回值总是模 256

    我有一个 bash 脚本方法 它返回输入值 然而 返回值始终是模 256 的值 我用 google 搜索了一段时间 发现this http www tldp org LDP abs html exitcodes html文章说它总是以 25
  • 如何查找连接到 AF_INET 套接字的客户端的 UID?

    有什么方法或类似的东西ucred for AF UNIX如果是AF INET插座 TCP在我的例子中 找出连接到我的套接字的客户端的UID 还有 proc net tcp但它显示了UID of the creator插座的而不是连接的cli

随机推荐