Author Topic: Retrieving Windows OS Version  (Read 13514 times)

nidud

  • Member
  • *****
  • Posts: 1800
    • https://github.com/nidud/asmc
Re: Retrieving Windows OS Version
« Reply #30 on: June 12, 2017, 11:13:08 PM »
The ASCII version is declared as bytes in winbase.inc, but this fails.

Code: [Select]
include stdio.inc
include tchar.inc
include winbase.inc

    .code

_tmain proc
    local RTL:OSVERSIONINFO

    mov RTL.dwOSVersionInfoSize,sizeof(OSVERSIONINFO)
    .if !RtlGetVersion( &RTL )
_tprintf("dwMajorVersion: %d\n", RTL.dwMajorVersion)
_tprintf("dwMinorVersion: %d\n", RTL.dwMinorVersion)
_tprintf("dwBuildNumber:  %d\n", RTL.dwBuildNumber)
_tprintf("dwPlatformId:   %d\n", RTL.dwPlatformId)
_tprintf("szCSDVersion:   %s\n", &RTL.szCSDVersion)       
    .endif
    xor eax,eax
    ret
_tmain endp

    end _tstart

asmc -pe -D__PE__ test.asm
Code: [Select]
dwMajorVersion: 6
dwMinorVersion: 1
dwBuildNumber:  7601
dwPlatformId:   2
szCSDVersion:   S

asmc -pe -D__PE__ -ws -D_UNICODE test.asm
Code: [Select]
dwMajorVersion: 6
dwMinorVersion: 1
dwBuildNumber:  7601
dwPlatformId:   2
szCSDVersion:   Service Pack 1

From winbase.inc
Code: [Select]
OSVERSIONINFOA STRUC
dwOSVersionInfoSize dd ?
dwMajorVersion dd ?
dwMinorVersion dd ?
dwBuildNumber dd ?
dwPlatformId dd ?
szCSDVersion db 128 dup(?) ; Maintenance string for PSS usage
OSVERSIONINFOA ENDS

OSVERSIONINFOW STRUC
dwOSVersionInfoSize dd ?
dwMajorVersion dd ?
dwMinorVersion dd ?
dwBuildNumber dd ?
dwPlatformId dd ?
szCSDVersion dw 128 dup(?) ; Maintenance string for PSS usage
OSVERSIONINFOW ENDS

ifdef _UNICODE
OSVERSIONINFO typedef OSVERSIONINFOW
else
OSVERSIONINFO typedef OSVERSIONINFOA
endif

From winnt.h
Code: [Select]
typedef struct _OSVERSIONINFOA {
    DWORD dwOSVersionInfoSize;
    DWORD dwMajorVersion;
    DWORD dwMinorVersion;
    DWORD dwBuildNumber;
    DWORD dwPlatformId;
    CHAR   szCSDVersion[ 128 ];     // Maintenance string for PSS usage
} OSVERSIONINFOA, *POSVERSIONINFOA, *LPOSVERSIONINFOA;

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;

same with _OSVERSIONINFOEXA (CHAR/WCHAR)

nidud

  • Member
  • *****
  • Posts: 1800
    • https://github.com/nidud/asmc
Re: Retrieving Windows OS Version
« Reply #31 on: June 12, 2017, 11:32:25 PM »
New test:
Code: [Select]
    local RTL:OSVERSIONINFOEX
    mov RTL.dwOSVersionInfoSize,sizeof(OSVERSIONINFOEX)
    .if !RtlGetVersion( &RTL )
_tprintf("dwMajorVersion:    %d\n", RTL.dwMajorVersion)
_tprintf("dwMinorVersion:    %d\n", RTL.dwMinorVersion)
_tprintf("dwBuildNumber:     %d\n", RTL.dwBuildNumber)
_tprintf("dwPlatformId:      %d\n", RTL.dwPlatformId)
_tprintf("szCSDVersion:      %s\n", &RTL.szCSDVersion)
_tprintf("wServicePackMajor: %d\n", RTL.wServicePackMajor)
_tprintf("wServicePackMinor: %d\n", RTL.wServicePackMinor)
    .endif

ASCII:
Code: [Select]
dwMajorVersion:    6
dwMinorVersion:    1
dwBuildNumber:     7601
dwPlatformId:      2
szCSDVersion:      S
wServicePackMajor: 65428
wServicePackMinor: 24

UNICODE:
Code: [Select]
dwMajorVersion:    6
dwMinorVersion:    1
dwBuildNumber:     7601
dwPlatformId:      2
szCSDVersion:      Service Pack 1
wServicePackMajor: 1
wServicePackMinor: 0

So.. there are no ASCII version, at least not in Win7.

As for printing in MASM32 you may try adding the switch /D__UNICODE__ to the assembler.

blue_devil

  • Member
  • **
  • Posts: 112
    • SCTZine
Re: Retrieving Windows OS Version
« Reply #32 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:
Code: [Select]
print addr rtlOsvx.szCSDVersiongave the correct answer. But the rest of the application turn chinese :dazzled: ::)
..Dreams make the future
But the past never lies..
BlueDeviL // SCT
My Code Site:
SCTZine Assembly

nidud

  • Member
  • *****
  • Posts: 1800
    • https://github.com/nidud/asmc
Re: Retrieving Windows OS Version
« Reply #33 on: June 13, 2017, 12:00:51 AM »
 :biggrin:

I used RtlGetVersion().
GetVersionEx() works with ASCII and Unicode

asmc -pe -D__PE__ test.asm
Code: [Select]
    local RTL:OSVERSIONINFOEX

    mov RTL.dwOSVersionInfoSize,sizeof(OSVERSIONINFOEX)
    .if GetVersionEx( &RTL )
_tprintf("dwMajorVersion:    %d\n", RTL.dwMajorVersion)
_tprintf("dwMinorVersion:    %d\n", RTL.dwMinorVersion)
_tprintf("dwBuildNumber:     %d\n", RTL.dwBuildNumber)
_tprintf("dwPlatformId:      %d\n", RTL.dwPlatformId)
_tprintf("szCSDVersion:      %s\n", &RTL.szCSDVersion)
_tprintf("wServicePackMajor: %d\n", RTL.wServicePackMajor)
_tprintf("wServicePackMinor: %d\n", RTL.wServicePackMinor)
    .endif

Code: [Select]
dwMajorVersion:    6
dwMinorVersion:    1
dwBuildNumber:     7601
dwPlatformId:      2
szCSDVersion:      Service Pack 1
wServicePackMajor: 1
wServicePackMinor: 0

blue_devil

  • Member
  • **
  • Posts: 112
    • SCTZine
Re: Retrieving Windows OS Version
« Reply #34 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:
..Dreams make the future
But the past never lies..
BlueDeviL // SCT
My Code Site:
SCTZine Assembly

jj2007

  • Member
  • *****
  • Posts: 9804
  • Assembler is fun ;-)
    • MasmBasic
Re: Retrieving Windows OS Version
« Reply #35 on: June 15, 2017, 12:06:49 AM »
PEB is the fastest

How can we resist the temptation to time this one?
Code: [Select]
This is Windows version 6.1, build 7601

54 ms   MbWinVersion
252 ms  RtlGetVersion

This is Windows version 6.1, build 7601
;)

blue_devil

  • Member
  • **
  • Posts: 112
    • SCTZine
Re: Retrieving Windows OS Version
« Reply #36 on: June 15, 2017, 12:16:23 AM »
PEB is the fastest

How can we resist the temptation to time this one?
Code: [Select]
This is Windows version 6.1, build 7601

54 ms   MbWinVersion
252 ms  RtlGetVersion

This is Windows version 6.1, build 7601
;)
:eusa_clap:
..Dreams make the future
But the past never lies..
BlueDeviL // SCT
My Code Site:
SCTZine Assembly

Siekmanski

  • Member
  • *****
  • Posts: 1929
Re: Retrieving Windows OS Version
« Reply #37 on: June 15, 2017, 12:34:42 AM »
GetVersionEx give the wrong windows version for Windows 8.1 ( it returns Windows 8 )
Creative coders use backward thinking techniques as a strategy.

blue_devil

  • Member
  • **
  • Posts: 112
    • SCTZine
Re: Retrieving Windows OS Version
« Reply #38 on: June 15, 2017, 12:53:31 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?
..Dreams make the future
But the past never lies..
BlueDeviL // SCT
My Code Site:
SCTZine Assembly

jj2007

  • Member
  • *****
  • Posts: 9804
  • Assembler is fun ;-)
    • MasmBasic
Re: Retrieving Windows OS Version
« Reply #39 on: June 15, 2017, 05:09:24 AM »
it is not possible to manifest console programs right?

Why not?

include \masm32\MasmBasic\MasmBasic.inc      ; download
  Init
  Print "Running with common controls version ", ComCtl32$()
  xchg MbWinVersion(), ecx
  Inkey Str$(" on Windows version %i.", MbWinVersion()), Str$(ecx)
EndOfCode


Code: [Select]
Running with common controls version 6.16 on Windows version 6.1

TWell

  • Member
  • ****
  • Posts: 748
Re: Retrieving Windows OS Version
« Reply #40 on: June 15, 2017, 04:51:26 PM »
Manifest can be external too, so you can add it afterwards.
My.exe.manifest
Code: [Select]
<?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>

nidud

  • Member
  • *****
  • Posts: 1800
    • https://github.com/nidud/asmc
Re: Retrieving Windows OS Version
« Reply #41 on: June 18, 2017, 06:44:15 PM »
GetVersionEx give the wrong windows version for Windows 8.1 ( it returns Windows 8 )

What version is the kernel header?

Code: [Select]
include stdio.inc
include tchar.inc
include winbase.inc

    .code

main proc
    .if GetModuleHandle("kernel32.dll")
mov ecx,[rax+0x3C]
movzx edx,[rax+rcx].IMAGE_NT_HEADERS.OptionalHeader.MinorOperatingSystemVersion
movzx eax,[rax+rcx].IMAGE_NT_HEADERS.OptionalHeader.MajorOperatingSystemVersion
printf("Windows: %d.%d\n", eax, edx)
    .else
perror("kernel32.dll")
    .endif
    xor eax,eax
    ret
main endp

    end _tstart
« Last Edit: June 18, 2017, 09:24:05 PM by nidud »

TWell

  • Member
  • ****
  • Posts: 748
Re: Retrieving Windows OS Version
« Reply #42 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
« Last Edit: June 18, 2017, 10:05:53 PM by TWell »

nidud

  • Member
  • *****
  • Posts: 1800
    • https://github.com/nidud/asmc
Re: Retrieving Windows OS Version
« Reply #43 on: June 18, 2017, 09:35:09 PM »
That example program crash in Windows 8.1

Yes, it was 32-bit code assembled as 64-bit so I updated the post above.

Quote
But a program with same idea show 6.3

If the OS is 64-bit the 32-bit kernel may not be the same version?

Vortex

  • Member
  • *****
  • Posts: 2033
Re: Retrieving Windows OS Version
« Reply #44 on: June 18, 2017, 09:46:16 PM »
nidud's method works fine on Windows XP 64-bit :

Code: [Select]
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

Code: [Select]
GetOSvers.exe
Major Operating System Version = 5
Minor Operating System Version = 2