看了国内部分几个内核注册表穿越的驱动,用来绕过市面上量最大的菜鸟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~)