Win9X? What is that?

While mucking around the .NET framework sometime back, I stumbled across something I thought was kind of funny. Funny only in that I had almost forgotten about it (kind of). Anyway, I was working on a demo, and was checking out what goes on under the hood of a file open as such:

      Stream f = File.Open(@”C:\windows\system32\ntoskrnl.exe”,

            FileMode.Open,

            FileAccess.Read,

            FileShare.ReadWrite);

 

And here’s what it eventually ended up calling somewhere down the line:

IsWin9X-1

Here’s the callstack:

IsWin9X-2

Here’s the registers, when the IP (Instruction Pointer) is at the 3rd line of the IsWin9X() function:

IsWin9X-3

And looking at the code of IsWin9x(), it calls a function immediately: System.Environment.OSVersion.get()

IsWin9X-5

IsWin9X-6

 

Now, let’s take a look at the return value of this function. The 3rd line of IsWin9X() indicates that it is a struct:

00000000  call        FFFF6E80 
00000005  mov         edx,eax 
00000007  cmp         dword ptr [edx+10h],1 
0000000b  sete        al 
0000000e  movzx       eax,al 
00000011  ret 

 

It is most certainly at least an OSVERSIONINFO struct (if not an OSVERSIONINFOEX) that was returned. I didn’t bother to verify it at the Win32 level, but System.Environment.OSVersion.get() most probably called GetVersionEx(). A good indicator that it is an OSVERSIONINFO struct is the offset referenced in that 3rd line of code: 10h (0x10/hex 10). That would be the 5th DWORD (4-byte value). Let’s see what the memory contents are based on the address in the eax/edx registers (image above):

IsWin9X-4

You can see the 5th DWORD highlighted above, and the value is 00000002. And from that same 3rd line of code, it is comparing it with the value 1. Let’s see what the OSVERSIONINFO struct (Unicode version) looks like in WinNT.h:

typedef struct _OSVERSIONINFOW {

    DWORD dwOSVersionInfoSize;

    DWORD dwMajorVersion;

    DWORD dwMinorVersion;

    DWORD dwBuildNumber;

    DWORD dwPlatformId;

    WCHAR  szCSDVersion[ 128 ];     // Maintenance string for PSS usage

} OSVERSIONINFOW, *POSVERSIONINFOW, *LPOSVERSIONINFOW, RTL_OSVERSIONINFOW, *PRTL_OSVERSIONINFOW;

 

According to that, it is checking the field dwPlatformId. And here are the possible values in WinNT.h (you may refer to the link above for OSVERSIONINFO):

//

// dwPlatformId defines:

//

 

#define VER_PLATFORM_WIN32s             0

#define VER_PLATFORM_WIN32_WINDOWS      1

#define VER_PLATFORM_WIN32_NT           2

 

Aha! So it is checking if it is indeed Win9X! And since I’m running WinNT (Windows 7), you can see from the memory window above that the value for that field is 2. So this looks like it is the OSVERSIONINFO struct. However, the first three DWORD’s look like absolute rubbish. I have no idea.

And finally, IsWin9X() basically returns 1 (true) if dwPlatformId is 1, and 0 (false) otherwise. Well, I know the .NET Framework supports Windows 98 and above, and not Windows 95, so I guess it’s checking to see if it is Win98. Since I don’t have any running Win98 anymore, I can’t check to see how System.IO.FileStream.Init() will behave otherwise… I’m not even sure I’d bother if I could. Win9X is dead. Long live WinNT.

Advertisements
This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s