反汇编内核函数的时候经常会看到mov eax, fs:[124].一直没弄清楚fs寄存器在ring0存放的是什么。今天查了下资料。

fs寄存器在Ring0中指向一个称为KPCR的数据结构,即FS段的起点与KPCR结构对齐。而在Ring0中fs寄存器一般为0x30。

这样看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

这样fs:[124]就指向KPRCB数据结构的第四个字节。由于KPRCB比较大,再此就不列出来了。查看其数据结构可以看到第四个字节指向CurrentThead(KTHREAD类型)。这样fs:[124]其实是指向当前线程的_KTHREAD。

===============================================================================================

应用实例:

以前看某些文章的时候,知道可以利用“活动进程链”隐藏或者检测进程。对于如何定位活动进程链一直没搞清楚,在看Rootkit那本书上说,通过PsGetCurrentProcess函数可以获得EPROCESS,但是书中解释的很模糊,一直没看明白。
今天利用WinDbg查看了各个结构,终于把疑问搞清楚了。
PsGetCurrentProcess函数反汇编后是这样:

lkd> u nt!PsGetCurrentProcess
nt!PsGetCurrentProcess:
8052b52c 64a124010000         mov          eax,dword ptr fs:[00000124h]
8052b532 8b4044                   mov          eax,dword ptr [eax+44h]
8052b535 c3                          ret

在用户模式下,FS指向TEB结构,而在内核模式下FS却指向KPCR(Kernel's Processor Control Region)结构。那么可以看到FS:[0x120]处就是KPRCB(Kernel's Processor Cotrol Block)结构(看下图红色高亮处)

lkd> dt nt!_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

展开KPRCB结构继续观察可以看到FS:[0x124]指向了KTHREAD结构

lkd> dt nt!_kprcb
nt!_KPRCB
        +0x000 MinorVersion          : Uint2B
        +0x002 MajorVersion          : Uint2B
   +0x004 CurrentThread         : Ptr32 _KTHREAD
        +0x008 NextThread            : Ptr32 _KTHREAD
        +0x00c IdleThread            : Ptr32 _KTHREAD
......本结构更多成员省略

继续查看KTHREAD结构可以看到KTHREAD+0x44处成员就是KPROCESS指针

lkd> dt nt!_kthread -v -r1
Matched nt!_KTHREAD
nt!_KTHREAD
struct _KTHREAD, 73 elements, 0x1c0 bytes
        +0x000 Header                : struct _DISPATCHER_HEADER, 6 elements, 0x10 bytes
           +0x000 Type                  : UChar
           +0x001 Absolute              : UChar
           +0x002 Size                  : UChar
           +0x003 Inserted              : UChar
           +0x004 SignalState           : Int4B
           +0x008 WaitListHead          : struct _LIST_ENTRY, 2 elements, 0x8 bytes
              +0x000 Flink                 : Ptr32 to struct _LIST_ENTRY, 2 elements, 0x8 bytes
              +0x004 Blink                 : Ptr32 to struct _LIST_ENTRY, 2 elements, 0x8 bytes
        +0x010 MutantListHead        : struct _LIST_ENTRY, 2 elements, 0x8 bytes
           +0x000 Flink                 : Ptr32 to struct _LIST_ENTRY, 2 elements, 0x8 bytes
              +0x000 Flink                 : Ptr32 to struct _LIST_ENTRY, 2 elements, 0x8 bytes
              +0x004 Blink                 : Ptr32 to struct _LIST_ENTRY, 2 elements, 0x8 bytes
           +0x004 Blink                 : Ptr32 to struct _LIST_ENTRY, 2 elements, 0x8 bytes
              +0x000 Flink                 : Ptr32 to struct _LIST_ENTRY, 2 elements, 0x8 bytes
              +0x004 Blink                 : Ptr32 to struct _LIST_ENTRY, 2 elements, 0x8 bytes
        +0x018 InitialStack          : Ptr32 to Void
        +0x01c StackLimit            : Ptr32 to Void
        +0x020 Teb                   : Ptr32 to Void
        +0x024 TlsArray              : Ptr32 to Void
        +0x028 KernelStack           : Ptr32 to Void
        +0x02c DebugActive           : UChar
        +0x02d State                 : UChar
        +0x02e Alerted               : [2] UChar
        +0x030 Iopl                  : UChar
        +0x031 NpxState              : UChar
        +0x032 Saturation            : Char
        +0x033 Priority              : Char
  +0x034 ApcState              : struct _KAPC_STATE, 5 elements, 0x18 bytes
           +0x000 ApcListHead           : [2] struct _LIST_ENTRY, 2 elements, 0x8 bytes
              +0x000 Flink                 : Ptr32 to struct _LIST_ENTRY, 2 elements, 0x8 bytes
              +0x004 Blink                 : Ptr32 to struct _LIST_ENTRY, 2 elements, 0x8 bytes
      +0x010 Process               : Ptr32 to struct _KPROCESS, 29 elements, 0x6c bytes

至此,我们已经搞清了PsGetCurrentProcess的流程
通过查DDK DOC发现MS对PsGetCurrentProcess函数是这样描述的:

PsGetCurrentProcess returns a pointer to the process of the current thread.
PEPROCESS
       PsGetCurrentProcess(
         );

该函数的返回值是EPROCESS指针。但是我们分析的结果是函数的返回值是KPROCESS的指针。
这样的话难道PsGetCurrentProcess 函数返回值既是EPROCESS的指针又是KPROCESS的指针?
带着疑问我们继续往下看:

lkd> dt nt!_eprocess
nt!_EPROCESS
   +0x000 Pcb                   : _KPROCESS
        +0x06c ProcessLock           : _EX_PUSH_LOCK
        +0x070 CreateTime            : _LARGE_INTEGER
        +0x078 ExitTime              : _LARGE_INTEGER
        +0x080 RundownProtect        : _EX_RUNDOWN_REF
   +0x084 UniqueProcessId       : Ptr32 Void
        +0x088 ActiveProcessLinks : _LIST_ENTRY

可以看到EPROCESS的第一个成员就是KPROCESS,这样我们就明白了为什么PsGetCurrentProcess 函数返回值既是EPROCESS的地址又是KPROCESS的地址了。在EPROCESS偏移0x84是进程的PID,偏移0x88(我的系统是XP SP2)就是我们要找的活动进程链了。

ring0下的 fs:[124]相关推荐

  1. fs:[124]对应CurrentThread

    反汇编内核函数的时候经常会看到mov eax, fs:[124].一直没弄清楚fs寄存器在ring0存放的是什么.今天查了下资料. fs寄存器在Ring0中指向一个称为KPCR的数据结构,即FS段的起 ...

  2. 【梅哥的Ring0湿润插入教程】重磅第三课:Ring0下的PE Loader及重加载内核秒杀一切内核级钩子(上篇)...

    [梅哥的Ring0湿润插入教程] Email:mlkui@163.com 转载请注明出处,谢绝喷子记者等,如引起各类不适请自觉滚J8蛋! 第三课:Ring0下PE Loader及重加载内核绕过一切内核 ...

  3. CVE-2018-8120 分析

    目录 CVE-2018-8120 分析 1.实验环境 1.1.操作系统 1.2.用到的分析工具 2.假如 2.1.我想提权 2.2. 有一个处于内核空间,极少被调用的函数 2.3.R3任意修改R0地址 ...

  4. Windows 中 FS 段寄存器

    代码运行在RING0(系统地址空间)和RING3(用户地址空间)时,FS段寄存器分别指向GDT(全局描述符表)中不同段:在RING3下,FS段值是0x3B(这是WindowsXP下值:在Windows ...

  5. Windows内核实验003 再次回到中断

    文章目录 两个实验 死循环 开启中断后的死循环 KiFastCallEntry 调用零环API的两个条件 分析KiFastCallEntry 什么是KPCR 完善代码 完整代码 之前的实验我们已经实现 ...

  6. Windows xp下IDT Hook和GDT的学习

    一.前言   对于IDT第一次的认知是int 2e ,在系统调用的时候原来R3进入R0的方式就是通过int 2e自陷进入内核,然后进入KiSystemService函数,在根据系统服务调用号调用系统服 ...

  7. Ubuntu16.04下Hadoop 2.7.3的安装与配置

    一.JAVA环境搭建 (1)下载JDK并解压(当前操作系统为Ubuntu16.04,jdk版本为jdk-8u111-linux-x64.tar.gz) 新建/usr/java目录,切换到jdk-8u1 ...

  8. c++读取utf8文件_Node.js 进阶之 fs 文件模块学习

    前言 文件操作是开发过程中并不可少的一部分.Node.js 中的 fs 模块是文件操作的封装,它提供了文件读取.写入.更名.删除.遍历目录.链接等 POSIX 文件系统操作.与其它模块不同的是,fs ...

  9. 日历控件,可运行在XHTML1.0下

    JCalendar.js 1 //基本函数库/ 2 var isIE = /msie/i.test(navigator.userAgent);3 var isDTD = /CSS1Compat/i.t ...

最新文章

  1. 2-Tenor AF AFT400-实战-Lync Server 2010-集成-2012-01-19
  2. Springboot与Spring的关系
  3. 手写数字识别项目代码——卷积神经网络LeNet-5模型
  4. vsftp 一键安装包
  5. bzoj 1058: [ZJOI2007]报表统计(set+multiset)
  6. (转)常见LCD接口
  7. pscad c语言程序,PSCAD入门教程(第8节):调用C语言函数及file reference组件使用...
  8. mayapython编译器_Maya 安装 Cython(详细)
  9. typeof和instanceof的区别
  10. Android常用颜色RGB值以及中英文名称
  11. Java音乐播放器设计
  12. iOS实现App之间的分享
  13. UVa 12112 - Iceman
  14. table表头行固定
  15. 搭建直播平台,你需要先知道这些
  16. 腾讯云注册与实名图文教程
  17. 前端学习-关于选择器的介绍和使用
  18. wap论坛php源码,家教平台教育论坛相关网站PHP源码+WAP手机端自适应
  19. 汉字乱码现象的分类解析
  20. 逻辑分析仪的使用--LA1010

热门文章

  1. JavaScript疑难杂症系列-事件循环
  2. zoj4110 Strings in the Pocket(manacher)
  3. 一切皆文件的编程思想
  4. 关于R语言的一些编程经验
  5. C#中Delegate和Event以及它们的区别(转载)
  6. 修改及查看mysql数据库的字符集
  7. 完成动态根据类别动态填充区域颜色
  8. 数据库设计中的14个技巧
  9. P1912 [NOI2009]诗人小G
  10. ASP.NET防止按F5键造成表单重复提交