浅谈Windows 2000/XP File Cache实现(http://webcrazy.yeah.net)_vacb_mapping_granularity-程序员宅基地

技术标签: struct  cache  file  windows  编程指南  pointers  object  

  浅谈Windows 2000/XP File Cache实现
              WebCrazy(http://webcrazy.yeah.net)

    声明:本文所叙内容为Windows NT/2000/XP的Cache管理内容,涉及内容均为Microsoft Undocumented内容。我在参考大量资料后分析而成,牵涉内容多多少少可能会有些许错误,甚至根本就是错误的,但本着学习交流的目的,权当是写下的笔记公布于此(http://webcrazy.yeah.net),希望能多加于交流([email protected]),以便我以后更新错误。

    记得早期dos下smartdrv.exe的功效就曾让我有较深的印象。我不记得我是在什么时候对这个小文件有兴趣且对其进行过学习的,这也是我对File Cache最初期的印象。在Windows NT/2000/XP中Cache管理部分更是让我有了现代操作系统实现File Cache的整体概念。读过《Inside Windows 2000》或是《Windows NT File System Internals》的肯定对此有比较深的理解,我不准备对他们已经涉及到的内容过于拘泥,我发现其实他们涉及到的许多东西并没有深入(虽然都有点出),或许也没有必要讲到具体实现上来,这会随着Windows的新版本的出现有些许改进变化。我得益于这两本书与其他许多资料,我也建议在往下看此文之前,首先好好的看一下他们。

    我们知道Cache部分最主要的是对文件(含网络远程文件)等较费时的IO操作作高速缓存(置入相对较快的内存中),既然其操作的对象主要是File(Windows中很多东西在底层均是作为File对象的),我们的叙述也已FILE对象开始。一个FILE对象,均有一个SECTION_OBJECT_POINTERS定义(详细的定义请参阅ntddk.h或ntifs.h中的FILE_OBJECT)。我在《探寻Windows NT/2000 Copy On Write机制》中指出过其定义:

     typedef struct _SECTION_OBJECT_POINTERS {
         PVOID DataSectionObject; //Control Area
         PVOID SharedCacheMap;
         PVOID ImageSectionObject; //Control Area
     } SECTION_OBJECT_POINTERS;

    因为成员DataSectionObject与ImageSectionObject均指向一称为Control Area的内部结构,而Control Area结构又指向一个称为Segment的内部结构。Segment由一个或多个原型PTE(Prototype PTE,PPTE)组成。PPTE是一个软件结构,我在《小议Windows NT/2000分页机制》结尾处提及过PPTE,也提及过PPTE不同于那边介绍的常规硬件PTE。PPTE的一个目的即是实现页面共享。而一个或多个PPTE(s)则组成了Subsection。这些基于kernel debug的ca命令的输出结果分析而成。

    成员SharedCacheMap则是真正的File Cache使用的结构。不同于FILE_OBJECT的另一个成员PrivateCacheMap,针对同一个文件,任何打开的指向这个文件的Handle指向的FILE_OBJECT结构的SharedCacheMap均是同一个值,这也是共享文件一个保证。我们来看在系统某一时刻同时指向shdocvw.dll的两个FILE_OBJECT(地址分别为80d37550与80db4860)的情况:

    //指向shdocvw.dll的第一个FILE_OBJECT:
    :fobj 80d37550
    DeviceObject * : 80EE2888
    Vpb * : 80EE2800
    FsContext * : E14D2D90
    FsContext2 * : E14D2EE8
    SecObjPointer * : 80DD15F4
    PrivateCacheMap * : 80EA70A0
        .
        .
        .
    FileName : /WINDOWS/system32/shdocvw.dll
        .
        .
        .

    //指向shdocvw.dll的第二个FILE_OBJECT:
    :fobj 80db4860
    DeviceObject * : 80EE2888
    Vpb * : 80EE2800
    FsContext * : E14D2D90
    FsContext2 * : E1183678
    SecObjPointer * : 80DD15F4
    PrivateCacheMap * : 80D6F2D8
        .
        .
        .
    FileName : /WINDOWS/system32/shdocvw.dll
        .
        .
        .

    从以上Softice的结果我们很容易的发现SECTION_OBJECT_POINTERS指向同一个内存区域,所以SharedCacheMap肯定指向同一个值,而PrivateCacheMap则是两个全然不同的值,进一步分析,FsContext也指向同一个值,而FsContext2则不同,实际上在实现FSD时,这两个成员一个为File Control Buffer(参阅ntifs.h中的FSRTL_COMMON_FCB_HEADER定义),一个指向Context Control Buffer,具体的用法可参考ntifs中的fastfat或是cdfs的实现,不在本文的讨论范围。

    分析过后FILE_OBJECT,我们可以得到一个结论:通过FILE_OBJECT我们可以得到这个FILE对象的一个或两个Control Area,而通过Control Area我们则可以得到Segment,既而即是Segment底下的Subsection与PPTEs,另外通过FILE_OBJECT我们也可以得到这文件所有实例的SharedCacheMap。事实上SharedCacheMap也有指针指向FILE_OBJECT,下面我会继续说明。

    记得我很早前就在《分析Windows NT/2000堆内存与虚拟内存组织》中定义过这样一个结构:

     typedef struct vad {
         void *StartingAddress;
         void *EndingAddress;
         struct vad *ParentLink;
         struct vad *LeftLink;
         struct vad *RightLink;
         ULONG Flags;
         ULONG MMCI;
         ULONG ProtoPTE;
     }VAD, *PVAD;

    实际上MMCI也即Control Area,我在《探寻Windows NT/2000 Copy On Write机制》中也作过解释。ProtoPTE即PPTE。

    有了这样一个概念以后,我们即可以很容易的发现PPTE是如何实现页面共享的。系统在初次访问PPTE所指向的页面时,由于PPTE的bit 0为无效,所以发生Page Fault,从而交由int e处理,即控制权由ntoskrnl.exe中的KiTrap0E交由MmAccessFault处理,然后通过查VAD,即可通过Control Area与PPTE定位PFN Database,读取在磁盘的内容,更新PTE实现共享的目的。

    详细的谈了FILE_OBJECT后,我们转向File Cache的讨论。Windows 2000/XP保留了由MmSystemCacheStart与MiSystemCacheStartExtra指向的两块系统虚拟内存区域专门用于System Cache。这专门的区域被分成大小为VACB_MAPPING_GRANULARITY(由ntifs.h中定义,值为0x40000,即256KB)的View。各View的使用情况由系统中的一个称为VACB的内部结构表示。这样系统中则有一个VACB数组,由CcVacbs指定。《Inside Windows 2000》中列举了VACB的四个成员,指出其包含一个重要的成员,即SharedCacheMap,下面是!dso命令的输出结果:

    kd> !dso VACB //Kernel Debug Extension Build 2167 Free
    Structure VACB - Size: 0x18
    000 BaseAddress 004 SharedCacheMap
    008 Overlay 010 LruList

    但通过分析,我发现Windows XP中VACB实际上由6个DWORD值组成,其第二个DWORD即SharedCacheMap。Windows XP使用6个DWORD,可能是其支持Larger Mapped Files的具体实现(FILE_OFFSET使用LARGE_INTEGER,虽然《Inside Windows 2000》中也指出过FileOffset成员,但不知为什么dso命令的输出结果没有显式的提供这样的一个成员,另我非常疑惑,难道又是版本间的差异吗?)。下面是XP底下的分析:

    kd> dd CcVacbs l 1
    80542fec 80ecc000
    kd> dd 80ecc000 //dd Vacb
    80ecc000 cb440000 80eaac78 00300000 00000000
    80ecc010 80eceda0 80ecf598 d4040000 80eaac78
    80ecc020 01000000 00000000 80ecd6a8 80ecede8
    80ecc030 c1100000 80eefed0 00000000 00000000
    80ecc040 80ece050 80542fe0 deb40000 ffa55538
    80ecc050 00000000 00000000 80ecd558 80ecc958

    kd> dd 80eaac78 l 12 //dd Vacb->SharedCacheMap
    80eaac78 013002ff 00000001 01a95400 00000000
    80eaac88 80eaac68 80eaaac0 01b00000 00000000
    80eaac98 ffffffff 7fffffff ffffffff 7fffffff
    80eaaca8 00000000 00000000 00000000 00000000
    80eaacb8 80eaa910 80ee2a80

    上面我曾提及SharedCacheMap也有指针指向FILE_OBJECT,我发现其位置在的第18个DWORD上,下面即Dump出FILE_OBJECT。
    kd> dd 80ee2a80 l 6 //dd FILE_OBJECT
    80ee2a80 00700005 80ee2888 80ee2800 80e7f9b0
    80ee2a90 00000000 80ee23a4

    FILE_OBJECT的定义已在ntddk.h中给出,所以很容易的得到其SECTION_OBJECT_POINTERS。
    kd> dd 80ee23a4 l 3 //dd FILE_OBJECT->SECTION_OBJECT_POINTERS
    80ee23a4 80e7f710 80eaac78 00000000
    kd> !ca 80e7f710 //!ca SECTION_OBJECT_POINTERS->DataSectionObject

    ControlArea @80e7f710
     Segment: e127a548 Flink 0 Blink 0
     Section Ref 1 Pfn Ref 275 Mapped Views 5f
     User Ref 0 WaitForDel 0 Flush Count 0
     File Object 80ee2a80 ModWriteCount 0 System Views 5f
     Flags (8088) NoModifiedWriting File WasPurged

     File: /$Mft
        .
        .
        .

    这样我们即dump出了CcVacbs指向的System Cache中的第一个VACB的内容,从ca命令的输出结果我们可以看出System Cache的第一个View由NTFS的元数据$Mft使用。Kernel Debug也提供一个叫filecache的命令,我在使用!filecache命令时曾查阅过其文档,文档中提及(WinDbg:6.0.00007.0):

    Each line of this extension's output represents a virtual address control block (VACB). When named files are mapped into the VACB, the names of these files are displayed. If "no name for file" is specified, this means that this VACB is being used to cache metadata.

    从上面的注释我还以为filecache命令通过遍历VACB数组,dump出所有Control Area,就像我上面的手工分析VACB过程一样。但实际上此命令输出的不仅仅只有这些内容。通过分析kdexts.dll中filecache的实现(Windows XP)中,发现其通过PsLoadedModuleList来实现dump filecache(具体内容需进一步学习)。

    最后还要指出的是系统通过CcIsFileCached宏来判断File是否被Cached。其在ntifs.h中定义,有了上面的分析后是非常容易理解的:

    #define CcIsFileCached(FO) ( /
     ((FO)->SectionObjectPointer != NULL) && /
     (((PSECTION_OBJECT_POINTERS)(FO)->SectionObjectPointer)->SharedCacheMap != NULL) /
    )

    本文未牵涉到另一个非常重要的数据结构PFN数据库,由MmPfnDatabase指定,PFN数据库中共享页面有PPTE的定义,实际上发生指向PPTE的页面的Page Fault后,查找完VAD后,系统会根据PFN数据库的PPTE完成下一步的工作。

    实际上关于Control Area、Subsection、PPTE、VACB、SharedCacheMap等的具体定义是我比较感兴趣的,而我目前为止仍对此只有些许概念。这也是我出此文的目的,也希望达到抛砖引玉的作用([email protected])。
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/freexploit/article/details/275416

智能推荐

TCP Dup ACK xxx#x分析-程序员宅基地

文章浏览阅读2k次。TCP Dup ACK xxx#x分析wireshark报文出现TCP Dup ACK xxx#x时,代表了数据段丢失 TCP 状态,xxx 代表数据丢失的位置(即wireshark报文显示界面最左边的那个序号位置), # 后面的x代表第几次丢失报文如上图所示,【TCP Dup ACK 175#1】就表示序号为175的那个报文第一次丢失..._tcp dup ack

webpack打包原理 ? 看完这篇你就懂了 !_webpack打包原理说的通俗易懂-程序员宅基地

文章浏览阅读3.9k次,点赞12次,收藏126次。前言[实践系列] 主要是让我们通过实践去加深对一些原理的理解。[实践系列]前端路由[实践系列]Babel 原理[实践系列]实践这一次,彻底搞懂浏览器缓存机制[实践系列]你能手写一个 Promise 吗?Yes I promise。有兴趣的同学可以关注[实践系列]。 求 star 求 follow~本文通过实现一个简单 webpack,来理解它的打包原理,看完不懂直接..._webpack打包原理说的通俗易懂

二叉树线索化仍不能解决的两个问题及原因_二叉树在线索化后,仍不能有效求解的问题是-程序员宅基地

文章浏览阅读6.6k次,点赞23次,收藏54次。利用建立的线索二叉树找某个节点的前驱或者后继,仍不能有效解决先序线索二叉树找先序前驱和后序线索二叉树找后序后继等两个问题能够解决四个1 先序线索二叉树中求先序后继2 中序线索二叉树中求中序后继3 中序线索二叉树中求中序前驱4 后序线索二叉树中求后序前驱_二叉树在线索化后,仍不能有效求解的问题是

安卓流式布局FlowLayout样例_流式flowlayout布局例题-程序员宅基地

文章浏览阅读524次。用途让布局里的控件自动换行效果图使用方法添加依赖implementation 'com.nex3z:flow-layout:1.3.1'代码<com.nex3z.flowlayout.FlowLayout ="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_paren_流式flowlayout布局例题

Android Studio 检查并删除无用资源文件_android 如何找出无用资源-程序员宅基地

文章浏览阅读6.8k次。背景有时项目中有很多的无用资源,包括xml文件、strings、colors文件中多余的定义等等,一个个删除,效率太低。解决方案在Android Studio中选择菜单“Analyze” --&gt; “Run inspaction by Name …”。在弹出的搜索窗口中输入想执行的检查类型,如“Unused Resources”。在搜索结果界面,右键点击“Unused resourc..._android 如何找出无用资源

如何查看Chrome浏览器曾经使用过的账号和密码?查看方法分享_x用户名用谷歌账号能查到吗-程序员宅基地

文章浏览阅读4.2k次。chrome浏览器是一款非常好用的搜索服务浏览器,这款软件使用起来超级的方便,不仅方便用户搜索,还有各种插件可以使用,操作起来超级的方便,可以随时满足用户的各种使用需求,让用户更加便捷的享受搜索服务,有很多用户在使用的时候会忘记自己的密码,今天小编就会大家一起来分享一个可以查看之前使用过的账号和密码的方法,这样使用起来就会更加的方便,如果忘记密码也可以使用手机一键寻找,操作超级的简单哦!如何查看Chrome浏览器曾经使用过的账号和密码打开Chrome浏览器,点击屏幕右上角的垂直3点图标。点击”设置“。_x用户名用谷歌账号能查到吗

随便推点

python-字符串作为代码执行(exec、eval、locals、compile)_python将字符串作为代码执行-程序员宅基地

文章浏览阅读1.7w次,点赞16次,收藏43次。字符串作为代码执行的方法:1、eval()构造器:eval(source, globals=None, locals=None, /)说明:输入一个【python表达式或code对象】参与计算。用于恶意攻击,窥视:再看下eval的参数globals和locals参数的用法,看栗子:一幕了然,局部变量空间和全局变量空间的优先级的先后顺序~2、e..._python将字符串作为代码执行

华为/思科清除路由器及交换机命令_华为交换机删除路由命令-程序员宅基地

文章浏览阅读1w次,点赞10次,收藏34次。华为:一、reset saved-configuration //重置保存配置输入命令后会出现:This will delete the configuration in the flash memory.The device configurations will be erased to reconfigure.Are you sure? (y/n)[n]:y二、reboot //重新启动输入命令后会出现:Info: The system is com..._华为交换机删除路由命令

HashMap面试,看这一篇就够了_java 8中为什么要引进红黑树,是为了解决什么场景的问题-程序员宅基地

文章浏览阅读2.4w次,点赞108次,收藏387次。历史热门文章:七种方式教你在SpringBoot初始化时搞点事情Java序列化的这三个坑千万要小心可以和面试官聊半个小时的volatile原理Java中七个潜在的内存泄露风险,你知道几个?JDK 16新特性一览啥?用了并行流还更慢了InnoDB自增原理都搞不清楚,还怎么CRUD?前言在一场面试中最能打动面试官的其实是细节,候选人对细节的了解程度决定了留给面试官的印象到底是“基础扎实”还是“基础薄弱”,如果候选人能够举一反三主动阐述自己对一些技术细节的理解和总结,那无疑是面试过程中._java 8中为什么要引进红黑树,是为了解决什么场景的问题

吃自己的饭,滴自己的汗,自己的事情自己干。_吃你的饭-程序员宅基地

文章浏览阅读1k次。 作家八月长安说,“我这样的普通人只能走一步看一步,不断安慰自己,无论经历什么,都将成为我的一部分。 然而,真正的成长应该是,我懂得选择让哪一部分经历成为我。全盘接受不过是懦弱。 常觉得准备的阶段是在浪费时间,只有当真正机会来临,而自己没有能力把握的时候,才能觉悟自己平时没有准备才是浪费了时间。 千万不要让本来努力就可以得到的..._吃你的饭

2021CCPC女生赛 C. 连锁商店(思维+状压DP)_2021ccpc女生赛c-程序员宅基地

文章浏览阅读1.2k次,点赞8次,收藏8次。链接题意:给出N个节点,给出M条边,我们只能从低节点跳到高节点。然后给出N个节点属于的公司,给出第i个公司第一次到给多少奖金。问从节点1开始,分别到达节点(1~n)最大奖金。分析:其实不难想到我们如果当前节点在x,有(a1,a2,a3…)这些节点可以到达节点x,那么我们选取(a1,a2,a3…)所有的状态转移过来就好了,状态表示我们可以用二进制,也可以用字符串数组等等,只要可以表示状态就行。状态转移有两种状态一种是在之前出现过,不用再加奖金了,把这个状态加入x另一种之前没有出现过,加上奖金并_2021ccpc女生赛c

qt 怎么设计个性化的滑块_前模哈夫式滑块怎么设计?以下3种结构设计方法,让你学以自用...-程序员宅基地

文章浏览阅读599次。汽车注塑模具中的哈夫模具也叫斜弹模,它是前模哈夫式滑块结构,滑块是斜运动脱离产品倒扣的,叫斜弹模可能比较容易理解,和斜顶运动原理相同。知乎视频​www.zhihu.com前模哈夫式滑块结构模具有3个优点: 01.前模哈夫式滑块比后模滑块占空间小,可以选用更小的注塑机台生产,节约成本 02.前模哈夫式滑块铲鸡是利用前模A板原身留锁模的,铲鸡强度够,且不容易涨模。 03.哈夫式滑块是留在前模,只需计算...