如何列出Python封装C库的外部编译库(如*.pyd)中的常量属性
针对.pyd模块隐藏整数常量的提取方案
这类由C编译生成的.pyd扩展模块,没出现在dir()结果中的整数常量,绝大多数都可以通过以下两种方法提取,无需暴力枚举属性名:
方法1:使用inspect模块遍历全量成员
dir()默认仅返回模块的公开属性,用inspect.getmembers可以遍历模块完整的属性字典,直接过滤出符合规则的整数常量:
import inspect import pixet # 可根据已知的常量命名前缀调整过滤规则,示例只过滤PX_开头的整数属性 int_constants = [ (name, value) for name, value in inspect.getmembers(pixet) if isinstance(value, int) and name.startswith("PX_") ] for name, val in int_constants: print(f"{name} = {val}")
如果模块的常量是通过__getattr__动态返回、没有预先存入属性字典,那上述方法会捞不到,可以用第二种静态解析方法。
方法2:静态提取.pyd文件的字符串表
.pyd本质是Windows标准DLL文件,C代码中注册常量时使用的属性名字符串必然会明文存在二进制文件的字符串表中,直接提取符合命名规则的字符串即可:
import re # 替换为你本地pixet.pyd的实际路径 pyd_file_path = r"C:\path\to\your\pixet.pyd" with open(pyd_file_path, "rb") as f: binary_content = f.read() # 正则匹配符合命名规则的常量名字符串,可根据实际前缀调整匹配规则 pattern = re.compile(rb"PX_[A-Z0-9_]+") raw_matches = pattern.findall(binary_content) # 去重并转成字符串格式 possible_const_names = list({item.decode("ascii") for item in raw_matches}) # 验证名称有效性,输出存在的整数常量 valid_constants = [] for name in possible_const_names: try: const_val = getattr(pixet, name) if isinstance(const_val, int): valid_constants.append((name, const_val)) except AttributeError: continue for name, val in valid_constants: print(f"{name} = {val}")
这类工业领域的SDK基本不会做字符串混淆,以上两种方法足以覆盖99%的场景,只有极少数做了二进制混淆的模块才需要用到动态调试hook的手段提取。
内容的提问来源于stack exchange,提问作者William
相关产品推荐
相关产品推荐

