可执行文件与共享对象

可执行文件与共享对象

我在做这件事时注意到了一些事情find /bin -exec file {} \;

file命令报告某些条目/binshared objects,而其他条目为executables。例如,

/bin/ntfsck:
ELF 64 位 LSB共享对象,x86-64,版本 1 (SYSV),
动态链接(使用共享库),适用于 GNU/Linux 2.6.24,BuildID[sha1]=312d93fd0d8653e7236a61db2e67b93c63225a00,已剥离

同一份报告gawk

/usr/bin/gawk:
ELF 64 位 LSB共享对象,x86-64,版本 1 (SYSV),
动态链接(使用共享库),适用于 GNU/Linux 2.6.24,
BuildID[sha1]=76bb13aac7e212164bd6e0d7b8a5d92db44543c9,已剥离

相反file/bin/echo是:

/bin/echo:
ELF 64 位 LSB可执行文件,x86-64,版本 1 (SYSV),
动态链接(使用共享库),适用于 GNU/Linux 2.6.24,
BuildID[sha1]=193e75fc13e9c4599e772b8d79125a5934cf601c,已剥离

本质上,我想知道executable文件和shared object文件。

答案1

太长不看

除了编译后的可执行文件可能与共享对象链接但不能与可执行文件链接之外,没有区别。


一般来说,编译可执行文件有两种方法

  • 使用静态链接:源代码中包含的外部库被编译,并且编译后的库(或链接器角度的对象)被添加到可执行文件本身;
  • 使用动态链接:源代码中包含的外部库被编译,但一条链接将已编译的库(或从链接器的角度来看是对象)添加到可执行文件中(如果需要,链接器会在运行时加载已编译的库/对象);

使用这些方法各有优点/缺点,但这不是问题的重点;

  • /bin/ntfsck并且/usr/bin/gawk是共享对象:这意味着可以编译可执行文件,然后将其链接到它们以使用它们的功能;
  • /bin/echo是可执行文件:这意味着可执行文件可能不是进行编译然后链接以使用其功能;

因此/bin/ntfsck/usr/bin/gawk从技术上讲,它们是编译后的库(或者从链接器的角度来看是对象),但是,正如人们可能已经预见到的,没有什么可以阻止共享对象作为可执行文件运行。

附注:还请注意file(针对每个报告):

动态链接(使用共享库)

这意味着它们每个都动态链接到(并且可能使用)其他共享对象。


1.“编译”的含义更为广泛,包括预处理、编译和链接。

答案2

另一个区别是可执行文件具有定义的入口点地址偏移,即 i386 为 0x08048000、x86 为 0x00400000 以及 arm 为 0x00010000。

共享对象文件可以是库,也可以是可执行文件。当它是可执行文件时,没有这样的偏移量。共享对象可执行文件可以说,是使用地址空间布局随机化 (ASLR) 的位置独立可执行文件 (PIE)。因此,当查看其 /proc/pid/maps 文件时,您会注意到与标准可执行文件相比,加载的段的位置在每次执行中都会有所不同。

此功能背后的想法是通过阻止攻击者执行面向返回的编程攻击来增加可执行文件的安全性。许多维护者决定在构建软件包时默认启用 PIE,例如从 Fedora 23 或 Ubuntu 17.10 开始。

相关内容