Recent

Author Topic: Getting System Information from the Windows Registry  (Read 839 times)

OLLI_S

  • Full Member
  • ***
  • Posts: 117
Re: Getting System Information from the Windows Registry
« Reply #15 on: October 09, 2019, 09:40:14 pm »
Thank you all for your feedback.
I forwarded the topic to my friend, so he can try implementing this in C++

440bx

  • Hero Member
  • *****
  • Posts: 1123
Re: Getting System Information from the Windows Registry
« Reply #16 on: October 10, 2019, 02:28:13 am »
I suspect it is probably more of just a dependency issue, since RtlGetVersion() and RtlGetNtVersionNumbers() are in different libraries.
That's a reasonable guess but, inspecting the implementation of RtlGetVersion and RtlGetNtVersionNumbers, both in ntdll.dll, doesn't support it.

On Windows 7, SP1, 64bit, build 7601:

Implementation of RtlGetNtVersionNumbers:
Code: ASM  [Select]
  1.                 public RtlGetNtVersionNumbers
  2. RtlGetNtVersionNumbers proc near        ; DATA XREF: .rdata:off_78F56298o
  3.  
  4. ; FUNCTION CHUNK AT 0000000078EB7C9D SIZE 00000008 BYTES
  5.  
  6.                 test    rcx, rcx
  7.                 jz      short loc_78E9517B
  8.                 mov     dword ptr [rcx], 6  
  9.  
  10. loc_78E9517B:                           ; CODE XREF: RtlGetNtVersionNumbers+3j
  11.                 test    rdx, rdx
  12.                 jz      short loc_78E95186
  13.                 mov     dword ptr [rdx], 1  
  14.  
  15. loc_78E95186:                           ; CODE XREF: RtlGetNtVersionNumbers+Ej
  16.                 test    r8, r8
  17.                 jnz     loc_78EB7C9D
  18.                 rep retn
  19. RtlGetNtVersionNumbers endp
  20.  
  21. ...
  22. more ntdll code/functions
  23. ...
  24.  
  25. ; START OF FUNCTION CHUNK FOR RtlGetNtVersionNumbers
  26.  
  27. loc_78EB7C9D:                           ; CODE XREF: RtlGetNtVersionNumbers+19j
  28.                 mov     dword ptr [r8], 0F0001DB1h
  29.                 retn
  30. ; END OF FUNCTION CHUNK FOR RtlGetNtVersionNumbers
  31.  
What's notable about the code above is that the major and minor Windows version and the build info are hardcoded, as they should be, since the only way those could change is by installing a different version of Windows.  It's clear in this function that no attempt is made to "massage" the values returned to the caller.

Implementation of RtlGetVersion:
Code: ASM  [Select]
  1.                 public RtlGetVersion
  2. RtlGetVersion   proc near               ; CODE XREF: RtlVerifyVersionInfo+57p
  3.                                         ; CheckWinSQMOptinValue+497F2p
  4.                                         ; DATA XREF: ...
  5.  
  6. arg_0           = dword ptr  8
  7. arg_8           = qword ptr  10h
  8.  
  9. ; FUNCTION CHUNK AT 0000000078E823E5 SIZE 00000066 BYTES
  10. ; FUNCTION CHUNK AT 0000000078EB48C9 SIZE 0000000A BYTES
  11. ; FUNCTION CHUNK AT 0000000078EEE6F9 SIZE 00000036 BYTES
  12.  
  13.                 push    rbx
  14.                 sub     rsp, 20h
  15.                 mov     rax, gs:30h
  16.                 mov     [rsp+28h+arg_8], rdi
  17.                 mov     rbx, rcx
  18.                 mov     r9, [rax+60h]
  19.                 mov     eax, [r9+118h]
  20.                 mov     [rcx+4], eax
  21.                 mov     eax, [r9+11Ch]
  22.                 mov     [rcx+8], eax
  23.                 movzx   eax, word ptr [r9+120h]
  24.                 mov     [rcx+0Ch], eax
  25.                 mov     eax, [r9+124h]
  26.                 mov     [rcx+10h], eax
  27.                 mov     r8, [r9+2F0h]
  28.                 test    r8, r8
  29.                 jz      loc_78EEE711
  30.                 cmp     word ptr [r8], 0
  31.                 jz      loc_78EEE711
  32.                 lea     rdi, [rcx+14h]
  33.                 xor     r10d, r10d
  34.                 mov     edx, 80h
  35.                 mov     rcx, rdi
  36.                 sub     r8, rdi
  37.                 mov     r11d, r10d
  38.  
  39. loc_78E79424:                           ; CODE XREF: RtlGetVersion+95j
  40.                 lea     rax, [rdx+7FFFFF7Eh]
  41.                 test    rax, rax
  42.                 jz      short loc_78E7944C
  43.                 movzx   eax, word ptr [r8+rcx]
  44.                 test    ax, ax
  45.                 jz      short loc_78E7944C
  46.                 mov     [rcx], ax
  47.                 add     rcx, 2
  48.                 sub     rdx, 1
  49.                 jnz     short loc_78E79424
  50.                 jmp     loc_78EB48C9
  51. ; ---------------------------------------------------------------------------
  52.  
  53. loc_78E7944C:                           ; CODE XREF: RtlGetVersion+7Ej
  54.                                         ; RtlGetVersion+88j
  55.                 test    rdx, rdx
  56.                 jz      loc_78EEE6F9
  57.  
  58. loc_78E79455:                           ; CODE XREF: RtlGetVersion+75353j
  59.                 mov     [rcx], r10w
  60.                 test    r11d, r11d
  61.                 js      loc_78EEE708
  62.  
  63. loc_78E79462:                           ; CODE XREF: RtlGetVersion+7535Cj
  64.                                         ; RtlGetVersion+75369j
  65.                 cmp     dword ptr [rbx], 11Ch
  66.                 mov     rdi, [rsp+28h+arg_8]
  67.                 jz      loc_78E823E5
  68.  
  69. loc_78E79473:                           ; CODE XREF: RtlGetVersion+907Dj
  70.                                         ; RtlGetVersion+9090j ...
  71.                 xor     eax, eax
  72.                 add     rsp, 20h
  73.                 pop     rbx
  74.                 retn
  75. RtlGetVersion   endp
  76.  
  77. ...
  78. more ntdll code/function/procedures
  79. ...
  80. ; START OF FUNCTION CHUNK FOR RtlGetVersion
  81.  
  82. loc_78E823E5:                           ; CODE XREF: RtlGetVersion+BDj
  83.                 movzx   eax, byte ptr [r9+123h]
  84.                 mov     ecx, 0FFh
  85.                 mov     [rbx+114h], ax
  86.                 movzx   eax, word ptr [r9+122h]
  87.                 and     ax, cx
  88.                 lea     rcx, [rsp+28h+arg_0]
  89.                 mov     [rbx+116h], ax
  90.                 mov     ax, ds:7FFE02D0h
  91.                 mov     byte ptr [rbx+11Ah], 0
  92.                 mov     [rbx+118h], ax
  93.                 call    RtlGetNtProductType
  94.                 test    al, al
  95.                 jz      loc_78E79473
  96.                 mov     eax, [rsp+28h+arg_0]
  97.                 mov     [rbx+11Ah], al
  98.                 cmp     eax, 1
  99.                 jnz     loc_78E79473
  100.                 jmp     loc_78EB48CE
  101. ; END OF FUNCTION CHUNK FOR RtlGetVersion
  102.  
  103. ; START OF FUNCTION CHUNK FOR RtlGetVersion
  104.  
  105. loc_78EB48C9:                           ; CODE XREF: RtlGetVersion+97j
  106.                 jmp     loc_78EEE6F9
  107. ; ---------------------------------------------------------------------------
  108.  
  109. loc_78EB48CE:                           ; CODE XREF: RtlGetVersion+9096j
  110.                 jmp     loc_78EEE71E
  111. ; END OF FUNCTION CHUNK FOR RtlGetVersion
  112.  
  113. ...
  114. more code for other things
  115. ....
  116.  
  117. ; START OF FUNCTION CHUNK FOR RtlGetVersion
  118.  
  119. loc_78EEE6F9:                           ; CODE XREF: RtlGetVersion+9Fj
  120.                                         ; RtlGetVersion:loc_78EB48C9j
  121.                 sub     rcx, 2
  122.                 mov     r11d, 80000005h
  123.                 jmp     loc_78E79455
  124. ; ---------------------------------------------------------------------------
  125.  
  126. loc_78EEE708:                           ; CODE XREF: RtlGetVersion+ACj
  127.                 mov     [rdi], r10w
  128.                 jmp     loc_78E79462
  129. ; ---------------------------------------------------------------------------
  130.  
  131. loc_78EEE711:                           ; CODE XREF: RtlGetVersion+4Ej
  132.                                         ; RtlGetVersion+59j
  133.                 xor     r10d, r10d
  134.                 mov     [rcx+14h], r10w
  135.                 jmp     loc_78E79462
  136. ; ---------------------------------------------------------------------------
  137.  
  138. loc_78EEE71E:                           ; CODE XREF: RtlGetVersion:loc_78EB48CEj
  139.                 mov     eax, 0FFEFh
  140.                 and     [rbx+118h], ax
  141.                 jmp     loc_78E79473
  142. ; END OF FUNCTION CHUNK FOR RtlGetVersion
  143.  
The one thing that is immediately noticeable in RtlGetVersion is that the values returned for the Windows major and minor version are not hardcoded, they are read from a data structure that is process specific.  The other thing that is noticeable is that, it shouldn't take that much code to return values that are supposed to be constant.

I would be surprised if RtlGetVersion didn't occasionally "lie" to the caller. If it didn't, its implementation would be much simpler.

It's unfortunate that the only API in Windows that tells the "truth" is undocumented. 
using FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.