windows x86系统调用(二)

一、前言

上一篇中已经将3环进入0环的流程分析完成完成了,以及提到了使用sysenter指令如何进行权限提升,在本章中我们将从msr查找0环处理函数到查找ssdt表项前的准备工作进行分析。

二、环境

调试机器:windows10
调试工具:windbg、x32dbg、ida8.3
被调试机器:windows 7 sp1 x86

三、词汇说明

ssdt:系统服务描述表

四、调用流程

4.1 查找入口函数

上一篇中提到使用sysenter进入0环是将msr寄存器的174项中的内容设置到了eip寄存器中,说明了0环的入口函数就为msr寄存器的174项内容的这个地址。
在这里插入图片描述
使用windbg可以查询到msr寄存的176存的内容是00000000`83e5d760这个地址,通过 u 指令查看这个地址上可以发现这个地址上是一个KiFastEntry函数。

4.2 分析准备工作

在正式分析之前需要先了解几个结构体才能更好的分析工作。

4.2.1 KPCR

该结构全称叫处理器控制区域,用于记录当前核心执行状态,在进入0环后fs指向的就该结构,在当前分析中我们需要使用该结构中的TSS、PrcbData这两个字段。一定切记0环中fs指向这个结构

//0x3748 bytes (sizeof)
struct _KPCR
{
    union
    {
        struct _NT_TIB NtTib;                                               //0x0
        struct
        {
            struct _EXCEPTION_REGISTRATION_RECORD* Used_ExceptionList;      //0x0
            VOID* Used_StackBase;                                           //0x4
            VOID* Spare2;                                                   //0x8
            VOID* TssCopy;                                                  //0xc
            ULONG ContextSwitches;                                          //0x10
            ULONG SetMemberCopy;                                            //0x14
            VOID* Used_Self;                                                //0x18
        };
    };
    struct _KPCR* SelfPcr;                                                  //0x1c
    struct _KPRCB* Prcb;                                                    //0x20
    UCHAR Irql;                                                             //0x24
    ULONG IRR;                                                              //0x28
    ULONG IrrActive;                                                        //0x2c
    ULONG IDR;                                                              //0x30
    VOID* KdVersionBlock;                                                   //0x34
    struct _KIDTENTRY* IDT;                                                 //0x38
    struct _KGDTENTRY* GDT;                                                 //0x3c
    struct _KTSS* TSS;                                                      //0x40
    USHORT MajorVersion;                                                    //0x44
    USHORT MinorVersion;                                                    //0x46
    ULONG SetMember;                                                        //0x48
    ULONG StallScaleFactor;                                                 //0x4c
    UCHAR SpareUnused;                                                      //0x50
    UCHAR Number;                                                           //0x51
    UCHAR Spare0;                                                           //0x52
    UCHAR SecondLevelCacheAssociativity;                                    //0x53
    ULONG VdmAlert;                                                         //0x54
    ULONG KernelReserved[14];                                               //0x58
    ULONG SecondLevelCacheSize;                                             //0x90
    ULONG HalReserved[16];                                                  //0x94
    ULONG InterruptMode;                                                    //0xd4
    UCHAR Spare1;                                                           //0xd8
    ULONG KernelReserved2[17];                                              //0xdc
    struct _KPRCB PrcbData;                                                 //0x120
}; 

4.2.1 KPRCB

该结构是kpcr的扩展属性,在分析中需要使用到CurrentThread属性,该属性就是当前执行线程的结构。

//0x3628 bytes (sizeof)
struct _KPRCB
{
    USHORT MinorVersion;                                                    //0x0
    USHORT MajorVersion;                                                    //0x2
    struct _KTHREAD* CurrentThread;                                         //0x4
    struct _KTHREAD* NextThread;                                            //0x8
    struct _KTHREAD* IdleThread;                                            //0xc
    UCHAR LegacyNumber;                                                     //0x10
    UCHAR NestingLevel;                                                     //0x11
    USHORT BuildType;                                                       //0x12
    CHAR CpuType;                                                           //0x14
    CHAR CpuID;                                                             //0x15
    union
    {
        USHORT CpuStep;                                                     //0x16
        struct
        {
            UCHAR CpuStepping;                                              //0x16
            UCHAR CpuModel;                                                 //0x17
        };
    };
    struct _KPROCESSOR_STATE ProcessorState;                                //0x18
    ULONG KernelReserved[16];                                               //0x338
    ULONG HalReserved[16];                                                  //0x378
    ULONG CFlushSize;                                                       //0x3b8
    UCHAR CoresPerPhysicalProcessor;                                        //0x3bc
    UCHAR LogicalProcessorsPerCore;                                         //0x3bd
    UCHAR PrcbPad0[2];                                                      //0x3be
    ULONG MHz;                                                              //0x3c0
    UCHAR CpuVendor;                                                        //0x3c4
    UCHAR GroupIndex;                                                       //0x3c5
    USHORT Group;                                                           //0x3c6
    ULONG GroupSetMember;                                                   //0x3c8
    ULONG Number;                                                           //0x3cc
    UCHAR PrcbPad1[72];                                                     //0x3d0
    struct _KSPIN_LOCK_QUEUE LockQueue[17];                                 //0x418
    struct _KTHREAD* NpxThread;                                             //0x4a0
    ULONG InterruptCount;                                                   //0x4a4
    ULONG KernelTime;                                                       //0x4a8
    ULONG UserTime;                                                         //0x4ac
    ULONG DpcTime;                                                          //0x4b0
    ULONG DpcTimeCount;                                                     //0x4b4
    ULONG InterruptTime;                                                    //0x4b8
    ULONG AdjustDpcThreshold;                                               //0x4bc
    ULONG PageColor;                                                        //0x4c0
    UCHAR DebuggerSavedIRQL;                                                //0x4c4
    UCHAR NodeColor;                                                        //0x4c5
    UCHAR PrcbPad20[2];                                                     //0x4c6
    ULONG NodeShiftedColor;                                                 //0x4c8
    struct _KNODE* ParentNode;                                              //0x4cc
    ULONG SecondaryColorMask;                                               //0x4d0
    ULONG DpcTimeLimit;                                                     //0x4d4
    ULONG PrcbPad21[2];                                                     //0x4d8
    ULONG CcFastReadNoWait;                                                 //0x4e0
    ULONG CcFastReadWait;                                                   //0x4e4
    ULONG CcFastReadNotPossible;                                            //0x4e8
    ULONG CcCopyReadNoWait;                                                 //0x4ec
    ULONG CcCopyReadWait;                                                   //0x4f0
    ULONG CcCopyReadNoWaitMiss;                                             //0x4f4
    volatile LONG MmSpinLockOrdering;                                       //0x4f8
    volatile LONG IoReadOperationCount;                                     //0x4fc
    volatile LONG IoWriteOperationCount;                                    //0x500
    volatile LONG IoOtherOperationCount;                                    //0x504
    union _LARGE_INTEGER IoReadTransferCount;                               //0x508
    union _LARGE_INTEGER IoWriteTransferCount;                              //0x510
    union _LARGE_INTEGER IoOtherTransferCount;                              //0x518
    ULONG CcFastMdlReadNoWait;                                              //0x520
    ULONG CcFastMdlReadWait;                                                //0x524
    ULONG CcFastMdlReadNotPossible;                                         //0x528
    ULONG CcMapDataNoWait;                                                  //0x52c
    ULONG CcMapDataWait;                                                    //0x530
    ULONG CcPinMappedDataCount;                                             //0x534
    ULONG CcPinReadNoWait;                                                  //0x538
    ULONG CcPinReadWait;                                                    //0x53c
    ULONG CcMdlReadNoWait;                                                  //0x540
    ULONG CcMdlReadWait;                                                    //0x544
    ULONG CcLazyWriteHotSpots;                                              //0x548
    ULONG CcLazyWriteIos;                                                   //0x54c
    ULONG CcLazyWritePages;                                                 //0x550
    ULONG CcDataFlushes;                                                    //0x554
    ULONG CcDataPages;                                                      //0x558
    ULONG CcLostDelayedWrites;                                              //0x55c
    ULONG CcFastReadResourceMiss;                                           //0x560
    ULONG CcCopyReadWaitMiss;                                               //0x564
    ULONG CcFastMdlReadResourceMiss;                                        //0x568
    ULONG CcMapDataNoWaitMiss;                                              //0x56c
    ULONG CcMapDataWaitMiss;                                                //0x570
    ULONG CcPinReadNoWaitMiss;                                              //0x574
    ULONG CcPinReadWaitMiss;                                                //0x578
    ULONG CcMdlReadNoWaitMiss;                                              //0x57c
    ULONG CcMdlReadWaitMiss;                                                //0x580
    ULONG CcReadAheadIos;                                                   //0x584
    ULONG KeAlignmentFixupCount;                                            //0x588
    ULONG KeExceptionDispatchCount;                                         //0x58c
    ULONG KeSystemCalls;                                                    //0x590
    ULONG AvailableTime;                                                    //0x594
    ULONG PrcbPad22[2];                                                     //0x598
    struct _PP_LOOKASIDE_LIST PPLookasideList[16];                          //0x5a0
    struct _GENERAL_LOOKASIDE_POOL PPNPagedLookasideList[32];               //0x620
    struct _GENERAL_LOOKASIDE_POOL PPPagedLookasideList[32];                //0xf20
    volatile ULONG PacketBarrier;                                           //0x1820
    volatile LONG ReverseStall;                                             //0x1824
    VOID* IpiFrame;                                                         //0x1828
    UCHAR PrcbPad3[52];                                                     //0x182c
    VOID* volatile CurrentPacket[3];                                        //0x1860
    volatile ULONG TargetSet;                                               //0x186c
    VOID (* volatileWorkerRoutine)(VOID* arg1, VOID* arg2, VOID* arg3, VOID* arg4); //0x1870
    volatile ULONG IpiFrozen;                                               //0x1874
    UCHAR PrcbPad4[40];                                                     //0x1878
    volatile ULONG RequestSummary;                                          //0x18a0
    struct _KPRCB* volatile SignalDone;                                     //0x18a4
    UCHAR PrcbPad50[56];                                                    //0x18a8
    struct _KDPC_DATA DpcData[2];                                           //0x18e0
    VOID* DpcStack;                                                         //0x1908
    LONG MaximumDpcQueueDepth;                                              //0x190c
    ULONG DpcRequestRate;                                                   //0x1910
    ULONG MinimumDpcRate;                                                   //0x1914
    ULONG DpcLastCount;                                                     //0x1918
    ULONG PrcbLock;                                                         //0x191c
    struct _KGATE DpcGate;                                                  //0x1920
    UCHAR ThreadDpcEnable;                                                  //0x1930
    volatile UCHAR QuantumEnd;                                              //0x1931
    volatile UCHAR DpcRoutineActive;                                        //0x1932
    volatile UCHAR IdleSchedule;                                            //0x1933
    union
    {
        volatile LONG DpcRequestSummary;                                    //0x1934
        SHORT DpcRequestSlot[2];                                            //0x1934
        struct
        {
            SHORT NormalDpcState;                                           //0x1934
            union
            {
                volatile USHORT DpcThreadActive:1;                          //0x1936
                SHORT ThreadDpcState;                                       //0x1936
            };
        };
    };
    volatile ULONG TimerHand;                                               //0x1938
    ULONG LastTick;                                                         //0x193c
    LONG MasterOffset;                                                      //0x1940
    ULONG PrcbPad41[2];                                                     //0x1944
    ULONG PeriodicCount;                                                    //0x194c
    ULONG PeriodicBias;                                                     //0x1950
    ULONGLONG TickOffset;                                                   //0x1958
    struct _KTIMER_TABLE TimerTable;                                        //0x1960
    struct _KDPC CallDpc;                                                   //0x31a0
    LONG ClockKeepAlive;                                                    //0x31c0
    UCHAR ClockCheckSlot;                                                   //0x31c4
    UCHAR ClockPollCycle;                                                   //0x31c5
    UCHAR PrcbPad6[2];                                                      //0x31c6
    LONG DpcWatchdogPeriod;                                                 //0x31c8
    LONG DpcWatchdogCount;                                                  //0x31cc
    LONG ThreadWatchdogPeriod;                                              //0x31d0
    LONG ThreadWatchdogCount;                                               //0x31d4
    volatile LONG KeSpinLockOrdering;                                       //0x31d8
    ULONG PrcbPad70[1];                                                     //0x31dc
    struct _LIST_ENTRY WaitListHead;                                        //0x31e0
    ULONG WaitLock;                                                         //0x31e8
    ULONG ReadySummary;                                                     //0x31ec
    ULONG QueueIndex;                                                       //0x31f0
    struct _SINGLE_LIST_ENTRY DeferredReadyListHead;                        //0x31f4
    ULONGLONG StartCycles;                                                  //0x31f8
    volatile ULONGLONG CycleTime;                                           //0x3200
    volatile ULONG HighCycleTime;                                           //0x3208
    ULONG PrcbPad71;                                                        //0x320c
    ULONGLONG PrcbPad72[2];                                                 //0x3210
    struct _LIST_ENTRY DispatcherReadyListHead[32];                         //0x3220
    VOID* ChainedInterruptList;                                             //0x3320
    LONG LookasideIrpFloat;                                                 //0x3324
    volatile LONG MmPageFaultCount;                                         //0x3328
    volatile LONG MmCopyOnWriteCount;                                       //0x332c
    volatile LONG MmTransitionCount;                                        //0x3330
    volatile LONG MmCacheTransitionCount;                                   //0x3334
    volatile LONG MmDemandZeroCount;                                        //0x3338
    volatile LONG MmPageReadCount;                                          //0x333c
    volatile LONG MmPageReadIoCount;                                        //0x3340
    volatile LONG MmCacheReadCount;                                         //0x3344
    volatile LONG MmCacheIoCount;                                           //0x3348
    volatile LONG MmDirtyPagesWriteCount;                                   //0x334c
    volatile LONG MmDirtyWriteIoCount;                                      //0x3350
    volatile LONG MmMappedPagesWriteCount;                                  //0x3354
    volatile LONG MmMappedWriteIoCount;                                     //0x3358
    volatile ULONG CachedCommit;                                            //0x335c
    volatile ULONG CachedResidentAvailable;                                 //0x3360
    VOID* HyperPte;                                                         //0x3364
    UCHAR PrcbPad8[4];                                                      //0x3368
    UCHAR VendorString[13];                                                 //0x336c
    UCHAR InitialApicId;                                                    //0x3379
    UCHAR LogicalProcessorsPerPhysicalProcessor;                            //0x337a
    UCHAR PrcbPad9[5];                                                      //0x337b
    ULONG FeatureBits;                                                      //0x3380
    union _LARGE_INTEGER UpdateSignature;                                   //0x3388
    volatile ULONGLONG IsrTime;                                             //0x3390
    ULONGLONG RuntimeAccumulation;                                          //0x3398
    struct _PROCESSOR_POWER_STATE PowerState;                               //0x33a0
    struct _KDPC DpcWatchdogDpc;                                            //0x3468
    struct _KTIMER DpcWatchdogTimer;                                        //0x3488
    VOID* WheaInfo;                                                         //0x34b0
    VOID* EtwSupport;                                                       //0x34b4
    union _SLIST_HEADER InterruptObjectPool;                                //0x34b8
    union _SLIST_HEADER HypercallPageList;                                  //0x34c0
    VOID* HypercallPageVirtual;                                             //0x34c8
    VOID* VirtualApicAssist;                                                //0x34cc
    ULONGLONG* StatisticsPage;                                              //0x34d0
    VOID* RateControl;                                                      //0x34d4
    struct _CACHE_DESCRIPTOR Cache[5];                                      //0x34d8
    ULONG CacheCount;                                                       //0x3514
    ULONG CacheProcessorMask[5];                                            //0x3518
    struct _KAFFINITY_EX PackageProcessorSet;                               //0x352c
    ULONG PrcbPad91[1];                                                     //0x3538
    ULONG CoreProcessorSet;                                                 //0x353c
    struct _KDPC TimerExpirationDpc;                                        //0x3540
    ULONG SpinLockAcquireCount;                                             //0x3560
    ULONG SpinLockContentionCount;                                          //0x3564
    ULONG SpinLockSpinCount;                                                //0x3568
    ULONG IpiSendRequestBroadcastCount;                                     //0x356c
    ULONG IpiSendRequestRoutineCount;                                       //0x3570
    ULONG IpiSendSoftwareInterruptCount;                                    //0x3574
    ULONG ExInitializeResourceCount;                                        //0x3578
    ULONG ExReInitializeResourceCount;                                      //0x357c
    ULONG ExDeleteResourceCount;                                            //0x3580
    ULONG ExecutiveResourceAcquiresCount;                                   //0x3584
    ULONG ExecutiveResourceContentionsCount;                                //0x3588
    ULONG ExecutiveResourceReleaseExclusiveCount;                           //0x358c
    ULONG ExecutiveResourceReleaseSharedCount;                              //0x3590
    ULONG ExecutiveResourceConvertsCount;                                   //0x3594
    ULONG ExAcqResExclusiveAttempts;                                        //0x3598
    ULONG ExAcqResExclusiveAcquiresExclusive;                               //0x359c
    ULONG ExAcqResExclusiveAcquiresExclusiveRecursive;                      //0x35a0
    ULONG ExAcqResExclusiveWaits;                                           //0x35a4
    ULONG ExAcqResExclusiveNotAcquires;                                     //0x35a8
    ULONG ExAcqResSharedAttempts;                                           //0x35ac
    ULONG ExAcqResSharedAcquiresExclusive;                                  //0x35b0
    ULONG ExAcqResSharedAcquiresShared;                                     //0x35b4
    ULONG ExAcqResSharedAcquiresSharedRecursive;                            //0x35b8
    ULONG ExAcqResSharedWaits;                                              //0x35bc
    ULONG ExAcqResSharedNotAcquires;                                        //0x35c0
    ULONG ExAcqResSharedStarveExclusiveAttempts;                            //0x35c4
    ULONG ExAcqResSharedStarveExclusiveAcquiresExclusive;                   //0x35c8
    ULONG ExAcqResSharedStarveExclusiveAcquiresShared;                      //0x35cc
    ULONG ExAcqResSharedStarveExclusiveAcquiresSharedRecursive;             //0x35d0
    ULONG ExAcqResSharedStarveExclusiveWaits;                               //0x35d4
    ULONG ExAcqResSharedStarveExclusiveNotAcquires;                         //0x35d8
    ULONG ExAcqResSharedWaitForExclusiveAttempts;                           //0x35dc
    ULONG ExAcqResSharedWaitForExclusiveAcquiresExclusive;                  //0x35e0
    ULONG ExAcqResSharedWaitForExclusiveAcquiresShared;                     //0x35e4
    ULONG ExAcqResSharedWaitForExclusiveAcquiresSharedRecursive;            //0x35e8
    ULONG ExAcqResSharedWaitForExclusiveWaits;                              //0x35ec
    ULONG ExAcqResSharedWaitForExclusiveNotAcquires;                        //0x35f0
    ULONG ExSetResOwnerPointerExclusive;                                    //0x35f4
    ULONG ExSetResOwnerPointerSharedNew;                                    //0x35f8
    ULONG ExSetResOwnerPointerSharedOld;                                    //0x35fc
    ULONG ExTryToAcqExclusiveAttempts;                                      //0x3600
    ULONG ExTryToAcqExclusiveAcquires;                                      //0x3604
    ULONG ExBoostExclusiveOwner;                                            //0x3608
    ULONG ExBoostSharedOwners;                                              //0x360c
    ULONG ExEtwSynchTrackingNotificationsCount;                             //0x3610
    ULONG ExEtwSynchTrackingNotificationsAccountedCount;                    //0x3614
    struct _CONTEXT* Context;                                               //0x3618
    ULONG ContextFlags;                                                     //0x361c
    struct _XSAVE_AREA* ExtendedState;                                      //0x3620
}; 

4.2.3 KTRAP_FRAME

该结构是保存3环的环境,在前切换进行0环后esp指向该结构中的HardwareSegSs属性,注意这个esp不是从msr的175位获取的,而是从TSS中获取的(当前不明白没关系,等分析了入口函数就清除了)。

//0x8c bytes (sizeof)
struct _KTRAP_FRAME
{
    ULONG DbgEbp;                                                           //0x0
    ULONG DbgEip;                                                           //0x4
    ULONG DbgArgMark;                                                       //0x8
    ULONG DbgArgPointer;                                                    //0xc
    USHORT TempSegCs;                                                       //0x10
    UCHAR Logging;                                                          //0x12
    UCHAR Reserved;                                                         //0x13
    ULONG TempEsp;                                                          //0x14
    ULONG Dr0;                                                              //0x18
    ULONG Dr1;                                                              //0x1c
    ULONG Dr2;                                                              //0x20
    ULONG Dr3;                                                              //0x24
    ULONG Dr6;                                                              //0x28
    ULONG Dr7;                                                              //0x2c
    ULONG SegGs;                                                            //0x30
    ULONG SegEs;                                                            //0x34
    ULONG SegDs;                                                            //0x38
    ULONG Edx;                                                              //0x3c
    ULONG Ecx;                                                              //0x40
    ULONG Eax;                                                              //0x44
    ULONG PreviousPreviousMode;                                             //0x48
    struct _EXCEPTION_REGISTRATION_RECORD* ExceptionList;                   //0x4c
    ULONG SegFs;                                                            //0x50
    ULONG Edi;                                                              //0x54
    ULONG Esi;                                                              //0x58
    ULONG Ebx;                                                              //0x5c
    ULONG Ebp;                                                              //0x60
    ULONG ErrCode;                                                          //0x64
    ULONG Eip;                                                              //0x68
    ULONG SegCs;                                                            //0x6c
    ULONG EFlags;                                                           //0x70
    ULONG HardwareEsp;                                                      //0x74
    ULONG HardwareSegSs;                                                    //0x78
    ULONG V86Es;                                                            //0x7c
    ULONG V86Ds;                                                            //0x80
    ULONG V86Fs;                                                            //0x84
    ULONG V86Gs;                                                            //0x88
}; 

4.3 分析KiFastEntry函数

IDA打开ntoskrnl.exe查找KiFastEntry函数。
在这里插入图片描述

   				mov     ecx, 23h ; '#'
                push    30h ; '0'
                pop     fs              ; 将fs寄存器设置为内核态的30
                mov     ds, ecx         ; ds设置为23
                mov     es, ecx         ; es设置为23
                mov     ecx, large fs:_KPCR.TSS ; 获取TSS
                mov     esp, [ecx+_KTSS.Esp0] ; 修改esp,将esp指向_KTRAP_FRAME结构的HardwareSegSs位置
                push    23h ; '#'       ; 保存三环的ss
                push    edx             ; 保存三环ESP
                pushf                   ; 保存标志寄存器
_KiFastCallEntry endp


; =============== S U B R O U T I N E =======================================


KiFastCallEntryCommon proc near         ; CODE XREF: _KiFastCallEntry2+23↑j

; FUNCTION CHUNK AT .text:004351D9 SIZE 00000024 BYTES

                push    2               ;2压入栈中,用于修改eflags
                add     edx, 8
                popf                    ; 将eflags存器设置为2
                or      byte ptr [esp+1], 2 ; 关闭中断
                push    1Bh             ; 保护3环CS
                push    dword ptr ds:0FFDF0304h ; 将返回地址压入栈中,ds后的地址是_KUSER_SHARED_DATA结构的SystemCallReturn属性
                push    0               ; 压入错误代码
                push    ebp             ; 保存三环ebp
                push    ebx             ; 保存三环ebx
                push    esi             ; 保存三环esi
                push    edi             ; 保存三环edi
                mov     ebx, large fs:_KPCR.SelfPcr ; ebx设置为kpcr结构指针
                push    3Bh ; ';'       ; 保存三环fs
                mov     esi, [ebx+_KPCR.PrcbData.CurrentThread] ; 将当前线程结构指针存入esi中
                push    dword ptr [ebx] ; 保存用户的Used_ExceptionList
                mov     dword ptr [ebx], 0FFFFFFFFh ; 填充用户异常链表
                mov     ebp, [esi+_KTHREAD.InitialStack] ; 设置栈底
                push    1
                sub     esp, 48h        ; 将esp进行提升,当前esp指向_KTRAP_FRAME头部
                sub     ebp, 29Ch       ; 提升栈底,提升后栈底也指向_KTRAP_FRAME头部
                mov     [esi+_KTHREAD.PreviousMode], 1 ; 设置线程模式
                cmp     ebp, esp        ; 判断堆栈是否正确
                jnz     loc_4351D9      ; 不正确就进行跳转,跳转后直接蓝屏
                test    byte ptr [ebp+_KTRAP_FRAME.SegCs], 1 ; 验证原CS为三环的CS
                jnz     short loc_43528C ; 如果原CS是三环的就进行跳转

在上面代码代码中做以下几步操作:

  1. 修改fs寄存器 ,将fs寄存器修改成0环使用的30;
  2. 从TSS中获取0环需要使用的esp(在这里我们就可以知道windows其实没有msr中的esp值).
  3. 关闭中断
  4. 向KTRAP_FRAME中保存3环的环境
  5. 从线程结构获取0环的栈底赋值给esp
  6. 修改线程执行模式
loc_43528C:      mov     [ebp+_KTRAP_FRAME._Eax], eax ; 保存eax
                mov     [ebp+_KTRAP_FRAME._Edx], edx ; 保存edx
                mov     ecx, large fs:_KPCR.PrcbData.CurrentThread ; 获取当前线程
                mov     ecx, [ecx+_KTHREAD.Process] ; 获取当前进程结构
                mov     eax, dword ptr [ecx+_EPROCESS.SecurityDomain]
                mov     ecx, dword ptr [ecx+(_EPROCESS.SecurityDomain+4)]
                mov     large fs:_KPCR.PrcbData.TrappedSecurityDomain, eax
                mov     large fs:_KPCR.PrcbData.TrappedSecurityDomain+4, ecx
                movzx   eax, large byte ptr fs:_KPCR.PrcbData.BpbKernelSpecCtrl
                cmp     large fs:_KPCR.PrcbData.BpbCurrentSpecCtrl, al
                jz      short loc_4352D8 ; 如果BpbCurrentSpecCtrl一样就进行跳转
                mov     large fs:_KPCR.PrcbData.BpbCurrentSpecCtrl, al ; 如果BpbCurrentSpecCtrl不一样就设置为al的值
                mov     ecx, 48h ; 'H'
                xor     edx, edx
                wrmsr                   ; 将eax中的值存入到msr寄存器的48位置

loc_4352D8:                             ; CODE XREF: KiFastCallEntryCommon+AC↑j
                movzx   edx, large byte ptr fs:_KPCR.PrcbData.___u102
                test    edx, 8
                jz      short loc_4352FB
                mov     eax, 1
                xor     edx, edx
                mov     ecx, 49h ; 'I'
                wrmsr                   ; 将msr寄存器的0x49位置设置为1
                jmp     loc_435418

以上指令主要也是保存一些值,最重要的将eax、edx保存到了KTRAP_FRAME结构中,这两个寄存器中分别保存了调用号和3环的esp指针。

 				mov     eax, [ebp+_KTRAP_FRAME._Eax]
                mov     edx, [ebp+_KTRAP_FRAME._Edx]

loc_43541E:                             ; CODE XREF: KiFastCallEntryCommon+56↑j
                and     [ebp+_KTRAP_FRAME.Dr7], 0 ; 将TRAP_FRAME的dr7设置为0
                test    [esi+_KTHREAD.Header.___u0.__s3.DebugActive], 0DFh ; 判断是否在调试模式
                mov     [esi+_KTHREAD.TrapFrame], ebp ; 设置KTHREAD结构中TrapFrame
                jnz     Dr_FastCallDrSave ; 如果是调试模式就进行跳转

loc_435432:                             ; CODE XREF: Dr_FastCallDrSave+D↑j
                                        ; Dr_FastCallDrSave+79↑j
                mov     ebx, [ebp+_KTRAP_FRAME._Ebp]
                mov     edi, [ebp+_KTRAP_FRAME._Eip]
                mov     [ebp+_KTRAP_FRAME.DbgArgPointer], edx ; 设置3环参数指针
                mov     [ebp+_KTRAP_FRAME.DbgArgMark], 0BADB0D00h
                mov     [ebp+_KTRAP_FRAME.DbgEbp], ebx
                mov     [ebp+_KTRAP_FRAME.DbgEip], edi
                sti                     ; 开启中断

在以上代码中主要流程如下:

  1. 验证3环是否存在硬件调试环境,如果存在就跳转到“ Dr_FastCallDrSave”这函数里面保存硬件调试使用到的寄存器。
  2. 将本次使用到的KTRAP_FEAME结构的地址存储到线程结构中
  3. 开启中断

五、总结

在本章中分析了函数在调用ssdt之前的步骤,这些步骤中主要是保存了3环的环境并且将执行环境切换到0环。

  • 27
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值