Windows version from `sys.getwindowsversion()` is wrong in binaries that do not declare Windows 10 support
還沒有人認領這個 Issue。
- 主要語言
- Python
- 星號
- 77.2k
- 分支
- 35.9k
- PR 合併指標
- PR 指標待擷取
描述
Bug report
Bug description:
Repro:
- Install Python for Windows (ideally create a new installation, since you'll need to patch it).
- Using Resource Hacker, or any other PE resource editing tool, remove the
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>line from the PE manifest, or just delete the whole manifest from the binary. Write back the patched binary. This enables compatibility shims for Windows 8 in the Win32 API when running the binary. - Run
...\python.exe -c "import sys; print(sys.getwindowsversion())" - Observe that the returned version indicates Windows 8 (major=6, minor=3) instead of the actual OS version (major=10, minor=0 for both Windows 10 and 11).
The root cause is very similar to https://issues.chromium.org/issues/494938698, see the full description there.
To retrieve the Windows version, Python reads the file version from kernel32.dll, because GetVersionEx will report old values due to backwards compatibility. However, GetFileVersionInfoW, which is used in the sysmodule.c implementation of sys.getwindowsversion() also has an internal compatibility shim where if the calling binary does not declare support for Windows 10, it will shim the actual DLL versions with a fake Windows 8 version for system libraries, resulting in sys.getwindowsversion() reporting a wrong OS version.
This is not an issue for python.exe directly, because it has a proper PE manifest that declares Windows 10 support, but it is an issue for apps that embed CPython and do not have a PE manifest, or do not declare Windows 10 support.
Proposed fix
Replace the whole implementation with a call to RtlGetVersion from ntdll, which is now officially documented, returns the correct version without shims and there's a substantial list of prominent projects relying on it already.
CPython versions tested on:
3.15
Operating systems tested on:
Windows
貢獻指南
從這裡開始
- 先讀完整個 Issue,再讀專案的貢獻指南。
- 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
- Fork 儲存庫,在一個分支上完成修改。
- 送出 Pull Request,並在描述裡引用這個 Issue 編號。
研究方向
從 Python/sysmodule.c 中 sys.getwindowsversion() 的實作開始,使用經過修補或不帶資訊清單的 Windows 二進位檔重現回報的結果。閱讀已記錄的 RtlGetVersion 進入點,並將其行為與目前的版本查詢進行比較。當不支援 Windows 10 的嵌入式二進位檔回報實際的 Windows 版本,而不是經過相容性 shim 修改的值時,即表示完成。
由索引模型根據 Issue 內容生成。
評估
- 技術堆疊
- c, python
- 領域
- operating-systems
- Issue 類型
- 缺陷
- 難度
- 4/5
- 預估耗時
- 3-5 天
- 活躍度
- 冷清
- 描述清晰度
- 基本清楚
- 新手友好度
- 55/100