在 64 位机器上使用静态链接库编译位置无关的可执行文件
Compile position-independent executable with statically linked library on 64 bit machine
当我尝试使用以下命令行进行编译时:
g++ code.cpp /usr/lib/x86_64-linux-gnu/libcrypto.a -ldl -Fpie -pie -o executable
我收到以下错误消息:
/usr/bin/ld: /tmp/ccNHn5FA.o: Die Umlagerung von
/tmp/ccNHn5FA.o: error adding symbols: Ungültiger Wert
collect2: error: ld returned 1 exit status
我想知道为什么这不起作用,因为完全相同的命令行在我的 32 位机器上工作正常。我做错了什么?
When I try to compile with the following command-line:
g++ code.cpp /usr/lib/x86_64-linux-gnu/libcrypto.a -ldl -Fpie -pie -o executable
I get the following error message...
编辑:我刚刚注意到 -Fpie
。我不相信那是一面真正的旗帜。 -fPIC
或 -fPIE
是编译器标志。 -pie
是程序的 linker 标志,-shared
是共享对象的等效 linker 标志。
/usr/lib/x86_64-linux-gnu/libcrypto.a
中的目标文件需要用 -fPIC
或 -fPIE
编译。
存档只是目标文件的集合。我相信readelf -rR
会告诉你里面有没有搬迁信息:
$ mkdir objects
$ cd objects/
$ cp /usr/lib/x86_64-linux-gnu/libcrypto.a .
$ ar x libcrypto.a
$ ls
a_bitstr.o cryptlib.o gost_asn1.o rsa_lib.o
...
$ readelf --relocs cryptlib.o
Relocation section '.rela.text' at offset 0x2700 contains 133 entries:
Offset Info Type Sym. Value Sym. Name + Addend
000000000008 000400000002 R_X86_64_PC32 0000000000000000 .bss + 9b
000000000010 001f00000004 R_X86_64_PLT32 0000000000000000 BUF_strdup - 4
...
Relocation section '.rela.data.rel.ro.local' at offset 0x3378 contains 41 entries:
Offset Info Type Sym. Value Sym. Name + Addend
000000000000 000500000001 R_X86_64_64 0000000000000000 .rodata.str1.1 + 3e
000000000008 000500000001 R_X86_64_64 0000000000000000 .rodata.str1.1 + 48
...
Relocation section '.rela.eh_frame' at offset 0x3750 contains 36 entries:
Offset Info Type Sym. Value Sym. Name + Addend
000000000020 000200000002 R_X86_64_PC32 0000000000000000 .text + 0
000000000058 000200000002 R_X86_64_PC32 0000000000000000 .text + b0
...
对于openssl,下载最新的可能最简单,然后用shared
配置得到-fPIC
。另请参阅 OpenSSL wiki 上的 Compilation and Installation。
相关,见。它是在 Android 的上下文中提出的,但它也适用于此处。它解释了为什么 -fPIC
和 -fPIE
都有效。
(comment) Why does this work on my 32 bit machine? Why is the result of the hardening-check (cheks if pie or not) negative when I compile only with -fPIC or -fPIE?
32 位和 64 位有不同的要求,所以我相信 32 位 i386 机器上的东西 "just work"。但是 64 位 x86_64 机器需要 -fPIE
或 -fPIC
。 其他人将不得不为您提供详细信息,因为我不认识他们。这里有一个 question/answer 应该解释一下:Why does gcc not implicitly supply the -fPIC flag when compiling static libraries on x86_64。
您的强化检查可能失败了,因为您编译时使用了重定位信息(-fPIC
或 -fPIE
),但您没有 link 使用重定位信息(-pie
对于程序或 -shared
用于共享对象)。因此 linker.
没有将相关部分添加到 Elf 二进制文件中
相关的,Tobias Klein 有一个名为 Checsec for auditing Elf binaries. Its similar to Microsoft's BinScope 的简洁工具。
我一直用它来验收测试二进制文件。 (我从事软件安全工作,这是我使用最佳实践确保程序符合规范的技巧之一)。
当我尝试使用以下命令行进行编译时:
g++ code.cpp /usr/lib/x86_64-linux-gnu/libcrypto.a -ldl -Fpie -pie -o executable
我收到以下错误消息:
/usr/bin/ld: /tmp/ccNHn5FA.o: Die Umlagerung von
/tmp/ccNHn5FA.o: error adding symbols: Ungültiger Wert
collect2: error: ld returned 1 exit status
我想知道为什么这不起作用,因为完全相同的命令行在我的 32 位机器上工作正常。我做错了什么?
When I try to compile with the following command-line:
g++ code.cpp /usr/lib/x86_64-linux-gnu/libcrypto.a -ldl -Fpie -pie -o executable
I get the following error message...
编辑:我刚刚注意到 -Fpie
。我不相信那是一面真正的旗帜。 -fPIC
或 -fPIE
是编译器标志。 -pie
是程序的 linker 标志,-shared
是共享对象的等效 linker 标志。
/usr/lib/x86_64-linux-gnu/libcrypto.a
中的目标文件需要用 -fPIC
或 -fPIE
编译。
存档只是目标文件的集合。我相信readelf -rR
会告诉你里面有没有搬迁信息:
$ mkdir objects
$ cd objects/
$ cp /usr/lib/x86_64-linux-gnu/libcrypto.a .
$ ar x libcrypto.a
$ ls
a_bitstr.o cryptlib.o gost_asn1.o rsa_lib.o
...
$ readelf --relocs cryptlib.o
Relocation section '.rela.text' at offset 0x2700 contains 133 entries:
Offset Info Type Sym. Value Sym. Name + Addend
000000000008 000400000002 R_X86_64_PC32 0000000000000000 .bss + 9b
000000000010 001f00000004 R_X86_64_PLT32 0000000000000000 BUF_strdup - 4
...
Relocation section '.rela.data.rel.ro.local' at offset 0x3378 contains 41 entries:
Offset Info Type Sym. Value Sym. Name + Addend
000000000000 000500000001 R_X86_64_64 0000000000000000 .rodata.str1.1 + 3e
000000000008 000500000001 R_X86_64_64 0000000000000000 .rodata.str1.1 + 48
...
Relocation section '.rela.eh_frame' at offset 0x3750 contains 36 entries:
Offset Info Type Sym. Value Sym. Name + Addend
000000000020 000200000002 R_X86_64_PC32 0000000000000000 .text + 0
000000000058 000200000002 R_X86_64_PC32 0000000000000000 .text + b0
...
对于openssl,下载最新的可能最简单,然后用shared
配置得到-fPIC
。另请参阅 OpenSSL wiki 上的 Compilation and Installation。
相关,见-fPIC
和 -fPIE
都有效。
(comment) Why does this work on my 32 bit machine? Why is the result of the hardening-check (cheks if pie or not) negative when I compile only with -fPIC or -fPIE?
32 位和 64 位有不同的要求,所以我相信 32 位 i386 机器上的东西 "just work"。但是 64 位 x86_64 机器需要 -fPIE
或 -fPIC
。 其他人将不得不为您提供详细信息,因为我不认识他们。这里有一个 question/answer 应该解释一下:Why does gcc not implicitly supply the -fPIC flag when compiling static libraries on x86_64。
您的强化检查可能失败了,因为您编译时使用了重定位信息(-fPIC
或 -fPIE
),但您没有 link 使用重定位信息(-pie
对于程序或 -shared
用于共享对象)。因此 linker.
相关的,Tobias Klein 有一个名为 Checsec for auditing Elf binaries. Its similar to Microsoft's BinScope 的简洁工具。
我一直用它来验收测试二进制文件。 (我从事软件安全工作,这是我使用最佳实践确保程序符合规范的技巧之一)。