首页 > 代码库 > NTDLL未文档化函数RtlGetNtVersionNumbers获取操作系统版本

NTDLL未文档化函数RtlGetNtVersionNumbers获取操作系统版本

作为新手,对获取操作系统版本号好奇过,因为曾经假象过一个场景:如果将来在windows xp环境下编译的程序,在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();}

运行结果:

OS:5.1.2600

这与我在命令提示符下运行ver结果一样的

verMicrosoft Windows XP [版本 5.1.2600]

这个函数能够准确的获取版本号,在实际运用中根据自己的需求决定吧

NTDLL未文档化函数RtlGetNtVersionNumbers获取操作系统版本