2018年2月9日星期五

查看系统的minifilter信息

标题:查看系统的minifilter信息

minifilter驱动也写几年了,别人的minifilter驱动也分析了几个。

突然之间,思想有所觉悟,看看系统的minifilter驱动框架的信息,因为系统不只是自己的驱动,还有别的驱动,甚至是系统自身的。

再比如,有时用procmon监控文件操作时,看到:FASTIO_NETWORK_QUERY_OPEN的结果是FAST IO DISALLOWED。
稍微懂点内核的人都知道,这是不好的,费时间和效率的,甚至想是哪个王八蛋驱动搞得这个结果。
这用procmon之身是查不出的,因为它的机制(ETW),尽管它用了minifilter,不信,你看调用栈。
咋办呢?相信你看完本文,你就能做到,做不到等于你看不懂本文。

看完本文,你应该能做到不卸载某个minifilter驱动,但是让它的效果失效。
那个驱动可以是别人的文件保护驱动,透明加解密驱动,杀毒软件的驱动等。

首先说明,本文不说原始的设备挂载的文件过来驱动,如:sfilter等。
这个应该简单,根据驱动(或设备)对象,依次能找到好多有用的信息/函数。

--------------------------------------------------------------------------------------------------

下面正式开始:

首先说下本文的实验环境:
0: kd> ||
.  0 64-bit Full kernel dump: C:\WINDOWS\livekd.dmp
0: kd> vertarget
Windows 8 Kernel Version 9200 MP (4 procs) Free x64
Product: WinNt, suite: TerminalServer SingleUserTS
Built by: 16299.15.amd64fre.rs3_release.170928-1534
Machine Name:
Kernel base = 0xfffff803`1968f000 PsLoadedModuleList = 0xfffff803`199f5fd0
Debug session time: Thu Jan 11 09:19:53.306 2018 (UTC + 8:00)
System Uptime: 0 days 2:41:56.055

查看系统上的minifilter驱动,只需要一个命令就可以了。
0: kd> !fltkd.filters

Filter List: ffffa28ba51f83a0 "Frame 1"
   FLT_FILTER: ffffa28bae0c8830 "PROCMON23" "385200"
Filter List: ffffa28ba4bd10c0 "Frame 0"
   FLT_FILTER: ffffa28ba7ecf350 "storqosflt" "244000"
   FLT_FILTER: ffffa28ba7db7a80 "wcifs" "189900"
      FLT_INSTANCE: ffffa28ba7df9950 "wcifs Instance" "189900"
      FLT_INSTANCE: ffffa28ba7dff950 "wcifs Instance" "189900"
   FLT_FILTER: ffffa28ba7e9fb40 "CldFlt" "180451"
   FLT_FILTER: ffffa28ba6136b30 "FileCrypt" "141100"
      FLT_INSTANCE: ffffa28ba7347460 "FileCrypt Instance" "141100"
   FLT_FILTER: ffffa28ba7e91010 "luafv" "135000"
      FLT_INSTANCE: ffffa28ba7e93010 "luafv" "135000"
   FLT_FILTER: ffffa28ba64cb750 "npsvctrig" "46000"
      FLT_INSTANCE: ffffa28ba65f8910 "npsvctrig" "46000"
   FLT_FILTER: ffffa28ba57e59a0 "Wof" "40700"
      FLT_INSTANCE: ffffa28ba61abb60 "Wof Instance" "40700"
      FLT_INSTANCE: ffffa28ba696a780 "Wof Instance" "40700"
      FLT_INSTANCE: ffffa28ba66d8460 "Wof Instance" "40700"
      FLT_INSTANCE: ffffa28ba6752b60 "Wof Instance" "40700"
   FLT_FILTER: ffffa28ba57e4490 "FileInfo" "40500"
      FLT_INSTANCE: ffffa28ba61c2b40 "FileInfo" "40500"
      FLT_INSTANCE: ffffa28ba618eb40 "FileInfo" "40500"
      FLT_INSTANCE: ffffa28ba64e1010 "FileInfo" "40500"
      FLT_INSTANCE: ffffa28ba66d8910 "FileInfo" "40500"
      FLT_INSTANCE: ffffa28ba734e910 "FileInfo" "40500"
      FLT_INSTANCE: ffffa28ba76feb40 "FileInfo" "40500"
 
这里有两个Filter List,这个不关系,不深入分析。
Filter List下有FLT_FILTER,这就是每个minifilter驱动,这其实是_FLT_FILTER结构,也可以用!fltkd.filter来查看。
FLT_FILTER下有FLT_INSTANCE,这就是这个minifilter附加了哪个设备/卷,这其实是_FLT_INSTANCE结构,也可以用!fltkd.instace来查看

这里选用FileCrypt,之所以选择这个,是因为这个信息全,有上下文。

0: kd> !fltkd.filter ffffa28ba6136b30

FLT_FILTER: ffffa28ba6136b30 "FileCrypt" "141100"
   FLT_OBJECT: ffffa28ba6136b30  [02000000] Filter
      RundownRef               : 0x0000000000000006 (3)
      PointerCount             : 0x00000001
      PrimaryLink              : [ffffa28ba7e91020-ffffa28ba7e9fb50]
   Frame                    : ffffa28ba4bd1010 "Frame 0"
   Flags                    : [00000002] FilteringInitiated
   DriverObject             : ffffa28ba63fcac0
   FilterLink               : [ffffa28ba7e91020-ffffa28ba7e9fb50]
   PreVolumeMount           : 0000000000000000  (null)
   PostVolumeMount          : 0000000000000000  (null)
   FilterUnload             : fffff801814eb820  filecrypt!FCFilterUnload
   InstanceSetup            : fffff801814ea010  filecrypt!FCInstanceSetup
   InstanceQueryTeardown    : fffff801814ea420  filecrypt!FCInstanceQueryTeardown
   InstanceTeardownStart    : 0000000000000000  (null)
   InstanceTeardownComplete : 0000000000000000  (null)
   ActiveOpens              : (ffffa28ba6136ce8)  mCount=0
   Communication Port List  : (ffffa28ba6136d38)  mCount=0
   Client Port List         : (ffffa28ba6136d88)  mCount=0
   VerifierExtension        : 0000000000000000
   Operations               : ffffa28ba6136de0
   OldDriverUnload          : 0000000000000000  (null)
   SupportedContexts        : (ffffa28ba6136c60)
      VolumeContexts           : (ffffa28ba6136c60)
         ALLOCATE_CONTEXT_NODE: ffffa28ba6135d80 "FileCrypt" [01] LookasideList (size=56)
      InstanceContexts         : (ffffa28ba6136c68)
      FileContexts             : (ffffa28ba6136c70)
      StreamContexts           : (ffffa28ba6136c78)
         ALLOCATE_CONTEXT_NODE: ffffa28ba6135ec0 "FileCrypt" [01] LookasideList (size=40)
      StreamHandleContexts     : (ffffa28ba6136c80)
      TransactionContext       : (ffffa28ba6136c88)
      (null)                   : (ffffa28ba6136c90)
   InstanceList             : (ffffa28ba6136b98)
      FLT_INSTANCE: ffffa28ba7347460 "FileCrypt Instance" "141100"

看到了吧!
这里显示不少的信息。
有些信息很明显,这里就不细说了。
这里主要说三个:
1.Operations成员里面存放是的指针,指针的类型后面说。
2.SupportedContexts是个数组,数组的大小后面给出,缩进的是显示的数组的内容。
3.InstanceList后面给出所有的实例,这个驱动只有一个,这和!fltkd.filters显示的是一样的。

--------------------------------------------------------------------------------------------------

说到实例,这里就先说下,插一道杠子。
0: kd> dt fltmgr!_FLT_INSTANCE ffffa28ba7347460
   +0x000 Base             : _FLT_OBJECT
   +0x030 OperationRundownRef : 0xffffa28b`a6caec20 _EX_RUNDOWN_REF_CACHE_AWARE
   +0x038 Volume           : 0xffffa28b`a730e7e0 _FLT_VOLUME
   +0x040 Filter           : 0xffffa28b`a6136b30 _FLT_FILTER
   +0x048 Flags            : 0 (No matching name)
   +0x050 Altitude         : _UNICODE_STRING "141100"
   +0x060 Name             : _UNICODE_STRING "FileCrypt Instance"
   +0x070 FilterLink       : _LIST_ENTRY [ 0xffffa28b`a6136c00 - 0xffffa28b`a6136c00 ]
   +0x080 ContextLock      : _EX_PUSH_LOCK
   +0x088 Context          : (null)
   +0x090 TransactionContexts : _CONTEXT_LIST_CTRL
   +0x098 TrackCompletionNodes : 0xffffa28b`a6aacc90 _TRACK_COMPLETION_NODES
   +0x0a0 CallbackNodes    : [50] (null)
0: kd> !fltkd.instance ffffa28ba7347460

FLT_INSTANCE: ffffa28ba7347460 "FileCrypt Instance" "141100"
   FLT_OBJECT: ffffa28ba7347460  [01000000] Instance
      RundownRef               : 0x0000000000000000 (0)
      PointerCount             : 0x00000001
      PrimaryLink              : [ffffa28ba6752b70-ffffa28ba7dff960]
   OperationRundownRef      : ffffa28ba6caec20
      Number                   : 4
      PoolToFree               : ffffa28ba72fe5d0
      OperationsRefs           : ffffa28ba72fe600  (0)
         PerProcessor Ref[0]      : 0xffffffffffffff56 (-85)
         PerProcessor Ref[1]      : 0x0000000000000006 (3)
         PerProcessor Ref[2]      : 0x00000000000000bc (94)
         PerProcessor Ref[3]      : 0xffffffffffffffe8 (-12)
   Flags                    : [00000000]
   Volume                   : ffffa28ba730e7e0 "\Device\HarddiskVolume4"
   Filter                   : ffffa28ba6136b30 "FileCrypt"
   TrackCompletionNodes     : ffffa28ba6aacc90
   ContextLock              : (ffffa28ba73474e0)
   Context                  : 0000000000000000
   CallbackNodes            : (ffffa28ba7347500)
   VolumeLink               : [ffffa28ba6752b70-ffffa28ba7dff960]
   FilterLink               : [ffffa28ba6136c00-ffffa28ba6136c00]
这里也有一些信息,很直白,都不说了。

--------------------------------------------------------------------------------------------------

继续上面的,咱可以换另一种看法:
0: kd> dt fltmgr!_FLT_FILTER ffffa28ba6136b30
   +0x000 Base             : _FLT_OBJECT
   +0x030 Frame            : 0xffffa28b`a4bd1010 _FLTP_FRAME
   +0x038 Name             : _UNICODE_STRING "FileCrypt"
   +0x048 DefaultAltitude  : _UNICODE_STRING "141100"
   +0x058 Flags            : 2 ( FLTFL_FILTERING_INITIATED )
   +0x060 DriverObject     : 0xffffa28b`a63fcac0 _DRIVER_OBJECT
   +0x068 InstanceList     : _FLT_RESOURCE_LIST_HEAD
   +0x0e8 VerifierExtension : (null)
   +0x0f0 VerifiedFiltersLink : _LIST_ENTRY [ 0x00000000`00000000 - 0x00000000`00000000 ]
   +0x100 FilterUnload     : 0xfffff801`814eb820     long  filecrypt!FCFilterUnload+0
   +0x108 InstanceSetup    : 0xfffff801`814ea010     long  filecrypt!FCInstanceSetup+0
   +0x110 InstanceQueryTeardown : 0xfffff801`814ea420     long  filecrypt!FCInstanceQueryTeardown+0
   +0x118 InstanceTeardownStart : (null)
   +0x120 InstanceTeardownComplete : (null)
   +0x128 SupportedContextsListHead : 0xffffa28b`a6135d80 _ALLOCATE_CONTEXT_HEADER
   +0x130 SupportedContexts : [7] 0xffffa28b`a6135d80 _ALLOCATE_CONTEXT_HEADER
   +0x168 PreVolumeMount   : (null)
   +0x170 PostVolumeMount  : (null)
   +0x178 GenerateFileName : (null)
   +0x180 NormalizeNameComponent : (null)
   +0x188 NormalizeNameComponentEx : (null)
   +0x190 NormalizeContextCleanup : (null)
   +0x198 KtmNotification  : (null)
   +0x1a0 SectionNotification : (null)
   +0x1a8 Operations       : 0xffffa28b`a6136de0 _FLT_OPERATION_REGISTRATION
   +0x1b0 OldDriverUnload  : (null)
   +0x1b8 ActiveOpens      : _FLT_MUTEX_LIST_HEAD
   +0x208 ConnectionList   : _FLT_MUTEX_LIST_HEAD
   +0x258 PortList         : _FLT_MUTEX_LIST_HEAD
   +0x2a8 PortLock         : _EX_PUSH_LOCK
这里之关心:Operations和SupportedContexts(SupportedContextsListHead),别的都很直白。
这里要和前面的!fltkd.filter结合讲会更好。
因为,我们不但关心FLT_REGISTRATION,还关心这个结构的FLT_CONTEXT_REGISTRATION和FLT_OPERATION_REGISTRATION子结构。
注意:这个结构的好些成员也是结构,如Frame是_FLTP_FRAME。

可以看到SupportedContexts和SupportedContextsListHead的值是一样的。
SupportedContexts的数组的大小是7,WIN8之前是6,增加了一个FLT_SECTION_CONTEXT。
尽管开发是时候是以FLT_CONTEXT_END结束的,但是实际上这个好像没有用。

点击SupportedContexts出现:
0: kd> dx -id 0,0,ffffa28ba514a080 -r1 (*((FLTMGR!_ALLOCATE_CONTEXT_HEADER * (*)[7])0xffffa28ba6136c60))
(*((FLTMGR!_ALLOCATE_CONTEXT_HEADER * (*)[7])0xffffa28ba6136c60))                 [Type: _ALLOCATE_CONTEXT_HEADER * [7]]
    [0]              : 0xffffa28ba6135d80 [Type: _ALLOCATE_CONTEXT_HEADER *]
    [1]              : 0x0 [Type: _ALLOCATE_CONTEXT_HEADER *]
    [2]              : 0x0 [Type: _ALLOCATE_CONTEXT_HEADER *]
    [3]              : 0xffffa28ba6135ec0 [Type: _ALLOCATE_CONTEXT_HEADER *]
    [4]              : 0x0 [Type: _ALLOCATE_CONTEXT_HEADER *]
    [5]              : 0x0 [Type: _ALLOCATE_CONTEXT_HEADER *]
    [6]              : 0x0 [Type: _ALLOCATE_CONTEXT_HEADER *]
空的是没有的,就是驱动编码时没有填写的。
看样子和他们定义的顺序时一一对应的。索引0对应FLT_VOLUME_CONTEXT,索引3对应FLT_STREAM_CONTEXT,等等。
分别点击0和3出现:
0: kd> dx -id 0,0,ffffa28ba514a080 -r1 ((FLTMGR!_ALLOCATE_CONTEXT_HEADER *)0xffffa28ba6135d80)
((FLTMGR!_ALLOCATE_CONTEXT_HEADER *)0xffffa28ba6135d80)                 : 0xffffa28ba6135d80 [Type: _ALLOCATE_CONTEXT_HEADER *]
    [+0x000] Filter           : 0xffffa28ba6136b30 [Type: _FLT_FILTER *]
    [+0x008] ContextCleanupCallback : 0xfffff801814eb7d0 [Type: void (__cdecl*)(void *,unsigned short)]
    [+0x010] Next             : 0x0 [Type: _ALLOCATE_CONTEXT_HEADER *]
    [+0x018] ContextType      : 0x1 [Type: unsigned short]
    [+0x01a] Flags            : 0x1 [Type: unsigned char]
    [+0x01b] AllocationType   : 0x1 [Type: unsigned char]
0: kd> dx -id 0,0,ffffa28ba514a080 -r1 ((FLTMGR!_ALLOCATE_CONTEXT_HEADER *)0xffffa28ba6135ec0)
((FLTMGR!_ALLOCATE_CONTEXT_HEADER *)0xffffa28ba6135ec0)                 : 0xffffa28ba6135ec0 [Type: _ALLOCATE_CONTEXT_HEADER *]
    [+0x000] Filter           : 0xffffa28ba6136b30 [Type: _FLT_FILTER *]
    [+0x008] ContextCleanupCallback : 0xfffff801814eb790 [Type: void (__cdecl*)(void *,unsigned short)]
    [+0x010] Next             : 0x0 [Type: _ALLOCATE_CONTEXT_HEADER *]
    [+0x018] ContextType      : 0x8 [Type: unsigned short]
    [+0x01a] Flags            : 0x1 [Type: unsigned char]
    [+0x01b] AllocationType   : 0x1 [Type: unsigned char]
分别点击上面的ContextCleanupCallback出现:
其实,你也可以自己输入,如果你的windbg不支持的话。
0: kd> u fffff801814eb7d0
filecrypt!FCCleanupVolumeContext:
fffff801`814eb7d0 4053            push    rbx
fffff801`814eb7d2 4883ec20        sub     rsp,20h
fffff801`814eb7d6 488bd9          mov     rbx,rcx
fffff801`814eb7d9 488b4908        mov     rcx,qword ptr [rcx+8]
fffff801`814eb7dd 4885c9          test    rcx,rcx
fffff801`814eb7e0 7413            je      filecrypt!FCCleanupVolumeContext+0x25 (fffff801`814eb7f5)
fffff801`814eb7e2 ba46436e76      mov     edx,766E4346h
fffff801`814eb7e7 ff1553caffff    call    qword ptr [filecrypt!_imp_ExFreePoolWithTag (fffff801`814e8240)]
0: kd> u fffff801814eb790
filecrypt!FCCleanupStreamContext:
fffff801`814eb790 4053            push    rbx
fffff801`814eb792 4883ec20        sub     rsp,20h
fffff801`814eb796 488bd9          mov     rbx,rcx
fffff801`814eb799 488b4918        mov     rcx,qword ptr [rcx+18h]
fffff801`814eb79d 4885c9          test    rcx,rcx
fffff801`814eb7a0 740d            je      filecrypt!FCCleanupStreamContext+0x1f (fffff801`814eb7af)
fffff801`814eb7a2 e81d0b0000      call    filecrypt!FCpFreeChamberId (fffff801`814ec2c4)
fffff801`814eb7a7 48c7431800000000 mov     qword ptr [rbx+18h],0

关于FLTMGR!_ALLOCATE_CONTEXT_HEADER和FLT_CONTEXT_REGISTRATION的关系,这里就不说了。

至此,上下文分析完毕。

--------------------------------------------------------------------------------------------------

下面分析重要的文件各种操作对应的处理函数。

首先要说说这个,对文件各种操作的类型的处理的数量。
我们开发的时候,经常这样写IRP_MJ_OPERATION_END,就是把这个放在数组的最后一个。
这个的定义是:
#define IRP_MJ_OPERATION_END                        ((UCHAR)0x80)

经过IDA分析FltRegisterFilter函数可知,它也是搜索这个标志,得到处理消息的个数的。

这是个数组,每个数组成员的大小,在X64上是:
0: kd> ?? sizeof(fltmgr!_FLT_OPERATION_REGISTRATION)
unsigned int64 0x20

这里先解释下,后面的命令显示那个数组的数量的问题。

简单的,你可以这么看:
0: kd> dt 0xffffa28b`a6136de0 _FLT_OPERATION_REGISTRATION
FLTMGR!_FLT_OPERATION_REGISTRATION
   +0x000 MajorFunction    : 0 ''
   +0x004 Flags            : 0
   +0x008 PreOperation     : 0xfffff801`814ebb70     _FLT_PREOP_CALLBACK_STATUS  filecrypt!FCPreCreate+0
   +0x010 PostOperation    : 0xfffff801`814eb890     _FLT_POSTOP_CALLBACK_STATUS  filecrypt!FCPostCreate+0
   +0x018 Reserved1        : (null)
这是显示第一个(索引为0)的MajorFunction == 0(即IRP_MJ_CREATE)的注册的信息。
还可以继续:
0: kd> dt 0xffffa28b`a6136de0 + @@(sizeof(FLTMGR!_FLT_OPERATION_REGISTRATION)) _FLT_OPERATION_REGISTRATION
FLTMGR!_FLT_OPERATION_REGISTRATION
   +0x000 MajorFunction    : 0x6 ''
   +0x004 Flags            : 0
   +0x008 PreOperation     : 0xfffff801`814ec040     _FLT_PREOP_CALLBACK_STATUS  filecrypt!FCPreSetInformation+0
   +0x010 PostOperation    : (null)
   +0x018 Reserved1        : (null)
直到出现:MajorFunction == IRP_MJ_OPERATION_END,如:
0: kd> dt 0xffffa28b`a6136e00 + @@(sizeof(FLTMGR!_FLT_OPERATION_REGISTRATION)) _FLT_OPERATION_REGISTRATION
FLTMGR!_FLT_OPERATION_REGISTRATION
   +0x000 MajorFunction    : 0x80 ''
   +0x004 Flags            : 0
   +0x008 PreOperation     : (null)
   +0x010 PostOperation    : (null)
   +0x018 Reserved1        : (null)
如果,对脚本熟悉,这里可以编写脚本处理。
也可以用另一种方式显示:
0: kd> dps 0xffffa28b`a6136de0 L80
ffffa28b`a6136de0  00000000`00000000
ffffa28b`a6136de8  fffff801`814ebb70 filecrypt!FCPreCreate
ffffa28b`a6136df0  fffff801`814eb890 filecrypt!FCPostCreate
ffffa28b`a6136df8  00000000`00000000
ffffa28b`a6136e00  00000000`00000006
ffffa28b`a6136e08  fffff801`814ec040 filecrypt!FCPreSetInformation
ffffa28b`a6136e10  00000000`00000000
ffffa28b`a6136e18  00000000`00000000
ffffa28b`a6136e20  00000000`00000080
ffffa28b`a6136e28  00000000`00000000
ffffa28b`a6136e30  00000000`00000000
ffffa28b`a6136e38  00000000`00000000
......

至此,文件的消息的处理函数分析完毕。
很幸运,这个驱动处理的消息/操作很少。

--------------------------------------------------------------------------------------------------

其实操作系统也提供了各种信息枚举的接口,不信,你看:
0: kd> x fltmgr!fltenum*
fffff801`800a0220 FLTMGR!FltEnumerateInstanceInformationByDeviceObject (void)
fffff801`800a9256 FLTMGR!FltEnumerateInstanceInformationByDeviceObject$fin$0 (void)
fffff801`800ae5a1 FLTMGR!FltEnumerateInstanceInformationByVolumeName$fin$0 (void)
fffff801`8009d580 FLTMGR!FltEnumerateInstances (void)
fffff801`800a5fb0 FLTMGR!FltEnumerateFilterInformation (void)
fffff801`800ae4a0 FLTMGR!FltEnumerateInstanceInformationByVolume (<no parameter info>)
fffff801`800ae290 FLTMGR!FltEnumerateFilters (<no parameter info>)
fffff801`800ae600 FLTMGR!FltEnumerateVolumes (<no parameter info>)
fffff801`800ae3b0 FLTMGR!FltEnumerateInstanceInformationByFilter (<no parameter info>)
fffff801`800ae4d0 FLTMGR!FltEnumerateInstanceInformationByVolumeName (<no parameter info>)
fffff801`800ae5d0 FLTMGR!FltEnumerateVolumeInformation (<no parameter info>)
一个编码的例子,可参考:
http://correy.webs.com/articles/computer/c/FltEnumerateFilters.C.txt
再结合本文的分析,你所能做的事都在于你的脑子了。


made by correy
made at 14:03 2018/1/10
http://correy.web.com

查看注册表回调的函数的地址

标题:查看注册表回调的函数的地址。

经IDA分析:
CmRegisterCallback调用了CmpRegisterCallbackInternal
CmRegisterCallbackEx调用了CmpRegisterCallbackInternal
CmpRegisterCallbackInternal调用了CmpInsertCallbackInListByAltitude
CmpInsertCallbackInListByAltitude用到了CmpCallbackListLock,CallbackListHead,CmpCallbackCookie,CmpCallBackCount。
这里用到的只有CallbackListHead和CmpCallBackCount。

注意:
由CmpRegisterCallbackInternal构造的传递给CmpInsertCallbackInListByAltitude的第一个参数是个结构。
这个结构的第六个成员(索引为5)是回调函数的地址。

注意:一般情况下CmpCallBackCount的值位0。

--------------------------------------------------------------------------------------------------

下面是简要的分析过程:
4: kd> ||
.  0 Remote KD: KdSrv:Server=@{<Local>},Trans=@{COM:Port=\\.\pipe\com1,Baud=115200,Pipe,Timeout=4000,Resets=2}
4: kd> vertarget
Windows 10 Kernel Version 14393 MP (6 procs) Free x64
Built by: 14393.1593.amd64fre.rs1_release.170731-1934
Machine Name:
Kernel base = 0xfffff802`d5478000 PsLoadedModuleList = 0xfffff802`d5776040
Debug session time: Sun Jan  7 10:57:14.914 2018 (UTC + 8:00)
System Uptime: 0 days 0:11:10.290

4: kd> dd nt!CmpCallBackCount l1
fffff802`d5794e98  00000004

0: kd> dq nt!CallbackListHead
fffff802`d5791c20  ffffbb89`e1685e00 ffffbb89`e1cab4d0
fffff802`d5791c30  00000000`00000000 01d38761`8331470c
fffff802`d5791c40  00000000`00000000 00000000`00000000 第一个是空的。
fffff802`d5791c50  fffff802`d5791c50 fffff802`d5791c50
fffff802`d5791c60  00000000`00060001 fffff802`d5791c68
fffff802`d5791c70  fffff802`d5791c68 00000000`00000000
fffff802`d5791c80  00000000`00060001 fffff802`d5791c88
fffff802`d5791c90  fffff802`d5791c88 00000000`00000000
0: kd> dq ffffbb89`e1cab4d0 下一个
ffffbb89`e1cab4d0  fffff802`d5791c20 ffffbb89`e4789d10
ffffbb89`e1cab4e0  00000000`00000000 01d38761`8331470a
ffffbb89`e1cab4f0  00000000`00000000 fffff802`d58bfa30
ffffbb89`e1cab500  00420074`000c000c ffffbb89`e17b9930
ffffbb89`e1cab510  ffffbb89`e1cab510 ffffbb89`e1cab510
ffffbb89`e1cab520  6d4e6f49`03090106 9369ee85`4faf2548
ffffbb89`e1cab530  006e0069`0057005c 00730077`006f0064
ffffbb89`e1cab540  00730079`0053005c 0033006d`00650074
0: kd> u fffff802`d58bfa30
nt!RegistryCallback:竟然是这个
fffff802`d58bfa30 4c8bdc          mov     r11,rsp
fffff802`d58bfa33 49895b08        mov     qword ptr [r11+8],rbx
fffff802`d58bfa37 49897310        mov     qword ptr [r11+10h],rsi
fffff802`d58bfa3b 57              push    rdi
fffff802`d58bfa3c 4883ec50        sub     rsp,50h
fffff802`d58bfa40 488b05f980eaff  mov     rax,qword ptr [nt!_security_cookie (fffff802`d5767b40)]
fffff802`d58bfa47 4833c4          xor     rax,rsp
fffff802`d58bfa4a 4889442440      mov     qword ptr [rsp+40h],rax
0: kd> dq ffffbb89`e4789d10 下一个
ffffbb89`e4789d10  ffffbb89`e1cab4d0 ffffbb89`e25b60e0
ffffbb89`e4789d20  00360061`00000000 01d38761`8331470c
ffffbb89`e4789d30  00000000`00000000 fffff805`ebdd1060
ffffbb89`e4789d40  00320035`000c000c ffffbb89`e3433cb0
ffffbb89`e4789d50  ffffbb89`e4789d50 ffffbb89`e4789d50
ffffbb89`e4789d60  58706e50`03040106 9369ee85`4a1d0d08
ffffbb89`e4789d70  ffffbb89`e3999210 ffffbb89`e47e5f10
ffffbb89`e4789d80  ffffbb89`e3ebe980 00000000`00000000
0: kd> u fffff805`ebdd1060 自己注册的,测试专用。
test!RegistryCallback [d:\users\administrator\source\repos\test\test\test.cpp @ 15]:
fffff805`ebdd1060 4c89442418      mov     qword ptr [rsp+18h],r8
fffff805`ebdd1065 4889542410      mov     qword ptr [rsp+10h],rdx
fffff805`ebdd106a 48894c2408      mov     qword ptr [rsp+8],rcx
fffff805`ebdd106f 4883ec18        sub     rsp,18h
fffff805`ebdd1073 c7042400000000  mov     dword ptr [rsp],0
fffff805`ebdd107a 8b0424          mov     eax,dword ptr [rsp]
fffff805`ebdd107d 4883c418        add     rsp,18h
fffff805`ebdd1081 c3              ret
0: kd> u test!RegistryCallback 反过来,验证下,也是正确的。
test!RegistryCallback [d:\users\administrator\source\repos\test\test\test.cpp @ 15]:
fffff805`ebdd1060 4c89442418      mov     qword ptr [rsp+18h],r8
fffff805`ebdd1065 4889542410      mov     qword ptr [rsp+10h],rdx
fffff805`ebdd106a 48894c2408      mov     qword ptr [rsp+8],rcx
fffff805`ebdd106f 4883ec18        sub     rsp,18h
fffff805`ebdd1073 c7042400000000  mov     dword ptr [rsp],0
fffff805`ebdd107a 8b0424          mov     eax,dword ptr [rsp]
fffff805`ebdd107d 4883c418        add     rsp,18h
fffff805`ebdd1081 c3              ret
0: kd> dq ffffbb89`e25b60e0 下一个
ffffbb89`e25b60e0  ffffbb89`e4789d10 ffffbb89`e1685e00
ffffbb89`e25b60f0  00000000`00000000 01d38761`8331470b
ffffbb89`e25b6100  00000000`00000000 fffff805`eb762fa0
ffffbb89`e25b6110  00000000`000c000c ffffbb89`ebfbc1a0
ffffbb89`e25b6120  ffffbb89`e25b6120 ffffbb89`e25b6120
ffffbb89`e25b6130  6944624f`03030406 00000000`00000000
ffffbb89`e25b6140  ffffbb89`e208a240 ffffce07`2ce7a960
ffffbb89`e25b6150  00000000`2125a355 00000000`00000000
0: kd> u fffff805`eb762fa0
registry!RegistryCallback: 还有这个?
fffff805`eb762fa0 48895c2408      mov     qword ptr [rsp+8],rbx
fffff805`eb762fa5 57              push    rdi
fffff805`eb762fa6 4881ec80000000  sub     rsp,80h
fffff805`eb762fad 488b05ac30ffff  mov     rax,qword ptr [registry!_security_cookie (fffff805`eb756060)]
fffff805`eb762fb4 4833c4          xor     rax,rsp
fffff805`eb762fb7 4889442470      mov     qword ptr [rsp+70h],rax
fffff805`eb762fbc 33db            xor     ebx,ebx
fffff805`eb762fbe 83fa0e          cmp     edx,0Eh
0: kd> dq ffffbb89`e1685e00 下一个
ffffbb89`e1685e00  ffffbb89`e25b60e0 fffff802`d5791c20
ffffbb89`e1685e10  00310030`00000000 01d38761`83314709
ffffbb89`e1685e20  00000000`00000000 fffff805`e99d7a50
ffffbb89`e1685e30  10000000`000c000c ffffbb89`e17c3ea0
ffffbb89`e1685e40  ffffbb89`e1685e40 ffffbb89`e1685e40
ffffbb89`e1685e50  6d4e624f`03030406 9369ee85`4f0dce38
ffffbb89`e1685e60  004c0074`00690042 0065006b`0063006f
ffffbb89`e1685e70  10000000`00000072 00000000`00001000
0: kd> u fffff805`e99d7a50
*** ERROR: Module load completed but symbols could not be loaded for SysmonDrv.sys
SysmonDrv+0x7a50: 这个不说了,你懂的。
fffff805`e99d7a50 48895c2408      mov     qword ptr [rsp+8],rbx
fffff805`e99d7a55 4889742410      mov     qword ptr [rsp+10h],rsi
fffff805`e99d7a5a 57              push    rdi
fffff805`e99d7a5b 4154            push    r12
fffff805`e99d7a5d 4155            push    r13
fffff805`e99d7a5f 4156            push    r14
fffff805`e99d7a61 4157            push    r15
fffff805`e99d7a63 4881ecc0000000  sub     rsp,0C0h
再下一个就是开头了。


--------------------------------------------------------------------------------------------------

另一个看法:
5: kd> dd nt!CmpCallBackCount l1
fffff802`d5794e98  00000003
5: kd> dps nt!CallbackListHead
fffff802`d5791c20  ffffbb89`e25b60e0
fffff802`d5791c28  ffffbb89`e1cab4d0
fffff802`d5791c30  00000000`00000000
fffff802`d5791c38  01d38761`8331470c
fffff802`d5791c40  00000000`00000000
fffff802`d5791c48  00000000`00000000 为空
fffff802`d5791c50  fffff802`d5791c50 nt!CmpPreloadedHivesList
fffff802`d5791c58  fffff802`d5791c50 nt!CmpPreloadedHivesList
fffff802`d5791c60  00000000`00060001
fffff802`d5791c68  fffff802`d5791c68 nt!CmpLoadWorkerEvent+0x8
fffff802`d5791c70  fffff802`d5791c68 nt!CmpLoadWorkerEvent+0x8
fffff802`d5791c78  00000000`00000000
fffff802`d5791c80  00000000`00060001
fffff802`d5791c88  fffff802`d5791c88 nt!CmpLoadWorkerDebugEvent+0x8
fffff802`d5791c90  fffff802`d5791c88 nt!CmpLoadWorkerDebugEvent+0x8
fffff802`d5791c98  00000000`00000000
5: kd> dps ffffbb89`e1cab4d0
ffffbb89`e1cab4d0  fffff802`d5791c20 nt!CallbackListHead
ffffbb89`e1cab4d8  ffffbb89`e4789d10
ffffbb89`e1cab4e0  00000000`00000000
ffffbb89`e1cab4e8  01d38761`8331470a
ffffbb89`e1cab4f0  00000000`00000000
ffffbb89`e1cab4f8  fffff802`d58bfa30 nt!RegistryCallback
ffffbb89`e1cab500  00420074`000c000c
ffffbb89`e1cab508  ffffbb89`e17b9930
ffffbb89`e1cab510  ffffbb89`e1cab510
ffffbb89`e1cab518  ffffbb89`e1cab510
ffffbb89`e1cab520  6d4e6f49`03090106
ffffbb89`e1cab528  9369ee85`4faf2548
ffffbb89`e1cab530  006e0069`0057005c
ffffbb89`e1cab538  00730077`006f0064
ffffbb89`e1cab540  00730079`0053005c
ffffbb89`e1cab548  0033006d`00650074
5: kd> dps ffffbb89`e4789d10
ffffbb89`e4789d10  ffffbb89`e1cab4d0
ffffbb89`e4789d18  ffffbb89`e25b60e0
ffffbb89`e4789d20  00360061`00000000
ffffbb89`e4789d28  01d38761`8331470c
ffffbb89`e4789d30  00000000`00000000
ffffbb89`e4789d38  fffff805`ebdd1060 test!RegistryCallback [d:\users\administrator\source\repos\test\test\test.cpp @ 15]
ffffbb89`e4789d40  00320035`000c000c
ffffbb89`e4789d48  ffffbb89`e3433cb0
ffffbb89`e4789d50  ffffbb89`e4789d50
ffffbb89`e4789d58  ffffbb89`e4789d50
ffffbb89`e4789d60  58706e50`03040106
ffffbb89`e4789d68  9369ee85`4a1d0d08
ffffbb89`e4789d70  ffffbb89`e3999210
ffffbb89`e4789d78  ffffbb89`e47e5f10
ffffbb89`e4789d80  ffffbb89`e3ebe980
ffffbb89`e4789d88  00000000`00000000
5: kd> dps ffffbb89`e25b60e0
ffffbb89`e25b60e0  ffffbb89`e4789d10
ffffbb89`e25b60e8  fffff802`d5791c20 nt!CallbackListHead
ffffbb89`e25b60f0  00000000`00000000
ffffbb89`e25b60f8  01d38761`8331470b
ffffbb89`e25b6100  00000000`00000000
ffffbb89`e25b6108  fffff805`eb762fa0 registry!RegistryCallback
ffffbb89`e25b6110  00000000`000c000c
ffffbb89`e25b6118  ffffbb89`ebfbc1a0
ffffbb89`e25b6120  ffffbb89`e25b6120
ffffbb89`e25b6128  ffffbb89`e25b6120
ffffbb89`e25b6130  6944624f`03030406
ffffbb89`e25b6138  00000000`00000000
ffffbb89`e25b6140  ffffbb89`e208a240
ffffbb89`e25b6148  ffffce07`2ce7a960
ffffbb89`e25b6150  00000000`2125a355
ffffbb89`e25b6158  00000000`00000000
再继续就从头开始了。

--------------------------------------------------------------------------------------------------

第三种分析思路:

1: kd> dd nt!CmpCallBackCount l1
fffff801`6919ae98  00000002

;注释:nt!CallbackListHead是个LIST_ENTRY结构的全局变量。
1: kd> x nt!CallbackListHead
fffff801`69197c20 nt!CallbackListHead = <no type information>
1: kd> dt nt!_LIST_ENTRY fffff801`69197c20
 [ 0xffff9d06`80d42870 - 0xffff9d06`7a3da980 ]
   +0x000 Flink            : 0xffff9d06`80d42870 _LIST_ENTRY [ 0xffff9d06`7a3da980 - 0xfffff801`69197c20 ]
   +0x008 Blink            : 0xffff9d06`7a3da980 _LIST_ENTRY [ 0xfffff801`69197c20 - 0xffff9d06`80d42870 ]
;注释:经过IDA的分析可知这个结构的大小是0x50.
1: kd> dps 0xffff9d06`7a3da980 L(0x50/@@(sizeof(void *)))
ffff9d06`7a3da980  fffff801`69197c20 nt!CallbackListHead
ffff9d06`7a3da988  ffff9d06`80d42870
ffff9d06`7a3da990  00000000`00000000
ffff9d06`7a3da998  01d38a03`2a85ebf0
ffff9d06`7a3da9a0  00000000`00000000
ffff9d06`7a3da9a8  fffff801`692c5a30 nt!RegistryCallback
ffff9d06`7a3da9b0  00420074`000c000c
ffff9d06`7a3da9b8  ffff9d06`79f6fcb0
ffff9d06`7a3da9c0  ffff9d06`7a3da9c0
ffff9d06`7a3da9c8  ffff9d06`7a3da9c0
1: kd> dps ffff9d06`80d42870 L(0x50/@@(sizeof(void *)))
ffff9d06`80d42870  ffff9d06`7a3da980
ffff9d06`80d42878  fffff801`69197c20 nt!CallbackListHead
ffff9d06`80d42880  00380002`00000000
ffff9d06`80d42888  01d38a03`2a85ebf1
ffff9d06`80d42890  00000000`00000000
ffff9d06`80d42898  fffff80a`bf002fa0
ffff9d06`80d428a0  00000001`000c000c
ffff9d06`80d428a8  ffff9d06`809702c0
ffff9d06`80d428b0  ffff9d06`80d428b0
ffff9d06`80d428b8  ffff9d06`80d428b0
自此结束了,在分析就是从头开始了,你看fffff801`69197c20 nt!CallbackListHead又出现了。

--------------------------------------------------------------------------------------------------


最后得出重要的脚本:
待定。


--------------------------------------------------------------------------------------------------

made by correy
made at 12:07 2018/1/7
http://correy.webs.com

查看映像回调的函数的地址

标题:查看映像回调的函数的地址。

经IDA分析:
PsSetLoadImageNotifyRoutine调用了PsSetLoadImageNotifyRoutineEx
PsSetLoadImageNotifyRoutineEx用到了PspLoadImageNotifyRoutine,PspLoadImageNotifyRoutineCount。

下面是简要的分析过程:
0: kd> ||
.  0 64-bit Full kernel dump: C:\WINDOWS\livekd.dmp
0: kd> vertarget
Windows 8 Kernel Version 9200 MP (8 procs) Free x64
Product: WinNt, suite: TerminalServer SingleUserTS
Built by: 16299.15.amd64fre.rs3_release.170928-1534
Machine Name:
Kernel base = 0xfffff800`95414000 PsLoadedModuleList = 0xfffff800`95775ff0
Debug session time: Fri Jan  5 20:23:00.320 2018 (UTC + 8:00)
System Uptime: 1 days 0:23:22.648
0: kd> dd nt!PspLoadImageNotifyRoutineCount L1
fffff800`95bfee80  00000001
0: kd> dq nt!PspLoadImageNotifyRoutine
fffff800`957ace80  ffffd489`9e93125f 00000000`00000000
fffff800`957ace90  00000000`00000000 00000000`00000000
fffff800`957acea0  00000000`00000000 00000000`00000000
fffff800`957aceb0  00000000`00000000 00000000`00000000
fffff800`957acec0  00000000`00000000 00000000`00000000
fffff800`957aced0  00000000`00000000 00000000`00000000
fffff800`957acee0  00000000`00000000 00000000`00000000
fffff800`957acef0  00000000`00000000 00000000`00000000
0: kd> dq ffffd489`9e93125f - @@(sizeof(void *)) L1
ffffd489`9e931257  fff80184`974e1000
0: kd> u fffff80184`974e10
ahcache!CitmpLoadImageCallback:
fffff801`84974e10 4885c9          test    rcx,rcx
fffff801`84974e13 0f8472010000    je      ahcache!CitmpLoadImageCallback+0x17b (fffff801`84974f8b)
fffff801`84974e19 4c8bdc          mov     r11,rsp
fffff801`84974e1c 55              push    rbp
fffff801`84974e1d 4156            push    r14
fffff801`84974e1f 4157            push    r15
fffff801`84974e21 4883ec60        sub     rsp,60h
fffff801`84974e25 4533ff          xor     r15d,r15d


最后得出重要的脚本:
0: kd> r @$t0=poi(nt!PspLoadImageNotifyRoutineCount);r @$t1=nt!PspLoadImageNotifyRoutine;.for(r @$t2=0; @$t2<@$t0; r @$t2=@$t2+1){.printf /D "ImageNotifyRoutine(%d):%y\n", (@$t2 + 1), ((poi(((poi(@$t1+@$t2*@@(sizeof(void *))))-@@(sizeof(void *))))>>8) | ff00000000000000)}
ImageNotifyRoutine(1):ahcache!CitmpLoadImageCallback (fffff801`84974e10)
ImageNotifyRoutine(2):Memory access error at ')>>8) | ff00000000000000)'


--------------------------------------------------------------------------------------------------

made by correy
made at 9:59 2018/1/7
http://correy.webs.com

查看线程回调的函数的地址

标题:查看线程回调的函数的地址。

经IDA分析:
PsSetCreateThreadNotifyRoutine调用了PspSetCreateThreadNotifyRoutine
PsSetCreateThreadNotifyRoutineEx也调用了PspSetCreateThreadNotifyRoutine

分析PspSetCreateThreadNotifyRoutine用到了PspCreateThreadNotifyRoutine,PspCreateThreadNotifyRoutineCount,PspCreateThreadNotifyRoutineNonSystemCount。

下面是简要的分析过程:
0: kd> ||
.  0 64-bit Full kernel dump: C:\WINDOWS\livekd.dmp
0: kd> vertarget
Windows 8 Kernel Version 9200 MP (8 procs) Free x64
Product: WinNt, suite: TerminalServer SingleUserTS
Built by: 16299.15.amd64fre.rs3_release.170928-1534
Machine Name:
Kernel base = 0xfffff800`95414000 PsLoadedModuleList = 0xfffff800`95775ff0
Debug session time: Fri Jan  5 20:23:00.320 2018 (UTC + 8:00)
System Uptime: 1 days 0:23:22.648
0: kd> dd nt!PspCreateThreadNotifyRoutineCount L1
fffff800`95bfee84  00000002
0: kd> dd nt!PspCreateThreadNotifyRoutineNonSystemCount l1
fffff800`95bfee88  00000000
0: kd> dq nt!PspCreateThreadNotifyRoutine
fffff800`957acc80  ffffd489`a0e2ec0f ffffd489`a6c4a1ff
fffff800`957acc90  00000000`00000000 00000000`00000000
fffff800`957acca0  00000000`00000000 00000000`00000000
fffff800`957accb0  00000000`00000000 00000000`00000000
fffff800`957accc0  00000000`00000000 00000000`00000000
fffff800`957accd0  00000000`00000000 00000000`00000000
fffff800`957acce0  00000000`00000000 00000000`00000000
fffff800`957accf0  00000000`00000000 00000000`00000000
0: kd> dq ffffd489`a0e2ec0f - @@(sizeof(void *)) L1
ffffd489`a0e2ec07  fff80187`22d16c00
0: kd> u fffff80187`22d16c
nvlddmkm+0x11d16c:
fffff801`8722d16c 48895c2408      mov     qword ptr [rsp+8],rbx
fffff801`8722d171 4889742410      mov     qword ptr [rsp+10h],rsi
fffff801`8722d176 57              push    rdi
fffff801`8722d177 4883ec20        sub     rsp,20h
fffff801`8722d17b 488bf1          mov     rsi,rcx
fffff801`8722d17e 418ad8          mov     bl,r8b
fffff801`8722d181 488b0df0b76e00  mov     rcx,qword ptr [nvlddmkm!nvDumpConfig+0x82f68 (fffff801`87918978)]
fffff801`8722d188 488bfa          mov     rdi,rdx

最后得出重要的脚本:
0: kd> r @$t0=(poi(nt!PspCreateThreadNotifyRoutineCount) + poi(nt!PspCreateThreadNotifyRoutineNonSystemCount));r @$t1=nt!PspCreateThreadNotifyRoutine;.for(r @$t2=0; @$t2<@$t0; r @$t2=@$t2+1){.printf /D "ThreadNotifyRoutine(%d):%y\n", (@$t2 + 1), ((poi(((poi(@$t1+@$t2*@@(sizeof(void *))))-@@(sizeof(void *))))>>8) | ff00000000000000)}
ThreadNotifyRoutine(1):nvlddmkm+0x11d16c (fffff801`8722d16c)
ThreadNotifyRoutine(2):mmcss!CiThreadNotification (fffff801`88081010)

--------------------------------------------------------------------------------------------------

made by correy
made at 9:59 2018/1/7
http://correy.webs.com