签到

05月06日
尚未签到

共有回帖数 0

    花非花雾非雾

    等级:
    win支持两种系统调用进入内核的方式,对于没有SYSENTER_CS_MSR,SYSENTER_EIP_MSR,SYSENTER_ESP_MSR的CPU,采用传统的int 2e指令进入。而现在的CPU基本都有了这几个MSR寄存器,所以咱们的系统一般通过sysenter快速系统调用进入内核。实际上,这两种方式的框架是大体相同的。
    首先来看看int 2e吧。

    执行int 2e时,CPU自动从当前任务TSS中取出ring0的SS和ESP并装入相应寄存器,接着依次将用户空间SS,ESP,EFLAGS,CS,EIP压入用户空间堆栈。然后从IDT表中取出0x2e号的向量,得到程序入口指针(KiSystemService)。关闭中断。跳转到KiSystemService处执行。
    nt!KiSystemService:
    80541441 6a00            push    0
    80541443 55              push    ebp
    80541444 53              push    ebx
    80541445 56              push    esi
    80541446 57              push    edi
    80541447 0fa0            push    fs
    保存寄存器,建立框架
    80541449 bb30000000      mov     ebx,30h
    8054144e 668ee3          mov     fs,bx
    fs中是0x30,相应的gdt表项指向内核中一片固定区域,里面有重要数据结构。最开始是一个称为_KPCR的数据结构。
    lkd 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   : Ptr32 Void
      +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
    80541451 64ff3500000000 push    dword ptr fs:[0]
    80541458 64c70500000000ffffffff mov dword ptr fs:[0],0FFFFFFFFh
    fs:[0]在_NT_TIB中,看看
    lkd DT !_NT_TIB
    nt!_NT_TIB
      +0x000 ExceptionList    : Ptr32 _EXCEPTION_REGISTRATION_RECORD
      +0x004 StackBase        : Ptr32 Void
      +0x008 StackLimit       : Ptr32 Void
      +0x00c SubSystemTib     : Ptr32 Void
      +0x010 FiberData        : Ptr32 Void
      +0x010 Version          : Uint4B
      +0x014 ArbitraryUserPointer : Ptr32 Void
      +0x018 Self             : Ptr32 _NT_TIB
    fs:[0]指向异常处理队列。结构化异常处理,即SEH,大家都懂的。
    首先将指向的队列指针保存,然后清空。
    80541463 648b3524010000 mov     esi,dword ptr fs:[124h]
    fs:[124]在_KPRCB中。这个结构很长,我们只看关心的
    lkd dt !_KPRCB
    nt!_KPRCB
      +0x000 MinorVersion     : Uint2B
      +0x002 MajorVersion     : Uint2B
      +0x004 CurrentThread    : Ptr32 _KTHREAD
      +0x008 NextThread       : Ptr32 _KTHREAD
      +0x00c IdleThread       : Ptr32 _KTHREAD
    所以esi现在指向表示当前线程的数据结构_KTHREAD
    8054146a ffb640010000    push    dword ptr [esi+140h]
    继续看_KTHREAD这个结构,也很长
    nt!_KTHREAD
      +0x000 Header           : _DISPATCHER_HEADER
      +0x010 MutantListHead   : _LIST_ENTRY
    ……
      +0x140 PreviousMode     : Char
    ……
    将先前的模式保存。先前模式即KernelMode或UserMode。

    80541470 83ec48          sub     esp,48h
    开辟一片栈空间,用以保存其他寄存器。
    80541473 8b5c246c        mov     ebx,dword ptr [esp+6Ch]
    即保存在堆栈中的cs
    80541477 83e301          and     ebx,1
    若是从UserMode发起的调用,则cs最低两位为00b,否则,11b
    8054147a 889e40010000    mov     byte ptr [esi+140h],bl
    新的当前线程PreviousMode
    80541480 8bec            mov     ebp,esp
    ebp based frame
    80541482 8b9e34010000    mov     ebx,dword ptr [esi+134h]
    _KTHREAD中
    +0x134 TrapFrame        : Ptr32 _KTRAP_FRAME
    用以保存框架的。
    80541488 895d3c          mov     dword ptr [ebp+3Ch],ebx
    将先前框架保存在本用于保存edx的地方。因为edx用于传递用户堆栈中参数块的指针
    8054148b 89ae34010000    mov     dword ptr [esi+134h],ebp
    保存当前框架
    80541491 fc              cld
    80541492 8b5d60          mov     ebx,dword ptr [ebp+60h]
    即ebp
    80541495 8b7d68          mov     edi,dword ptr [ebp+68h]
    即eip
    80541498 89550c          mov     dword ptr [ebp+0Ch],edx
    用户堆栈参数块
    8054149b c74508000ddbba mov     dword ptr [ebp+8],0BADB0D00h
    805414a2 895d00          mov     dword ptr [ebp],ebx
    805414a5 897d04          mov     dword ptr [ebp+4],edi
    805414a8 f6462cff        test    byte ptr [esi+2Ch],0FFh
    _KTHREAD中
    +0x02c DebugActive      : UChar
    是否处于处于受调试状态中

    805414ac 0f858afeffff    jne     nt!Dr_kss_a (8054133c)

    上面若不在调试状态,便接着走下来到了这里。
    nt!KiSystemService+0x71:
    805414b2 fb              sti
    开中断
    805414b3 e9e7000000      jmp     nt!KiFastCallEntry+0x8f (8054159f)
    看到这里是nt!KiFastCallEntry,说明将要跳转的是和FastCall公用的。

    nt!KiFastCallEntry+0x8f:
    8054159f 8bf8            mov     edi,eax
    eax中是系统调用号
    805415a1 c1ef08          shr     edi,8
    805415a4 83e730          and     edi,30h
    805415a7 8bcf            mov     ecx,edi
    XP中将图形界面的操作也移动到了内核(win32k.sys),其系统调用号大于0x1000,而传统的则小于0x1000
    故操作之后若为ntoskrnl导出,则ecx == 0x0,否则,0x10(0x20,,0x30会出现吗?不知道。。不过XP应该是不会了)
    805415a9 03bee0000000    add     edi,dword ptr [esi+0E0h]
    这里是_KTHREAD的
      +0x0e0 ServiceTable     : Ptr32 Void
    这个是指向系统调用表的。
    之后edi指向KeServiceDescriptorTable(ecx == 0x0)KeServiceDescriptorTableShadow(ecx == 0x10),?(ecx == 20),?(ecx == 0x30)
    805415af 8bd8            mov     ebx,eax
    805415b1 25ff0f0000      and     eax,0FFFh
    805415b6 3b4708          cmp     eax,dword ptr [edi+8]
    是否超出了最大表项
    805415b9 0f8333fdffff    jae     nt!KiBBTUnexpectedRange (805412f2)


    若超出了范围(调用号超过0x1000,即调用win32k中的服务,因为系统调用表第0项是表示ntoskrnl导出的服务,是小于0x1000的),则到了这里

    nt!KiBBTUnexpectedRange:
    805412f2 83f910          cmp     ecx,10h
    805412f5 7539            jne     nt!KiBBTUnexpectedRange+0x3e (80541330)

    若不等于0x10h,则失败,到了这里
    nt!KiBBTUnexpectedRange+0x3e:
    80541330 b81c0000c0      mov     eax,0C000001Ch
    80541335 e9d4020000      jmp     nt!KiFastCallEntry+0xfe (8054160e)
    0x0C000001C即STATUS_UNSUCCESSFUL,然后该干嘛干嘛了。这些之后调用PsConvertToGuiThread,这些不是重点,咱们就不看了。有兴趣可以自己看看。

    楼主 2015-11-26 14:24 回复

共有回帖数 0
  • 回 帖
  • 表情 图片 视频
  • 发表

登录直线网账号

Copyright © 2010~2015 直线网 版权所有,All Rights Reserved.沪ICP备10039589号 意见反馈 | 关于直线 | 版权声明 | 会员须知