Skip to content

Instantly share code, notes, and snippets.

@valgur
Created October 8, 2023 16:43
Show Gist options
  • Select an option

  • Save valgur/28fa0ee0e3c59af301a6e10396981e0c to your computer and use it in GitHub Desktop.

Select an option

Save valgur/28fa0ee0e3c59af301a6e10396981e0c to your computer and use it in GitHub Desktop.
Downloads and extracts all .deb files of libc6-dev and its dependencies for given Ubuntu release
import re
import subprocess
import sys
import tempfile
from pathlib import Path
import requests
def get_package_info(package_name, ubuntu_version, arch):
domain = "https://launchpad.net"
print(f"Loading {package_name} info...")
path = f"/ubuntu/{ubuntu_version}/{arch}/{package_name}"
html = requests.get(f"{domain}{path}").text
latest_version = re.search(rf'href="{path}/([^"]+)"', html).group(1)
info_html = requests.get(f"{domain}{path}/{latest_version}").text
deb_url = re.search(rf'href="([^"]+\.deb)"', info_html).group(1)
depends = []
if '<dl id="depends">' in info_html:
depends_section = info_html.split('<dl id="depends">')[1].split("</dl>")[0]
depends = re.findall(rf'{arch}/([^/"]+)"', depends_section)
return latest_version, deb_url, depends
def get_transitive_dev_packages(root_package, ubuntu_version, arch="amd64"):
def recurse(pkg):
if pkg not in info and pkg.endswith("-dev"):
version, deb_url, depends = get_package_info(pkg, ubuntu_version, arch)
info[pkg] = version, deb_url
for dep in depends:
recurse(dep)
info = {}
recurse(root_package)
return info
def download_dev_packages(output_dir, ubuntu_version, pkg_name, arch="amd64"):
packages = get_transitive_dev_packages(pkg_name, ubuntu_version, arch)
for package, (version, deb_url) in packages.items():
print(f"Downloading {package} {version}...")
deb = requests.get(deb_url).content
with open(f"{output_dir}/{package}_{version}_{arch}.deb", "wb") as f:
f.write(deb)
def extract_deb(deb_path, output_dir):
return subprocess.check_call(["dpkg-deb", "-xv", deb_path, output_dir])
def main(argv):
output_dir = Path(argv[1])
ubuntu_version = argv[2]
pkg = "libc6-dev"
with tempfile.TemporaryDirectory() as temp_dir:
temp_dir = Path(temp_dir)
temp_dir.mkdir(exist_ok=True, parents=True)
download_dev_packages(temp_dir, ubuntu_version, pkg)
for deb in temp_dir.glob("*.deb"):
extract_deb(deb, output_dir)
if __name__ == "__main__":
main(sys.argv)
@valgur
Copy link
Copy Markdown
Author

valgur commented Oct 8, 2023

The list of symbols defined in the .a and .so files can then be dumped from the extracted files using:

find usr -name '*.a' -type f | xargs objdump -t | grep ' F .text' | awk 'NF>1{print $NF}' | sort -u > static.list
find usr -name '*.so' -type f | xargs objdump -T | grep ' DF .text' | awk 'NF>1{print $NF}' | sort -u > shared.list

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment