diff --git a/.dockerignore b/.dockerignore index 9f75ecdd1..f9e90df43 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,2 +1,16 @@ # venv .venv/ + +# ignore binaries that are potentially tainted by the host system +# E.g. the binary could reference source code on the host system +# this is a problem because inside docker we won't have access to +# the host system +tests/**/binaries/*.o +tests/**/binaries/*.out +tests/**/binaries/gosample.x* +tests/**/binaries/div_zero_binary/core +tests/**/binaries/div_zero_binary/binary +!tests/**/binaries/*.go + +# ignore QEMU test images (could also be tainted) +tests/qemu-tests/images diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 7b7652ff3..e2ea8bf02 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -6,8 +6,7 @@ jobs: strategy: fail-fast: false matrix: - # archlinux is removed for now until we use virtualenv for deps install - images: [ubuntu18.04, ubuntu20.04, ubuntu22.04, debian10, debian11] + images: [ubuntu18.04, ubuntu20.04, ubuntu22.04, debian10, debian11, archlinux] runs-on: ubuntu-latest timeout-minutes: 30 @@ -23,7 +22,7 @@ jobs: key: ${{ matrix.images }}-cache-images-{hash} - name: Docker Build ${{ matrix.images }} - run: docker-compose pull ${{ matrix.images }} + run: docker-compose build ${{ matrix.images }} - name: Test on ${{ matrix.images }} run: docker-compose run ${{ matrix.images }} ./tests.sh diff --git a/gdbinit.py b/gdbinit.py index 2dec8b7c6..8bf44d21a 100644 --- a/gdbinit.py +++ b/gdbinit.py @@ -2,6 +2,7 @@ import cProfile import glob import locale import os +import site import sys import time from glob import glob @@ -30,6 +31,14 @@ if not os.path.exists(venv_path): site_pkgs_path = glob(os.path.join(venv_path, "lib/*/site-packages"))[0] +# add virtualenv's site-packages to sys.path and run .pth files +site.addsitedir(site_pkgs_path) + +# remove existing, system-level site-packages from sys.path +for site_packages in site.getsitepackages(): + if site_packages in sys.path: + sys.path.remove(site_packages) + # Set virtualenv's bin path (needed for utility tools like ropper, pwntools etc) bin_path = os.path.join(venv_path, "bin") os.environ["PATH"] = bin_path + os.pathsep + os.environ.get("PATH") @@ -37,7 +46,6 @@ os.environ["PATH"] = bin_path + os.pathsep + os.environ.get("PATH") # Add gdb-pt-dump directory to sys.path so it can be imported gdbpt = path.join(directory, "gdb-pt-dump") sys.path.append(directory) -sys.path.append(site_pkgs_path) sys.path.append(gdbpt) # warn if the user has different encoding than utf-8 diff --git a/pwndbg/wrappers/readelf.py b/pwndbg/wrappers/readelf.py index e7c5df510..3f7364081 100644 --- a/pwndbg/wrappers/readelf.py +++ b/pwndbg/wrappers/readelf.py @@ -23,7 +23,7 @@ def get_got_entry(local_path: str) -> Dict[RelocationType, List[str]]: entries: Dict[RelocationType, List[str]] = {category: [] for category in RelocationType} for line in readelf_out.splitlines(): - if not line or not line[0].isdigit(): + if not line or not line[0].isdigit() or " " not in line: continue category = line.split()[2] # TODO/FIXME: There's a bug here, somehow the IRELATIVE relocation might point to somewhere in .data.rel.ro, which is not in .got or .got.plt diff --git a/setup-dev.sh b/setup-dev.sh index b86caf9f8..75fcd20c1 100755 --- a/setup-dev.sh +++ b/setup-dev.sh @@ -120,9 +120,6 @@ Include = /etc/pacman.d/mirrorlist [extra-debug] Include = /etc/pacman.d/mirrorlist -[community-debug] -Include = /etc/pacman.d/mirrorlist - [multilib-debug] Include = /etc/pacman.d/mirrorlist EOF diff --git a/tests/gdb-tests/tests/test_commands_elf.py b/tests/gdb-tests/tests/test_commands_elf.py index 34e3d6e5a..c8096b2eb 100644 --- a/tests/gdb-tests/tests/test_commands_elf.py +++ b/tests/gdb-tests/tests/test_commands_elf.py @@ -131,7 +131,8 @@ def test_command_got_for_target_binary_and_loaded_library(): assert out[2] == "" assert re.match(r"State of the GOT of .*/libc.so.6:", out[3]) m = re.match( - r"GOT protection: Partial RELRO \| Found (\d+) GOT entries passing the filter", out[4] + r"GOT protection: (?:Partial|Full) RELRO \| Found (\d+) GOT entries passing the filter", + out[4], ) got_entries_count = int(m.group(1)) assert got_entries_count > 0 @@ -145,7 +146,8 @@ def test_command_got_for_target_binary_and_loaded_library(): assert out[1] == "" assert re.match(r"State of the GOT of .*/libc.so.6:", out[2]) m = re.match( - r"GOT protection: Partial RELRO \| Found (\d+) GOT entries passing the filter", out[3] + r"GOT protection: (?:Partial|Full) RELRO \| Found (\d+) GOT entries passing the filter", + out[3], ) assert int(m.group(1)) > got_entries_count # We should have more entries now got_entries_count = int(m.group(1)) @@ -161,7 +163,8 @@ def test_command_got_for_target_binary_and_loaded_library(): assert out[3] == "" assert re.match(r"State of the GOT of .*/libc.so.6:", out[4]) m = re.match( - r"GOT protection: Partial RELRO \| Found (\d+) GOT entries passing the filter", out[5] + r"GOT protection: (?:Partial|Full) RELRO \| Found (\d+) GOT entries passing the filter", + out[5], ) got_entries_count = int(m.group(1)) assert len(out) == (6 + got_entries_count) @@ -176,18 +179,20 @@ def test_command_got_for_target_binary_and_loaded_library(): assert out[2] == "" assert re.match(r"State of the GOT of .*/ld-linux-x86-64.so.2:", out[3]) m = re.match( - r"GOT protection: Partial RELRO \| Found (\d+) GOT entries passing the filter", out[4] + r"GOT protection: (?:Partial|Full) RELRO \| Found (\d+) GOT entries passing the filter", + out[4], ) got_entries_count = int(m.group(1)) for i in range(got_entries_count): assert re.match(r"\[0x[0-9a-f]+\] .* -> .*", out[5 + i]) - assert out[5 + i + 1] == "" + assert out[5 + got_entries_count] == "" # Second should be libc.so.6 - out = out[5 + i + 2 :] + out = out[5 + got_entries_count + 1 :] assert re.match(r"State of the GOT of .*/libc.so.6:", out[0]) m = re.match( - r"GOT protection: Partial RELRO \| Found (\d+) GOT entries passing the filter", out[1] + r"GOT protection: (?:Partial|Full) RELRO \| Found (\d+) GOT entries passing the filter", + out[1], ) got_entries_count = int(m.group(1)) assert len(out) == (2 + got_entries_count) @@ -207,18 +212,20 @@ def test_command_got_for_target_binary_and_loaded_library(): # Second should be ld-linux-x86-64.so.2 assert re.match(r"State of the GOT of .*/ld-linux-x86-64.so.2:", out[0]) m = re.match( - r"GOT protection: Partial RELRO \| Found (\d+) GOT entries passing the filter", out[1] + r"GOT protection: (?:Partial|Full) RELRO \| Found (\d+) GOT entries passing the filter", + out[1], ) got_entries_count = int(m.group(1)) for i in range(got_entries_count): assert re.match(r"\[0x[0-9a-f]+\] .* -> .*", out[2 + i]) - assert out[2 + i + 1] == "" - out = out[2 + i + 2 :] + assert out[2 + got_entries_count] == "" + out = out[2 + got_entries_count + 1 :] # Third should be libc.so.6 assert re.match(r"State of the GOT of .*/libc.so.6:", out[0]) m = re.match( - r"GOT protection: Partial RELRO \| Found (\d+) GOT entries passing the filter", out[1] + r"GOT protection: (?:Partial|Full) RELRO \| Found (\d+) GOT entries passing the filter", + out[1], ) got_entries_count = int(m.group(1)) assert len(out) == (2 + got_entries_count) @@ -234,8 +241,12 @@ def test_command_got_for_target_binary_and_loaded_library(): assert re.match(r"\[0x[0-9a-f]+\] puts@GLIBC_[0-9.]+ -> .*", out[4]) assert out[5] == "" assert re.match(r"State of the GOT of .*/ld-linux-x86-64.so.2:", out[6]) - assert out[7] == "GOT protection: Partial RELRO | Found 0 GOT entries passing the filter" + assert re.match( + r"GOT protection: (?:Partial|Full) RELRO \| Found 0 GOT entries passing the filter", out[7] + ) assert out[8] == "" assert re.match(r"State of the GOT of .*/libc.so.6:", out[9]) - assert out[10] == "GOT protection: Partial RELRO | Found 0 GOT entries passing the filter" + assert re.match( + r"GOT protection: (?:Partial|Full) RELRO \| Found 0 GOT entries passing the filter", out[10] + ) assert len(out) == 11