Compile position-independent executable with statically linked library on 64 bit machine

好久不见. 提交于 2019-12-11 04:16:45

问题


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:

/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

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?


回答1:


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

The object files in /usr/lib/x86_64-linux-gnu/libcrypto.a need to be compiled with either -fPIC or -fPIE.

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

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.

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

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.


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



来源:https://stackoverflow.com/questions/30573254/compile-position-independent-executable-with-statically-linked-library-on-64-bit

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!