打算写一个监视系统SSDT调用情况的程序
很简单的ssdt hook就能实现的。
下面是hook函数。
__declspec(naked) HookStub()
{
__asm
{
push eax ;-->save Index
push eax
call HookBody ;-->Get Routine Information
; HookBody获取调用函数的参数个数,调用堆栈等记录发给ring3
pop edx ; --> index
test eax,eax
jz _Filter_ ;FALSE -->just return UNSUCCESSFULL
lea esi,g_SSDTMonitor
mov ebx,[esi+0xC]
mov edi,[ebx+edx*4] ; -->OrgRoutine
jmp edi
_Filter_:
mov esi,KeServiceDescriptorTable
mov ebx,[esi+0xC]
xor ecx,ecx
mov cl,[ebx + edx] ; -->Params
mov edi,[esp]
add esp,ecx
add esp,4
mov eax,0xC0000001
jmp edi
}
}
在虚拟机运行时是正常的
不过在实机运行时蓝屏了
看错误存储时发现 pop edx 得到的值不是Index而是非常大
导致mov edi,[ebx+edx*4]时内存访问错误蓝屏。
实机有360 hook了KiFastCallEntry的,在设计前看了下,发现它的hook现场都保护了
从call ebx --> HookStub 时eax确实是系统服务Index。
而却windbg显示的调用堆栈确实是从call ebx来的。。。(被欺骗了)
手动看了下esp,发现返回地址不是KiFastCallEntry
竟然是在Hookport模块里。
顿时醒悟了。。。
原来在Hookport里面的过滤函数都又直接调用了系统服务
现场已经被破坏了,eax物是人非啊,内牛满面啊
而且,这种现场是完全没有必要保护的,不是人家没保护
因为这种现场所以东西都是没用的。。。
没有统一hook标准的世界危机重重啊
也许你从DriverEntry里回溯IopLoadDriver地址,如果IopLoadDriver已经被hook了。。。
也许你用NtSetEvent回溯KiFastCallEntry的call ebx,如果NtSetEvent的调用是从别处而来。。。
也许你在mov edi,edi处写个eb xx,别人却给你直接jmp xxxx了
。。。
为了能比较好动态卸载驱动,而且没有必要过滤所有系统调用
所以不采用KiFastCallEntry这类的hook
也许我得为每个调用都写个
push xx
jmp xxxx
在安全领域原来所有都是不安全的
至少在设计上必须假设所有都是不安全的
才能进行安全的设计
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课