从Entry Point到main函数调用(二):GetVersion

从Entry Point到main函数调用(2):GetVersion

之前(1)篇中大致介绍了mainCRTStartup,但是其中一些调用到的函数并未深究,现打算逐一剖析它们。

 

GetVersion

GetVersion函数是kernel32.dll中提供的API,用于获取当前Win平台的版本。准确的说,GetVersion可以获得3个信息:

1. OSPlatformId

2. OSBuildNumber

3. OSMinorVersion

4. OSMajorVersion

其中比较诡异的是OSPlatformId,在GetVersion的过程当中它被获得过,但是返回的时候又没了...所以只剩下2、3、4

 

可以用OD来跟进GetVersion:

mov     eax, dword ptr fs:[18]
mov     ecx, dword ptr [eax+30]
mov     eax, dword ptr [ecx+B0]        // 获取 OSPlatformId
movzx   edx, word ptr [ecx+AC]         // 获取 OSBuildNumber 
xor     eax, FFFFFFFE
shl     eax, 0E                        // 几次左移,把OSPlatformId的信息给移没了...
or      eax, edx
shl     eax, 8
or      eax, dword ptr [ecx+A8]        // 获取 OSMinorVersion
shl     eax, 8
or      eax, dword ptr [ecx+A4]        // 获取 OSMajorVersion
retn

GetVersion主要是去PEB(Process Environment Block)结构中访问当前的OS信息,每个进程都会有自己独立的PEB。想要获取当前进程的PEB地址,首先要先访问TEB(Thread Environment Block )结构。因为TEB结构的30偏移量处中存放了PEB结构的指针。FS 寄存器指向了当前活动线程的TEB结构,其中偏移位置18表示了FS 段寄存器在内存中的镜像地址。

TEB结构
000  指向SEH链指针
004  线程堆栈顶部
008  线程堆栈底部
00C  SubSystemTib
010  FiberData
014  ArbitraryUserPointer
018  FS段寄存器在内存中的镜像地址
020  进程PID
024  线程ID
02C  指向线程局部存储指针
030  PEB结构地址(进程结构)
034  上个错误号

 

因此

mov     eax, dword ptr fs:[18]

mov     ecx, dword ptr [eax+30]

两句表示根据TEB获取PEB的指针,并且存放在ECX中。拿到PEB的指针后,就可以去PEB中拿OS的信息。

PEB结构中关于OS信息的偏移量如下:

PEB 写道
typedef struct _PEB // Size: 0x1D8
……
/*0A4*/ ULONG OSMajorVersion;
/*0A8*/ ULONG OSMinorVersion;
/*0AC*/ USHORT OSBuildNumber;
/*0AE*/ USHORT OSCSDVersion;
/*0B0*/ ULONG OSPlatformId;
……

 

如果是XP用户,那么GetVersion最终的返回值应该是:0A280105 。

其中 0A28表示XP build版本是2600,01表示OSMinorVersion,05表示OSMajorVersion 。

 

中间被忽略掉的 OSPlatformId 信息可以为:

  • VER_PLATFORM_WIN32s 或 0x0000,用于指定 Microsoft Windows 3.1。

  • VER_PLATFORM_WIN32_WINDOWS 或 0x0001,用于指定 Windows 95、Windows 98 或从其继承的操作系统。

  • VER_PLATFORM_WIN32_NT 或 0x0010,用于指定 Windows NT 或从其继承的操作系统。

另外,还有一些补充的OS信息如下:

(摘录自 http://msdn.microsoft.com/zh-cn/library/ms724833%28v=VS.85%29.aspx )

 

Operating system Version number dwMajorVersion dwMinorVersion
Windows 7 6.1 6 1
Windows Server 2008 R2 6.1 6 1
Windows Server 2008 6.0 6 0
Windows Vista 6.0 6 0
Windows Server 2003 R2 5.2 5 2
Windows Home Server 5.2 5 2
Windows Server 2003 5.2 5 2
Windows XP Professional x64 Edition 5.2 5 2
Windows XP 5.1 5 1
Windows 2000 5.0 5 0