gpt4 book ai didi

python-2.7 - 从没有此类信息构建的 pyd 中检索 Python 版本

转载 作者:行者123 更新时间:2023-12-02 21:17:46 25 4
gpt4 key购买 nike

在 Windows 上,我有一个 Python 库 (*.pyd),我需要检查链接的 Python 版本。它可以是 Python 2.7.x 或 3.x。

当我使用 win32api 运行类似的东西时(改编自此处:https://stackoverflow.com/a/20064736/2741329):

def get_pyd_python_version(pyd_path):
"""
Get the python version required by the passed pyd library
"""
import win32api
print("- pyd path: %s" % str(pyd_path))
try:
info = win32api.GetFileVersionInfo(pyd_path, '\\')
except win32api.error as 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

我得到:在图像文件中找不到指定的资源类型。

相同的函数可以按预期与其他“正确”构建的 pyd 库(例如,win32api.pyd)一起使用。

由于与不完整 pyd 一起使用的 Dependency Walker 正确显示了 DLL,我想知道是否有一种方法可以通过编程方式(使用 Python)从这样的事实中获取版本信息。

--- 编辑 ---

基于 pefile 库和 @vyktor 答案,我通过下载这个 fork 来完成这项工作:https://github.com/BlackXeronic/pefile_py3并使用这样的方法(还检查架构):

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 to pyd: %s" % dll_path)

pe = pefile.PE(dll_path)
if pe.is_dll():
for 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))

这是我使用 Python 3.4.3 解释器得到的结果:

python env: v.3.4
pefile lib: v.1.2.10-139
path to pyd: C:/Python27/DLLs/bz2.pyd
>>> importing python27.dll: v.27 [x86] <<<

最佳答案

我正在 C:\Python32\DLLs\bz2.pyd 上对此进行测试,但我没有看到任何与 python 相关的详细信息(文件刚刚重命名为 .dll >):

bz2.pyc properties screenshot

与 python 版本相关的唯一信息位于 IAT 内:

bz2.pyc imports screenshot

所以你只需要解析 PE 文件并查找导入 DLL 名称即可。关于 loading IAT from file 有几个问题我使用 pefile 做到了这一点扩展名(由 gmas80 in a 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" for more information.
>>> import pefile
>>> p = pefile.PE(r'C:\Python32\DLLs\bz2.pyd')
>>> p.is_dll()
True
>>> for 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
>>> for entry in p.DIRECTORY_ENTRY_IMPORT:
... print entry.dll
...
python27.dll
MSVCR90.dll
KERNEL32.dll

您只需编写一个查找 pythonXX.dll 字符串的检查即可。

不幸的是,这仅适用于 python 2.7(也许有人可以找到 pefile 的 3.2 分支)。


据我所知,WinAPI 本身不提供在文件内查找导入的简单方法,因此使用嵌入所有结构的第 3 方扩展是执行此操作的最佳方法。

关于python-2.7 - 从没有此类信息构建的 pyd 中检索 Python 版本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29552221/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com