Retrieve Python version from pyd built without such an information -
on windows, have python library (*.pyd), , need check linked python version. can python 2.7.x or 3.x.
when run using win32api
(adapted here: https://stackoverflow.com/a/20064736/2741329):
def get_pyd_python_version(pyd_path): """ python version required passed pyd library """ import win32api print("- pyd path: %s" % str(pyd_path)) try: info = win32api.getfileversioninfo(pyd_path, '\\') except win32api.error e: print(str(e.strerror) + " > " + pyd_path) return "" python_version = "%s.%s.%s.%s" % ( str(win32api.hiword(info['fileversionms'])), str(win32api.loword(info['fileversionms'])), str(win32api.hiword(info['fileversionls'])), str(win32api.loword(info['fileversionls']))) return python_version
i get: the specified resource type cannot found in image file.
the same function works expected other "properly" built pyd libraries (e.g., win32api.pyd
).
since dependency walker used incomplete pyd shows dll, wondering if there way programmatically (with python) version info such fact.
--- edit ---
based both on pefile
library , on @vyktor answer, have got working downloading fork: https://github.com/blackxeronic/pefile_py3 , using such approach (that checks architecture):
from __future__ import absolute_import, print_function import sys sys.path.append('./pefile_py3-master') import pefile print("python env: v.%s.%s" % (sys.version_info.major, sys.version_info.minor)) print("pefile lib: v.%s" % pefile.__version__) dll_path = r'c:/python27/dlls/bz2.pyd' print("path pyd: %s" % dll_path) pe = pefile.pe(dll_path) if pe.is_dll(): entry in pe.directory_entry_import: if "python" in entry.dll: if pe.file_header.machine == 0x14c: arch = "x86" elif pe.file_header.machine == 0x8664: arch = "x64" else: arch = "unknown" print(">>> importing %s: v.%s [%s] <<<" % (entry.dll, entry.dll[6:8], arch))
this using python 3.4.3 interpreter:
python env: v.3.4 pefile lib: v.1.2.10-139 path pyd: c:/python27/dlls/bz2.pyd >>> importing python27.dll: v.27 [x86] <<<
i testing on c:\python32\dlls\bz2.pyd
, haven't seen python related info in details (file renamed .dll
):
the relevant information python version inside iat:
so have parse pe file , import dll names. there few questions loading iat file , did using pefile
extension (suggested gmas80 in comment):
c:\python27>python.exe python 2.7.2 (default, jun 12 2011, 15:08:59) [msc v.1500 32 bit (intel)] on win32 type "help", "copyright", "credits" or "license" more information. >>> import pefile >>> p = pefile.pe(r'c:\python32\dlls\bz2.pyd') >>> p.is_dll() true >>> entry in p.directory_entry_import: ... print entry.dll ... python32.dll msvcr90.dll kernel32.dll >>> p = pefile.pe(r'c:\python27\dlls\bz2.pyd') >>> p.is_dll() true >>> entry in p.directory_entry_import: ... print entry.dll ... python27.dll msvcr90.dll kernel32.dll
and write check looks pythonxx.dll
string.
unfortunately works python 2.7 (maybe find 3.2 fork of pefile).
as far know winapi doesn't offer simple way of looking imports inside file, using 3rd party extension has structures embedded best way of doing this.