Linux   发布时间:2022-04-01  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了linux – 使用glibc而不是默认库编译的C程序:执行时拒绝权限大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

概述

这是我关于stackoverflow的第一个问题,所以我会尽力做好. 语境: 我想提供一个可以在每个Linux发行版上运行的程序(例如,一个将使用C 11的程序,在没有C 11库的系统上运行). 为此,我想复制我的程序使用的所有库,并将它们放在带有可执行文件的文件夹中,这样它就可以使用这些库而不是系统库. 我有2个环境要测试: – Opensuse,(GNU libC)2.19 – Ubuntu,
这是我关于stackoverflow的第一个问题,所以我会尽力做好.

语境:

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

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

我在Opensuse下编译我的程序,并在Ubuntu下运行它.该程序使用认库时效果很好.

项目:

这是main.c:

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

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

+ 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]

做了一些研究,最后找到了this post,他们解释了一下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]

问题:

现在,当我在我的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下拥有相同的树
lib文件夹中的2个库是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)

除非您还要复制所需的所有库,否则它将无法工作.

虑使用-R作为链接

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

大佬总结

以上是大佬教程为你收集整理的linux – 使用glibc而不是默认库编译的C程序:执行时拒绝权限全部内容,希望文章能够帮你解决linux – 使用glibc而不是默认库编译的C程序:执行时拒绝权限所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。