【原创】如何使PsSetCreateProcessNotifyRoutine等3个函数设置的监控历程从内核中脱链
【作者】drcool
大家都知道在内核环境下有三个函数分别可以设置Process, Thread, Image的相关通知函数,他们是PsSetCreateProcessNotifyRoutine,PsSetCreateThreadNotifyRoutine,PsSetLoadImageNotifyRoutine。在DDK里面都有详细的介绍。通过这三个函数,我们就可以设置历程,对进程建立和销毁,线程建立和销毁,以及模块加载这些过程进行监控,也就是得到相关的通知。在DDK里面也明确指出,进行这些设置的内核模块是不能卸载的,也就是说,通过这些函数设置的监控历程一旦设置就要一直工作下去,直到系统关闭。但是通过对这三个函数的研究发现,DDK的说法是不正确的。下面我们就来看看,如何让这些监控历程从内核中脱链并失效。本文所使用的方法可以适用于Win2000和XPSP2以及2003SP1,其他操作系统平台的原理是一样的,只不过具体的内核相关偏移需要修改。
1. Win2000的情况
对于PsSetCreateProcessNotifyRoutine(
IN PCREATE_PROCESS_NOTIFY_ROUTINE NotifyRoutine,
IN BOOLEAN Remove
);,最后一个参数Remove为TRUE时,就是对NotifyRoutine从内核中卸载。我们所需要的就是找到NotifyRoutine的内核地址,然后调用这个函数就可以了。那么如何获得这个内核地址呢?经过对PsSetCreateProcessNotifyRoutine进行反汇编我们发现,PsSetCreateProcessNotifyRoutine能设置8个监控历程,这和DDK的描述是一致的,它们依次顺序存放在0x80483720开始的8个ULONG里面,而监控历程的个数,存放在0x8046dc38中。所以我们的工作可以描述如下(伪代码):
ULONG *p1=0x80483720; ULONG *p2=0x8046dc38;
for(i=0;i<8;i++,p1++)if(*p1)PsSetCreateProcessNotifyRoutine(*p1,TRUE);
这样我们就完成了对监控函数的卸载。
但是Thread, Image的监控函数在2000下是没有相关的卸载函数的。于是我们进一步发现,其实三个函数在内部所做的工作是类似的,一是在固定地址存放函数地址,二是增加函数个数的计数。因此卸载工作完全可以我们自己来做。接上面的定义,对于Process监控的卸载(伪代码描述):*p2=0; memset(p1,0,32); 两句话就完成了。对于Thread, Image,过程是一样的,只不过p1和p2变了。
对于PsSetCreateThreadNotifyRoutine,ULONG *p1=0x804836e0; ULONG *p2=0x8046cfc4;
对于PsSetLoadImageNotifyRoutine, ULONG *p1=0x80483760; ULONG *p2=0x80483740;
自己手动来卸载的方式还可以抵御PsSetCreateProcessNotifyRoutine被HOOK的情况。
2. XPSP2的情况
对于Process我们依然可以采用2000下面的文档化的方法,也就是PsSetCreateProcessNotifyRoutine(NotifyRoutine,TRUE);同时内核中有又了两个用于卸载的函数,PsRemoveCreateThreadNotifyRoutine,PsRemoveLoadImageNotifyRoutine(NotifyRoutine)。下面我们就来看看如何得到这些NotifyRoutine的地址并使用这些函数来卸载。并且我们还要讨论如何利用手工来卸载函数,这样也是为了抵御相互内核函数被HOOK的情况。
现看PsSetCreateProcessNotifyRoutine的情况:
nt!PsSetCreateProcessNotifyRoutine:
805cf44c 8bff mov edi,edi
805cf44e 55 push ebp
805cf44f 8bec mov ebp,esp
805cf451 53 push ebx
805cf452 33db xor ebx,ebx
805cf454 385d0c cmp [ebp+0xc],bl
805cf457 56 push esi
805cf458 57 push edi
805cf459 7464 jz nt!PsSetCreateProcessNotifyRoutine+0x73 (805cf4bf)
805cf45b bf40395680 mov edi,0x80563940
805cf460 57 push edi
805cf461 e8a6ce0300 call nt!ExReferenceCallBackBlock (8060c30c)
805cf466 8bf0 mov esi,eax
805cf468 85f6 test esi,esi
805cf46a 741f jz nt!PsSetCreateProcessNotifyRoutine+0x3f (805cf48b)
805cf46c 56 push esi
805cf46d e89acc0300 call nt!ExGetCallBackBlockRoutine (8060c10c)
805cf472 3b4508 cmp eax,[ebp+0x8]
805cf475 750d jnz nt!PsSetCreateProcessNotifyRoutine+0x38 (805cf484)
805cf477 56 push esi
805cf478 6a00 push 0x0
805cf47a 57 push edi
805cf47b e8c0cd0300 call nt!ExCompareExchangeCallBack (8060c240)
805cf480 84c0 test al,al
805cf482 7517 jnz nt!PsSetCreateProcessNotifyRoutine+0x4f (805cf49b)
805cf484 56 push esi
805cf485 57 push edi
805cf486 e883cf0300 call nt!ExDereferenceCallBackBlock (8060c40e)
805cf48b 43 inc ebx
805cf48c 83c704 add edi,0x4
805cf48f 83fb08 cmp ebx,0x8
805cf492 72cc jb nt!PsSetCreateProcessNotifyRoutine+0x14 (805cf460)
805cf494 b87a0000c0 mov eax,0xc000007a
805cf499 eb64 jmp nt!PsSetCreateProcessNotifyRoutine+0xb3 (805cf4ff)
805cf49b b860395680 mov eax,0x80563960
805cf4a0 83c9ff or ecx,0xffffffff
805cf4a3 f00fc108 lock xadd [eax],ecx
805cf4a7 56 push esi
805cf4a8 8d049d40395680 lea eax,[nt!PspCreateProcessNotifyRoutine (80563940)+ebx*4]
805cf4af 50 push eax
805cf4b0 e859cf0300 call nt!ExDereferenceCallBackBlock (8060c40e)
805cf4b5 56 push esi
805cf4b6 e83bcc0300 call nt!ExWaitForCallBacks (8060c0f6)
805cf4bb 33ff xor edi,edi
805cf4bd eb38 jmp nt!PsSetCreateProcessNotifyRoutine+0xab (805cf4f7)
805cf4bf 53 push ebx
805cf4c0 ff7508 push dword ptr [ebp+0x8]
805cf4c3 e848cd0300 call nt!ExAllocateCallBack (8060c210)
805cf4c8 8bf0 mov esi,eax
805cf4ca 3bf3 cmp esi,ebx
805cf4cc 7507 jnz nt!PsSetCreateProcessNotifyRoutine+0x89 (805cf4d5)
805cf4ce b89a0000c0 mov eax,0xc000009a
805cf4d3 eb2a jmp nt!PsSetCreateProcessNotifyRoutine+0xb3 (805cf4ff)
805cf4d5 bf40395680 mov edi,0x80563940
805cf4da 6a00 push 0x0
805cf4dc 56 push esi
805cf4dd 57 push edi
805cf4de e85dcd0300 call nt!ExCompareExchangeCallBack (8060c240)
805cf4e3 84c0 test al,al
805cf4e5 751f jnz nt!PsSetCreateProcessNotifyRoutine+0xba (805cf506)
805cf4e7 83c304 add ebx,0x4
805cf4ea 83c704 add edi,0x4
805cf4ed 83fb20 cmp ebx,0x20
805cf4f0 72e8 jb nt!PsSetCreateProcessNotifyRoutine+0x8e (805cf4da)
805cf4f2 bf0d0000c0 mov edi,0xc000000d
805cf4f7 56 push esi
805cf4f8 e8ed820100 call nt!SepFreeCapturedString (805e77ea)
805cf4fd 8bc7 mov eax,edi
805cf4ff 5f pop edi
805cf500 5e pop esi
805cf501 5b pop ebx
805cf502 5d pop ebp
805cf503 c20800 ret 0x8
805cf506 33c9 xor ecx,ecx
805cf508 b860395680 mov eax,0x80563960
805cf50d 41 inc ecx
805cf50e f00fc108 lock xadd [eax],ecx
805cf512 33c0 xor eax,eax
805cf514 ebe9 jmp nt!PsSetCreateProcessNotifyRoutine+0xb3 (805cf4ff)
为了配合后面的手动卸载,再看两个函数:
nt!ExAllocateCallBack:
8060c210 8bff mov edi,edi
8060c212 55 push ebp
8060c213 8bec mov ebp,esp
8060c215 6843627262 push 0x62726243
8060c21a 6a0c push 0xc
8060c21c 6a01 push 0x1
8060c21e e845f7f3ff call nt!ExAllocatePoolWithTag (8054b968)
8060c223 85c0 test eax,eax
8060c225 740f jz nt!ExAllocateCallBack+0x26 (8060c236)
8060c227 8b4d08 mov ecx,[ebp+0x8]
8060c22a 832000 and dword ptr [eax],0x0
8060c22d 894804 mov [eax+0x4],ecx
8060c230 8b4d0c mov ecx,[ebp+0xc]
8060c233 894808 mov [eax+0x8],ecx
8060c236 5d pop ebp
8060c237 c20800 ret 0x8
这个函数在设置监控函数时用到
nt!ExCompareExchangeCallBack:
8060c240 8bff mov edi,edi
8060c242 55 push ebp
8060c243 8bec mov ebp,esp
8060c245 56 push esi
8060c246 8b750c mov esi,[ebp+0xc]
8060c249 85f6 test esi,esi
8060c24b 7412 jz nt!ExCompareExchangeCallBack+0x1f (8060c25f)
8060c24d 6a08 push 0x8
8060c24f 5a pop edx
8060c250 8bce mov ecx,esi
8060c252 e809f9ffff call nt!ExAcquireRundownProtectionEx (8060bb60)
8060c257 84c0 test al,al
8060c259 0f84a2000000 je nt!ExCompareExchangeCallBack+0xc1 (8060c301)
8060c25f 8b5508 mov edx,[ebp+0x8]
8060c262 53 push ebx
8060c263 8b1a mov ebx,[edx]
8060c265 8bc3 mov eax,ebx
8060c267 334510 xor eax,[ebp+0x10]
8060c26a 895d0c mov [ebp+0xc],ebx
8060c26d 83f807 cmp eax,0x7
8060c270 7717 ja nt!ExCompareExchangeCallBack+0x49 (8060c289)
8060c272 85f6 test esi,esi
8060c274 7407 jz nt!ExCompareExchangeCallBack+0x3d (8060c27d)
8060c276 8bce mov ecx,esi
8060c278 83c907 or ecx,0x7
8060c27b eb02 jmp nt!ExCompareExchangeCallBack+0x3f (8060c27f)
8060c27d 33c9 xor ecx,ecx
8060c27f 8bc3 mov eax,ebx
8060c281 f00fb10a lock cmpxchg [edx],ecx
8060c285 3bc3 cmp eax,ebx
8060c287 75da jnz nt!ExCompareExchangeCallBack+0x23 (8060c263)
8060c289 83e3f8 and ebx,0xfffffff8
8060c28c 3b5d10 cmp ebx,[ebp+0x10]
8060c28f 755f jnz nt!ExCompareExchangeCallBack+0xb0 (8060c2f0)
8060c291 85db test ebx,ebx
8060c293 7457 jz nt!ExCompareExchangeCallBack+0xac (8060c2ec)
8060c295 57 push edi
8060c296 64a124010000 mov eax,fs:[00000124]
8060c29c 8bf8 mov edi,eax
8060c29e 8db7d4000000 lea esi,[edi+0xd4]
8060c2a4 ff0e dec dword ptr [esi]
8060c2a6 874510 xchg [ebp+0x10],eax
8060c2a9 833d5c4b568000 cmp dword ptr [nt!ExpCallBackFlush (80564b5c)],0x0
8060c2b0 7414 jz nt!ExCompareExchangeCallBack+0x86 (8060c2c6)
8060c2b2 b95c4b5680 mov ecx,0x80564b5c
8060c2b7 e856fbffff call nt!ExfAcquirePushLockExclusive (8060be12)
8060c2bc b95c4b5680 mov ecx,0x80564b5c
8060c2c1 e8cef9ffff call nt!ExfReleasePushLock (8060bc94)
8060c2c6 ff06 inc dword ptr [esi]
8060c2c8 7513 jnz nt!ExCompareExchangeCallBack+0x9d (8060c2dd)
8060c2ca 8d4734 lea eax,[edi+0x34]
8060c2cd 3900 cmp [eax],eax
8060c2cf 740c jz nt!ExCompareExchangeCallBack+0x9d (8060c2dd)
8060c2d1 b101 mov cl,0x1
8060c2d3 c6474901 mov byte ptr [edi+0x49],0x1
8060c2d7 ff150c914d80 call dword ptr [nt!_imp_HalRequestSoftwareInterrupt (804d910c)]
8060c2dd 8b550c mov edx,[ebp+0xc]
8060c2e0 83e207 and edx,0x7
8060c2e3 42 inc edx
8060c2e4 8bcb mov ecx,ebx
8060c2e6 e8e1f8ffff call nt!ExReleaseRundownProtectionEx (8060bbcc)
8060c2eb 5f pop edi
8060c2ec b001 mov al,0x1
8060c2ee eb10 jmp nt!ExCompareExchangeCallBack+0xc0 (8060c300)
8060c2f0 85f6 test esi,esi
8060c2f2 740a jz nt!ExCompareExchangeCallBack+0xbe (8060c2fe)
8060c2f4 6a08 push 0x8
8060c2f6 5a pop edx
8060c2f7 8bce mov ecx,esi
8060c2f9 e8cef8ffff call nt!ExReleaseRundownProtectionEx (8060bbcc)
8060c2fe 32c0 xor al,al
8060c300 5b pop ebx
8060c301 5e pop esi
8060c302 5d pop ebp
8060c303 c20c00 ret 0xc
8060c306 cc int 3
8060c307 cc int 3
8060c308 cc int 3
8060c309 cc int 3
8060c30a cc int 3
8060c30b cc int 3
这个函数在卸载监控函数时用到,用于取地址
nt!ExReferenceCallBackBlock:
8060c30c 8bff mov edi,edi
8060c30e 55 push ebp
8060c30f 8bec mov ebp,esp
8060c311 53 push ebx
8060c312 57 push edi
8060c313 8b7d08 mov edi,[ebp+0x8]
8060c316 6a07 push 0x7
8060c318 5b pop ebx
8060c319 8b0f mov ecx,[edi]
8060c31b 84cb test bl,cl
8060c31d 740d jz nt!ExReferenceCallBackBlock+0x20 (8060c32c)
8060c31f 8d51ff lea edx,[ecx-0x1]
8060c322 8bc1 mov eax,ecx
8060c324 f00fb117 lock cmpxchg [edi],edx
8060c328 3bc1 cmp eax,ecx
8060c32a 75ed jnz nt!ExReferenceCallBackBlock+0xd (8060c319)
8060c32c 85c9 test ecx,ecx
8060c32e 0f8480000000 je nt!ExReferenceCallBackBlock+0xa8 (8060c3b4)
8060c334 8bc1 mov eax,ecx
8060c336 23c3 and eax,ebx
8060c338 757e jnz nt!ExReferenceCallBackBlock+0xac (8060c3b8)
8060c33a 56 push esi
8060c33b 64a124010000 mov eax,fs:[00000124]
8060c341 8bf0 mov esi,eax
8060c343 ff8ed4000000 dec dword ptr [esi+0xd4]
8060c349 6a02 push 0x2
8060c34b bb5c4b5680 mov ebx,0x80564b5c
8060c350 59 pop ecx
8060c351 8bd3 mov edx,ebx
8060c353 33c0 xor eax,eax
8060c355 f00fb10a lock cmpxchg [edx],ecx
8060c359 85c0 test eax,eax
8060c35b 7407 jz nt!ExReferenceCallBackBlock+0x58 (8060c364)
8060c35d 8bcb mov ecx,ebx
8060c35f e8aefaffff call nt!ExfAcquirePushLockExclusive (8060be12)
8060c364 8b3f mov edi,[edi]
8060c366 83e7f8 and edi,0xfffffff8
8060c369 7412 jz nt!ExReferenceCallBackBlock+0x71 (8060c37d)
8060c36b 8bcf mov ecx,edi
8060c36d e8c4f7ffff call nt!ExAcquireRundownProtection (8060bb36)
8060c372 84c0 test al,al
8060c374 7507 jnz nt!ExReferenceCallBackBlock+0x71 (8060c37d)
8060c376 83650800 and dword ptr [ebp+0x8],0x0
8060c37a 8b7d08 mov edi,[ebp+0x8]
8060c37d 6a02 push 0x2
8060c37f 33c9 xor ecx,ecx
8060c381 8bd3 mov edx,ebx
8060c383 58 pop eax
8060c384 f00fb10a lock cmpxchg [edx],ecx
8060c388 83f802 cmp eax,0x2
8060c38b 7407 jz nt!ExReferenceCallBackBlock+0x88 (8060c394)
8060c38d 8bcb mov ecx,ebx
8060c38f e800f9ffff call nt!ExfReleasePushLock (8060bc94)
8060c394 ff86d4000000 inc dword ptr [esi+0xd4]
8060c39a 7513 jnz nt!ExReferenceCallBackBlock+0xa3 (8060c3af)
8060c39c 8d4634 lea eax,[esi+0x34]
8060c39f 3900 cmp [eax],eax
8060c3a1 740c jz nt!ExReferenceCallBackBlock+0xa3 (8060c3af)
8060c3a3 b101 mov cl,0x1
8060c3a5 c6464901 mov byte ptr [esi+0x49],0x1
8060c3a9 ff150c914d80 call dword ptr [nt!_imp_HalRequestSoftwareInterrupt (804d910c)]
8060c3af 85ff test edi,edi
8060c3b1 5e pop esi
8060c3b2 754c jnz nt!ExReferenceCallBackBlock+0xf4 (8060c400)
8060c3b4 33c0 xor eax,eax
8060c3b6 eb4a jmp nt!ExReferenceCallBackBlock+0xf6 (8060c402)
8060c3b8 83e1f8 and ecx,0xfffffff8
8060c3bb 83f801 cmp eax,0x1
8060c3be 894d08 mov [ebp+0x8],ecx
8060c3c1 753a jnz nt!ExReferenceCallBackBlock+0xf1 (8060c3fd)
8060c3c3 8bd3 mov edx,ebx
8060c3c5 e896f7ffff call nt!ExAcquireRundownProtectionEx (8060bb60)
8060c3ca 84c0 test al,al
8060c3cc 742f jz nt!ExReferenceCallBackBlock+0xf1 (8060c3fd)
8060c3ce 8b17 mov edx,[edi]
8060c3d0 8bc2 mov eax,edx
8060c3d2 23c3 and eax,ebx
8060c3d4 03c3 add eax,ebx
8060c3d6 3bc3 cmp eax,ebx
8060c3d8 7719 ja nt!ExReferenceCallBackBlock+0xe7 (8060c3f3)
8060c3da 8bc2 mov eax,edx
8060c3dc 83e0f8 and eax,0xfffffff8
8060c3df 394508 cmp [ebp+0x8],eax
8060c3e2 750f jnz nt!ExReferenceCallBackBlock+0xe7 (8060c3f3)
8060c3e4 8d4a07 lea ecx,[edx+0x7]
8060c3e7 8bc2 mov eax,edx
8060c3e9 f00fb10f lock cmpxchg [edi],ecx
8060c3ed 3bc2 cmp eax,edx
8060c3ef 75dd jnz nt!ExReferenceCallBackBlock+0xc2 (8060c3ce)
8060c3f1 eb0a jmp nt!ExReferenceCallBackBlock+0xf1 (8060c3fd)
8060c3f3 8b4d08 mov ecx,[ebp+0x8]
8060c3f6 8bd3 mov edx,ebx
8060c3f8 e8cff7ffff call nt!ExReleaseRundownProtectionEx (8060bbcc)
8060c3fd 8b7d08 mov edi,[ebp+0x8]
8060c400 8bc7 mov eax,edi
8060c402 5f pop edi
8060c403 5b pop ebx
8060c404 5d pop ebp
8060c405 c20400 ret 0x4
下面我们就来具体分析一下:
a.设置过程,通过nt!ExAllocateCallBack分配12字节的空间ULONG d[3],是3个ULONG,在第二个ULONG里面存放的是监控函数的地址。然后通过ExCompareExchangeCallBack这个关键的函数进行后续的设置工作,指针d经过变换后存放在固定的位置,并增加相关计数。对d的变换是这样的,把它的低三位置1,也就是 or 7,这在汇编代码里面可以看的很清楚,这样做的可以的原因是,ExAllocatePoolWithTag所分配的内存是8字节对齐的。函数内部的其他工作是大部分是为了同步操作,就不多研究了。
b.卸载工作,不过是设置的逆过程,也就是取得d指针,再取得函数指针,比较是否是要卸载的函数,如果是则减少计数,释放12字节空间(这个应该是内部做),相应位置置0。
好了,下面我们来分别说明两种方法,利用文档函数的方法和手动方法(伪代码如下):
1) ULONG *p1=0x80563940; //连续的8个ULONG存放不同的d指针
ULONG *p2=0x80563960; //函数个数的计数
ULONG *d;
for(i=0;i<8;i++,p1++)
{
if(*p1)
{
d=*p1&0xfffffff8;
PsSetCreateProcessNotifyRoutine(d[1],TRUE);
}
*p1=0;
}
//上面是利用文档化函数的方法
*p2=0;
for(i=0;i<8;i++,p1++)
{
if(*p1)
{
*p1&=0xfffffff8;
ExfreePool(*p1);
}
*p1=0;
}
//这是手工的卸载方法
对于Thread和Image的过程是类似的,只不过p1和p2的值变化了。
对于PsSetCreateThreadNotifyRoutine,ULONG *p1=0x80563900; ULONG *p2=0x80563920;
对于PsSetLoadImageNotifyRoutine, ULONG *p1=0x805638e0; ULONG *p2=0x805638c8;
对于2003下面,也可以使用XP下的方法(手动和利用文档化函数都是可以的),只不过p1和p2的值有了变化,原理都是一样的。
对于PsSetCreateProcessNotifyRoutine,ULONG *p1=0x808ad260;ULONG *p2=0x808ad280;
对于PsSetCreateThreadNotifyRoutine, ULONG *p1=0x808ad220; ULONG *p2=0x808ad240;
对于PsSetLoadImageNotifyRoutine, ULONG *p1=0x808ad200; ULONG *p2=0x808ad1e8;
下面给出实际测试通过的代码,2003的代码大家可以参照着写出来:
void Remove2000()
{
int i;
unsigned long *D1=(unsigned long *)0x80483720, *D2=(unsigned long *)0x8046DC38, *E1=(unsigned long *)0x804836e0, *E2=(unsigned long *)0x8046cfc4, *F1=(unsigned long *)0x80483760, *F2=(unsigned long *)0x80483740;
*D2=0;
for(i=0;i<8;i++) D1[i]=0;
*E2=0;
for(i=0;i<8;i++) E1[i]=0;
*F2=0;
for(i=0;i<8;i++) F1[i]=0;
}
//利用文档化函数方法
void RemoveXPSP2()
{
int i;
ULONG *D1=(ULONG *)0x80563940; //连续的8个ULONG存放不同的d指针
ULONG *D2=(ULONG *)0x80563960; //函数个数的计数
ULONG *E1=(ULONG *)0x80563900; ULONG *E2=(ULONG *)0x80563920;
ULONG *F1=(ULONG *)0x805638e0; ULONG *F2=(ULONG *)0x805638c8;
unsigned long *d;
for(i=0;i<8;i++,D1++)
{
if(*D1)
{
d=(ULONG *)(*D1&0xfffffff8);
PsSetCreateProcessNotifyRoutine((PCREATE_PROCESS_NOTIFY_ROUTINE)d[1],TRUE);
}
*D1=0;
}
for(i=0;i<8;i++,E1++)
{
if(*E1)
{
d=(ULONG *)(*E1&0xfffffff8);
PsRemoveCreateThreadNotifyRoutine(d[1]);
}
*E1=0;
}
for(i=0;i<8;i++,F1++)
{
if(*F1)
{
d=(ULONG *)(*F1&0xfffffff8);
PsRemoveLoadImageNotifyRoutine(d[1]);
}
*F1=0;
}
}
//手动删除方法
void RemoveXPSP2V2()
{
int i;
ULONG *D1=(ULONG *)0x80563940; //连续的8个ULONG存放不同的d指针
ULONG *D2=(ULONG *)0x80563960; //函数个数的计数
ULONG *E1=(ULONG *)0x80563900; ULONG *E2=(ULONG *)0x80563920;
ULONG *F1=(ULONG *)0x805638e0; ULONG *F2=(ULONG *)0x805638c8;
unsigned long *d;
*D2=0;
for(i=0;i<8;i++,D1++)
{
if(*D1)
{
d=(ULONG *)(*D1&0xfffffff8);
ExFreePool(d);
}
*D1=0;
}
*E2=0;
for(i=0;i<8;i++,E1++)
{
if(*E1)
{
d=(ULONG *)(*E1&0xfffffff8);
ExFreePool(d);
}
*E1=0;
}
*F2=0;
for(i=0;i<8;i++,F1++)
{
if(*F1)
{
d=(ULONG *)(*F1&0xfffffff8);
ExFreePool(d);
}
*F1=0;
}
}
欢迎访问我的博客:http://blog.sina.com.cn/tigerDeng
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课