windows系统调用

来源:互联网 发布:文员办公软件 编辑:程序博客网 时间:2024/05/19 21:04


1.x86为支持快速系统调用增加了 sysentersysexit3个寄存器

2.当执行int 0x2etss中装入本线程的系统空间堆栈寄存器和堆栈指针esp再依次把用户的空间堆栈ss esp eflags cs eip压入用户空间堆栈然后执行中断服务程序

3.NtReadFile() api界面函数

        _declspec(naked)__stdcall

        NtreadFile(intdummy0,int dummy1,int dummy2)

        {

                  _asm{

                                    pushebp

                                    movebp,esp

                                    moveax ,152

                                    leaedx,8[ebp]//指向参数快的起点 lea edx [ebp - 8]

                                    int0x2e

                                    popebp

                                    ret9 //堆栈上有9个参数 ret 0x24

                           }

        }

拷贝用户空间的堆栈参数到系统的空间堆栈,ebp用做框架指针

3个参数完全的虚设的,这样的函数成为stub函数。

4.现在windows采取的方案,

_stdcall

NtReadFile()

{

        __asm

        {

                  moveax,152

                 mov ecx,KUSER_SHARED_SYSCALL

                  call[ecx]

                  ret9

        }

}

 

KUSER_SHARED_SYSCALL指向0x7ffe0300,代表KiIntSystamCall

kifastSystemCall的地址,并在系统初始化时候决定。

5.ntdll是系统共用dll,在用户空间的地址是0x7ffe0300,在系统空间的地址是

0xffdf0000,但映射到同一物理内存,

6.系统调用的内核入口

        中断0x2e对应的处理函数是KISystemservice(),所以当cpu指向0x2e

中断以后,就进入这个函数,并将用户的上下文,保存到系统的系统堆栈中,

如下图:

 

 

KiSystemService()设置fs段寄存器,fs指向kPCR数据结构,esi指向Kthread姐欧股,PCR[KPCR_CURRENT_THREAD]= FS:KPCR_CURRENT_THREAD ,即当前的线程上下文,

KPCR_CURRENT_THREAD是个宏定义,#defineKPCR_CURRENT_THREAD 0x124,也就是说,当前线程的上下文放在pcr0x124处,实际当前线程上下文在一个叫kpcrb的数据结构中,结构如下,

这个结构中有关于cpu的很多信息,例如当前运行的线程,线程队列等等

7.系统的空间堆栈

        堆栈段寄存器ss和堆栈指针esp保存在tss数据结构中,cpu有个任务寄存器(tr

当进入系统空间的时候,cpu会根据trtss中获取ssesp

        1.获取tss中的ss esp

        2.保存用户空间上下文

        3.获取中断的cseip

8.每个cpu对应一个_KPCR结构,如下

kpcr结构

kd> dt _KPcr

nt!_KPCR

  +0x000 NtTib           : _NT_TIB

  +0x01c SelfPcr         : Ptr32_KPCR

  +0x020 Prcb            : Ptr32_KPRCB

  +0x024 Irql            : UChar

  +0x028 IRR             : Uint4B

  +0x02c IrrActive       : Uint4B

  +0x030 IDR             : Uint4B

  +0x034 KdVersionBlock  : Ptr32Void

  +0x038 IDT             : Ptr32_KIDTENTRY

  +0x03c GDT             : Ptr32_KGDTENTRY

  +0x040 TSS             : Ptr32_KTSS

  +0x044 MajorVersion    : Uint2B

  +0x046 MinorVersion    : Uint2B

  +0x048 SetMember       : Uint4B

  +0x04c StallScaleFactor : Uint4B

  +0x050 DebugActive     : UChar

  +0x051 Number          : UChar

  +0x052 Spare0          : UChar

  +0x053 SecondLevelCacheAssociativity : UChar

  +0x054 VdmAlert        : Uint4B

  +0x058 KernelReserved  : [14]Uint4B

  +0x090 SecondLevelCacheSize : Uint4B

  +0x094 HalReserved     : [16]Uint4B

  +0x0d4 InterruptMode   : Uint4B

  +0x0d8 Spare1          : UChar

  +0x0dc KernelReserved2 : [17]Uint4B

  +0x120 PrcbData        : _KPRCB

KPCRB结构

kd> dt _KPRCB

nt!_KPRCB

  +0x000 MinorVersion    : Uint2B

  +0x002 MajorVersion    : Uint2B

  +0x004 CurrentThread   : Ptr32_KTHREAD

  +0x008 NextThread      : Ptr32_KTHREAD

  +0x00c IdleThread      : Ptr32_KTHREAD

  +0x010 Number          : Char

  +0x011 Reserved        : Char

  +0x012 BuildType       : Uint2B

  +0x014 SetMember       : Uint4B

  +0x018 CpuType         : Char

  +0x019 CpuID           : Char

  +0x01a CpuStep         : Uint2B

  +0x01c ProcessorState  :_KPROCESSOR_STATE

  +0x33c KernelReserved  : [16]Uint4B

  +0x37c HalReserved     : [16]Uint4B

  +0x3bc PrcbPad0        : [92]UChar

  +0x418 LockQueue       : [16]_KSPIN_LOCK_QUEUE

  +0x498 PrcbPad1        : [8]UChar

  +0x4a0 NpxThread       : Ptr32_KTHREAD

  +0x4a4 InterruptCount  : Uint4B

  +0x4a8 KernelTime      : Uint4B

  +0x4ac UserTime        : Uint4B

  +0x4b0 DpcTime         : Uint4B

  +0x4b4 DebugDpcTime    : Uint4B

  +0x4b8 InterruptTime   : Uint4B

  +0x4bc AdjustDpcThreshold : Uint4B

  +0x4c0 PageColor       : Uint4B

  +0x4c4 SkipTick        : Uint4B

  +0x4c8 MultiThreadSetBusy : UChar

  +0x4c9 Spare2          : [3]UChar

  +0x4cc ParentNode      : Ptr32_KNODE

  +0x4d0 MultiThreadProcessorSet : Uint4B

  +0x4d4 MultiThreadSetMaster : Ptr32 _KPRCB

  +0x4d8 ThreadStartCount : [2] Uint4B

  +0x4e0 CcFastReadNoWait : Uint4B

  +0x4e4 CcFastReadWait  : Uint4B

  +0x4e8 CcFastReadNotPossible : Uint4B

  +0x4ec CcCopyReadNoWait : Uint4B

  +0x4f0 CcCopyReadWait  : Uint4B

  +0x4f4 CcCopyReadNoWaitMiss : Uint4B

  +0x4f8 KeAlignmentFixupCount : Uint4B

  +0x4fc KeContextSwitches : Uint4B

  +0x500 KeDcacheFlushCount : Uint4B

  +0x504 KeExceptionDispatchCount : Uint4B

  +0x508 KeFirstLevelTbFills : Uint4B

  +0x50c KeFloatingEmulationCount : Uint4B

  +0x510 KeIcacheFlushCount : Uint4B

  +0x514 KeSecondLevelTbFills : Uint4B

  +0x518 KeSystemCalls   : Uint4B

  +0x51c SpareCounter0   : [1]Uint4B

  +0x520 PPLookasideList : [16]_PP_LOOKASIDE_LIST

  +0x5a0 PPNPagedLookasideList : [32] _PP_LOOKASIDE_LIST

  +0x6a0 PPPagedLookasideList : [32] _PP_LOOKASIDE_LIST

  +0x7a0 PacketBarrier   : Uint4B

  +0x7a4 ReverseStall    : Uint4B

  +0x7a8 IpiFrame        : Ptr32Void

  +0x7ac PrcbPad2        : [52]UChar

  +0x7e0 CurrentPacket   : [3]Ptr32 Void

  +0x7ec TargetSet       : Uint4B

  +0x7f0 WorkerRoutine   :Ptr32     void

  +0x7f4 IpiFrozen       : Uint4B

  +0x7f8 PrcbPad3        : [40]UChar

  +0x820 RequestSummary  : Uint4B

  +0x824 SignalDone      : Ptr32_KPRCB

  +0x828 PrcbPad4        : [56]UChar

  +0x860 DpcListHead     :_LIST_ENTRY

  +0x868 DpcStack        : Ptr32Void

  +0x86c DpcCount        : Uint4B

  +0x870 DpcQueueDepth   : Uint4B

  +0x874 DpcRoutineActive : Uint4B

  +0x878 DpcInterruptRequested : Uint4B

  +0x87c DpcLastCount    : Uint4B

  +0x880 DpcRequestRate  : Uint4B

  +0x884 MaximumDpcQueueDepth : Uint4B

  +0x888 MinimumDpcRate  : Uint4B

  +0x88c QuantumEnd      : Uint4B

  +0x890 PrcbPad5        : [16]UChar

  +0x8a0 DpcLock         : Uint4B

  +0x8a4 PrcbPad6        : [28]UChar

  +0x8c0 CallDpc         : _KDPC

  +0x8e0 ChainedInterruptList : Ptr32 Void

  +0x8e4 LookasideIrpFloat : Int4B

  +0x8e8 SpareFields0    : [6]Uint4B

  +0x900 VendorString    : [13]UChar

  +0x90d InitialApicId   : UChar

  +0x90e LogicalProcessorsPerPhysicalProcessor : UChar

  +0x910 MHz             : Uint4B

  +0x914 FeatureBits     : Uint4B

  +0x918 UpdateSignature :_LARGE_INTEGER

  +0x920 NpxSaveArea     :_FX_SAVE_AREA

  +0xb30 PowerState      :_PROCESSOR_POWER_STATE

9.kpcr构分析

        kpcr第一个成分kpcr_tib其中保存exceptionList SEH的核心

        Irql记录当前cpuIRQL

10.系统调用的返回

        当从系统调用返回就进入了callebx

        回复用户空间线程的上下文,关中断,后边是两个宏,CHECK_FOR_APC_DELIVERTRAP_EPILOGCHECK_FOR_APC_DELIVER的作用是检查当前用户是否有异步过程调用,即apc,如果有,为用户空间执行相应的函数做好准备,apc机制和linuxsignal机制类似。当cpuAPC_LEVEL降低到PASSIVE_LEVEL的时候,可能引起线程的切换,

void fastcall

kfLowerIrql(KIRQL newIrql)

{

        if(newIrql> KeGetPcr() ->Irql)

        {

                  for(;;);

        }

        HalpLowerIrql(NewIrql);

}

函数HalpLowerIrql(NewIrql);中可能会引起线程的切换,

 

 

KiDispatch相当于执行软中断,执行完dpc函数后,如果kpcrQUantumEnd字段非0就进行线程的调度和切换

        

11.快速系统调用

        pentium II开始增加了sysentersysexit两条指令和3msr寄存器来实现系统调用。

 

0 0
原创粉丝点击