aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/win-dll.py
blob: e77e7ed12effc5543520439caea63d5ba977bcaf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#!/usr/bin/env python3
# Get non-system DLL dependencies
import pefile
import os
import os.path
import sys

def is_system(filename):
    """Return true if the file is a system file. Very ad-hoc."""
    return filename.startswith('/c/Windows')

def get_imports(filename):
    """Return list of dll imports"""
    if is_system(filename):
        return []
    with pefile.PE(filename) as pe:
        try:
            imports = pe.DIRECTORY_ENTRY_IMPORT
        except AttributeError:
            imports = []
        return [e.dll.decode() for e in imports]

def search_dll(name, libraries_path):
    """Search :param name: in :param libraries_path:"""
    for path in libraries_path:
        filename = os.path.join(path, name)
        if os.path.isfile(filename):
            return filename
    return None

def get_dependencies(name, libraries_path, cache):
    """Return the non-system dll dependencies of :param name:"""
    deps = get_imports(name)
    res = []
    for lib in deps:
        if lib in cache:
            continue
        # Search on the path
        filename = search_dll(lib, libraries_path)
        # Always add in the cache
        cache[lib] = filename
        if filename is not None:
            if not is_system(filename):
                res.append(filename)
            res.extend(get_dependencies(filename, libraries_path, cache))
    return res

if __name__ == '__main__':
    if len(sys.argv) != 2:
        print('usage: {} ldd-file'.format(sys.argv[0]))
        sys.exit(1)

    libraries_path = os.environ['PATH'].split(os.pathsep)
    filename = sys.argv[1]
    cache = {}
    res = get_dependencies(filename, libraries_path, cache)
    for f in res:
        print(f)