Retrieving the operating system version by reading data from kernel32 :
include GetOSvers64.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 PROC PARMAREA=4*QWORD
invoke GetModuleHandle,ADDR kernel32
test rax,rax
jz @f
xor rcx,rcx
mov ecx,IMAGE_DOS_HEADER.e_lfanew[rax]
add rax,rcx
movzx r8,IMAGE_NT_HEADERS.OptionalHeader.MajorOperatingSystemVersion[rax]
movzx r9,IMAGE_NT_HEADERS.OptionalHeader.MinorOperatingSystemVersion[rax]
invoke wsprintf,ADDR buffer,ADDR str1,r8,r9
invoke StdOut,ADDR buffer
@@:
invoke ExitProcess,0
start ENDP
StdOut PROC uses r14 r15 string:QWORD PARMAREA=5*QWORD
; Function from the Masm64 package
; rcx = text address
LOCAL bwrt:QWORD
mov r14,rcx ; store address in r14
mov rax,r14
sub rax,1
@@:
add rax,1
cmp BYTE PTR [rax],0 ; get the text length
jne @B
sub rax,r14 ; sub original address from RAX
mov r15,rax ; save string length into r15
invoke GetStdHandle,STD_OUTPUT_HANDLE
mov rcx,rax
lea r9,bwrt
xor r10,r10
invoke WriteFile,rcx,r14,r15,r9,r10
mov rax,bwrt ; return value is bytes written
ret
StdOut ENDP
END start
With C:#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
int __cdecl main(void)
{
HMODULE hMod = GetModuleHandle(TEXT("kernel32.dll"));
IMAGE_NT_HEADERS *pNtHdr = (IMAGE_NT_HEADERS*)(((LONGLONG)hMod)+((IMAGE_DOS_HEADER*)hMod)->e_lfanew);
printf("%u.%u\n", pNtHdr->OptionalHeader.MajorOperatingSystemVersion, pNtHdr->OptionalHeader.MinorOperatingSystemVersion);
return 0;
}
Quote from: TimoVJL on January 15, 2024, 08:28:14 PM
With C:#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
int __cdecl main(void)
{
HMODULE hMod = GetModuleHandle(TEXT("kernel32.dll"));
IMAGE_NT_HEADERS *pNtHdr = (IMAGE_NT_HEADERS*)(((LONGLONG)hMod)+((IMAGE_DOS_HEADER*)hMod)->e_lfanew);
printf("%u.%u\n", pNtHdr->OptionalHeader.MajorOperatingSystemVersion, pNtHdr->OptionalHeader.MinorOperatingSystemVersion);
return 0;
}
When the above code is compiled and run on my machine the output is
10
This command line snippet
systeminfo | findstr /B /C:"OS Name" /C:"OS Version"
outputs
OS Name: Microsoft Windows 11 Pro
OS Version: 10.0.22631 N/A Build 22631
Check kernel32.dll header.
Many of us might want to know, how dll was linked.
Also version info of that dll is interesting.
Hi Timo,
Thanks for the C code.
Quote from: TimoVJL on January 15, 2024, 09:29:45 PM
Check kernel32.dll header.
Many of us might want to know, how dll was linked.
Also version info of that dll is interesting.
Hi Timo:
I am not sure what you are asking here "Check kernel32.dll header." ???
The kernel32.dll Product version is 10.0.22621.2506
It is different from the OS version: 10.0.22631
I linked your program with Pelles 12
polink.exe /release /MACHINE:X64 /SUBSYSTEM:CONSOLE /STACK:10485760
QuoteWindows 8.1 and later pretend to be Windows 8 (legacy/trac#28096 (moved)).
If we want to display the real Windows version, we can use GetFileVersionInfo() to check the version of Kernel32.dll:
https://docs.microsoft.com/en-au/windows/desktop/SysInfo/getting-the-system-version
https://gitlab.torproject.org/tpo/core/tor/-/issues/28097
QuoteNote, that Microsoft doesn't make things easy with their internal version numbering. One would assume that Windows 11 would have a major version number set as 11. But this doesn't seem to be the case. They still consider Windows 11 to have a major version number of 10. So, to distinguish between Windows 10 and 11 you need to rely on the BuildNumber. Anything greater or equal to 20000 will indicate Windows 11. Anything from [10000 to 20000), Windows 10.
https://dennisbabkin.com/blog/?t=how-to-tell-the-real-version-of-windows-your-app-is-running-on