#!/usr/bin/env python3 """ dll2def.py - Create a module-definition (.def) file from a Windows DLL. Usage ----- python dll2def.py library.dll [optional_output.def] The script writes a .def file next to the DLL (or to the explicitly supplied output path) and prints a short summary. Requires -------- pip install pefile """ from __future__ import annotations import argparse import sys from pathlib import Path import pefile def build_def_text(dll_path: Path) -> str: """Return the complete .def file text for *dll_path*.""" pe = pefile.PE(dll_path.as_posix(), fast_load=True) pe.parse_data_directories(directories=[pefile.DIRECTORY_ENTRY['IMAGE_DIRECTORY_ENTRY_EXPORT']]) if not hasattr(pe, 'DIRECTORY_ENTRY_EXPORT'): raise ValueError(f"'{dll_path.name}' has no export table.") lines: list[str] = [] lines.append(f'LIBRARY "{dll_path.name}"') lines.append('EXPORTS') for sym in pe.DIRECTORY_ENTRY_EXPORT.symbols: # Symbol names can be None (export-by-ordinal only) name = sym.name.decode(errors='replace') if sym.name else f'#{sym.ordinal}' lines.append(f' {name}') # A final newline keeps MSVC's LIB.EXE happy return '\n'.join(lines) + '\n' def parse_args(argv: list[str]) -> argparse.Namespace: p = argparse.ArgumentParser(description="Generate a .def file from a DLL's export table.") p.add_argument('dll', type=Path, help='Path to the input DLL') p.add_argument('out', nargs='?', type=Path, help='Optional .def output path (default: DLL name with .def extension)') return p.parse_args(argv) def main(argv: list[str] | None = None) -> None: args = parse_args(argv or sys.argv[1:]) dll_path: Path = args.dll.expanduser().resolve() if not dll_path.is_file(): sys.exit(f"Error: '{dll_path}' is not a file.") out_path: Path = (args.out or dll_path.with_suffix('.def')).expanduser().resolve() try: def_text = build_def_text(dll_path) except Exception as exc: sys.exit(f"Failed to read exports: {exc}") out_path.write_text(def_text, encoding='utf-8') print(f"Wrote {out_path} ({len(def_text.splitlines()) - 2} exports)") if __name__ == '__main__': main()