News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Get Version by TEB

Started by ic2, January 09, 2007, 07:36:47 AM

Previous topic - Next topic

ic2

This is an old code founded on the net that get the OS with-out calling a api.  It is just about the only good example of how to use  TEB/PEB.  It works for my xp no service pack.  the return value is (6).

On my Win95b it returns (2), it should have returned (1)

On my Win98se it returns (2) which is correct.

could someone check this code especially on win95 machine and NT type machines with service packs and post the results,

It's a very popular old code but I don't think it was really tested on a win95 machine when it was in development and I can't figure out a way to correct it.

The arrows below points out where the problems may be.  I think something is mis-placed or over written.

Thanks in advance.



;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.386
.model flat, STDCALL
option casemap :none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc


includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib


;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;-- return values from OS_GetOS
.const
Equ_1 equ 1
Equ_2 equ 2
Equ_3 equ 3
Equ_4 equ 4
Equ_5 equ 5
Equ_6 equ 6
Equ_7 equ 7

Equ_UNKNOWN_999 equ 9999

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

.data?
WINDOW_VERSION DWORD   ?


.code


OS_GetOS proc


pushad                                  ;  store all registers
mov WINDOW_VERSION, Equ_UNKNOWN_999

ifndef __POASM__
assume fs:nothing
endif 

    mov ebx,fs:[18h]                    ;  get self pointer from TEB
    mov eax,fs:[30h]                    ;  get pointer to PEB / database

.if eax==7FFDF000h && ebx==7FFDE000h    ;  WinNT based
    mov ebx,[eax+0A8h]                  ;  get OSMinorVersion
    mov eax,[eax+0A4h]                  ;  get OSMajorVersion

.if eax==5 && ebx==0                    ;  is it Windows 2000?
    mov WINDOW_VERSION, Equ_5

.elseif eax==5 && ebx==1                ;  is it Windows XP?
        mov WINDOW_VERSION, Equ_6

.elseif eax==5 && ebx==2                ;  is it Windows 2003?
        mov WINDOW_VERSION, Equ_7

.elseif eax<=4                          ;  is it Windows NT?
        mov WINDOW_VERSION, Equ_4
.endif

.else

; Win9X based
    mov edx,00530000h       ; the magic value to search
    mov eax,fs:[18h]            ; get the TEB base address
    mov ebx,[eax+58h]       ; TEB-base + 58h (W95)  < ------------
    mov ecx,[eax+7Ch]       ; TEB-base + 7Ch (WME)
    mov eax,[eax+54h]       ; TEB-base + 54h (W98)  < ------------

.if ebx==edx                                        ; is it Windows 95?
    mov WINDOW_VERSION, Equ_1

.elseif eax==edx                                    ; is it Windows 98?
    mov WINDOW_VERSION, Equ_2

.elseif ecx==edx                                    ; is it Windows ME?
    mov WINDOW_VERSION, Equ_3
.endif
.endif                                              ; END of base check NT/9X


popad                                   ;  restore all registers
mov eax,WINDOW_VERSION
ret                                     ;  return to caller

OS_GetOS endp

; ######################################################   
dwtoa proc dwValue:DWORD, lpBuffer:DWORD

    push ebx
    push esi
    push edi

    mov eax, dwValue
    mov edi, [lpBuffer]

    test eax,eax
    jnz sign

  zero:
    mov word ptr [edi],30h
    jmp dtaexit

  sign:
    jns pos
    mov byte ptr [edi],'-'
    neg eax
    add edi, 1

  pos:
    mov ecx, 3435973837
    mov esi, edi

    .while (eax > 0)
      mov ebx,eax
      mul ecx
      shr edx, 3
      mov eax,edx
      lea edx,[edx*4+edx]
      add edx,edx
      sub ebx,edx
      add bl,'0'
      mov [edi],bl
      add edi, 1
    .endw

    mov byte ptr [edi], 0       ;  terminate the string
                                ;  We now have all the digits,
                                ;  but in reverse order.
    .while (esi < edi)
      sub edi, 1
      mov al, [esi]
      mov ah, [edi]
      mov [edi], al
      mov [esi], ah
      add esi, 1
    .endw

  dtaexit:

    pop edi
    pop esi
    pop ebx


    ret

dwtoa endp

; ######################################################   
; ######################################################   
; ######################################################   

start:
invoke OS_GetOS
PUSH offset WINDOW_VERSION
PUSH eax
CALL dwtoa


PUSH 0
PUSH 0
PUSH  offset WINDOW_VERSION
PUSH 0
CALL MessageBox

invoke ExitProcess,0



end start


:make
set name=getOS_1

;    \masm32\bin\ml /c /coff %name%.bat
;    \masm32\bin\Link /subsystem:windows %name%.obj

;    if exist *.bak del *.bak
;    if exist *.obj del *.obj
;    echo.


TNick

Strange (I didn't debug to see why), mostly returns 9999, but sometimes returns 6 (4 9999 and 1 6, 3 9999 and 1 6, ... no pattern, I think) on XP Home Edition SP 2

six_L

Quote1、Processing the Address of PEB Through Random

    In the XP system, Creating the Process is the _NtCreateProcessEx function,not
the _NtCreateProcess function. the _NtCreateProcess call _PspCreateProcess@36 function mainly
to finish the work of the Process created.

PAGE:004B4649          CALL _PspCreateProcess@36       ; PspCreateProcess(x,x,x,x,x,x,x,x,x)
;The work of the Process created is consist of setting the EPROCESS, Creating the Address area
;of the original Process, and so on. Setting PEB with CALL _MmCreatePeb.

PAGE:004B428E          push    eax
PAGE:004B428F          push    ebx
PAGE:004B4290          push    dword ptr [ebp-60h]
PAGE:004B4293          call    _MmCreateProcessAddressSpace@12 ; mCreateProcessAddressSpace(x,x,x)
PAGE:004B43E5          lea     eax, [ebx+1B0h]
PAGE:004B43EB          push    eax
PAGE:004B43EC          lea     eax, [ebp-40h]
PAGE:004B43EF          push    eax
PAGE:004B43F0          push    ebx
PAGE:004B43F1          call    _MmCreatePeb@12
              ; MmCreatePeb(x,x,x) and MmCreatePeb call by the _MiCreatePebOrTeb
PAGE:004B4A61 ; __stdcall MmCreatePeb(x,x,x)
PAGE:004B4A61  _MmCreatePeb@12 proc near               
              ; CODE XREF : PspCreateProcess(x,x,x,x,x,x,x,x,x)+303 p
PAGE:004B4A61
PAGE:004B4A61 ; FUNCTION CHUNK AT PAGE:005267FF SIZE 000000DC BYTES
PAGE:004B4A61
PAGE:004B4A61           push    3Ch
PAGE:004B4A63           push    offset dword_42DAA8
PAGE:004B4A68           call    __SEH_prolog
PAGE:004B4A6D           xor     ebx, ebx
PAGE:004B4A6F           mov     [ebp-20h], ebx
PAGE:004B4A72           mov     [ebp-4Ch], ebx
PAGE:004B4A75           mov     [ebp-48h], ebx
PAGE:004B4A78           mov     [ebp-2Ch], ebx
PAGE:004B4A7B           mov     esi, [ebp+8]
PAGE:004B4A7E           push    esi
PAGE:004B4A7F           call    _KeAttachProcess@4   ; KeAttachProcess(x)
PAGE:004B4A84           push    2
PAGE:004B4A86           pop     edi
PAGE:004B4A87           push    edi
PAGE:004B4A88           push    (offset loc_4FFFFE+2)
PAGE:004B4A8D           push    1
PAGE:004B4A8F           lea     eax, [ebp-2Ch]
PAGE:004B4A92           push    eax
PAGE:004B4A93           lea     eax, [ebp-4Ch]
PAGE:004B4A96           push    eax
PAGE:004B4A97           push    ebx
PAGE:004B4A98           push    ebx
PAGE:004B4A99           lea     eax, [ebp-20h]
PAGE:004B4A9C           push    eax
PAGE:004B4A9D           push    esi
PAGE:004B4A9E           push    ds:_InitNlsSectionPointer
PAGE:004B4AA4           call    _MmMapViewOfSection@40 ; MmMapViewOfSection(x,x,x,x,x,x,x,x,x,x)
PAGE:004B4AA9           mov     [ebp-24h], eax
PAGE:004B4AAC           cmp     eax, ebx
PAGE:004B4AAE           jl      loc_5267FF
PAGE:004B4AB4           lea     eax, [ebp-1Ch]
               ; Attention the 210 value, it looks a Flag. You'll find the follow, if the
          ; value != 210, then the mapping address could not creat a random value,
          ; it is same as the former value, is always at 7FFDF000 address.
PAGE:004B4AB7           push    eax
PAGE:004B4AB8           push    210h
               ; Attention the value !
PAGE:004B4ABD           push    esi
PAGE:004B4ABE           call    _MiCreatePebOrTeb@12
       ; MiCreatePebOrTeb(x,x,x),the fact work finished by the _MiCreatePebOrTeb@12 function
PAGE:004B01AE           call    _ExAllocatePoolWithTag@12 ; ExAllocatePoolWithTag(x,x,x)
PAGE:004B01B3           mov     esi, eax
PAGE:004B01B5           test    esi, esi
PAGE:004B01B7           jz      loc_52678E
PAGE:004B01BD           mov     eax, [ebp+arg_8]
PAGE:004B01C0           mov     ecx, [ebp+arg_8]
PAGE:004B01C3           and     eax, 0FFFh
PAGE:004B01C8           neg     eax
PAGE:004B01CA           sbb     eax, eax
PAGE:004B01CC           neg     eax
PAGE:004B01CE           shr     ecx, 0Ch
PAGE:004B01FB           cmp     [ebp+arg_8], 210h
PAGE:004B0202           jz      loc_4B4A0A
            ;Here is the compartion of 210 and the pushed value,estimating the pushed value == 210.
PAGE:004B0208 loc_4B0208:         ; CODE XREF: MiCreatePebOrTeb(x,x,x)+48AD j
PAGE:004B0208           mov     edi, [ebp+arg_C]
PAGE:004B020B           mov     eax, _MmHighestUserAddress
PAGE:004B0210           push    edi
PAGE:004B0211           push    dword ptr [ebx+11Ch]
PAGE:004B0217           add     eax, 0FFFF0001h
PAGE:004B021C           push    1000h
PAGE:004B0221           push    eax
PAGE:004B0222           mov     eax, [ebp+arg_8]
PAGE:004B0225           add     eax, 0FFFh
PAGE:004B022A           and     eax, 0FFFFF000h
PAGE:004B022F           push    eax
PAGE:004B0230           call    _MiFindEmptyAddressRangeDownTree@20
              ; MiFindEmptyAddressRangeDownTree(x,x,x,x,x)
PAGE:004B0235           test    eax, eax
PAGE:004B0237           mov     [ebp+arg_C], eax
PAGE:004B023A           jl      loc_5267A5
              ; Here is the crux
PAGE:004B4A0A loc_4B4A0A:          ; CODE XREF: MiCreatePebOrTeb(x,x,x)+66 j
PAGE:004B4A0A           mov     edi, _MmHighestUserAddress
              ;it always is 7FFEFFFF
PAGE:004B4A10           lea     eax, [ebp+var_C]
PAGE:004B4A13           push    eax
PAGE:004B4A14           add     edi, 0FFFF0001h
              ; at the time, edi == 7FFE0000
PAGE:004B4A1A           call    _KeQueryTickCount@4 ; KeQueryTickCount(x)
PAGE:004B4A1F           mov     eax, [ebp+var_C]
PAGE:004B4A22           and     eax, 0Fh
              ; only get the last array value, for example, it is 0C at the time.
PAGE:004B4A25           cmp     eax, 1
              ; judging eax == 01 at the time
PAGE:004B4A28           mov     [ebp+var_C], eax
PAGE:004B4A2B           jbe     loc_4B4928
              ; if eax == 01, then jmp processing
PAGE:004B4A31 loc_4B4A31:   ; CODE XREF: MiCreatePebOrTeb(x,x,x)+4792 j
PAGE:004B4A31           shl     eax, 0Ch
PAGE:004B4A34           sub     edi, eax
PAGE:004B4A36           lea     eax, [edi+0FFFh]
PAGE:004B4A3C           push    eax
PAGE:004B4A3D           push    edi
PAGE:004B4A3E           push    ebx
PAGE:004B4A3F           mov     [ebp+var_4], edi
PAGE:004B4928 loc_4B4928:   ; CODE XREF: MiCreatePebOrTeb(x,x,x)+488F j
             ;      .if eax == 1,
             ;             mov eax,2
             ;      .endif
             ; This prevented the PEB address == 7FFDF000 at end. it is 7FFDE000
PAGE:004B4928           push    2
PAGE:004B492A           pop     eax
PAGE:004B492B           mov     [ebp+var_C], eax
PAGE:004B492E           jmp     loc_4B4A31

             ; It can't be forecasted since the KeTickCount is a counter of process
.text:0041CAA8          mov     edi, edi
.text:0041CAAA          push    ebp
.text:0041CAAB          mov     ebp, esp
.text:0041CAAD          mov     ecx, _KeTickCount.High1Time
.text:0041CAB3          mov     eax, [ebp+arg_4]
.text:0041CAB6          mov     [eax+4], ecx
.text:0041CAB9          mov     edx, _KeTickCount.LowPart
.text:0041CABF          mov     [eax], edx


     On the above analysing, we knew: if eax is 1, 2 through the Random, All of the
PEB address is 7FFDE000,this prevented that the PEB address is 7FFDF000 at all time,
bring on the code which used the stack value will be false.

1    7FFDE000
2    7FFDE000
3    7FFDD000
4    7FFDC000
5    7FFDB000
6    7FFDA000
7    7FFD9000
8    7FFD8000
9    7FFD7000
A    7FFD6000
B    7FFD5000
C    7FFD4000
D    7FFD3000
E    7FFD2000
F    7FFD1000
0    7FFDE000

     The above list is the PEB address in all status by any possibility, we found the
probability of 7FFDE000 is the most high,== 1/8,all of others is 1/16. but, Although
it is that, we also can't use the PEB address stably。

regards

ic2

This is strange.  The sample i posted works for my xp Pro, 95 and 98 bringing the same results i indicated above.  So than I put the code at the very beginning of a very large project that usually works perfectly for all three of those OS and now I get 9999 on 9x OS but still get (6) for xp Pro. This is strange.

It changed everything, from working to non-working.

Anyway, if it did not work for XP Home it's no good for use as is.  Thanks for checking TNick.  I guest six_L finding has alot to do with this also... this is the strangest thing I ever seen.  I know TEB is tricky but this is just plain crazy but very interesting.  Now it all seem *finally* proven to be totally useless.  what a bomber.

Seb

It returned 9999 on my XP Home.

Edit: Geez, I tested running it twice in a row after it had returned 9999 and it gave me 6. :eek

Synfire

ic2,

Not to cross post, but a while back I posted a macro for ToutEnMasm on the Windows Programming Forum that did exactly what you are trying to do here. I've used it for years, originally written by Homer, it can be obtained from this post.

Regards,
Bryant Keller

ic2

Thanks Synfire but I get the same results as with the other code on XP Pro no-sp = (6), Win95b = (2), Win98se = (2) but I *can* place it in my project and it works unlike before which caused my app not to even execute ...  Anyway, at lease I got a real start now :)

The main problem for me seems to be distinguishing win95 from win98 other than winME and xp Home which I don't own.

Seh, how did you call it twice in a row.  When i tried it it default to what ever is in the first line of code ... mov ecx,666

Do you have to do the same thing using the IdentifyOS macro?  Are you near sure of accurate result?  If so, could you post an example.

I wonder if there another simpler method that can distinguish the difference between win95 and win98 that can be used after the IdentifyOS macro to retrieve those results with-out direct api calling or something else to search the garbage for something that would not be in 98 but would show up in 95 OS only.  It seem these two numbers makes NO difference.  Is anyone else having the same problem with this.

[eax+58h]==Win95
[eax+54h]==Win98


PS: six_L, what tool you used to extract all of that information. Is it Softice ?  I don't know how to debug with nothing more than messagebox.  Seems like a lot more knowledge is needed than just knowing how to use a debugger for what you come up with.  This is where i wish to be someday...

Seb

Quote from: ic2 on January 13, 2007, 10:09:09 AM
Seh, how did you call it twice in a row.  When i tried it it default to what ever is in the first line of code ... mov ecx,666

Well, I simply ran the EXE three times, the first two times it gave me 9999 and the third time it returned 6. And then after updating my post, I tested it again, and it would vary - sometimes it did give me 6, but most of the time the result was 9999.

six_L

QuotePS: six_L, what tool you used to extract all of that information. Is it Softice ?  I don't know how to debug with nothing more than messagebox.  Seems like a lot more knowledge is needed than just knowing how to use a debugger for what you come up with.  This is where i wish to be someday...
the text is not written by me, i only translated.
Quote1.8 Driver Debugging
As we should debug a kernel-mode code an appropriate debugger is required. SoftICE by Compuware ( http://www.compuware.com/products/numega/index.htm ) is the best choice. Also you can use Microsoft Kernel Debugger. It requires two computers - a target and a host. The target is the system being debugged, and the host is the system running the debugger. Mark Russinovich ( http://www.sysinternals.com/ ) has written the utility LiveKd that allows the use of the standard Microsoft Kernel Debugger on a live system, without needing two computers.
regards

ic2

One more question six_L, i know you are busy.  I'm finding it hard to locate the download page for Softice.  I been to SoftPedia a while back and did not find nothing but bittolorent and other junk like they were saying I needed all of this junk long before i can install softice which i still did not never find.  It's more than  enough keep up with masm32 so i dropped it because I thought i might miss something important while fooling around elsewhere ...  Hee hee.

They talk devPartners, securitychecker, devPart Simlation etc.   Do you have a closer direct link to the Softice download page?  I think it is only a trial version and cost big money, I read some where someone paid  $999.00  so I don't want to be fiddling around and download the wrong stuff, fire them up, make a stupit mistake, mess things up than try to re-install while never being allow to do so.  We all been there at one time or another. 

Also, I like the two computer idea.  Can that be also done with softice.  Would M$ Kernel Debugger be just as strong and easy to learn as softice.

I I reading about it for a few weeks so I can overcome my fear before i start downloading.  I'm sure they are very serious and want some personal information to eye ball me until i buy or die all for a Grand :) I'm still skimming though the link pages right now and still don't even see the word Softice. 
Anyway, how great can it be to receive hard facts from someone with real life *E x p e r i e N C E* and he ask for nothing in return.  hutch and Hiro ways has rubbed off on a lot of people.  That's all i really needed to know.  D end until we figure this thing out ...

six_L whooo!!!  whoooo!!!

hutch--

ic2,

Tread carefully here, SoftIce and its successors are commercial software and we will prevent anyone from posting links to illegal copies of any software.

>  It's more than  enough keep up with masm32 so i dropped it because I thought i might miss something important while fooling around elsewhere ...  Hee hee.

This forum and particularly the Campus is for assembler programmers, if you are not interested in this style of programming, you should be asking questions elsewhere.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php