看了国内部分几个内核注册表穿越的驱动,用来绕过市面上量最大的菜鸟rootkit们,因为只会勾SSDT就出来混的真的有很多啊……

 

大概这么几个思路

 

1.      懒得处理,直接调用Zw***Key

2.      Map一份kernel.exe到内存中,按照内核基址重定位,把Nt***Key的部分拷贝到内存中,自己调用无SSDT/Inline hook的注册表操作。当然,CmpCallback要清0

3.      CmpCallback清零,自己通过KCBroutine hook(hook  _CM_KEY_CONTROL_BLOCK->KeyHive->GetCellRoutine)栈回溯得到以下地址:

 

b23d0e40 8063578a nt!CmDeleteKey

b23d0e48 8063234a nt!CmEnumerateKey

b23d0e58 80632724 nt!CmQueryValueKey

b23d0e5c 80632170 nt!CmDeleteValueKey

b23d0e60 80633cd2 nt!CmSetValueKey

b23d0e68 8063578a nt!CmDeleteKey

b23d0e7c 80632422 nt!CmEnumerateValueKey

 

再通过内存爆搜得到CmpParseKey (不爆搜的话就用sudami说过的交叉引用搜索,写ark的时候这么干过,听起来很拉风但是编码量比爆搜要多不少= =)

 

entry point减去一个值然后……就搜吧= =

// INIT:005E045A                mov     [ebp+var_30], offset _CmpCloseKeyObject@20; CmpCloseKeyObject(x,x,x,x,x)

// INIT:005E0461                 mov     [ebp+var_2C], offset _CmpDeleteKeyObject@4; CmpDeleteKeyObject(x)

// INIT:005E0468                 mov     [ebp+var_28], offset _CmpParseKey@40 ;CmpParseKey(x,x,x,x,x,x,x,x,x,x)

// INIT:005E046F                 mov     [ebp+var_24], offset _CmpSecurityMethod@36; CmpSecurityMethod(x,x,x,x,x,x,x,x,x)

// INIT:005E0476                 mov     [ebp+var_20], offset _CmpQueryKeyName@20 ;CmpQueryKeyName(x,x,x,x,x)

// INIT:005E047D                 call    _ObCreateObjectType@16 ; ObCrea

 

然后自己实现ssdt部分直接调用Cm***Key (操作方法详见WRK~