hello, everybody.
here a code written by Thomas Kruse. when i tested it on the windows xp home edition, it returned -1(unknown).
what's error my usage?

regards.


;@echo off
;goto make
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.386
.model flat, STDCALL
option casemap :none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
include \masm32\include\masm32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\masm32.lib

include \masm32\Macros\macros.asm
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;-- return values from OS_GetOS
.const
OS_UNKNOWN equ -1
OS_WIN95 equ 1
OS_WIN98 equ 2
OS_WINME equ 3
OS_WINNT equ 4
OS_WIN2K equ 5
OS_WINXP equ 6
OS_WIN2K3 equ 7
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code

OS_GetOS proc
local _theReturnValue:DWORD

pushad ; store all registers
mov _theReturnValue,OS_UNKNOWN
assume fs:nothing
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 _theReturnValue,OS_WIN2K
.elseif eax==5 && ebx==1 ; is it Windows XP?
mov _theReturnValue,OS_WINXP
.elseif eax==5 && ebx==2 ; is it Windows 2003?
mov _theReturnValue,OS_WIN2K3
.elseif eax<=4 ; is it Windows NT?
mov _theReturnValue,OS_WINNT
.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 _theReturnValue,OS_WIN95
.elseif eax==edx ; is it Windows 98?
mov _theReturnValue,OS_WIN98
.elseif ecx==edx ; is it Windows ME?
mov _theReturnValue,OS_WINME
.endif
.endif ; of base check NT/9X
popad ; restore all registers
mov eax,_theReturnValue
ret ; return to caller
OS_GetOS endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:
invoke OS_GetOS
invoke MessageBox,NULL,str$(eax),chr$("---GetOS Test ---"),MB_OK or MB_ICONASTERISK
invoke ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

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.
Posted on 2005-01-04 08:20:25 by dcskm4200
You could just use GetVersionEx. Windows xp will be Windows NT 5.1
Posted on 2005-01-04 08:31:07 by QuantumMatrix1024
Thanks you replying.

Thomas Kruse said:
Detecting operating systems without Microsoft Advanced Programming Interface.

Today nearly all programmers use the Advanced Programming Interface (API) to receive information?s about given system values. By using this API?s, we don?t have to take care which operating system is currently available. But sometimes it might be needful to avoid the usage of such API?s. This situation is given during development of software
protections in order to avoid importing functions which - eventually - will point a reverse engineer to a solution.


i have thought he is right at all time.

regards
Posted on 2005-01-04 08:50:08 by dcskm4200
"Advanced Programming Interface"... hehe. The first A is for 'Application'.

The problem with Kruse's approach is that he is accessing some *very* version-dependant structures, and there's no guarantee whatsoever these structures won't change... theoretically, even a service pack or hotfix could change things around.
Posted on 2005-01-04 10:44:22 by f0dder
That man shouldn't be allowed to come near a computer again, and his magazines should be burnt.

What do you need the OS version for in your protection scheme?
Posted on 2005-01-04 12:37:29 by Sephiroth3
Just in case you were curious, here's how you'd get the OS version using the API:



LOCAL versionInfo:OSVERSIONINFO

...

; Get the operating system version
mov versionInfo.dwOSVersionInfoSize, SIZEOF OSVERSIONINFO
invoke GetVersionEx, ADDR versionInfo
.IF versionInfo.dwMajorVersion == 5
.IF versionInfo.dwMinorVersion == 2
; Windows Server 2003
.ELSEIF versionInfo.dwMinorVersion == 1
; Windows XP
.ELSEIF versionInfo.dwMinorVersion == 0
; Windows 2000
.ENDIF
.ELSEIF versionInfo.dwMajorVersion == 4
.IF versionInfo.dwMinorVersion == 0
.IF versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT
; Windows NT 4.0
.ELSEIF versionInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS
; Windows 95
.ENDIF
.ELSEIF versionInfo.dwMinorVersion == 90
; Windows ME
.ELSEIF versionInfo.dwMinorVersion == 10
; Windows 98
.ENDIF
.ELSEIF versionInfo.dwMajorVersion == 3
.IF versionInfo.dwMinorVersion == 51
; Windows NT 3.51
.ENDIF
.ELSE
; Windows 3.1 or earlier
.ENDIF

; Service pack is a string at "ADDR [versionInfo+20]"
; Build number is in "versionInfo.dwBuildNumber"


Spara
Posted on 2005-01-04 12:44:08 by Sparafusile
Thanks all who replyed my question.
;============================
f0dder,
today hook_technology has been used generally. we can't guarantee really our system is controled by pure windows operation.
which proc will need to change some *very* version-dependant structures? i don't ensure: if the structures has been changed, my windows operation isn't natural.
;===================================
Sephiroth3,
it sounds you don't like him. i'm a newbie. i tested the approach for learning.
;===================================
Sparafusile,
thanks you very much.
I don' know there has a another way without using the API CALL.


best regards.
Posted on 2005-01-04 19:40:03 by dcskm4200

today hook_technology has been used generally. we can't guarantee really our system is controled by pure windows operation.

It's the old cat-and-mouse game... which always ends up hurting end-users. In case you're worried about hooking, well... what stops an evil-doer putting a breakpoint on access to the PEB instead of GetVersion*? etc etc etc.


which proc will need to change some *very* version-dependant structures? i don't ensure: if the structures has been changed, my windows operation isn't natural.

What I'm saying is that Kruse's code accesses (reads) some undocumented windows structures. While it might never happen, you have no guarantee that microsoft will not change the layout of some of these structures.

Better to stick with the API, especially for something like getting the windows version.
Posted on 2005-01-04 19:50:18 by f0dder
f0dder,
Thanks you again.

1. if i wasn't wrong, your meaning is : Until now microsoft didn't change the structures.
2. with using Thomas Kruse's the approach, we can estimate that our system is normal. meaning: if calling OS_GetOS proc return parameter is right, then our system is normal; if calling OS_GetOS proc return parameter is error, then our system maybe some problems. is it right?


best regards
Posted on 2005-01-05 00:21:25 by dcskm4200
Advanced Programming Interface (API)??? haha :)
Where did he get that from?
Posted on 2005-01-05 07:10:29 by dev_zero

1. if i wasn't wrong, your meaning is : Until now microsoft didn't change the structures.

Microsoft havechanged the structures - but only some parts of it, and appearantly not the location of major+minor version. But nothing stops them from doing it, as this is internal & undocumented.


2. with using Thomas Kruse's the approach, we can estimate that our system is normal. meaning: if calling OS_GetOS proc return parameter is right, then our system is normal; if calling OS_GetOS proc return parameter is error, then our system maybe some problems. is it right?

Nope, why would it indicate that "our system is normal"?
Posted on 2005-01-05 07:29:43 by f0dder


if calling OS_GetOS proc return parameter is error, then our system maybe some problems. is it right?


Not a 'problem' just a change.
Posted on 2005-01-05 07:58:13 by QuantumMatrix1024
dev_zero,
here is the last section of the paper written by Thomas Kruse.

Conclusions
Resolving the operating system by using this technique is only one possibility to avoid the usage of Advanced Programming Interface functions. Other functions, for example GetCommandLine[1], IsDebuggerPresent[1] or named functions in this essay could be rewritten in the same way. In other words: the reverse engineer isn?t able to set breakpoints on API function calls, because they didn?t exist. And mixing different operating system solutions together makes life even harder for him.

References
[1] Microsoft Corporation, Microsoft Developer Network, http://msdm.microsoft.com
[2] Yuschuk, O., Olly Debugger, http://home.t-online.de/home/ollydbg
[3] Hutchenson, S., MASM V8, http://www.masmforum.com

Copyright c
2004 and published by the Assembly-Programming-Journal. Single print or electronic copies for personal use only are permitted. Reproduction and distribution without permission is prohibited.

your means:
The approach of getting OS version got from you or others ? it isn't his researched result ?
;=====================================================================
f0dder,
you gave me a lot of information that i need. as a newbie, i can't judge which way of getting OS version is better.
thanks thanks you again.

if you let your proc to run on all windows platform, you must know which windows operation system is your Proc will be run. until now, i understand his approach isn't entiretiely right.


best regards.
Posted on 2005-01-05 08:44:04 by dcskm4200
Nope, why would it indicate that "our system is normal"?
Not a 'problem' just a change.


according to Jeremy Gordon's <<Win32 Exception handling for assembler programmers >>, i knew that the fs register is used by debug application, anti-debug application, virus application,or anti-virus application. most of normal application don't need to use the fs register. in my windows operation system, I only installed some debug software (softice, ollydbg), I didn't start up them. but I tested the OS_GetOS is error result. so i thought the structures has been changed. if microsoft didn't change, who changed the structures? i guessed virus maybe change the structures. (now, I knew my comprehending is wrong, because f0dder said that Microsoft have changed some parts of the structures.)

best regards.
Posted on 2005-01-05 10:02:18 by dcskm4200
hi
just a quick noob question .... :)
what is that thing about TEB :


assume fs:nothing
mov ebx,fs:[18h]
mov eax,fs:[30h]

.if eax==7FFDF000h && ebx==7FFDE000h

mov ebx,[eax+0A8h]


and if i mov ebx fs:[18h] it would be = to 7ffdf000h ?!?!?!??!
im very very very confused :? :? :?
Posted on 2005-01-05 12:18:42 by GR33d
GR33d,

what is that thing about TEB,
and if i mov ebx fs:[18h] it would be = to 7ffdf000h ?!?!?!??!
im very very very confused

here is the LINK for explaining .
http://www.assembly-journal.com/viewarticle.php?id=144&layout=abstract

regards.
Posted on 2005-01-05 19:06:36 by dcskm4200
oh :shock:


now i get it :)

thx !
Posted on 2005-01-06 09:25:52 by GR33d
Build number:



osvi.dwBuildNumber & 0xffff


Evil. =)
Posted on 2005-01-09 13:15:56 by evil__donkey
hi, evil__donkey

osvi.dwBuildNumber & 0xffff what's means ?
how modify the code?

regards.
Posted on 2005-01-09 20:43:59 by dcskm4200
This will output a string like "Windows 2000 Service Pack 4"

DATA SECTION

szOSVersionW db "Windows",0
szOSVersion0 db "%s %u.%u %s",0
szOSVersion1 db "%s 95 %s",0
szOSVersion2 db "%s 98 %s",0
szOSVersion3 db "%s ME %s",0
szOSVersion5 db "%s NT4 %s",0
szOSVersion6 db "%s 2000 %s",0
szOSVersion7 db "%s XP %s",0
szOSVersion8 db "%s 2003 %s",0

CODE SECTION

GetWindowsString FRAME pOutString
LOCAL osvi :OSVERSIONINFO
LOCAL buffer[256] :B

invoke IsBadWritePtr,[pOutString],1
or eax,eax
jz >
xor eax,eax
dec eax
ret
:

mov D[osvi.dwOSVersionInfoSize],SIZEOF OSVERSIONINFO
invoke GetVersionExA,ADDR osvi
cmp D[osvi.dwMajorVersion],4
jne >>.XP2K
cmp D[osvi.dwMinorVersion],0
jne >
cmp D[osvi.dwPlatformId],VER_PLATFORM_WIN32_WINDOWS
jne >.NT4
invoke wsprintfA,[pOutString],offset szOSVersion1,offset szOSVersionW,\
OFFSET osvi.szCSDVersion
add esp,16
jmp >>.OSVERSION
.NT4
invoke wsprintfA,[pOutString],offset szOSVersion5,offset szOSVersionW,\
OFFSET osvi.szCSDVersion
add esp,16
jmp >>.OSVERSION
:
cmp D[osvi.dwMinorVersion],10
jne >
invoke wsprintfA,[pOutString],offset szOSVersion2,offset szOSVersionW,\
OFFSET osvi.szCSDVersion
add esp,16
jmp >>.OSVERSION
:
cmp D[osvi.dwMinorVersion],90
jne >
invoke wsprintfA,[pOutString],offset szOSVersion3,offset szOSVersionW,\
OFFSET osvi.szCSDVersion
add esp,16
jmp >>.OSVERSION
:
.XP2K
cmp D[osvi.dwMajorVersion],5
jne >>.OTHER
cmp D[osvi.dwMinorVersion],0
jne >
invoke wsprintfA,[pOutString],offset szOSVersion6,offset szOSVersionW,\
OFFSET osvi.szCSDVersion
add esp,16
jmp >>.OSVERSION
:
cmp D[osvi.dwMinorVersion],1
jne >
invoke wsprintfA,[pOutString],offset szOSVersion7,offset szOSVersionW,\
OFFSET osvi.szCSDVersion
add esp,16
jmp >.OSVERSION
:
cmp D[osvi.dwMinorVersion],2
jne >
invoke wsprintfA,[pOutString],offset szOSVersion8,offset szOSVersionW,\
OFFSET osvi.szCSDVersion
add esp,16
jmp >.OSVERSION
:
jmp >.OSVERSION
.OTHER
; Other
invoke wsprintfA,[pOutString],offset szOSVersion0,offset szOSVersionW,\
[osvi.dwMajorVersion],[osvi.dwMinorVersion],OFFSET osvi.szCSDVersion
add esp,24
.OSVERSION

RET
ENDF
Posted on 2005-01-09 21:32:23 by donkey