Created: 2005-04-13 Updated: 2005-04-14
Article attribute: translation
Article submission:
sfqry (MQPHK163_AT_163.COM)
Non-API function detection operating system type
Author: Thomas Kruse, nbw
source:
The assembly-programing-journal, Vol. 1, No. 1 (2004)
http://www.assembly-journal.com
Abstract
summary
Today Near 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..................
Almost all programmers now use the Extension Program Interface (API) to get operating system information. With an AIP function, we don't need to care about the specific status of the operating system used.
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.
But sometimes you can't use the API function. For example, when developing protection software, it is necessary to prevent the function information information to be referenced to the reverse direction.
THISSAY Show Up A Way To Detect The Today Given Operating Systems from Microsoft: Windows 95, 98, Me - The Non NT-BASED
Operating Systems - And Windows NT4, 2000, XP, 2003 - The NT-based Operating Systems.
This article describes how to detect the currently used operating system, Microsoft: Windows 95, 98, ME - non-NT core, and Windows NT4, 2000, XP -NT kernel systems.
The Shown Source Code Is in Microsoft Assembler Style (MASM [3]).
The code given here is a Microsoft assembly system (MASM [3]).
KeyWords: Microsoft Operating Systems, Software Protection, Assembly Programming, System Internals
Keywords: Microsoft operating system, software protection, assembler, system kernel
The Author Thomas Kruse Has His Main Research Focus ON OPERATING-SYSTEM INDEPENDENT CODE OPTIMISING AND SOFTWARE-Protection Development. He is associate
Editor Of Assembly-Journal and Codebreakers-journal.
Author Thomas Kruse is committed to the study of code and software protection systems independently of the operating system, and also the editor of Assembly-Journal and CodeBreakers-Journal. I. Introduction
Introduction
When analyysing the structure of the thread environment block (Teb - Also Known As Thread Information Block Tib) ON ONFORMATION BLOCK TIB
DiffERENT OPERATING SYSTEMS, We Find Additional Data Followed by this Structure. This Structure. This Structure. this Additional Data Seems to Have - On Non
NT-based Operating Systems - No Logical Structure or Length Definition, Where NT-based Operating Systems Store THE INFORMATION
INSIDE The Process Environment Block (PEB). The Only Way To Figure Out The Meaning Of this Data For Non NT-based Operating
Systems is to debugate systems [2].
Analyze thread environment blocks of different operating systems (TEB --- also called thread information block TIB), we can see additional data of this structure. For non-NT kernel systems, these additional data do not have logical structures or length definitions, and systems for NT kernels saves the information environment block (PEB) information. Determining the only way to significant in non-NT core systems, is to debug the same program in different operating systems.
Ii. Application Start
Program start
There Are Many Ways in Detecting An Operating System. It Could Be Done by Using The Windows API Function GetversionEx [1]
And Checking The Version Values Returned In Structure OsversionInfo (EX) [1], or by Accessing Register Cs. Another Way IS
Analyztes During Start Up of an Application. There Area SESTEMS PREPARE
Several Registers Before Executing The First Instruction:
There are many ways to detect the operating system. You can use the Windows API function GetversionEx [1], then check the return value or check the CS register. Another way is to analyze the value of the register to start running. There are many rules that have a lot of processing registers prior to the operating system execution program.
Startup Values for Windows 95/98 / ME
Windows 95/98 / ME boot value (translation: prior to program execution)
EAX == Application Entry Point
EAX == Program entry
EBX == 00530000H, A Fixed Value
Determine the value
Startup Values for Windows NT / 2000 / XP / 2003
Windows NT / 2000 / XP / 2003 Start Value EAX == NULL
EBX == 7FFDF000H, Pointer to (PEB)
EBX == 7FFDF000H, PEB pointer
By Knowing this rules we where able to check the operation system base during start up. But we need to store the register
Values of eax and ebx for further usage - Or resolve the in a different way.
With the above characteristics, we can determine the operating system type at startup. However, in order to use the use of EAX, EBX or other methods can be used in order to use it.
A. Thread Environment Block
A. Thread environment block
The Teb IS Prepared During Application Start Up and Contain Pointers To Thread Related Additional Data. The Teb Structure IS
Available On All Operating Systems. It's size is defined to 34h bytes. The teb address could be resolved by accessing the
Segment Register Fs in The Following Way:
The program started before the program was initialized and containing the thread reproduction data pointer. The TEB structure is valid in all operating systems. Its size is 34 bytes. The TEB address can be obtained by using the FS register to get the following method:
Assume fs: Nothing
Mov Eax, FS: [18h]
The Register Eax Will Contain The Base Address of this Block. The Teb Contains - At Address 18h Inside The Structure - a Pointer
To itself:
The EAX register contains a TEB address. The 18h bit in the TEB structure is a pointer to this TEB.
PSELF DWORD?; 18H Pointer to TEB / TIB
THE Last Entry of Teb Is The Pointer to Process Database. On NT-BASED OPERATING SYSTEMS THIS VALUE WILL POINT TOE THE ADDRESS
Of Process Environment Block (See Section II-C)
The last content of the TEB is a pointer to process data. In the NT core system, this value points to the process environment block (refer to the II-C part)
B. Additional Data Following Teb
B. TEB add-on data
Told In Section I, this Additional Data Has No Logical Structure and Differs on Each Non NT-BASED OPERATING SYSTEM. ON Windows
NT, 2000, XP and 2003 this Additional Data IS Defined As Follows:
Part I said that there is no logical structure and specific definitions in each non-NT core system (the translation: here seems to be the NT core structure). In Windows NT, 2000, XP, and 2003, these data are as follows:
NT_TEB_ADDON STRUCT
LastStatusValue DWORD?; 04H (38H TEB)
Countownedlocks DWORD?; 08H (3ch teb)
Harden ;; 0CH (40H TEB)
NT_TEB_ADDON ENDS
Windows 95, 98, ME Didn't Have Such A Structure; The Additional Data IS Scrambled!
Windows 95, 98, and ME do not have these data structures. Additional data is completely confusing!
C. Process Environment Block
C. Process Environment Block
Windows NT-Based Operating Systems Store Process Related Data Inside The Process Environment Block. The address of this
Structure is avaliable by accessing the segment register fs:
The NT kernel system stores the process-related data in the process environment block. The address of this structure can be obtained by operating the FS register:
Assume fs: Nothing
Mov Eax, FS: [30H]
The Register Eax Will Contain The Base Address Of PEB.
The EAX register is a PEB base address.
PPROCESS DWORD?; 30H Pointer to Process Database
The Version Information Is Stored Inside The PEB Structure:
The operating system information is stored in the PEB structure:
Osmajorversion DWORD DWORD?; A4H <= 4-> NT / 5-> 2K / XP / 2K3
OsminorVersion DWORD?; A8H 0-> 2K / 1-> XP / 2-> 2K3
D. NT-based definitions
D. Definition in the NT core
Windows NT, 2000, XP and 2003 Use Fixed Addresses to Store PEB and TEB. The PEB IS ALWAYS Stored At Address 7FFDF000H
And teb is starting at 7ffde000h. by Knowing these Two fixed value, it is possible to detect the Operating system base.
Windows NT, 2000, XP And 2003 uses fixed data storage PEB and TEB. PEB is always stored in 7FFDF000H, and TEB always starts with 7FFDE000H. You know these 2 fixed data, you can detect the operating system type.
Iii. The trick
Iii. Some skills
Section II-B HAS Shown An Add-on Structure for NT-BASED OPERATING SYSTEMS. The Data EXISTS ON NON NT-BASED OPERATING
Systems, Too. But it is stored in a different way. to resolve correct memory positions - Related to Detect the Operating System
Part II-B describes the storage of additional data in the NT core system. In the non-NT core system, there are also these data. But the storage method is different. By getting the position of these data, the operating system type can be detected.
- We use a trick the analyse the additional data.- We use some techniques to analyze these additional data
IF We Take a Closer Look to the NT Teb Addon Structure Shown In Section II-B, We See The entry LasterrorValue. NEARLY
All Windows API's Will Return An Error Value Which IS Accessible Via getLastError [1]. in addition to this, it is possible to
Manipulate the lasterrorvalue via setLastError [1] API. by use this api and monitoring the memory area behind the teb,
The Locations for the lasterrorvalue area:
If you take a closer look at the NT TEB additional data that II-B said, you can find the LastErrorValue at the entrance. Almost all APIs with relations with getLastError [1] have to return an error value. Some techniques can be used to use the Error value returned by SetLastError [1], in order to use this API and detect the memory behind the TEB, the LASTERRORVALUE is listed below:
Windows 95 - TEB-BASE 60H
Windows 98 - Teb-Base 60H
Windows Me - Teb-Base 74H
NOW WE Are Aable To Detect Windows Me Or Windows 95/98. First Step To Our Solution, But Not The Final One. It is Possible To
Detect a Difference Between Windows 95 and Windows 98.
You can now detect Windows ME or Windows 95/98. This is the first step in solving the problem and has not until the end. It is possible to detect differences between Windows 95 and Windows 98.
Section II Showed The Start Up Values and their Rules. The Start Up Value of Ebx on Non Nt-based OS 00530000H. EXACTLY
THIS VALUE WILL BE FOUND INSIDE The Additional Data Part - Close To The Now Resolved LasterrorValue. by Analysising It's Location,
The Result Will BE:
Part II illustrates the initialization value and their laws. For non-NT kernel systems, EBX is initially 00530000H. And this value can be found from the additional data - very close to LastErrorValue. To analyze this data, the specific location is listed below:
Windows 95 - TEB-BASE 58H
Windows 98 - TEB-BASE 54H
Windows Me - Teb-Base 7ch
NOW WE Are Aable to Difer Between Each Non Nt-based Operating System.
Now we can distinguish between a non-NT kernel system.
IV. Code Creation
Iv. Create code
Right now, we where able the detect the version information for each operating system. We want an operating systemindependent code, we need to structure the given information's. Also it should be possible to resolve the version information
Workflow Independent. Section Vi Will Show The Complete Solution In AssuseMbler.
Now we can detect version information of each operating system. In order to let the code does not rely on the operating system, we need to organize the required information into a structure. And it is necessary to let the type information independently. Part VI will give a complete assembly solution.
First Of All, We get the base addresses of peb and teb and resolve the OPERATING SYSTEM BASE by Analysising Them:
First, get the base address of the PEB and TEB, by analyzing them to obtain different operating system information.
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
.lse
Win9x based
.ndif; Base Check NT / 9X
THE VERSION INFORMATION for NT-based Operation Systems Is Stored Inside Peb. We Only Have To Analyze The VALUES OF
The version information of the NT kernel is stored in the PEB. We just need to analyze these data:
OsmajorVersion and OsminorVersion:
MOV EBX, [EAX 0A8H]; Get OSMINORVERSION
Mov Eax, [EAX 0A4H]; Get Osmajorversion
.IF EAX == 5 && EBX == 0; Is IT Windows 2000?
.ELSEIF EAX == 5 && EBX == 1; Is IT Windows XP?
.ELSEIF EAX == 5 && EBX == 2; Is IT Windows 2003?
.ELSEIF EAX <= 4; Is IT Windows NT?
.endif
Non NT-BASED OPERATING SYSTEMS COLLD BE Detected by Analyysing The Additional Data Area Behind Teb, Searching The Value
00530000h:
The non-NT core operating system can be analyzed by analyzing TEB additional data, search 00530000h:
Mov EDX, 00530000H; The 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?
.ELSEIF EAX == EDX; Is IT Windows 98?
.ELSEIF ECX == EDX; Is IT Windows ME?
.endif
V. Conclusions
V. Conclusion
Resolving the Operating System by Using this Technique Is Only One Possibility To Avoid The Usage of Advanced Programming
Interface functions, for example, isdebuggerpresent [1] or named functions in this Essay, ISDEBUGERPRESENT [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 The Didn't. And Mixing Different Operating System Solutions Together Makes Life Even Harden.
This technology is used to avoid a method of using an API function. Many other functions, such as getcommandline [1], isdebuggerpresent [1], or some of this article can be rewritten by using the same method. In other words: The reverse person does not intercept the associated API function, because it is not used at all. Also, if the processing of different operating systems is mixed together, it will be more difficult to analyze them.
Vi. Appendix
Appendix
.const
; - Return Values from OS_GETOS
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 _ThereeturnValue, 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
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
.ndif; Base Check NT / 9X
Popad; restore all registers
Mov Eax, _thereturnValue
Ret; Return to Caller
OS_GETOS ENDP