kernel32里的 GetVersion 函数的逆向分析

十二月 14th, 2009 by shyandsy
4

今天在家调试程序,跟进了一个函数kernel32里面的GetVersion函数。最近刚好在学逆向。心一横,干脆把它逆了。

代码如下:

0043846A  |.  FF15 70F14500 call    dword ptr [<&KERNEL32.GetVersion>]                ;  kernel32.GetVersion

7C81126A >  64:A1 18000000       mov     eax, dword ptr fs:[18]         ; 获得当前线程的TEB地址
7C811270    8B48 30                       mov     ecx, dword ptr [eax+30]        ; 在TEB偏移30h处获得PEB地址
7C811273    8B81 B0000000        mov     eax, dword ptr [ecx+B0]
7C811279    0FB791 AC000000   movzx   edx, word ptr [ecx+AC]
7C811280    83F0 FE                       xor     eax, FFFFFFFE
7C811283    C1E0 0E                      shl     eax, 0E
7C811286    0BC2                            or      eax, edx
7C811288    C1E0 08                      shl     eax, 8
7C81128B    0B81 A8000000        or      eax, dword ptr [ecx+A8]
7C811291    C1E0 08         shl       eax, 8
7C811294    0B81 A4000000        or      eax, dword ptr [ecx+A4]
7C81129A    C3                                retn
解析:

今天在家调试程序,跟进了一个函数kernel32里面的GetVersion函数。最近刚好在学逆向。心一横,干脆把它逆了。

代码如下:

0043846A  |.  FF15 70F14500 call    dword ptr [<&KERNEL32.GetVersion>]                ;  kernel32.GetVersion

7C81126A >  64:A1 18000000       mov     eax, dword ptr fs:[18]         ; 获得当前线程的TEB地址
7C811270    8B48 30                       mov     ecx, dword ptr [eax+30]        ; 在TEB偏移30h处获得PEB地址
7C811273    8B81 B0000000        mov     eax, dword ptr [ecx+B0]
7C811279    0FB791 AC000000   movzx   edx, word ptr [ecx+AC]
7C811280    83F0 FE                       xor     eax, FFFFFFFE
7C811283    C1E0 0E                      shl     eax, 0E
7C811286    0BC2                            or      eax, edx
7C811288    C1E0 08                      shl     eax, 8
7C81128B    0B81 A8000000        or      eax, dword ptr [ecx+A8]
7C811291    C1E0 08         shl       eax, 8
7C811294    0B81 A4000000        or      eax, dword ptr [ecx+A4]
7C81129A    C3                                retn

解析:
mov     eax, dword ptr fs:[18]
FS里面存档的是当前线程环境块(_TEB结构),_TEB结构如下:
kd> dt _TEB
ntdll!_TEB
+0×000 NtTib            : _NT_TIB
+0×01c EnvironmentPointer : Ptr32 Void
+0×020 ClientId         : _CLIENT_ID
+0×028 ActiveRpcHandle  : Ptr32 Void
+0×02c ThreadLocalStoragePointer : Ptr32 Void
+0×030 ProcessEnvironmentBlock : Ptr32 _PEB
+0×034 LastErrorValue   : Uint4B
+0×038 CountOfOwnedCriticalSections : Uint4B
+0×03c CsrClientThread  : Ptr32 Void
+0×040 Win32ThreadInfo  : Ptr32 Void
+0×044 User32Reserved   : [26] Uint4B
+0×0ac UserReserved     : [5] Uint4B
+0×0c0 WOW32Reserved    : Ptr32 Void
+0×0c4 CurrentLocale    : Uint4B
+0×0c8 FpSoftwareStatusRegister : Uint4B
+0×0cc SystemReserved1  : [54] Ptr32 Void
+0×1a4 ExceptionCode    : Int4B
+0×1a8 ActivationContextStack : _ACTIVATION_CONTEXT_STACK
+0×1bc SpareBytes1      : [24] UChar
+0×1d4 GdiTebBatch      : _GDI_TEB_BATCH
+0×6b4 RealClientId     : _CLIENT_ID
+0×6bc GdiCachedProcessHandle : Ptr32 Void
+0×6c0 GdiClientPID     : Uint4B
+0×6c4 GdiClientTID     : Uint4B
+0×6c8 GdiThreadLocalInfo : Ptr32 Void
+0×6cc Win32ClientInfo  : [62] Uint4B
+0×7c4 glDispatchTable  : [233] Ptr32 Void
+0xb68 glReserved1
: [29] Uint4B
+0xbdc glReserved2      : Ptr32 Void
+0xbe0 glSectionInfo    : Ptr32 Void
+0xbe4 glSection        : Ptr32 Void
+0xbe8 glTable          : Ptr32 Void
+0xbec glCurrentRC      : Ptr32 Void
+0xbf0 glContext        : Ptr32 Void
+0xbf4 LastStatusValue  : Uint4B
+0xbf8 StaticUnicodeString : _UNICODE_STRING
+0xc00 StaticUnicodeBuffer : [261] Uint2B
+0xe0c DeallocationStack : Ptr32 Void
+0xe10 TlsSlots         : [64] Ptr32 Void
+0xf10 TlsLinks         : _LIST_ENTRY
+0xf18 Vdm              : Ptr32 Void
+0xf1c ReservedForNtRpc : Ptr32 Void
+0xf20 DbgSsReserved    : [2] Ptr32 Void
+0xf28 HardErrorsAreDisabled : Uint4B
+0xf2c Instrumentation  : [16] Ptr32 Void
+0xf6c WinSockData      : Ptr32 Void
+0xf70 GdiBatchCount    : Uint4B
+0xf74 InDbgPrint       : UChar
+0xf75 FreeStackOnTermination : UChar
+0xf76 HasFiberData     : UChar
+0xf77 IdealProcessor   : UChar
+0xf78 Spare3           : Uint4B
+0xf7c ReservedForPerf  : Ptr32 Void
+0xf80 ReservedForOle   : Ptr32 Void
+0xf84 WaitingOnLoaderLock : Uint4B
+0xf88 Wx86Thread       : _Wx86ThreadState
+0xf94 TlsExpansionSlots : Ptr32 Ptr32 Void
+0xf98 ImpersonationLocale : Uint4B
+0xf9c IsImpersonating  : Uint4B
+0xfa0 NlsCache         : Ptr32 Void
+0xfa4 pShimData        : Ptr32 Void
+0xfa8 HeapVirtualAffinity : Uint4B
+0xfac CurrentTransactionHandle : Ptr32 Void
+0xfb0 ActiveFrame      : Ptr32 _TEB_ACTIVE_FRAME
+0xfb4 SafeThunkCall    : UChar
+0xfb5 BooleanSpare     : [3] UChar

显然,偏移量18位置在_NT_TIB这个结构里, _NT_TIB如下:
kd> dt _NT_TIB
ntdll!_NT_TIB
+0×000 ExceptionList    : Ptr32 _EXCEPTION_REGISTRATION_RECORD
+0×004 StackBase        : Ptr32 Void
+0×008 StackLimit       : Ptr32 Void
+0×00c SubSystemTib     : Ptr32 Void
+0×010 FiberData        : Ptr32 Void
+0×010 Version          : Uint4B
+0×014 ArbitraryUserPointer : Ptr32 Voi
d
+0×018 Self             : Ptr32 _NT_TIB
OK,这样我们就知道dword ptr fs:[18]其实是   +0×018 Self    : Ptr32 _NT_TIB,
就是说这句话实际上是把当前线程TEB地址放入了eax中

mov     ecx, dword ptr [eax+30]
把TEB基址偏移30h处的4个字节放入ecx  , +0×030 ProcessEnvironmentBlock : Ptr32 _PEB
即获得当前线程PEB地址,放入ecx
mov     eax, dword ptr [ecx+B0]
要知道这是什么意思就需要先查看_PEB结构,_PEB结构如下:
kd> dt _PEB
ntdll!_PEB
+0×000 InheritedAddressSpace : UChar
+0×001 ReadImageFileExecOptions : UChar
+0×002 BeingDebugged    : UChar
+0×003 SpareBool        : UChar
+0×004 Mutant           : Ptr32 Void
+0×008 ImageBaseAddress : Ptr32 Void
+0×00c Ldr              : Ptr32 _PEB_LDR_DATA
+0×010 ProcessParameters : Ptr32 _RTL_USER_PROCESS_PARAMETERS
+0×014 SubSystemData    : Ptr32 Void
+0×018 ProcessHeap      : Ptr32 Void
+0×01c FastPebLock      : Ptr32 _RTL_CRITICAL_SECTION
+0×020 FastPebLockRoutine : Ptr32 Void
+0×024 FastPebUnlockRoutine : Ptr32 Void
+0×028 EnvironmentUpdateCount : Uint4B
+0×02c KernelCallbackTable : Ptr32 Void
+0×030 SystemReserved   : [1] Uint4B
+0×034 AtlThunkSListPtr32 : Uint4B
+0×038 FreeList         : Ptr32 _PEB_FREE_BLOCK
+0×03c TlsExpansionCounter : Uint4B
+0×040 TlsBitmap        : Ptr32 Void
+0×044 TlsBitmapBits    : [2] Uint4B
+0×04c ReadOnlySharedMemoryBase : Ptr32 Void
+0×050 ReadOnlySharedMemoryHeap : Ptr32 Void
+0×054 ReadOnlyStaticServerData : Ptr32 Ptr32 Void
+0×058 AnsiCodePageData : Ptr32 Void
+0×05c OemCodePageData  : Ptr32 Void
+0×060 UnicodeCaseTableData : Ptr32 Void
+0×064 NumberOfProcessors : Uint4B
+0×068 NtGlobalFlag     : Uint4B
+0×070 CriticalSectionTimeout : _LARGE_INTEGER
+0×078 HeapSegmentReserve : Uint4B
+0×07c HeapSegmentCommit : Uint4B
+0×080 HeapDeCommitTotalFreeThreshold : Uint4B
+0×084 HeapDeCommitFreeBlockThreshold : Uint4B
+0×088 NumberOfHeaps    : Uint4B
+0×08c MaximumNumberOfHeaps : Uint4B
+0×090 ProcessHeaps
: Ptr32 Ptr32 Void
+0×094 GdiSharedHandleTable : Ptr32 Void
+0×098 ProcessStarterHelper : Ptr32 Void
+0×09c GdiDCAttributeList : Uint4B
+0×0a0 LoaderLock       : Ptr32 Void
+0×0a4 OSMajorVersion   : Uint4B
+0×0a8 OSMinorVersion   : Uint4B
+0×0ac OSBuildNumber    : Uint2B
+0×0ae OSCSDVersion     : Uint2B
+0×0b0 OSPlatformId     : Uint4B
+0×0b4 ImageSubsystem   : Uint4B
+0×0b8 ImageSubsystemMajorVersion : Uint4B
+0×0bc ImageSubsystemMinorVersion : Uint4B
+0×0c0 ImageProcessAffinityMask : Uint4B
+0×0c4 GdiHandleBuffer  : [34] Uint4B
+0×14c PostProcessInitRoutine : Ptr32     void
+0×150 TlsExpansionBitmap : Ptr32 Void
+0×154 TlsExpansionBitmapBits : [32] Uint4B
+0×1d4 SessionId        : Uint4B
+0×1d8 AppCompatFlags   : _ULARGE_INTEGER
+0×1e0 AppCompatFlagsUser : _ULARGE_INTEGER
+0×1e8 pShimData        : Ptr32 Void
+0×1ec AppCompatInfo    : Ptr32 Void
+0×1f0 CSDVersion       : _UNICODE_STRING
+0×1f8 ActivationContextData : Ptr32 Void
+0×1fc ProcessAssemblyStorageMap : Ptr32 Void
+0×200 SystemDefaultActivationContextData : Ptr32 Void
+0×204 SystemAssemblyStorageMap : Ptr32 Void
+0×208 MinimumStackCommit : Uint4B
这句话就是说把当前PEB的OSPlatformId放入eax中
movzx   edx, word ptr [ecx+AC]
+0×0ac OSBuildNumber    : Uint2B是2个字节,要放入edx则需要字节扩展。从word扩展到dword,高位填0.
这句话就是说把当前PEB的OSBuildNumber放到edx中。

xor          eax, FFFFFFFE
PEB的OSPlatformId异或FFFFFFFE,存入eax中

shl     eax, 0E
eax寄存器逻辑左移14位
or      eax, edx
eax与edx或操作,然后保存到eax中
shl     eax, 8
eax寄存器逻辑左移8位
or      eax, dword ptr [ecx+A8]
eax或 OSMinorVersion,然后保存到eax
shl       eax, 8
eax寄存器逻辑左移8位
or      eax, dword ptr [ecx+A4]
eax或 OSMajorVersion,然后保存到eax
retn
返回值在eax中
Posted in 汇编与逆向

4 Responses to “kernel32里的 GetVersion 函数的逆向分析”

  1. MqtAmWj0 说:

    Great article very important information i found here G4HHemM0gfsNW8

  2. 好贴,正好是我想找的资料,谢谢分享!

  3. 好贴,正好是我想找的资料,谢谢分享!

  4. 不错,我来支持一下!

Leave a Reply

վ:Ħ Ϻgay ŰĦ Ϻ տ ɽ ɽ ŰĦ Ϻ˹˾ ŰĦ ϺŰĦ ˹˾ ݰĦ ŰĦ Ħ ϺĦ ͬ־ Ѽ˹˾ ŰĦ ϺѼ ɳ᳡ shenzhen massage ŰĦ ͬ־ Ϸʿյά ϲŰĦ 人˿ఴĦ ɽ˹˾ Ϻ Ѽ˿ Ħ ֣ŰĦ ˹˾ ݼѼ Ϻ ǿ Ϻ ڰ᳡۸ °˾
ӣǵɽǵݸǵ麣ǵɽǵɳǵɽǵǵǵǵϺǵǵǵǵݸǵɽǵ麣ǵǵɽǵɽǵǵǵǵǵǵǵǵϺǵŰĦϺǵɽanĦൺǵӰװϷϺǵϾŰĦϾŰĦϾŰĦ㶫huλ㽭huңhuң
ӣҸĻȾ,ɾӹȫ.
ugg boots cheap UGG Boots UGG Boots Sale UGG Bailey Button Triplet ugg australia uk mens ugg boots new ghd hair straighteners coach handbags outlet
ӣվĶ٣ÿ쿴ɾ, ұ˫Ϊ˴Ǯ;ãӲҪɾҾɾվɾipҲ㡣
ɹͷ Ҹ θ Ƽʪõķ ҸƷ ƾõҽԺ 򾲶ʮζ ƹɹͷҩ θҩ ҽԺ ɹͷô ƹɹͷõҽԺ θҽԺ ̿۸ lovegreen californianews
ӣǵάɽǵάݸǵά麣ǵάɽǵάɳǵάɽǵάǵάǵάǵάϺǵάǵάǵάǵάݸǵάɽǵά麣ǵάǵάɽǵάɽǵάǵάǵάǵάǵάǵάǵάǵάϺװ˿㰴ĦϺǵάɽСlaohujiϷǵӰװϾСϾСϾС㽭huϷɽǵά˿㰴Ħ