可执行文件与共享对象


13

我在这样做时注意到了一些事情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文件之间的区别。


Answers:


14

l

除了已编译的可执行文件可能链接到共享对象而不链接到可执行文件之外,没有任何区别。


通常,有两种方法可编译1可执行文件:

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

使用这些方法中的每一种都有优点/缺点,但这不是问题的重点。

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

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

另外,请注意 file报告(针对每个报告):

动态链接(使用共享库)

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


1.“编译”旨在获得更广泛的接受,包括预处理,编译和链接。


1
动态链接到其他共享对象,在OS中?还是共享库本身?
Dr.jacky

@ Mr.Hyde在OS中,更具体地说,是在链接器中必须预先配置的位置,以便链接器可以在需要时在运行时加载它们。参见此处第3.2章。
kos 2015年

实际上,可以使用dlopen:D 示例
Adam Zahran

6

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

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

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


有趣的答案。缺少一些资源(如果您添加了一些链接,尤其是对于入口点部分,那会很好),但是我搜索了一些关于此的stackoverflow问题。但是绝对是个好答案。
Sergiy Kolodyazhnyy
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.