따라 다릅니다. Intel의 Linux가 32 비트 응용 프로그램 (적절한 소프트웨어가 설치된 상태)과의 하위 호환성을 유지하므로 IA-32 (Intel 32 비트) 용으로 컴파일 된 것이 amd64에서 실행될 수 있습니다. 다음 code
은 RedHat 7.3 32 비트 시스템 (2002 년경, gcc 버전 2.96)에서 컴파일 된 다음 바이너리가 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를 처음부터 설치"에서 2018 년에 임의의 다른 Linux 배포로 이동하는 것보다 이식성이 향상 될 것입니다. .
amd64 용으로 컴파일 된 것은 32 비트 전용 Linux 릴리스에서는 실행되지 않습니다 (이전 하드웨어는 새 하드웨어에 대해 알지 못함). 라이브러리와 심지어 시스템 호출 도 거꾸로 이식 할 수 없으므로 컴파일 트릭이 필요하거나 이전 컴파일러 등을 구해야 할 수도 있기 때문에 고대 시스템에서 실행되도록 현대 시스템에서 컴파일 된 새 소프트웨어의 경우에도 마찬가지입니다. 이전 시스템에서 컴파일 중입니다. (이것은 고대의 오래된 가상 머신을 유지하는 좋은 이유입니다.)
건축은 중요하다. amd64 (또는 IA-32)는 ARM 또는 MIPS와 크게 다르므로이 중 하나의 바이너리는 다른 바이너리에서 실행될 것으로 예상되지 않습니다. 어셈블리 수준 main
에서 IA-32의 코드 섹션은 다음을 통해 컴파일됩니다 gcc -S code.c
.
main:
pushl %ebp
movl %esp,%ebp
movl $99,%eax
popl %ebp
ret
amd64 시스템이 처리 할 수있는 기능 (Linux 시스템의 경우 amd64와 대조적으로 OpenBSD는 32 비트 바이너리를 지원 하지 않습니다 . 오래된 아치 와의 하위 호환성으로 인해 공격자는 CVE-2014-8866 및 친구와 같이 더 큰 공간을 확보 할 수 있습니다 ). 한편 빅 엔디안 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"를 넣습니다)
compat-glibc.x86_64 1:2.12-4.el7.centos
또는 glibc를 사용하는 오래된 방식에 대한 ABI 변경 (Application Binary Interface) 또는 C ++ 11 또는 기타 C ++ 릴리스로 인한 최근 변경에 대해 걱정할 수도 있습니다. 라이브러리 문제를 피하기 위해 정적 (디스크에서 이진 크기를 크게 증가)을 컴파일 할 수도 있지만 이전 바이너리 배포가 이전 Linux 배포판에서 동적 (RedHat : yes)의 모든 것을 컴파일하는지 여부에 달려 있습니다. 반면에 다른 라이브러리를 사용하기 위해 patchelf
동적 (ELF, 아마도 a.out
형식화 되지 않음 ) 바이너리를 다시 트리거 할 수 있습니다 .
하나! 프로그램을 실행할 수 있다는 것은 한 가지 일이며 실제로 다른 유용한 일을합니다. 오래된 32 비트 인텔 바이너리는 끔찍하고 지원되지 않는 보안 문제가있는 OpenSSL 버전에 의존하거나 보안 문제가 있거나 최신 웹 서버와 전혀 협상 할 수없는 경우가 있습니다. 서버는 이전 프로토콜 및 이전 프로그램의 암호를 거부하거나 SSH 프로토콜 버전 1이 더 이상 지원되지 않거나 ...