问题
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