Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
nurupo committed Jun 2, 2020
1 parent 7d82fe7 commit 0fa5b8f
Showing 1 changed file with 48 additions and 17 deletions.
65 changes: 48 additions & 17 deletions mingw_ldd/mingw_ldd.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
# THE SOFTWARE.

import argparse
import concurrent.futures
import os
import pefile
import sys
Expand All @@ -45,36 +46,66 @@ def get_dependency(pe_data):
return deps


def _find_dll(dll, dlls, dll_lookup_dirs, arch):
# (found, new_dll_path?, new_pe_data)
dll_lower = dll.lower()
if dll_lower in dlls:
return (True, None, None)
for dir in dll_lookup_dirs:
dll_path = find_file_ignore_case(dir, dll_lower)
if not dll_path:
continue
new_pe_data = pefile.PE(dll_path)
if new_pe_data.FILE_HEADER.Machine == arch:
return (True, dll_path, new_pe_data)
return (False, None, None)


def dep_tree(pe, dll_lookup_dirs):
dlls = {}
deps = {}
dlls_blacklist = []
pe_data = pefile.PE(pe)
arch = pe_data.FILE_HEADER.Machine

def find_dll(dll):
# (found, new_dll_path?, new_pe_data)
dll_lower = dll.lower()
if dll_lower in dlls:
return (True, None, None)
for dir in dll_lookup_dirs:
dll_path = find_file_ignore_case(dir, dll_lower)
if not dll_path:
continue
new_pe_data = pefile.PE(dll_path)
if new_pe_data.FILE_HEADER.Machine == arch:
return (True, dll_path, new_pe_data)
return (False, None, None)

def dep_tree_impl(pe, pe_data):
pe = os.path.abspath(pe)
if pe in deps:
return
deps[pe] = []
for dll in get_dependency(pe_data):
dll_to_future_result = []
with concurrent.futures.ProcessPoolExecutor() as executor:
future_to_dll = {executor.submit(_find_dll, dll, dlls, dll_lookup_dirs, arch): dll for dll in get_dependency(pe_data)}
dll_to_future_result = [(future_to_dll[future], future.result()) for future in concurrent.futures.as_completed(future_to_dll)]
for (dll, (found_dll, new_dll_path, _)) in dll_to_future_result:
deps[pe].append(dll)
dll_lower = dll.lower()
if dll_lower in dlls:
deps[pe].append(dll)
# it's a cached dll, nothing to do
if found_dll and not new_dll_path:
continue
dlls[dll_lower] = 'not found'
for dir in dll_lookup_dirs:
dll_path = find_file_ignore_case(dir, dll)
if not dll_path or dll_path in dlls_blacklist:
continue
new_pe_data = pefile.PE(dll_path)
if new_pe_data.FILE_HEADER.Machine == arch:
dlls[dll_lower] = dll_path
dep_tree_impl(dll_path, new_pe_data)
break
else:
dlls_blacklist.append(dll_path)
deps[pe].append(dll)
# it's a new dll, cache it
elif found_dll and new_dll_path:
dlls[dll_lower] = new_dll_path
# dll wasn't found, cache that it wasn't found
elif not found_dll:
dlls[dll_lower] = 'not found'
# recursively process newly found dlls
for (dll, (found_dll, new_dll_path, new_pe_data)) in dll_to_future_result:
if found_dll and new_dll_path:
dep_tree_impl(new_dll_path, new_pe_data)

dep_tree_impl(pe, pe_data)
return (dlls, deps)
Expand Down

0 comments on commit 0fa5b8f

Please sign in to comment.