在 64 位机器上用静态链接库编译位置无关的可执行文件 [英] Compile position-independent executable with statically linked library on 64 bit machine

查看:31
本文介绍了在 64 位机器上用静态链接库编译位置无关的可执行文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我尝试使用以下命令行进行编译时:

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...

EDIT:我刚刚注意到 -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 的上下文中提出的,但它也适用于此.它解释了为什么 -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.

(comment) 为什么这可以在我的 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.其他人将不得不向您提供详细信息,因为我不认识他们. 这是一个应该解释它的问题/答案:为什么 gcc 在 x86_64 上编译静态库时不隐式提供 -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 二进制文件.它类似于微软的 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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆