find_deps.py 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. #!/usr/bin/env python3
  2. #
  3. # Copyright (C) 2024 Stefan Weil
  4. #
  5. # SPDX-License-Identifier: MIT
  6. #
  7. # Find the DLL files which are required for a given set of
  8. # Windows executables and libraries.
  9. import argparse
  10. import os
  11. import pefile
  12. VERBOSE = False
  13. def find_dependencies(binary, search_path, analyzed_deps):
  14. pe = pefile.PE(binary)
  15. pe.parse_data_directories()
  16. if VERBOSE:
  17. print(f'{binary}:')
  18. # print(pe.dump_info())
  19. for entry in pe.DIRECTORY_ENTRY_IMPORT:
  20. name = entry.dll.decode('utf-8')
  21. if name in analyzed_deps:
  22. if VERBOSE:
  23. print(f'skip {name} (already analyzed)')
  24. continue
  25. analyzed_deps.add(name)
  26. fullpath = os.path.join(search_path, name)
  27. if not os.path.exists(fullpath):
  28. # Not found, maybe system DLL. Skip it.
  29. if VERBOSE:
  30. print(f'skip {name} (not found, maybe system DLL)')
  31. continue
  32. print(fullpath)
  33. analyzed_deps = find_dependencies(fullpath, search_path, analyzed_deps)
  34. return analyzed_deps
  35. def main():
  36. """
  37. Command-line interface for universal dependency scanner.
  38. """
  39. parser = argparse.ArgumentParser(description='Find and copy DLL dependencies')
  40. parser.add_argument('files', nargs='+', help='Paths to executable or library files')
  41. parser.add_argument('--dlldir', dest='dlldir', default='/mingw64/bin/',
  42. help='path to dll files')
  43. args = parser.parse_args()
  44. # try:
  45. # Find dependencies
  46. analyzed_deps = set()
  47. for binary in args.files:
  48. if True:
  49. analyzed_deps = find_dependencies(binary, args.dlldir, analyzed_deps)
  50. # except:
  51. # print(f'error: failed to find dependencies for {binary}')
  52. if __name__ == '__main__':
  53. main()