作為新手,對擷取作業系統版本号好奇過,因為曾經假象過一個場景:自己的程式在windows xp環境下編譯,在windows 2003,
windows 7,windows 8是否需要提權或者相容處理,如果程式在windows 7以上版本需要特殊處理又該怎樣判斷作業系統版本呢。
帶着這個好奇也了解過GetVersion和GetVersionEx函數,他們的最低使用需求是Windows 2000,以下是一些官方的測試代碼。
GetVersion function
#include <windows.h>
#include <stdio.h>
void main()
{
DWORD dwVersion = 0;
DWORD dwMajorVersion = 0;
DWORD dwMinorVersion = 0;
DWORD dwBuild = 0;
dwVersion = GetVersion();
// Get the Windows version.
dwMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
dwMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVersion)));
// Get the build number.
if (dwVersion < 0x80000000)
dwBuild = (DWORD)(HIWORD(dwVersion));
printf("Version is %d.%d (%d)\n",
dwMajorVersion,
dwMinorVersion,
dwBuild);
}
運作結果:
Version is 5.1 (2600)
GetVersionEx function
#include <windows.h>
#include <stdio.h>
void main()
{
OSVERSIONINFO osvi;
BOOL bIsWindowsXPorLater;
ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&osvi);
bIsWindowsXPorLater =
( (osvi.dwMajorVersion > 5) ||
( (osvi.dwMajorVersion == 5) && (osvi.dwMinorVersion >= 1) ));
if(bIsWindowsXPorLater)
printf("The system meets the requirements.\n");
else printf("The system does not meet the requirements.\n");
}
運作結果:
The system meets the requirements.
今天偶然看見一個文章(GetVersionEx 如何區分win8和win8.1)和部落格(Windows系統版本判定那些事兒)介紹這兩個函數,說是在判斷 Win8和Win8.1的時候有問題,可以正常傳回值:
對于一個未加特殊處理的應用程式用GetVersionEx擷取win8和win8.1系統版本,一律都是6.2
這是多麼的坑人啊,令人敬畏。
從以上内容了解到了一個ntdll未公開的函數RtlGetNtVersionNumbers,了解到這個函數以後,我用工具檢視了ntdll.dll導出函數,的确還真有這個呢。
檢視導出函數可以用exescope/pexplorer/CFF explorer,選擇導出-->ntdll.dll/導出表檢視器/導出目錄就可以找到導出位址了。
網友公布的函數使用方法我也在本地編譯了一次
#include <stdio.h>
#include <windows.h>
typedef void (__stdcall *NTPROC)(DWORD*,DWORD*,DWORD*);
void GetWinVer()
{
HINSTANCE hinst = LoadLibrary("ntdll.dll");
DWORD dwMajor,dwMinor,dwBuildNumber;
NTPROC proc = (NTPROC)GetProcAddress(hinst,"RtlGetNtVersionNumbers");
proc(&dwMajor,&dwMinor,&dwBuildNumber);
dwBuildNumber&=0xffff;
printf("OS:%d.%d.%d\n",dwMajor,dwMinor,dwBuildNumber);
FreeLibrary(hinst);
}
void main(void)
{
GetWinVer();
}
運作結果:
ver
Microsoft Windows XP [版本 5.1.2600]