LIEF
LIEF copied to clipboard
Rewriting NEEDED section creates broken .so
Describe the bug
Modifying the NEEDED section in libcrypto.so
mangles the version needs section.
Original:
Version needs section '.gnu.version_r' contains 2 entries:
Addr: 0x0000000000037240 Offset: 0x037240 Link: 4 (.dynstr)
000000: Version: 1 File: libdl.so.2 Cnt: 1
0x0010: Name: GLIBC_2.2.5 Flags: none Version: 9
0x0020: Version: 1 File: libc.so.6 Cnt: 5
0x0030: Name: GLIBC_2.4 Flags: none Version: 10
0x0040: Name: GLIBC_2.3 Flags: none Version: 8
0x0050: Name: GLIBC_2.7 Flags: none Version: 7
0x0060: Name: GLIBC_2.3.4 Flags: none Version: 6
0x0070: Name: GLIBC_2.2.5 Flags: none Version: 5
Modified:
Version needs section '.gnu.version_r' contains 2 entries:
Addr: 0x0000000000037240 Offset: 0x037240 Link: 4 (.dynstr)
000000: Version: 1120 File: Cnt: 0
0x0020: Version: 1 File: libc.so.6 Cnt: 5
0x0030: Name: GLIBC_2.4 Flags: none Version: 10
0x0040: Name: GLIBC_2.3 Flags: none Version: 8
0x0050: Name: GLIBC_2.7 Flags: none Version: 7
0x0060: Name: GLIBC_2.3.4 Flags: none Version: 6
0x0070: Name: GLIBC_2.2.5 Flags: none Version: 5
Running ldd
on the modified .so produces the following error message:
/tmp/libcrypto_modified.so: error while loading shared libraries: /tmp/libcrypto_modified.so: unsupported version 1120 of Verneed record
To Reproduce Steps to reproduce the behavior:
Run the following script:
import lief
def replace_needed(file_name,
out_file_name,
so_name,
new_so_name):
elf = lief.parse(file_name)
for lib in elf.dynamic_entries:
if lib.tag == lief.ELF.DYNAMIC_TAGS.NEEDED and lib.name == so_name:
print("Replacing needed library: {} with {} in {}".format(
lib.name, new_so_name, file_name))
lib.name = new_so_name
elf.write(out_file_name)
replace_needed("/usr/lib64/libcrypto.so.1.0.1e",
"/tmp/libcrypto_modified.so",
"libz.so.1",
"libz.so.1")
Check the resulting /tmp/libcrypto_modified.so
file with readelf -V
. The original libcrypto.so.1.0.1e
is from the quay.io/pypa/manylinux2010_x86_64
image so the easiest might be to run the example in that Docker image. I can also upload the .so somewhere if you prefer.
Expected behavior A valid .so file.
Environment (please complete the following information):
- System and Version : CentOS 6.10 (quay.io/pypa/manylinux2010_x86_64)
- Target format: ELF
- LIEF commit version: 0.10.1-bfe5414
I think it is related to https://github.com/lief-project/LIEF/issues/369 and https://github.com/lief-project/LIEF/issues/239
Indeed, the modified library seems to suffer from the same dynamic symbol number mismatch. I tried the workaround posted in #239 to use lief.ELF.DYNSYM_COUNT_METHODS.SECTION
and that yields the correct number of symbols, but it doesn't change the invalid Verneed record. There might be two separate bugs here.
Should have been fixed with the refactoring of the ELF builder.