判断操作系统[zt]

来源:互联网 发布:中文分词 python库 re 编辑:程序博客网 时间:2024/06/06 16:38
分析不同操作系统的线程环境块(TEB --- 也叫做线程信息块 TIB),我们可以看到这个结构的附加数据。对于非NT内核的系统,这些附加数据没有逻辑结构或者长度定义,而对于NT内核的系统他们保存了进程环境块(PEB)的信息。确定非NT内核系统中这些数据意义的唯一方法,就是在不同的操作系统中调试同一个程序。    
程序启动前TEB便被初始化并且含有线程重定位数据指针。TEB结构在所有的操作系统中都是有效的。它的大小是34字节。TEB地址可以利用FS寄存器配合下面的方法来获取:
assume fs:nothing
mov eax,fs:[18h]
TEB最后的内容为指向进程数据的指针。在NT内核系统中,这个值指向进程环境块
在每个非NT内核系统中附加数据块没有逻辑结构和具体定义(译注:这里好像应该是NT内核结构)。在Windows NT,2000,XP和2003,这些数据如下:

NT_TEB_ADDON struct

LastErrorValue DWORD ? ; 00h (34h TEB)
LastStatusValue DWORD ? ; 04h (38h TEB)
CountOwnedLocks DWORD ? ; 08h (3Ch TEB)
HardErrorsMode DWORD ? ; 0Ch (40h TEB)

NT_TEB_ADDON ends

Windows 95, 98, ME 没有这些数据结构。附加数据完全很混乱!
NT内核的系统把进程相关数据存储在进程环境块中。这个结构的地址可以通过操作FS寄存器来获取:
assume fs:nothing
mov eax,fs:[30h]
EAX寄存器中便是PEB基地址。
操作系统信息被存储在PEB结构中:

OSMajorVersion DWORD ? ; A4h <=4->NT / 5->2K/XP/2K3
OSMinorVersion DWORD ? ; A8h 0->2K / 1->XP / 2->2K3

Windows NT, 2000, XP and 2003采用固定数据存储PEB和TEB。PEB总是被存放在7FFDF000h,TEB总是从7FFDE000h开始。知道了这2个固定数据,就可以检测出来操作系统类型。
如果仔细看一下NT TEB附加数据,可以发现入口处的LastErrorValue。几乎所有跟GetLastError[1]有关系的API都要返回一个错误值。可以采用一些技巧来利用SetLastError[1] 返回的这个Error值,为了使用这个API并且检测TEB后面的内存,下面列出来LastErrorValue 的位置:
Windows 95 - TEB-base + 60h
Windows 98 - TEB-base + 60h
Windows ME - TEB-base + 74h
对于非NT内核的系统,EBX初始为00530000h。并且这个值可以从附加数据中查出来 - 与LastErrorValue非常近。为了分析这个数据,下面列出来具体位置:

Windows 95 - TEB-base + 58h
Windows 98 - TEB-base + 54h
Windows ME - TEB-base + 7Ch



    .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 _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 
原创粉丝点击