The MASM Forum

General => The Campus => Topic started by: bluedevil on June 06, 2017, 01:40:10 AM

Title: Retrieving Windows OS Version
Post by: bluedevil on June 06, 2017, 01:40:10 AM
Hello;
There were several threads opened in the past in MASM forum; these are about retrieving Windows' version:
http://www.masmforum.com/board/index.php?topic=11963.0
http://masm32.com/board/index.php?topic=4653.0
http://www.masmforum.com/board/index.php?PHPSESSID=8d46cd4ecb1688be429ab49694ec53e6&topic=6488.0;wap2
http://masm32.com/board/index.php?topic=3629.0


OK! I have written some code about this issue. I want my code to understand which version of Windows it is running - in the lowest level- and prints as much info as about windows version structure
In this code i used:
APIs:
GetVersion (https://msdn.microsoft.com/en-us/library/windows/desktop/ms724439(v=vs.85).aspx)
GetVersionEx (https://msdn.microsoft.com/en-us/library/windows/desktop/ms724451(v=vs.85).aspx)
RtlGetVersion (https://msdn.microsoft.com/en-us/library/mt723418(v=vs.85).aspx)
Structures:
OSVERSIONINFO  (https://msdn.microsoft.com/en-us/library/windows/desktop/ms724834(v=vs.85).aspx)
OSVERSIONINFOEX  (https://msdn.microsoft.com/en-us/library/windows/desktop/ms724833(v=vs.85).aspx)
RTL_OSVERSIONINFOEXW (https://msdn.microsoft.com/en-us/library/ff563620(v=vs.85).aspx)

I have compiled this by using ML.exe v14 (why? because i have forgot that binary inside the masm/bin directory)
I have tested on win10x64, win7x86, winXpx86, and works. But i have some issues

1.Getting info from PEB is just awesome and fast:
print "Read From Process Environment Block:",13,10
    ASSUME FS:Nothing
    mov edx,fs:[30h] ;PEB.InheritedAddressSpace
    ASSUME  FS:ERROR
    mov     eax,[edx+0A4h] ;eax = Major Version
    push eax
    push    edx
    print   ustr$(eax),'.'
    pop     edx
    push edx
    mov     eax,[edx+0A8h] ;eax = Minor Version
    print   ustr$(eax),'.'
    pop edx
    mov eax,[edx+0ACh] ;eax = build
    and eax,0FFFFh ;because win 7 collapses
    print ustr$(eax),13,10,13,10
pop eax

I can retrieve version(maj,min,build) from PEB. Can i get ServicePack info from here. Here are some documentations.
PEB Structure MSDN (https://msdn.microsoft.com/en-us/library/windows/desktop/aa813706(v=vs.85).aspx)
A Good PDF about PEB (http://blog.rewolf.pl/blog/wp-content/uploads/2013/03/PEB_Evolution.pdf)
Windows Heap Overflows using the Process Environment Block (PEB) (http://www.open-security.org/texts/9)
According to these docs PEB structure also provides us

+0x1f0 CSDVersion : _UNICODE_STRING "Service Pack 1"

Which i couldn't managed to retrieve. But also is it possible to get Servicepack maj and min version numbers to retrieve from PEB?

2. I want to make a single executable which can run on all windows versions (i mean at least win xp to win 10 - but from 3.1 to 10 would be awesome :eusa_dance: seriously is that possible?) and checks version. Win XP returns 0 while using GetVersion API. And also Win XPdoenst retrieve Service pack maj min versions. Is it normal?
3.RtlGetVersion doesnt retrieve service pack versions on windows 7 :/ Am i doing wrong?

4. I cant compile RtlGetSuiteMask (https://msdn.microsoft.com/en-us/library/windows/desktop/mt668928(v=vs.85).aspx)  I just want to try this NTAPI but masm gave error like not defined even i declared "ntdll.lib". So is this api useless or can i make this NTAPI run? Or is this impossible?

5.Finally; i am just trying to learn stuff. I want to print every element on OSVERSIONINFO, OSVERSIONINFOEX, RTL_OSVERSIONINFOEXW. That is why i am asking here.

Replies are welcome
Title: Re: Retrieving Windows OS Version
Post by: aw27 on June 06, 2017, 02:36:22 AM
I have just 3 comments:
1) There are new APIs for Windows 7 and above.
2) RtlGetVersion was thought for device drivers, but is obsolete as well for new Windows release.
3) Using the PEB for whatever is subject to changes without notice between Windows releases.
Anyway for Windows 10:
   +0x0a4 OSMajorVersion   : Uint4B
   +0x0a8 OSMinorVersion   : Uint4B
   +0x0ac OSBuildNumber    : Uint2B
   +0x0ae OSCSDVersion     : Uint2B
   +0x0b0 OSPlatformId     : Uint4B
   +0x0b4 ImageSubsystem   : Uint4B
   +0x0b8 ImageSubsystemMajorVersion : Uint4B
   +0x0bc ImageSubsystemMinorVersion : Uint4B

Quote
A Good PDF about PEB
The best documentation is Windbg, but is a pain to learn to work with it  :badgrin:
Title: Re: Retrieving Windows OS Version
Post by: bluedevil on June 06, 2017, 07:08:11 AM
Quote from: aw27 on June 06, 2017, 02:36:22 AM
The best documentation is Windbg, but is a pain to learn to work with it  :badgrin:
Totally aggree with that!!
Title: Re: Retrieving Windows OS Version
Post by: jj2007 on June 06, 2017, 09:58:26 AM
include \masm32\MasmBasic\MasmBasic.inc      ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  Print Str$("This is Windows version %i", MbWinVersion()), Str$(".%i", ecx)
  void MbWinVersion()
  Print Str$(", build %i", dx)
EndOfCode


Output:
This is Windows version 6.1, build 7601

A look under the hood with Olly:
RtlGetNtVersion Ú$  8BFF                         mov edi, edi                           ; ntdll.RtlGetNtVersionNumbers
77B0B35F        ³.  55                           push ebp
77B0B360        ³.  8BEC                         mov ebp, esp
77B0B362        ³.  8B45 08                      mov eax, [ebp+8]
77B0B365        ³.  85C0                         test eax, eax
77B0B367        ³. 74 06                        jz short 77B0B36F
77B0B369        ³.  C700 06000000                mov dword ptr [eax], 6                 ; major version
77B0B36F        ³>  8B45 0C                      mov eax, [ebp+0C]
77B0B372        ³.  85C0                         test eax, eax
77B0B374        ³. 74 06                        jz short 77B0B37C
77B0B376        ³.  C700 01000000                mov dword ptr [eax], 1                 ; minor version
77B0B37C        ³>  8B45 10                      mov eax, [ebp+10]
77B0B37F        ³.  85C0                         test eax, eax
77B0B381        ³. 0F85 3F4D0300                jnz 77B400C6                           ; get build # and come back here
77B0B387        ³>  5D                           pop ebp
77B0B388        À.  C2 0C00                      retn 0C
...
77B400C6        Ú> ÀC700 B11D00F0                mov dword ptr [eax], F0001DB1          ; $1DB1=7601
77B400CC        À. E9 B6B2FCFF                  jmp 77B0B387


Note the sophisticated method used by the OS to return 6.1 and the build number 8)
Title: Re: Retrieving Windows OS Version
Post by: Raistlin on June 06, 2017, 03:25:50 PM
Could'nt Test  ::)- as per normal - virus scanner went nuts - Symantec Endpoint ...
Seems you have the same problems as me - Version Info Block and Manifest.
I used the following longer code blocks in my enumerator ExtremeID - re:
GetVersion, GetVersionEx, OSVERSIONINFO ,OSVERSIONINFOEX  etc. - which
seems to work well. There is also a couple of tricks to enumerate all intermediate
SKU's (Microsoft stock keeping units) operating systems - but I do find your
method intriguing (shorter & thus faster) and will investigate feasibility.
Title: Re: Retrieving Windows OS Version
Post by: bluedevil on June 06, 2017, 06:48:30 PM
Quote from: Raistlin on June 06, 2017, 03:25:50 PM
but I do find your
method intriguing (shorter & thus faster) and will investigate feasibility.
Thank you 8)

Quote from: jj2007 on June 06, 2017, 09:58:26 AM
include \masm32\MasmBasic\MasmBasic.inc      ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  Print Str$("This is Windows version %i", MbWinVersion()), Str$(".%i", ecx)
  void MbWinVersion()
  Print Str$(", build %i", dx)
EndOfCode


Output:
This is Windows version 6.1, build 7601

A look under the hood with Olly:
RtlGetNtVersion Ú$  8BFF                         mov edi, edi                           ; ntdll.RtlGetNtVersionNumbers
77B0B35F        ³.  55                           push ebp
77B0B360        ³.  8BEC                         mov ebp, esp
77B0B362        ³.  8B45 08                      mov eax, [ebp+8]
77B0B365        ³.  85C0                         test eax, eax
77B0B367        ³. 74 06                        jz short 77B0B36F
77B0B369        ³.  C700 06000000                mov dword ptr [eax], 6                 ; major version
77B0B36F        ³>  8B45 0C                      mov eax, [ebp+0C]
77B0B372        ³.  85C0                         test eax, eax
77B0B374        ³. 74 06                        jz short 77B0B37C
77B0B376        ³.  C700 01000000                mov dword ptr [eax], 1                 ; minor version
77B0B37C        ³>  8B45 10                      mov eax, [ebp+10]
77B0B37F        ³.  85C0                         test eax, eax
77B0B381        ³. 0F85 3F4D0300                jnz 77B400C6                           ; get build # and come back here
77B0B387        ³>  5D                           pop ebp
77B0B388        À.  C2 0C00                      retn 0C
...
77B400C6        Ú> ÀC700 B11D00F0                mov dword ptr [eax], F0001DB1          ; $1DB1=7601
77B400CC        À. E9 B6B2FCFF                  jmp 77B0B387


Note the sophisticated method used by the OS to return 6.1 and the build number 8)

Your code works like charm on Win10x64 (i have masmbasic). And i saw the trick comes from RtlGetNtVersionNumbers. But according to these links:
https://source.winehq.org/WineAPI/RtlGetNtVersionNumbers.html
http://man.docs.sk/3w/rtlgetntversionnumbers.html
We can get only major minor and build. How can you get ServicePack info jj2007 ?
Title: Re: Retrieving Windows OS Version
Post by: jj2007 on June 06, 2017, 08:23:03 PM
This relates to a post by adeyblue (http://masm32.com/board/index.php?topic=4653.msg50238#msg50238). The problem here is really the lack of documentation by M$. Wine has it, though (https://source.winehq.org/WineAPI/RtlGetNtVersionNumbers.html).

Note this is a can of worms, as even Microsoft admits (https://msdn.microsoft.com/windows/compatibility/operating-system-version-changes-in-windows-8-1):
QuoteWe have made some significant changes in how the GetVersion(Ex) APIs work in Windows 8.1 due to undesirable customer behaviors resulting from how the GetVersion(Ex) APIs have been used in the past.

In previous versions of Windows, calling the GetVersion(Ex) APIs would return the actual version of the operating system (OS), unless the process had been mitigated by an app compat shim to give it a different version. This was done on a provisional basis and was relatively incomplete in terms of the number of processes that Microsoft could reasonably shim in a release. Many applications fell through the cracks because they didn't get shimmed due to poorly designed version checks.

The number one reason to do a version check is to show some message of OS supportability for the application. However due to the poor checks, the message would often show that the app needed to be run on XP or later, which of course the newest OS is. More often than not, the newest OS would run the application without any issues if not for these checks.

If there was a Pulitzer prize for software documentation, the author would be a hot candidate :P

Another real jewel from the same MSDN page:#include <VersionHelpers.h>
...
    if (!IsWindows8OrGreater())
    {
       MessageBox(NULL, "You need at least Windows 8", "Version Not Supported", MB_OK);
    }


There are a few more:See also

IsWindowsXPSP1OrGreater
IsWindowsXPSP2OrGreater
IsWindowsXPSP3OrGreater
IsWindowsVistaOrGreater
IsWindowsVistaSP1OrGreater
IsWindowsVistaSP2OrGreater
IsWindows7OrGreater
IsWindows7SP1OrGreater
IsWindows8OrGreater
IsWindows8Point1OrGreater
IsWindowsServer


The main purpose of these "helper" functions is evidently to help kick Windows XP out of the software market, because programs written with these new "helpers" will probably not run on XP 8)
Title: Re: Retrieving Windows OS Version
Post by: bluedevil on June 06, 2017, 09:33:17 PM
@jj2007 i am totally aggre with you!

1. I have seen these functions while searching, but as you say these apis wont work on a xp machine?
See also

IsWindowsXPSP1OrGreater
IsWindowsXPSP2OrGreater
IsWindowsXPSP3OrGreater
IsWindowsVistaOrGreater
IsWindowsVistaSP1OrGreater
IsWindowsVistaSP2OrGreater
IsWindows7OrGreater
IsWindows7SP1OrGreater
IsWindows8OrGreater
IsWindows8Point1OrGreater
IsWindowsServer

But i will make an example with these 8)

BTW i am reading fresh new "Windows Internals 7" right at the moment, and it says on page 55:
QuoteWith so many different editions of Windows and each having the same kernel image, how does the system know which edition is booted? By querying the registry values "ProductType" and "ProductSuite" under the HKLM\SYSTEM\CurrentControlSet\Control\ProductOptions key. "ProductType" is used to distinguish whether the system is a client system or a server system (of any flavor). These values are loaded into the registry based on the licensing policyfile described earlier. The valid values are listed in Table 2-3. This can be queried from the user-mode "VerifyVersionInfo" function or from a device deriver using the kernel-mode support function "RtlVerifyVersion" and "RtlVerifyVersionInfo", both documented in the Windows Driver Kit  (WDK).

And with this info i checked "VerifyVersionInfo" function:
QuoteThe VerifyVersionInfo function retrieves version information about the currently running operating system and compares it to the valid members of the lpVersionInfo structure. This enables you to easily determine the presence of a required set of operating system version conditions. It is preferable to use VerifyVersionInfo rather than calling the GetVersionEx function to perform your own comparisons.

I will implement this function in my very first free time :t Because according to MSDN VerifyVersionInfo needs Win2000 and above.
Title: Re: Retrieving Windows OS Version
Post by: jj2007 on June 06, 2017, 09:52:51 PM
Quote from: blue_devil on June 06, 2017, 09:33:17 PM
@jj2007 i am totally aggre with you!

1. I have seen these functions while searching, but as you say these apis wont work on a xp machine?
...
according to MSDN VerifyVersionInfo needs Win2000 and above.

You already gave the answer :biggrin:

Yes, they will probably work (XP>2000), all you have to do is download and install a few gigabytes of "appcompat shi*" SDK or similar to get the VersionHelper.h and its macros.

Btw I am shocked that so far nobody has tested RtlVerifyVersionInfo here, another magic answer to the old "hey, which Windows are you??" question :shock:

Here is one more for the fans of Douglas Adams:include \masm32\MasmBasic\MasmBasic.inc
WhichWindowsAreYou? MACRO
  EXITM Chr$("This is Windows 42")
ENDM
  Init
  Inkey WhichWindowsAreYou?()
EndOfCode


In the end, I picked RtlGetNtVersionNumbers for MbWinVersion() because it's hard-coded into ntdll. No chance for any tricks, this is the real thing. But of course, undocumented, use at your own risk bla bla, and don't forget to put some bets on the possibility that one day in the near future (2100?) Micros**t may remove that function (used e.g. in C:\Windows\System32\msvcrt.dll) from ntdll 8)
Title: Re: Retrieving Windows OS Version
Post by: TWell on June 06, 2017, 10:21:46 PM
Verifying the System Version (https://msdn.microsoft.com/en-us/library/windows/desktop/ms725491(v=vs.85).aspx)
Quote[ Use of the VerifyVersionInfo function to verify the currently running operating system is not recommended. Instead, use the Version Helper APIs]
QuoteThe Version Helper functions use the VerifyVersionInfo function, so the behavior IsWindows8Point1OrGreater and IsWindows10OrGreater are similarly affected by the presence and content of the manifest.
QuoteVerifyVersionInfo function
Compares a set of operating system version requirements to the corresponding values for the currently running version of the system. This function is subject to manifest-based behavior. For more information, see the Remarks section.
link (http://iamgyg.blog.163.com/blog/static/3822325720158662658280/)
:P
Title: Re: Retrieving Windows OS Version
Post by: hutch-- on June 06, 2017, 11:31:14 PM
Its easy to write software for XP, use the old API functions in Win32.hlp. For later stuff up to XP, look for one of the older (pre Vista) SDK's where you got offline help files. If you try and use the later stuff you will run into M$ dirty work excluding XP by design.
Title: Re: Retrieving Windows OS Version
Post by: nidud on June 07, 2017, 03:22:54 AM
deleted
Title: Re: Retrieving Windows OS Version
Post by: bluedevil on June 08, 2017, 02:10:18 AM
Quote from: nidud on June 07, 2017, 03:22:54 AM
Maybe the LINK version in the dll header could give a clue about "version trickery".

ver32.exe:

include stdio.inc
include tchar.inc
include winbase.inc

    .code

main proc
    .if LoadLibrary("ntdll.dll")
mov edi,eax
mov ebx,[edi+0x3C]
movzx eax,[edi+ebx].IMAGE_NT_HEADERS.OptionalHeader.MajorLinkerVersion
movzx edx,[edi+ebx].IMAGE_NT_HEADERS.OptionalHeader.MinorLinkerVersion
printf("Link:    %d.%d\n", eax, edx)
movzx eax,[edi+ebx].IMAGE_NT_HEADERS.OptionalHeader.MajorOperatingSystemVersion
movzx edx,[edi+ebx].IMAGE_NT_HEADERS.OptionalHeader.MinorOperatingSystemVersion
printf("Windows: %d.%d\n", eax, edx)
FreeLibrary(edi)
    .else
printf("NTDLL not found..\n")
    .endif
    xor eax,eax
    ret
main endp

    end _tstart


ver64.exe:

include stdio.inc
include tchar.inc
include winbase.inc

    .code

main proc
    .if LoadLibrary("ntdll.dll")
mov rdi,rax
mov ebx,[rdi+0x3C]
movzx eax,[rdi+rbx].IMAGE_NT_HEADERS.OptionalHeader.MajorLinkerVersion
movzx edx,[rdi+rbx].IMAGE_NT_HEADERS.OptionalHeader.MinorLinkerVersion
printf("Link:    %d.%d\n",rax,rdx)
movzx eax,[rdi+rbx].IMAGE_NT_HEADERS.OptionalHeader.MajorOperatingSystemVersion
movzx edx,[rdi+rbx].IMAGE_NT_HEADERS.OptionalHeader.MinorOperatingSystemVersion
printf("Windows: %d.%d\n",rax,rdx)
FreeLibrary(rdi)
    .else
printf("NTDLL not found..\n")
    .endif
    xor eax,eax
    ret
main endp

    end _tstart


Win7-64

ver32:
Link: 9.0
Windows: 6.1

ver64:
Link: 9.0
Windows: 6.1

Thanks for your reply. nidud. I want to ask smth to you.
1.Where did you compile these sources? Under MASM32 or another assembler?
2.Those include files => stdio.inc, tchar.inc, winbase.inc. Where did you find them. I mean i use masm32 v11 and under the include directory there is no files like that.


And generally i want to ask a question. We find several instances of version information. But service pack information is still obscure. I wonder did microsoft put an integer like -version info- to specify the service pack? Or did they (or 3rd parties) retrieves this information from "build" numbers. Like:
Quote6.1.7600.16385    4A5BDADB (14th July 2009)    1,286,144    Windows 7
6.1.7601.17514    4CE7B96E (20th November 2010)    1,288,488    Windows 7 SP1
Look above, maybe microsoft or other people retrieve build numbers and compares with hardcoded numbers and says this is service pack 1?

For example Win10 has no service pack right at the moment. Maybe it will 4 years later ok? So can we code a example that could gives us win10's sp info? Is it that much hidden  :badgrin:
Title: Re: Retrieving Windows OS Version
Post by: aw27 on June 08, 2017, 03:03:09 AM
RtlGetVersion has the Service pack in the returned structure. Unlike others this one still works for Windows 10 although Microsoft is trying to pull away from it.

It is also in the PEB as shown above:
+0x0ae OSCSDVersion (32-bit only)
for Windows 64 bit is at:
+0x122 OSCSDVersion
The current values should be 0

Title: Re: Retrieving Windows OS Version
Post by: nidud on June 08, 2017, 03:39:50 AM
deleted
Title: Re: Retrieving Windows OS Version
Post by: aw27 on June 08, 2017, 03:57:03 AM
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:)
Title: Re: Retrieving Windows OS Version
Post by: nidud on June 08, 2017, 05:44:16 AM
deleted
Title: Re: Retrieving Windows OS Version
Post by: aw27 on June 08, 2017, 06:00:14 AM
Quote from: nidud on June 08, 2017, 05:44:16 AM
:biggrin:
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:
Title: Re: Retrieving Windows OS Version
Post by: rsala on June 08, 2017, 06:20:01 AM
The following code works perfectly well in all 64-bit Windows systems (including Windows 10):

.Data

dwMajorVersion   DD   0
dwMinorVersion   DD   0

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

.Code

   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
      .EndIf
      Invoke GetProcAddress, Rdi, szMinorVersion
      .If Rax
         Lea Rcx, dwMinorVersion
         Push Rcx
         Call Rax
         Pop Rax
      .EndIf
      Invoke FreeLibrary, Rdi

      ;Major version in dwMajorVersion
      ;Minor version in dwMinorVersion

   .EndIf

Regards!
Title: Re: Retrieving Windows OS Version
Post by: aw27 on June 08, 2017, 07:05:05 AM
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
Title: Re: Retrieving Windows OS Version
Post by: jj2007 on June 08, 2017, 08:06:39 AM
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 (https://technet.microsoft.com/en-us/windows/release-info.aspx)

See reply #3.
Title: Re: Retrieving Windows OS Version
Post by: Vortex on June 09, 2017, 04:59:41 AM
Reading the Windows OS version from the registry :

include     GetOSver64.inc

.data

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

.data?

hKey        dq ?
buffer      db 32 dup(?)

.code

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

LOCAL hOutPut:QWORD
LOCAL bWritten:QWORD
LOCAL sl:QWORD
LOCAL _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
    ret

StdOut ENDP

END
Title: Re: Retrieving Windows OS Version
Post by: jj2007 on June 09, 2017, 06:24:43 AM
Nice example :t

include \masm32\MasmBasic\MasmBasic.inc      ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  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
  Next
  Inkey "ok?"
EndOfCode


Output:CurrentVersion  6.1
CurrentBuild    7601
SoftwareType    System
CurrentType     Multiprocessor Free
InstallDate     0
RegisteredOrganization
RegisteredOwner Jochen
SystemRoot      C:\Windows
InstallationType        Client
EditionID       HomePremium
ProductName     Windows 7 Home Premium
CurrentBuildNumber      7601
BuildLab        7601.win7sp1_ldr.170427-1518
Title: Re: Retrieving Windows OS Version
Post by: rsala on June 09, 2017, 07:05:04 AM
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.
Title: Re: Retrieving Windows OS Version
Post by: jj2007 on June 09, 2017, 08:00:16 AM
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\MasmBasic.inc
  Init
  Print Str$("This is Windows version %i", MbWinVersion()), Str$(".%i", ecx)
  void MbWinVersion()
  Inkey Str$(", build %i", dx)
EndOfCode

On Win10:
This is Windows version 10.0, build 14393

********************************************************************************************

include \masm32\MasmBasic\MasmBasic.inc
  Init
  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
  Next
  Inkey "ok?"
EndOfCode

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
Title: Re: Retrieving Windows OS Version
Post by: bluedevil on June 12, 2017, 05:08:28 PM
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?

EDIT:
OK under same place there are 2 new keys for Win10 ppl:
CurrentMajorVersionNumber
CurrentMinorVersionNumber
these 2 keys retrieve win10 version number
Title: Re: Retrieving Windows OS Version
Post by: jj2007 on June 12, 2017, 05:55:34 PM
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.
Title: Re: Retrieving Windows OS Version
Post by: TWell on June 12, 2017, 06:07:23 PM
Windows 10 uses RtlGetVersion in over 250 programs in system32 folder.
Quite safe to use it ?
Title: Re: Retrieving Windows OS Version
Post by: jj2007 on June 12, 2017, 06:49:38 PM
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?
Title: Re: Retrieving Windows OS Version
Post by: bluedevil on June 12, 2017, 08:53:19 PM
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;
} RTL_OSVERSIONINFOEXW, *PRTL_OSVERSIONINFOEXW;


szCSDVersion is WCHAR, i port this to my asm code:
RTL_OSVERSIONINFOEXW STRUCT
  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 ?
RTL_OSVERSIONINFOEXW ENDS


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?
Title: Re: Retrieving Windows OS Version
Post by: nidud on June 12, 2017, 11:13:08 PM
deleted
Title: Re: Retrieving Windows OS Version
Post by: nidud on June 12, 2017, 11:32:25 PM
deleted
Title: Re: Retrieving Windows OS Version
Post by: bluedevil on June 12, 2017, 11:59:50 PM
@nidud: immediate reply
dude i just added "/D__UNICODE__" to assembler. And you know what happened? This line:
print addr rtlOsvx.szCSDVersion
gave the correct answer. But the rest of the application turn chinese :dazzled: ::)
Title: Re: Retrieving Windows OS Version
Post by: nidud on June 13, 2017, 12:00:51 AM
deleted
Title: Re: Retrieving Windows OS Version
Post by: bluedevil on June 14, 2017, 11:33:26 PM
OK, thanks ppl for taking your time and sharing thoughts. I attached my code. I have tested on:
Win10 x64 - Host machine
Win07 x86 - Guest
WinXP x86 - Guest
All worked.
I could retrieve information from GetVersion, GetVersionEx, RtlGetVersion, PEB and Registry. Only retrieving version info from msvcrt.dll is wrong both in Win10 and Win7. But for me PEB is the fastest and reliable.
Thanks again  8) :eusa_dance:
Title: Re: Retrieving Windows OS Version
Post by: jj2007 on June 15, 2017, 12:06:49 AM
Quote from: blue_devil on June 14, 2017, 11:33:26 PMPEB is the fastest

How can we resist the temptation to time this one?This is Windows version 6.1, build 7601

54 ms   MbWinVersion
252 ms  RtlGetVersion

This is Windows version 6.1, build 7601

;)
Title: Re: Retrieving Windows OS Version
Post by: bluedevil on June 15, 2017, 12:16:23 AM
Quote from: jj2007 on June 15, 2017, 12:06:49 AM
Quote from: blue_devil on June 14, 2017, 11:33:26 PMPEB is the fastest

How can we resist the temptation to time this one?This is Windows version 6.1, build 7601

54 ms   MbWinVersion
252 ms  RtlGetVersion

This is Windows version 6.1, build 7601

;)
:eusa_clap:
Title: Re: Retrieving Windows OS Version
Post by: Siekmanski on June 15, 2017, 12:34:42 AM
GetVersionEx give the wrong windows version for Windows 8.1 ( it returns Windows 8 )
Title: Re: Retrieving Windows OS Version
Post by: bluedevil on June 15, 2017, 12:53:31 AM
Quote from: Siekmanski on June 15, 2017, 12:34:42 AM
GetVersionEx give the wrong windows version for Windows 8.1 ( it returns Windows 8 )

Yes because of M$**, right jj2007?
I could't manifest the console programs. msdn says:
Quote[GetVersionEx may be altered or unavailable for releases after Windows 8.1. Instead, use the Version Helper functions]

With the release of Windows 8.1, the behavior of the GetVersionEx API has changed in the value it will return for the operating system version. The value returned by the GetVersionEx function now depends on how the application is manifested.

Applications not manifested for Windows 8.1 or Windows 10 will return the Windows 8 OS version value (6.2). Once an application is manifested for a given operating system version, GetVersionEx will always return the version that the application is manifested for in future releases. To manifest your applications for Windows 8.1 or Windows 10, refer to Targeting your application for Windows.

it is not possible to manifest console programs right?
Title: Re: Retrieving Windows OS Version
Post by: jj2007 on June 15, 2017, 05:09:24 AM
Quote from: blue_devil on June 15, 2017, 12:53:31 AMit is not possible to manifest console programs right?

Why not?

include \masm32\MasmBasic\MasmBasic.inc      ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  Print "Running with common controls version ", ComCtl32$()
  xchg MbWinVersion(), ecx
  Inkey Str$(" on Windows version %i.", MbWinVersion()), Str$(ecx)
EndOfCode


Running with common controls version 6.16 on Windows version 6.1
Title: Re: Retrieving Windows OS Version
Post by: TWell on June 15, 2017, 04:51:26 PM
Manifest can be external too, so you can add it afterwards.
My.exe.manifest<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
  <application>
     <!-- Windows 10 -->
     <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
     <!-- Application supports Windows 8.1 -->
     <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
     <!-- Application supports Windows 8 -->
     <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
     <!-- Application supports Windows 7 -->
     <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
     <!-- Application supports Windows Vista -->
     <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
  </application>
</compatibility>

</assembly>
Title: Re: Retrieving Windows OS Version
Post by: nidud on June 18, 2017, 06:44:15 PM
deleted
Title: Re: Retrieving Windows OS Version
Post by: TWell on June 18, 2017, 09:00:14 PM
That example program crash in Windows 8.1
But a program with same idea show 6.3
Title: Re: Retrieving Windows OS Version
Post by: nidud on June 18, 2017, 09:35:09 PM
deleted
Title: Re: Retrieving Windows OS Version
Post by: Vortex on June 18, 2017, 09:46:16 PM
nidud's method works fine on Windows XP 64-bit :

include     GetOSvers.inc

.data

kernel32    db 'kernel32.dll',0
str1        db 'Major Operating System Version = %u',13,10
            db 'Minor Operating System Version = %u',13,10,0

.data?

buffer      db 128 dup(?)

.code

start:

    invoke  GetModuleHandle,ADDR kernel32
    test    eax,eax
    jz      @f
   
    add     eax,IMAGE_DOS_HEADER.e_lfanew[eax]

    movzx   ecx,IMAGE_NT_HEADERS.OptionalHeader.MajorOperatingSystemVersion[eax]
           
    movzx   edx,IMAGE_NT_HEADERS.OptionalHeader.MinorOperatingSystemVersion[eax]

    invoke  wsprintf,ADDR buffer,ADDR str1,ecx,edx
    invoke  StdOut,ADDR buffer
@@:
    invoke  ExitProcess,0

END start


GetOSvers.exe
Major Operating System Version = 5
Minor Operating System Version = 2
Title: Re: Retrieving Windows OS Version
Post by: bluedevil on June 19, 2017, 05:00:33 PM
Quote from: jj2007 on June 15, 2017, 05:09:24 AM
Quote from: blue_devil on June 15, 2017, 12:53:31 AMit is not possible to manifest console programs right?

Why not?

include \masm32\MasmBasic\MasmBasic.inc      ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  Print "Running with common controls version ", ComCtl32$()
  xchg MbWinVersion(), ecx
  Inkey Str$(" on Windows version %i.", MbWinVersion()), Str$(ecx)
EndOfCode


Running with common controls version 6.16 on Windows version 6.1

Johen, i have already added manifest to my latest source code, but it is not working on Win8.1 like yours? Do you have any idea of "why"?
And-1 did you compile your app with sussystem console or windows?
And-2 you share xp manifest with your source but it returns true results before and after win8.1 windowses. But according to the MSDN we should use a new manifest which mentioned here:
Targeting your application for Windows (https://msdn.microsoft.com/en-us/library/windows/desktop/dn481241(v=vs.85).aspx)
Thanks for reply =)
Title: Re: Retrieving Windows OS Version
Post by: jj2007 on June 19, 2017, 05:42:55 PM
Yes, built as subsystem console (see OPT_Susy Console in the source).

Try the attachment, it incorporates the new MSDN stuff. I am curious to see how it behaves. For me it says 6.16 on Win7-64, and "6.16 on Windows 10.0" on Win10.

But attention, it chokes on Win XP: The system cannot execute the specified program (from a DOS prompt). The pressure to use manifests is part of the Micros**t strategy to force users away from Win XP.

If you like it complicated, read App (executable) manifest (https://msdn.microsoft.com/en-us/windows/compatibility/application-executable-manifest) :biggrin:
Title: Re: Retrieving Windows OS Version
Post by: TWell on June 19, 2017, 06:04:12 PM
Another test:
rename OsVersionX.exe to OsVersionX1.exe
create OsVersionX1.exe.manifest from http://masm32.com/board/index.php?topic=6299.msg67763#msg67763

and now it show 6.3 in Windows 8.1
original exe show 6.2

Quite weird ::)

EDIT:
Oops. That OsVersionX.exe didn't have resource section :(
Title: Re: Retrieving Windows OS Version
Post by: jj2007 on June 19, 2017, 06:09:59 PM
Quote from: TWell on June 19, 2017, 06:04:12 PMand now it show 6.3 in Windows 8.1
original exe show 6.2

And what does it show in XP? Sorry, no time to build the exe right now...
Title: Re: Retrieving Windows OS Version
Post by: TWell on June 19, 2017, 06:41:32 PM
My XP don't have gdiplus 1.1
ManifestedConsoleProgram.exe have depedency with it.
After removing that, it runs in XP.Running with common controls version 6.00 on Windows version 5.1
Title: Re: Retrieving Windows OS Version
Post by: Siekmanski on June 19, 2017, 07:13:15 PM
Hi nidud,

Quote from: nidud on June 18, 2017, 06:44:15 PM
Quote from: Siekmanski on June 15, 2017, 12:34:42 AM
GetVersionEx give the wrong windows version for Windows 8.1 ( it returns Windows 8 )

What version is the kernel header?


Windows 6.3  :t
Title: Re: Retrieving Windows OS Version
Post by: bluedevil on June 19, 2017, 07:25:05 PM
@Johen when i look your executable with CFF explorer there is resource section (with the manifest inside). But when i look up my executable unfortunately there is no resource section, even if i add manifest file :/
I am not sure but maybe i have the wrong parameters on LINK.EXE? I still couldn't fint where i do wrong?
Title: Re: Retrieving Windows OS Version
Post by: nidud on June 19, 2017, 07:41:27 PM
deleted
Title: Re: Retrieving Windows OS Version
Post by: jj2007 on June 19, 2017, 07:47:06 PM
Quote from: blue_devil on June 19, 2017, 07:25:05 PMI am not sure but maybe i have the wrong parameters on LINK.EXE? I still couldn't fint where i do wrong?

Yes, check your settings. RichMasm sets the linkers args if it finds either MySourceName.rc or rsrc.rc (see source in Reply #46), but other IDEs may require more explicit instructions; IIRC qEditor checks for rsrc.rc.
Title: Re: Retrieving Windows OS Version
Post by: bluedevil on June 21, 2017, 09:37:36 PM
This is my project options. My ML.EXE is now UASM32.exe actually. But i have tried original ml.exe and ml.exe from visual studio. I also tried original LINK.EXE and POLINK.EXE as you see below. Hmm but neither the worked for me. I could't make a console app with .rsrc section.

Compile RC : 4,O,$B\RC.EXE /v,1
Assemble   : 3,O,$B\ML.EXE /c /coff /Cp /nologo /I"$I",2
Link       : 5,O,$B\POLINK.EXE /SUBSYSTEM:CONSOLE /RELEASE /VERSION:4.0 /LIBPATH:"$L" /OUT:"$5",3
Run        : 0,0,,5
Res To Obj : rsrc.obj,O,$B\CVTRES.EXE,rsrc.res
Asm Module : *.obj,O,$B\ML.EXE /c /coff /Cp /nologo /I"$I",*.asm


Your MasmBasic wants GuiData.zip [\Masm32\MasmBasic\Res\GuiData\GuiData.zip] even i upgraded the last version of MB. And also i couldn't find the config file of MB to link and assemble. I mean Johen what MB executes when i press F6? I couldn't find that?


Title: Re: Retrieving Windows OS Version
Post by: TWell on June 21, 2017, 11:18:34 PM
is that 4 missing from that link line?
polink can link .res file without cvtres.exe
Title: Re: Retrieving Windows OS Version
Post by: jj2007 on June 22, 2017, 01:16:49 AM
Quote from: blue_devil on June 21, 2017, 09:37:36 PMYour MasmBasic wants GuiData.zip [\Masm32\MasmBasic\Res\GuiData\GuiData.zip] even i upgraded the last version of MB. And also i couldn't find the config file of MB to link and assemble. I mean Johen what MB executes when i press F6?

By default, it tries to execute Uasm32.exe, with a set of reasonable commandline options. The fact that it asks for GuiData.zip means most probably that you have an old myname.rc or rsrc.rc in the same folder. Or do you have something like this at the end of your code?Rsrc
#include "resource.h"
IDI_APPLICATION ICON "\\Masm32\\MasmBasic\\icons\\Smiley.ico" // Calc, Disk, Editor, Eye, Globe, MasmBasic, Smiley
01 RT_MANIFEST "\\Masm32\\MasmBasic\\Res\\XpManifest.xml" // works with tooltips
59 RCDATA "\\Masm32\\MasmBasic\\Res\\GuiData\\GuiData.zip" // multilanguage menu & toolbar; ID must be 59
Rsrc


In this case, put //59 RCDATA to disable that. And sorry, this is my fault, I didn't check :icon_redface:
Title: Re: Retrieving Windows OS Version
Post by: bluedevil on June 22, 2017, 01:34:20 AM
1. You still dont say the "reasonable commandline options" :eusa_dance:
2. I was trying to compile the source that you have shared on post #46. In your asc file it is written that "59 RCDATA   "\\Masm32\\MasmBasic\\Res\\GuiData\\GuiData.zip"   ". That is why i am asking 8)

@TWell 4 is missing because this is compling as a Console program. When the subsystem is "WINDOWS" there will be an extra ",4". Am i wrong?
Title: Re: Retrieving Windows OS Version
Post by: jj2007 on June 22, 2017, 01:39:07 AM
Quote from: blue_devil on June 22, 2017, 01:34:20 AM
1. You still dont say the "reasonable commandline options" :eusa_dance:
2. I was trying to compile the source that you have shared on post #46. In your asc file it is written that "59 RCDATA   "\\Masm32\\MasmBasic\\Res\\GuiData\\GuiData.zip"   ". That is why i am asking 8)

As I wrote above, comment it out: //59 RCDATA

Re options, here is what the output windows says:

** Start C:\Masm32\MasmBasic\Res\bldallRM.bat **
**** 32-bit assembly ****

*** Assemble, link and run ManifestedConsoleProgram ***

*** Assemble using \masm32\bin\HJWasm32 /c /coff  tmp_file.asm ***
HJWasm v2.31, May 15 2017, Masm-compatible assembler.
Portions Copyright (c) 1992-2002 Sybase, Inc. All Rights Reserved.
Source code is available under the Sybase Open Watcom Public License.

*** MasmBasic version 19.06.2017 ***
----------------------------------------
WARNING duplicate include file ntdll.inc
----------------------------------------
Tmp_File.asm: 6 lines, 2 passes, 180 ms, 0 warnings, 0 errors

*** Link  ManifestedConsoleProgram.obj rsrc.res  using polink, sub CONSOLE ***


***  build all took 2685 ms  ***
« OK »


Nothing special, but of course, it can't find the GuiData.zip on your machine :icon_redface: