在Linux的一个“风格”上编译的Linux可执行文件是否会在另一个上运行?

Modified on: Thu, 12 Jul 2018 11:09:00 +0800

在一种Linux上编译的一个小的,非常简单的程序(如下面所示的程序)的可执行文件是否会以不同的风格运行?还是需要重新编译?

机器架构在这种情况下是否重要?

int main()
{
  return (99);
}
作者:TRiG,JCDeen

最佳答案

这取决于。为IA-32(英特尔32位)编译的东西可以在amd64上运行,因为英特尔上的Linux保留了与32位应用程序(安装了合适的软件)的向后兼容性。这是在RedHat 7.3 32位系统(大约2002年,gcc版本2.96)上编译的code,然后将二进制文件复制到Centos 7.4 64位系统(大约2017年)并运行:

-bash-4.2$ file code
code: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.2.5, not stripped
-bash-4.2$ ./code
-bash: ./code: /lib/ld-linux.so.2: bad ELF interpreter: No such file or directory
-bash-4.2$ sudo yum -y install glibc.i686
...
-bash-4.2$ ./code ; echo $?
99

古老的RedHat 7.3到Centos 7.4(基本上是RedHat Enterprise Linux 7.4)保留在同一个“发行版”系列中,因此可能比从2002年从一些随机的“Linux从头开始”安装到其他一些随机Linux更具可移植性分发于2018年。

为amd64编译的东西不能在仅32位的Linux版本上运行(旧硬件不了解新硬件)。在现代系统上编译的新软件也适用于古老的东西,如库和甚至系统调用可能不是向后可移植的,因此可能需要编译技巧,或者获得旧的编译器等,或者可能改为编译旧系统。 (这是保持古老旧事物的虚拟机的一个很好的理由。)

架构确实很重要; amd64(或IA-32)与ARM或MIPS有很大不同,因此其中一个的二进制文件不会在另一个上运行。在汇编级别,IA-32上代码的main部分通过gcc -S code.c编译到

main: pushl %ebp movl %esp,%ebp movl $99,%eax popl %ebp ret

amd64系统可以处理(在Linux系统上 - 相比之下,amd64 上的OpenBSD 不支持32位二进制文​​件;向后兼容旧archs确实可以让攻击者摆脱空间,例如< a href =“http://cve.circl.lu/cve/CVE-2014-8866”rel =“noreferrer”> CVE-2014-8866 和朋友们)。同时在big-endian MIPS系统 main上编译到:

main: .frame $fp,8,$31 .mask 0x40000000,-4 .fmask 0x00000000,0 .set noreorder .set nomacro addiu $sp,$sp,-8 sw $fp,4($sp) move $fp,$sp li $2,99 move $sp,$fp lw $fp,4($sp) addiu $sp,$sp,8 j $31 nop

英特尔处理器不知道如何处理,同样适用于MIPS上的英特尔组装。

您可以使用QEMU或其他模拟器来运行外部代码(可能非常非常慢)。

然而!您的代码是非常简单的代码,因此可移植性问题比其他任何代码都少;程序通常使用随时间变化的库(glibc,openssl,...);对于那些人可能还需要安装各种库的旧版本(例如RedHat通常将“compat”放在包名称中的某处)

main:
    pushl %ebp
    movl %esp,%ebp
    movl $99,%eax
    popl %ebp
    ret

或者可能担心ABI更改(应用程序二进制接口)用于使用glibc的旧事物,或者最近由于C ++ 11或其他C ++版本而发生的更改。也可以编译静态(大大增加磁盘上的二进制大小)以尽量避免库问题,不过一些旧的二进制文件是否这样做取决于旧的Linux发行版是否正在编译大多数动态(RedHat:是)。另一方面,patchelf之类的东西可以重新激活动态(ELF,但可能不是a.out格式)二进制文件来使用其他库。

然而!能够运行一个程序是一回事,实际上做另一个有用的东西。旧的32位英特尔二进制文件可能存在安全问题,如果它们依赖于一个版本的OpenSSL,其中存在一些可怕且未向后移植的安全问题,或者该程序可能无法与现代Web服务器进行协商(如现代服务器拒绝旧程序的旧协议和密码),或者不再支持SSH协议版本1,或者......

作者:Community,thrig

相关问答

添加新评论