下面是通过fltmc进行文件过滤驱动加载的常用命令。
1
2
|
fltmc load DelProtect
fltmc unload DelProtect
|
写过MiniFIlter驱动的都知道FltUnregisterFilter用于注销回调。
但是MSDN中有这样一段话:
A minifilter driver can only call FltUnregisterFilter to unregister itself, not another minifilter driver.
意思就是驱动应该自身去调用这个函数,而不是使用其他微过滤驱动去调用。
为此我写了一个驱动去实验,发现再调用后驱动就在调用FltUnregisterFilter后一去不复返了。
在对这个函数进行下断后,发现PCHunter在调用移除过滤器后确实会调用FltUnregisterFilter。
上双机调试环境,把IDA拖入fltmgr,启动sync,Windbg 和 ret-sync联调。
1
2
3
|
.load F:\github\ret
-
sync\ext_windbg\sync\x64\Release\sync.dll
!sync
bp fltmgr!FltUnregisterFilter
|
先追踪一去不复返的原因。
经过调试发现ExWaitForRundownProtectionRelease
导致了函数的无限等待。
找到了这个原因,让我们看看MSDN,根据Remarks可知,需要通过调用 来释放保护,这个函数才能返回。
再次调试,看看这个对象的引用计数是怎样的。
在调用Remove之后,我们断在函数FltUnregisterFilter处:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
1
: kd> g
Breakpoint
0
hit
fltmgr!FltUnregisterFilter:
fffff880`
011bd6a0
488bc4
mov rax,rsp
1
: kd> r
rax
=
0000000000000000
rbx
=
fffffa8062f7cd10 rcx
=
fffffa80629a8430
rdx
=
fffff88003071126 rsi
=
fffffa8062a2b4c2 rdi
=
fffff88003071224
rip
=
fffff880011bd6a0 rsp
=
fffff880030710a8 rbp
=
fffff88003071b60
r8
=
fffff88003071226 r9
=
0000000000000000
r10
=
fffff880009f1b20
r11
=
fffffa8062a2b4ae r12
=
0000000000000000
r13
=
0000000000000001
r14
=
0000000000000001
r15
=
fffffa806298a060
iopl
=
0
nv up ei pl zr na po nc
cs
=
0010
ss
=
0018
ds
=
002b
es
=
002b
fs
=
0053
gs
=
002b
efl
=
00000246
fltmgr!FltUnregisterFilter:
fffff880`
011bd6a0
488bc4
mov rax,rsp
|
第一个参数即是_FLT_FILTER
的指针
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
1
: kd> dt fltmgr!_FLT_FILTER @rcx
+
0x000
Base : _FLT_OBJECT
+
0x020
Frame :
0xfffffa80
`
617afac0
_FLTP_FRAME
+
0x028
Name : _UNICODE_STRING
"DelProtect"
+
0x038
DefaultAltitude : _UNICODE_STRING
"345101"
+
0x048
Flags :
2
( FLTFL_FILTERING_INITIATED )
+
0x050
DriverObject :
0xfffffa80
`
6140aa50
_DRIVER_OBJECT
+
0x058
InstanceList : _FLT_RESOURCE_LIST_HEAD
+
0x0d8
VerifierExtension : (null)
+
0x0e0
VerifiedFiltersLink : _LIST_ENTRY [
0x00000000
`
00000000
-
0x00000000
`
00000000
]
+
0x0f0
FilterUnload :
0xfffff880
`
05076130
long
DelProtect!DelProtectUnload
+
0
+
0x0f8
InstanceSetup :
0xfffff880
`
05076000
long
DelProtect!DelProtectInstanceSetup
+
0
+
0x100
InstanceQueryTeardown :
0xfffff880
`
050761a0
long
DelProtect!DelProtectInstanceQueryTeardown
+
0
+
0x108
InstanceTeardownStart :
0xfffff880
`
05076070
void DelProtect!DelProtectInstanceTeardownStart
+
0
+
0x110
InstanceTeardownComplete :
0xfffff880
`
050760d0
void DelProtect!DelProtectInstanceTeardownComplete
+
0
+
0x118
SupportedContextsListHead : (null)
+
0x120
SupportedContexts : [
6
] (null)
+
0x150
PreVolumeMount : (null)
+
0x158
PostVolumeMount : (null)
+
0x160
GenerateFileName : (null)
+
0x168
NormalizeNameComponent : (null)
+
0x170
NormalizeNameComponentEx : (null)
+
0x178
NormalizeContextCleanup : (null)
+
0x180
KtmNotification : (null)
+
0x188
Operations :
0xfffffa80
`
629a86c0
_FLT_OPERATION_REGISTRATION
+
0x190
OldDriverUnload : (null)
+
0x198
ActiveOpens : _FLT_MUTEX_LIST_HEAD
+
0x1e8
ConnectionList : _FLT_MUTEX_LIST_HEAD
+
0x238
PortList : _FLT_MUTEX_LIST_HEAD
+
0x288
PortLock : _EX_PUSH_LOCK
|
接下来我们看看相关的计数
1
2
3
4
|
1
: kd> ?? ((fltmgr!_FLT_FILTER
*
) (@rcx))
-
>Base.RundownRef
struct _EX_RUNDOWN_REF
+
0x000
Count :
0xc
+
0x000
Ptr :
0x00000000
`
0000000c
Void
|
可以看到再我们卸载时这个Count为0xC。
在调用ExWaitForRundownProtectionRelease
之前,我们再看一次计数
1
2
3
4
|
1
: kd> ?? ((fltmgr!_FLT_FILTER
*
) (
0xfffffa80629a8430
))
-
>Base.RundownRef
struct _EX_RUNDOWN_REF
+
0x000
Count :
2
+
0x000
Ptr :
0x00000000
`
00000002
Void
|
可以看到此时的计数是2。
那么我们接下来测试PCHunter。
再调用移除过滤器后我们也成功断在了入口处。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
1
: kd> g
Breakpoint
0
hit
fltmgr!FltUnregisterFilter:
fffff880`
011226a0
488bc4
mov rax,rsp
0
: kd> r
rax
=
fffff880011226a0 rbx
=
fffff80004773fe0 rcx
=
fffffa8061f83500
rdx
=
fffffa8061f83500 rsi
=
fffffa806110d040 rdi
=
fffffa8061f83500
rip
=
fffff880011226a0 rsp
=
fffff880060cebc8 rbp
=
0000000000000080
r8
=
0000000000000000
r9
=
0000000000000000
r10
=
0000000000000001
r11
=
fffffa80643553dc r12
=
fffffa8061f83500 r13
=
fffff88006555ca0
r14
=
0000000000000000
r15
=
fffff80000b96080
iopl
=
0
nv up ei ng nz na po nc
cs
=
0010
ss
=
0018
ds
=
002b
es
=
002b
fs
=
0053
gs
=
002b
efl
=
00000286
fltmgr!FltUnregisterFilter:
fffff880`
011226a0
488bc4
mov rax,rsp
|
我们看一下引用计数,现在是0xa。
1
2
3
4
|
0
: kd> ?? ((fltmgr!_FLT_FILTER
*
) (@rcx))
-
>Base.RundownRef
struct _EX_RUNDOWN_REF
+
0x000
Count :
0xa
+
0x000
Ptr :
0x00000000
`
0000000a
Void
|
放过去,运行到调用ExWaitForRundownProtectionRelease
之前,发现引用计数变为了0。
1
2
3
4
|
1
: kd> ?? ((fltmgr!_FLT_FILTER
*
) (
0xfffffa8061f83500
))
-
>Base.RundownRef
struct _EX_RUNDOWN_REF
+
0x000
Count :
0
+
0x000
Ptr : (null)
|
因此PCHunter肯定是调用了ExReleaseRundownProtection
去释放运行时保护。
Let’s try it!
关键代码如下:
1
2
3
|
PEX_RUNDOWN_REF RunRefs
=
(PEX_RUNDOWN_REF)((char
*
)ppFltList[i]
+
offset);
ExReleaseRundownProtection(RunRefs);
FltUnregisterFilter(ppFltList[i]);
|
重新编译驱动,下断。
1
2
|
bp fltmgr!FltUnregisterFilter
bp fltmgr!FltUnregisterFilter
+
130
|
第一次断下记录rcx
1
2
3
4
5
6
7
|
0
: kd> r
rax
=
0000000000000000
rbx
=
fffffa8062f29510 rcx
=
fffffa8062ed7890
rdx
=
000000000000000a
rsi
=
fffffa8062bf1a62 rdi
=
fffff88006569224
rip
=
fffff880011ba6a0 rsp
=
fffff88006569098 rbp
=
fffff88006569b60
r8
=
fffffa8062ed7898 r9
=
0000000000000000
r10
=
fffff8000460d820
r11
=
fffffa8062bf1a4e r12
=
0000000000000000
r13
=
0000000000000001
r14
=
0000000000000001
r15
=
fffffa8062a07060
|
第二次断下查看计数,Ok! 效果和PCHunter一样了。
1
2
3
4
|
1
: kd> ?? ((fltmgr!_FLT_FILTER
*
) (
0xfffffa8062ed7890
))
-
>Base.RundownRef
struct _EX_RUNDOWN_REF
+
0x000
Count :
0
+
0x000
Ptr : (null)
|
然后就成功移除掉了。
更多【摘微过滤驱动回调的研究】相关视频教程:www.yxfzedu.com