« VC程序查错之内存访问异常POOL驱动不能处理异常的解决方法 »

ObRegisterCallbacks返回0xC0000022(拒绝访问)解决方案

ObRegisterCallbacks这个函数是在Vista sp1之后的版本中添加的,可用来监控系统中对进线程句柄的操作,如打开进程、复制线程句柄等。

但是使用这个函数对驱动有特殊的要求,必须使用特殊的签名才行!否则这个函数会返回0xC0000022(拒绝访问),逆向此函数可以看到以下是有关是否加签名的判断:

PAGE:00000001404AA75D                 call    MmVerifyCallbackFunction
PAGE:00000001404AA762                 cmp     eax, ebx
PAGE:00000001404AA764                 jz      short loc_1404AA7E1
PAGE:00000001404AA766
PAGE:00000001404AA766 loc_1404AA766:                          ; CODE XREF: ObRegisterCallbacks+11Bj
PAGE:00000001404AA766                 mov     rcx, [rsi+rbp+18h]
PAGE:00000001404AA76B                 cmp     rcx, rbx
PAGE:00000001404AA76E                 jz      short loc_1404AA779
PAGE:00000001404AA770                 call    MmVerifyCallbackFunction
PAGE:00000001404AA775                 cmp     eax, ebx
PAGE:00000001404AA777                 jz      short loc_1404AA7E1

函数调用了两次MmVerifyCallbackFunction函数,在此函数里通过调用堆栈找到调用ObRegisterCallbacks函数的驱动,进而得到驱动的_LDR_DATE_TABLE_ENTRY,然后判断+0x68位置的flag & 0x20是否为零,如果为0就不允许使用此函数。所以要想让没有签名的函数也使用此函数,只需按以下步骤操作即可:

方案一

1.根据DriverObject,得到_LDR_DATE_TABLE_ENTRY结构,_LDR_DATE_TABLE_ENTRY结构位于DriverObject的DriverSection项

2.将_LDR_DATE_TABLE_ENTRY结构中+0x68的flag的值或0x20即可。

方案二

伪造ObRegisterCallbacks函数的返回地址,这种方法在shellcode编写中较为常用,具体做法请参考gyzy写的《基于栈指纹检测缓冲区溢出的一点思路》

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

日历

最新评论及回复

最近发表

Powered By Z-Blog 2.0 bate Build Theme by toboku

Copyright langouster. Some Rights Reserved.   苏ICP备06046736号