You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
pwndbg/tests/gdb-tests/tests/test_glibc.py

59 lines
2.6 KiB
Python

from __future__ import annotations
import os
import shutil
import tempfile
import gdb
import pytest
import pwndbg.gdblib.info
import pwndbg.glibc
import tests
# We used the same binary as heap tests since it will use libc, and many functions are mainly for debugging the heap
HEAP_MALLOC_CHUNK = tests.binaries.get("heap_malloc_chunk.out")
@pytest.mark.parametrize(
"have_debugging_information", [True, False], ids=["does-not-have-(*)", "have-(*)"]
)
def test_parsing_info_sharedlibrary_to_find_libc_filename(start_binary, have_debugging_information):
# Check if we can find the libc if nothing special happens
if not have_debugging_information:
# Make sure the (*) in the output of `info sharedlibrary` won't affect the result
gdb.execute("set debug-file-directory")
start_binary(HEAP_MALLOC_CHUNK)
gdb.execute("break break_here")
gdb.execute("continue")
if not have_debugging_information:
assert "(*)" in pwndbg.gdblib.info.sharedlibrary()
libc_path = pwndbg.glibc.get_libc_filename_from_info_sharedlibrary()
assert libc_path is not None
# Create 3 copies of the libc with the filenames: libc-2.36.so, libc6_2.36-0ubuntu4_amd64.so, libc.so
# Note: The version in the above filename doesn't matter, just some tests for the common libc names we might use with LD_PRELOAD
test_libc_names = ["libc-2.36.so", "libc6_2.36-0ubuntu4_amd64.so", "libc.so"]
with tempfile.TemporaryDirectory() as tmp_dir:
for test_libc_name in test_libc_names:
test_libc_path = os.path.join(tmp_dir, test_libc_name)
shutil.copy(libc_path, test_libc_path)
gdb.execute(f"set environment LD_PRELOAD={test_libc_path}")
start_binary(HEAP_MALLOC_CHUNK)
gdb.execute("break break_here")
gdb.execute("continue")
# Check if we can find the libc loaded by LD_PRELOAD
if not have_debugging_information:
assert "(*)" in pwndbg.gdblib.info.sharedlibrary()
assert pwndbg.glibc.get_libc_filename_from_info_sharedlibrary() == test_libc_path
# Unfortunatly, if we used LD_PRELOAD to load libc, we might cannot find the libc's filename
# In this case, the function should return None instead of crashing
test_libc_path = os.path.join(tmp_dir, "a_weird_name_that_does_not_look_like_a_1ibc.so")
shutil.copy(libc_path, test_libc_path)
gdb.execute(f"set environment LD_PRELOAD={test_libc_path}")
start_binary(HEAP_MALLOC_CHUNK)
gdb.execute("break break_here")
gdb.execute("continue")
assert pwndbg.glibc.get_libc_filename_from_info_sharedlibrary() is None