在64位计算机上使用静态链接库编译与位置无关的可执行文件 [英] Compile position-independent executable with statically linked library on 64 bit machine
问题描述
当我尝试使用以下命令行进行编译时:
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
我收到以下错误消息:
/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位计算机上完全相同的命令行可以正常工作.我在做什么错了?
I am wondering why this does not work, because exactly the same command line on my 32 bit machine works fine. What am I doing wrong?
推荐答案
当我尝试使用以下命令行进行编译时:
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
是程序的链接器标志,而-shared
是共享对象的等效链接器标志.
EDIT: I just noticed -Fpie
. I don't believe that's a real flag. -fPIC
or -fPIE
are compiler flags. -pie
is a linker flag for programs, and -shared
is the equivalent linker flag for shared objects.
/usr/lib/x86_64-linux-gnu/libcrypto.a
中的目标文件需要使用-fPIC
或-fPIE
进行编译.
The object files in /usr/lib/x86_64-linux-gnu/libcrypto.a
need to be compiled with either -fPIC
or -fPIE
.
档案只是目标文件的集合.我相信readelf -rR
会告诉您其中是否有搬迁信息:
An archive is just a collection of object files. I believe readelf -rR
will tell you if there's relocation information in them:
$ 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上的编译和安装.
For openssl, its probably easiest to download the latest, and then configure with shared
to get -fPIC
. Also see Compilation and Installation on the OpenSSL wiki.
相关内容,请参见位置独立的可执行文件.它是在Android环境中提出的,但它也适用于Android.解释了为什么-fPIC
和-fPIE
都起作用.
Related, see Position Independent Executables. It was asked in the context of Android, but it applies here as well. It explains why both -fPIC
and -fPIE
work.
(注释)为什么这在我的32位计算机上有效?当我仅使用-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机器上的东西可以正常工作".但是64位x86_64机器需要-fPIE
或-fPIC
. 其他人将不得不向您提供详细信息,因为我不了解它们.这是一个应该对其进行解释的问题/答案:
32-bit and 64-bit have different requirements, so I believe things "just work" on 32-bit i386 machines. But 64-bit x86_64 machines need -fPIE
or -fPIC
. Someone else will have to give you the details because I don't know them. Here's an question/answer that should explain it: Why does gcc not implicitly supply the -fPIC flag when compiling static libraries on x86_64.
您的加固检查可能失败了,因为您使用重定位信息(-fPIC
或-fPIE
)进行了编译,但未链接重定位信息(程序为-pie
或共享对象为-shared
).因此,链接器并未将相关部分添加到Elf二进制文件中.
Your hardening checks probably failed because you compiled with relocation information (-fPIC
or -fPIE
), but you did not link with relocation information (-pie
for programs or -shared
for shared objects). So the relevant sections were not added to the Elf binary by the linker.
相关的,Tobias Klein有一个名为 Checsec 的简洁工具,用于审核Elf二进制文件.它类似于Microsoft的 BinScope .
Related, Tobias Klein has a neat tool called Checsec for auditing Elf binaries. Its similar to Microsoft's BinScope.
我一直使用它来接受测试二进制文件. (我从事软件安全方面的工作,这是我确保使用最佳实践构建符合规范的程序的窍门之一.
I use it all the time to acceptance test binaries. (I work in software security, and this is one of my tricks to ensure programs are built to specification using best practices).
这篇关于在64位计算机上使用静态链接库编译与位置无关的可执行文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!