首页
社区
课程
招聘
[分享]X86系统调用_下(Ring0)
2020-6-3 21:32 4673

[分享]X86系统调用_下(Ring0)

2020-6-3 21:32
4673

紧接上文, sysenter 指令最终导致进入内核模块的 KiFastSystemCall

在分析这个函数之前需要补充一些知识

1.) FS寄存器的值存的是什么?在R3 FS寄存器的值是0x3B, 在R0 FS寄存器的值是0x30

这里我们对 0x30 选择子进行拆分如下:

kd> dg 30
                                  P Si Gr Pr Lo
Sel    Base     Limit     Type    l ze an es ng Flags
---- -------- -------- ---------- - -- -- -- -- --------
0030 ffdff000 00001fff Data RW Ac 0 Bg Pg P  Nl 00000c93

得到的是 Base: ffdff000, 那么这个数据段指向的是什么呢?我们用 WinDbg 的 !pcr 指令查看:

kd> !pcr
KPCR for Processor 0 at ffdff000:
    Major 1 Minor 1
    NtTib.ExceptionList: 8054a4b0
        NtTib.StackBase: 8054acf0
       NtTib.StackLimit: 80547f00
     NtTib.SubSystemTib: 00000000
          NtTib.Version: 00000000
      NtTib.UserPointer: 00000000
          NtTib.SelfTib: 00000000
                SelfPcr: ffdff000
                   Prcb: ffdff120
                   Irql: 00000000
                    IRR: 00000000
                    IDR: ffffffff
          InterruptMode: 00000000
                    IDT: 8003f400
                    GDT: 8003f000
                    TSS: 80042000
          CurrentThread: 80553740
             NextThread: 00000000
             IdleThread: 80553740
              DpcQueue:  0x80553da0 0x80500df0 [Normal] nt!KiTimerExpiration

通过上面我们可以知道,其是一个 KPCR 结构体, 继续用 WinDbg 查看, 如下, 由此我们可以知道 FS 指向的是一个名为 KPCR 的结构体(注意在 R3 指向的 TEB结构体)

kd> dt _KPCR ffdff000
nt!_KPCR
   +0x000 NtTib            : _NT_TIB
   +0x01c SelfPcr          : 0xffdff000 _KPCR
   +0x020 Prcb             : 0xffdff120 _KPRCB
   +0x024 Irql             : 0 ''
   +0x028 IRR              : 0
   +0x02c IrrActive        : 0
   +0x030 IDR              : 0xffffffff
   +0x034 KdVersionBlock   : 0x80546ab8 Void          // 指向 _DBGKD_GET_VERSION64 结构体
   +0x038 IDT              : 0x8003f400 _KIDTENTRY
   +0x03c GDT              : 0x8003f000 _KGDTENTRY
   +0x040 TSS              : 0x80042000 _KTSS
   +0x044 MajorVersion     : 1
   +0x046 MinorVersion     : 1
   +0x048 SetMember        : 1
   +0x04c StallScaleFactor : 0x8a0
   +0x050 DebugActive      : 0 ''
   +0x051 Number           : 0 ''
   +0x052 Spare0           : 0 ''
   +0x053 SecondLevelCacheAssociativity : 0 ''
   +0x054 VdmAlert         : 0
   +0x058 KernelReserved   : [14] 0
   +0x090 SecondLevelCacheSize : 0
   +0x094 HalReserved      : [16] 0
   +0x0d4 InterruptMode    : 0
   +0x0d8 Spare1           : 0 ''
   +0x0dc KernelReserved2  : [17] 0
   +0x120 PrcbData         : _KPRCB

2). 陷阱帧(_KTRAP_FRAME),用于保存 R3 的寄存器参数结构体,如下:

kd> dt _KTRAP_FRAME 0x8054acf0
nt!_KTRAP_FRAME
   +0x000 DbgEbp           : 0x27f
   +0x004 DbgEip           : 0
   +0x008 DbgArgMark       : 0
   +0x00c DbgArgPointer    : 0
   +0x010 TempSegCs        : 0
   +0x014 TempEsp          : 0
   +0x018 Dr0              : 0x1f80
   +0x01c Dr1              : 0
   +0x020 Dr2              : 0
   +0x024 Dr3              : 0
   +0x028 Dr6              : 0
   +0x02c Dr7              : 0
   +0x030 SegGs            : 0
   +0x034 SegEs            : 0
   +0x038 SegDs            : 0
   +0x03c Edx              : 0
   +0x040 Ecx              : 0
   +0x044 Eax              : 0
   +0x048 PreviousPreviousMode : 0
   +0x04c ExceptionList    : (null)
   +0x050 SegFs            : 0
   +0x054 Edi              : 0
   +0x058 Esi              : 0
   +0x05c Ebx              : 0
   +0x060 Ebp              : 0
   +0x064 ErrCode          : 0
   +0x068 Eip              : 0
   +0x06c SegCs            : 0
   +0x070 EFlags           : 0
   +0x074 HardwareEsp      : 0
   +0x078 HardwareSegSs    : 0   ; TSS 中的 ESP0 默认指向的是这个位置
   +0x07c V86Es            : 0
   +0x080 V86Ds            : 0
   +0x084 V86Fs            : 0
   +0x088 V86Gs            : 0

3). 系统服务表和SSDT、SSDTShadow

系统服务表(System service table),结构如下, 是用来记录指定模块对外导出的函数相关信息, 包括(Ntoskrl.exe、Win32k.Sys)

struct System_service_table
{
    PVOID ServiceTableAddr; // 函数地址表的地址 (4字节成员)
    ULONG Count;            // 当前系统服务表被调用的次数
    ULONG ServiceLimit;     // 系统服务表中函数的个数
    PVOID ArgMentTable;     // 系统参数表地址 (1字节成员)
}

SSDT表(非UI线程所使用的表)

在 WinXp 上是导出的全局变量 KeServiceDescriptorTable(记录了SSDT表的起始地址), 在此表中只包含了记录 Ntoskrl.exe 内核模块导出的函数相关信息的系统服务表,如下:

kd> dd KeServiceDescriptorTable
80553fa0  80502b8c 00000000 0000011c 80503000   ; 此为 Ntoskrl.exe 的系统服务表, 该模块记录了一般处理系统功能性的函数
80553fb0  00000000 00000000 00000000 00000000
80553fc0  00000000 00000000 00000000 00000000
80553fd0  00000000 00000000 00000000 00000000

SSDTShadow表(UI线程所使用的表)

在 WinXp 上是导出的全局变量 KeServiceDescriptorTableShadow  记录了SSDTShadow表的起始地址), 在此表中包含了 Ntoskrl.exe、Win32k.Sys导出的函数相关信息的系统服务表,如下:

kd> dd KeServiceDescriptorTableShadow
80553f60  80502b8c 00000000 0000011c 80503000   ; 此为 Ntoskrl.exe 的系统服务表, 该模块记录了一般处理系统功能性的函数
80553f70  bf999b80 00000000 0000029b bf99a890   ; 此为 Win32k.Sys 的系统服务表(又称影子表), 该模块记录了关于系统UI界面的函数
80553f80  00000000 00000000 00000000 00000000
80553f90  00000000 00000000 00000000 00000000

根据线程的不一样, 使用的表也是不一样的, 线程中的 KPCR.PrcbData.CurrentThread.ServiceTable 所指向的地址也不一样, (0x80553fa0 或 0x80553f60)


4). 现在我们开始分析 KiFastSystemCall  函数, 以下是我个人分析(如有错误请指教)

请查看附件


5). 最后要注意的是 int 0x2E 进入内核,更快速调用还是有不一样, INT 0x2E操作大体如下


阿里云助力开发者!2核2G 3M带宽不限流量!6.18限时价,开 发者可享99元/年,续费同价!

最后于 2020-6-3 21:34 被灵幻空间编辑 ,原因: 排版问题
上传的附件:
收藏
点赞1
打赏
分享
最新回复 (1)
雪    币: 259
活跃值: (283)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
ZwCopyAll 2020-6-4 18:01
2
0
666
游客
登录 | 注册 方可回帖
返回