Masm32 SDK description, downloads and other helpful links

Main Menu

Retrieving Windows OS Version

Started by bluedevil, June 06, 2017, 01:40:10 AM

Previous topic - Next topic


Quote from: nidud on June 08, 2017, 03:39:50 AM
This in turn makes it rather (intensionally) difficult to get the true version of Win64 from inside a Win32 application.
I don't think so, RtlGetVersion  will give the correct answer. GetVersionEx will require an appropriate  manifest to give the correct answer.
These are APIs, the C runtime does not use any detour hook (till now  :lol:)




Quote from: nidud on June 08, 2017, 05:44:16 AM
RtlUnwindEx found..
Good. But what this has to do with the discussion about how to find the OS service pack? You said it depends, I said it is always possible.  :badgrin:


The following code works perfectly well in all 64-bit Windows systems (including Windows 10):


dwMajorVersion   DD   0
dwMinorVersion   DD   0

szMsvcrtDll      DB   "msvcrt.dll", 0
szMajorVersion   DB    "_get_winmajor", 0
szMinorVersion   DB    "_get_winminor", 0


   Invoke LoadLibrary, Addr szMsvcrtDll
   .If Rax
      Mov Rdi, Rax
      Invoke GetProcAddress, Rdi, Addr szMajorVersion
      .If Rax
         Lea Rcx, dwMajorVersion
         Push Rcx
         Call Rax
         Pop Rax
      Invoke GetProcAddress, Rdi, szMinorVersion
      .If Rax
         Lea Rcx, dwMinorVersion
         Push Rcx
         Call Rax
         Pop Rax
      Invoke FreeLibrary, Rdi

      ;Major version in dwMajorVersion
      ;Minor version in dwMinorVersion


EC coder


Quote from: rsala on June 08, 2017, 06:20:01 AM
szMsvcrtDll      DB   "msvcrt.dll", 0
There is more World outside the C runtime - it simply wraps the API calls to find the OS version.  :P


Quote from: blue_devil on June 08, 2017, 02:10:18 AMWin10 has no service pack right at the moment.

But you can get a build number:This is Windows version 10.0, build 14393

Compare to Windows 10 current versions by servicing option

See reply #3.


Reading the Windows OS version from the registry :



buffsize    dd 32
subKey      db 'SOFTWARE\Microsoft\Windows NT\CurrentVersion',0
valName     db 'CurrentVersion',0


hKey        dq ?
buffer      db 32 dup(?)


start PROC

    sub     rsp,6*8+8

    invoke  RegOpenKeyEx,HKEY_LOCAL_MACHINE,ADDR subKey,0,\
            KEY_ALL_ACCESS,ADDR hKey

    xor     r8,r8
    invoke  RegQueryValueEx,hKey,ADDR valName,r8,\
            r8,ADDR buffer,ADDR buffsize

    invoke  StdOut,ADDR buffer
    invoke  RegCloseKey,hKey

    invoke  ExitProcess,0

start ENDP

StdOut PROC lpszText:QWORD


    sub     rsp,5*8+8

    mov     _lpszText,rcx
    invoke  GetStdHandle,STD_OUTPUT_HANDLE
    mov     hOutPut,rax

    invoke  lstrlen,_lpszText
    mov     sl,rax

    invoke  WriteFile,hOutPut,_lpszText,sl,ADDR bWritten,0
    mov     rax,bWritten




Nice example :t

include \masm32\MasmBasic\      ; download
  GetRegArray "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion", cv$(), val$()
  For_ ecx=0 To eax-1
      PrintLine cv$(ecx), Tb$, val$(ecx)      ; print names and values
  Inkey "ok?"

Output:CurrentVersion  6.1
CurrentBuild    7601
SoftwareType    System
CurrentType     Multiprocessor Free
InstallDate     0
RegisteredOwner Jochen
SystemRoot      C:\Windows
InstallationType        Client
EditionID       HomePremium
ProductName     Windows 7 Home Premium
CurrentBuildNumber      7601
BuildLab        7601.win7sp1_ldr.170427-1518


My Windows 10 PRO shows v6.3, which is the version for Windows 8.1, if running GetOSver64.exe and the same happens with GetVersionEx API function. Using msvcrt.dll, in the example above, works fine.
EC coder


On Win10, I get the wrong version 6.3 on one of the registry entries (CurrentVersion), see below. Erol's 64-bit version doesn't do anything on both my Win7-64 and Win10 machines, except if I run it as admin; the 32-bit version works fine as normal user.

include \masm32\MasmBasic\
  Print Str$("This is Windows version %i", MbWinVersion()), Str$(".%i", ecx)
  void MbWinVersion()
  Inkey Str$(", build %i", dx)

On Win10:
This is Windows version 10.0, build 14393


include \masm32\MasmBasic\
  SetReg64 ; get the values that a 64-bit application would get
  GetRegArray "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion", cv$(), val$()
  For_ ecx=0 To eax-1
      PrintLine cv$(ecx), Tb$, val$(ecx)      ; print names and values
  Inkey "ok?"

On Win10:
SystemRoot      C:\WINDOWS
BuildBranch     rs1_release
BuildGUID       ffffffff-ffff-ffff-ffff-ffffffffffff
BuildLab        14393.rs1_release_sec.170427-1353
BuildLabEx      14393.1198.amd64fre.rs1_release_sec.170427-1353
CompositionEditionID    Core
CurrentBuild    14393
CurrentBuildNumber      14393
CurrentMajorVersionNumber       10
CurrentMinorVersionNumber       0
CurrentType     Multiprocessor Free
CurrentVersion  6.3
EditionID       Core
InstallationType        Client
InstallDate     1474513890
ProductName     Windows 10 Home
ReleaseId       1607
SoftwareType    System
UBR     1198
PathName        C:\WINDOWS
Customizations  ModernApps


When we get into Registry [HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion] on Win10, it still says version "6.3" even if "ProductName: Windows 10 Pro".  Why and isnt this stupid? What does m$ want to do?

OK under same place there are 2 new keys for Win10 ppl:
these 2 keys retrieve win10 version number
..Dreams make the future
But the past never lies..
BlueDeviL // SCT
My Code Site:
BlueDeviL Github


Quote from: blue_devil on June 12, 2017, 05:08:28 PM
OK under same place there are 2 new keys for Win10 ppl:

Exactly. And you are somehow supposed to guess which is the right one. You find that confusing? That's harmless. Windows is a giant pile of micro-s**t. Gigabytes of s**t, in the registry and on your harddisk.


Windows 10 uses RtlGetVersion in over 250 programs in system32 folder.
Quite safe to use it ?


Quote from: TWell on June 12, 2017, 06:07:23 PMQuite safe to use it ?

"Safe" is everything that has been used more than once in Windows. Remember the Redmond folks accumulate their shyte. And if you are worried about "exotic functions" used in drivers, have a look at the simple task "play a video". It's an incredible mess of many dozens of mostly incompatible drivers written by dozens of more or less competent teams all over the world. Do you really think they could abandon any function that has ever been used somewhere without getting a s**tstorm from users whose "toddler learns walking" videos don't play any more?


Actually a little out of this topic:
This from MSDN:
typedef struct _OSVERSIONINFOEXW {
  ULONG  dwOSVersionInfoSize;
  ULONG  dwMajorVersion;
  ULONG  dwMinorVersion;
  ULONG  dwBuildNumber;
  ULONG  dwPlatformId;
  WCHAR  szCSDVersion[128];
  USHORT wServicePackMajor;
  USHORT wServicePackMinor;
  USHORT wSuiteMask;
  UCHAR  wProductType;
  UCHAR  wReserved;

szCSDVersion is WCHAR, i port this to my asm code:
  dwOSVersionInfoSize DWORD ?
  dwMajorVersion DWORD ?
  dwMinorVersion DWORD ?
  dwBuildNumber DWORD ?
  dwPlatformId DWORD ?
  szCSDVersion BYTE  128  dup (?)------------------->should this be BYTE or WORD or something else?
  wServicePackMajor WORD ?
  wServicePackMinor WORD ?
  wSuiteMask WORD ?   
  wProductType BYTE ?
  wReserved BYTE ?

and also i cannot print szCSDVersion beause it is unicode?
i use this from GetVersionExA and it works:
print           "Service Pack String.......:",9
print addr osvxa.szCSDVersion

But this from RtlGetVersion doesnt work because of Unicode?
print           "Service Pack String.......:",9
print addr rtlOsvx.szCSDVersion

i search the forum but no proper answers.

What is in my mind:
I want to declare the variable as wide char,
then print it on the console.
Isnt this simplicity possible?
..Dreams make the future
But the past never lies..
BlueDeviL // SCT
My Code Site:
BlueDeviL Github