可执行文件与共享对象

Ser*_*nyy 16 files executable

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

file命令报告了/binare 中的 一些条目shared objects,而其他条目报告为executables. 例如,

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

相同的报告 gawk

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

与此相反file/bin/echo是:

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

本质上,我想知道executable文件和shared object文件之间有什么区别。

kos*_*kos 16

Tl;博士

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


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

  • 使用静态链接:编译源代码中包含的外部库,并将编译后的库(或链接器视角中的对象)添加到可执行文件本身;
  • 使用动态链接:包含在源代码被编译外部库但一个链接(在链接器的透视图或对象),将编译库加入到可执行文件(和编译库/对象是由链接器在运行时,如果装载需要);

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

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

所以/bin/ntfsck/usr/bin/gawk是技术上编译的库(或链接器视角中的对象),但是,正如人们可能已经预见的那样,没有什么可以阻止共享对象作为可执行文件运行。

在旁注中,还要注意file报告(对于每个报告):

动态链接(使用共享库)

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


1. “编译”的意思是更广泛的接受,包括预处理、编译和链接。


小智 8

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

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

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