hook ssdt 内核方面的大神来解答下疑惑

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hook ssdt 内核方面的大神来解答下疑惑相关的知识,希望对你有一定的参考价值。

比如某个程序hook了ssdt表,
请问ssdt表
是每个程序都有一个, 程序hook了以后, 不会影响到其他的程序对ssdt的操作
还是系统总共只有一个, 程序hook了以后, 所有其它程序的对ssdt的操作都要经过hook程序的筛选?

一般在内核SSDT HOOK的时候就是直接钩住SSDT表替换NtOpenProcess的地址来达到保护进程的目的。而在InlineHook中,侧需要更进一步的了解NtOpenProcess函数,才能更好的做inlinehook。
首先说说Windows中用户层 OpenProces,WIN32函数OpenProces执行后,调用NTDLL.DLL中NtOpenProcess函数,然后此函数INT2E自陷进入内核,开始从SSDT表中查找NtOpenProcess函数地址,继而在内核中执行NtOpenProcess函数。这是OpenProcess调用的路径。如图。

那么就这样说,在Windows中,OpenProcess函数是对NtOpenProcess调用的一个包装。NtOpenProcess包含在内核模块NTOSKRNL.EXE当中。
内核中NtOpenProcess函数结构如下:
NTSTATUS NtOpenProcess (
OUT PHANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId OPTIONAL);

ClientID参数是OpenProcess传递的实际PID。这个参数是可选的,但是根据我们的观察,OpenProcess在调用NtOpenProcess的时候总是使用这个参数。
在内核中执行的时候,NtOpenProcess主要实现3个功能:

1. 它通过调用PsLookupProcessByProcessId函数来验证进程是否存在。
2. 它通过调用ObOpenObjectByPointer来打开进程的句柄。
3. 如果打开进程句柄成功,就将句柄返回给调用者。
那么很自然的,PsLookupProcessByProcessId函数和ObOpenObjectByPointer函数就成为我们inlinehook的目标
先看PsLookupProcessByProcessId函数:
lkd> u 805caefa
nt!NtOpenProcess+0x1fc:
805caefa 45 inc ebp
805caefb dc50ff fcom qword ptr [eax-1]
805caefe 75d4 jne nt!NtOpenProcess+0x1d6 (805caed4)
805caf00 e8617a0000 call nt!PsLookupProcessByProcessId (805d2966)
805caf05 ebde jmp nt!NtOpenProcess+0x1e7 (805caee5)
805caf07 8d45e0 lea eax,[ebp-20h]
805caf0a 50 push eax
805caf0b ff75cc push dword ptr [ebp-34h]
lkd> u nt!PsLookupProcessByProcessId
nt!PsLookupProcessByProcessId:
805d2966 8bff mov edi,edi
805d2968 55 push ebp
805d2969 8bec mov ebp,esp
805d296b 53 push ebx
805d296c 56 push esi
805d296d 64a124010000 mov eax,dword ptr fs:[00000124h]
805d2973 ff7508 push dword ptr [ebp+8]
805d2976 8bf0 mov esi,eax
805d2978 ff8ed4000000 dec dword ptr [esi+0D4h]
805d297e ff35c0385680 push dword ptr [nt!PsThreadType+0x4 (805638c0)]
805d2984 e803ad0300 call nt!ExEnumHandleTable+0x408 (8060d68c)
805d2989 8bd8 mov ebx,eax
805d298b 85db test ebx,ebx
805d298d c745080d0000c0 mov dword ptr [ebp+8],0C000000Dh
805d2994 7432 je nt!PsLookupProcessByProcessId+0x62 (805d29c8)
再看ObOpenObjectByPointer函数:
lkd> u 805caf15
nt!NtOpenProcess+0x217:
805caf15 8d8548ffffff lea eax,[ebp-0B8h]
805caf1b 50 push eax
805caf1c ff75c8 push dword ptr [ebp-38h]
805caf1f ff75dc push dword ptr [ebp-24h]
805caf22 e8bd07ffff call nt!ObOpenObjectByPointer (805bb6e4)
805caf27 8bf8 mov edi,eax
805caf29 8d8548ffffff lea eax,[ebp-0B8h]
805caf2f 50 push eax
lkd> u nt!ObOpenObjectByPointer
nt!ObOpenObjectByPointer:
805bb6e4 8bff mov edi,edi
805bb6e6 55 push ebp
805bb6e7 8bec mov ebp,esp
805bb6e9 81ec94000000 sub esp,94h
805bb6ef 53 push ebx
805bb6f0 8b5d08 mov ebx,dword ptr [ebp+8]
805bb6f3 56 push esi
805bb6f4 57 push edi
知道NtOpenProcess执行的过程后,为防止打开某特定进程的句柄,可以直接inlinehook ObOpenObjectByPointer函数,Hook 这个函数有一大好处,那就是进程线程都一起保护了
ObOpenObjectByPointer(
IN PVOID Object,
IN ULONG HandleAttributes,
IN PACCESS_STATE PassedAccessState OPTIONAL,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_TYPE ObjectType OPTIONAL,
IN KPROCESSOR_MODE AccessMode,
OUT PHANDLE Handle
)
NTSTATUS
T_ObOpenObjectByPointer(
IN PVOID Object,
IN ULONG HandleAttributes,
IN PACCESS_STATE PassedAccessState OPTIONAL,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_TYPE ObjectType OPTIONAL,
IN KPROCESSOR_MODE AccessMode,
OUT PHANDLE Handle
)

PEPROCESS EPROCESS;
if ((Object != NULL) && (MmIsAddressValid(Object))) // 地址有效性验证

if (OBJECT_TO_OBJECT_HEADER(Object) -> Type == *PsProcessType) // 若为进程对象

if ((PsGetCurrentProcess() != ProtectedProcess)) // 若操作者不是受保护的进程自己

if (Object == ProtectedProcess) // 若被操作进程是受保护进程

return STATUS_ACCESS_DENIED; // 拒绝访问




else
if (OBJECT_TO_OBJECT_HEADER(Object) -> Type == *PsThreadType) // 若为线程对象

EPROCESS = IoThreadToProcess(Object); // 获取线程对应进程的 EPROCESS
if (EPROCESS == ProtectedProcess) // 若是受保护进程

if ((PsGetCurrentProcess() != ProtectedProcess)) // 若操作者不是受保护进程自己

return STATUS_ACCESS_DENIED; // 拒绝访问





// 正常调用,执行原 API
return My_ObOpenObjectByPointer(
Object,
HandleAttributes,
PassedAccessState,
DesiredAccess,
ObjectType,
AccessMode,
Handle
);


My_ObOpenObjectByPointer(
Object,
HandleAttributes,
PassedAccessState,
DesiredAccess,
ObjectType,
AccessMode,
Handle
);
函数中,执行完ObOpenObjectByPointer函数前几字节后JMP到ObOpenObjectByPointer函数内部。

在系统内核有一个内核文件的加载的镜像(内核模块),NTOSKRNL或ntkrnlpa及ntkrnlmp、ntkrnlup、ntkrpamp都是OS内核文件,它提供了一整套核心态函数,供用户态和核心态调用,我们在用户态调用的函数大多数在最后都进入了核心态如kernel32.dll的OpenProcess,在调用OpenProcess,以后会进入Ntdll.dll中的NtOpenProcess然后调用系统函数调用号进入核心态的NtOpenProcess,所以核心态的钩子才是王道,核心态的钩子有SSDT HOOK和SDT INLINE HOOK,上面说了,内核导出了一系列的函数供用户态调用,那么导出的这个函数表就是SSDT(系统服务描述表),它的地址可由内核导出的一个变量 KeServiceDescriptorTable 查询,每4个字节(long 大小)为一个地址,在SSDT HOOK时我们只需要修改SSDT表中的地址为我们的地址即可,相当简单.

例:修改NtOpenProcess:

*(ULONG*)(KeServiceDescriptorTable+(0x7A*4))=(ULONG)MyOpenProcess

0x7A为NtOpenProcess的系统调用号,每个调用号占4个字节,KeServiceDescriptorTable+(0x7A*4)就代表了NtOpenProcess地址的存放位置,MyOpenProcess为我们自定义的函数,这样系统在执行NtOpenProcess的时候就会跳到MyOpenProcess里。还有一种就是Inline Hook它和用户态的一样直接修改函数前5个字节即可,这里不再赘述。但是在核心态的inline hook比较危险,这涉及到多线程调用,有兴趣的朋友可以去查阅该方面资料。
参考技术A 系统Hook就要筛选全部的,如果不是系统Hook就不会咯~~~本回答被提问者采纳

SSDT HOOK是啥

SSDT的全称是System Services Descriptor Table,系统服务描述符表
一般来说此表与链接系统内核的API密切相关,对此有一项应用就是杀毒软件的主动防御,当然病毒也可以通过修改主动防御的SSDT来绕过杀软的主动防御。SSDT hook一般是用来隐藏进程运行程序的,这里就介绍这些更多的参考我的空间文章:
http://hi.baidu.com/rabby163/blog/item/73c71f54dcf10c1c3a293508.html

参考资料:http://hi.baidu.com/rabby163/blog/item/73c71f54dcf10c1c3a293508.html

参考技术A SSDT的全称是System Services Descriptor Table,系统服务描述符表
一般来说此表与链接系统内核的API密切相关,对此有一项应用就是杀毒软件的主动防御,当然病毒也可以通过修改主动防御的SSDT来绕过杀软的主动防御。SSDT hook一般是用来隐藏进程运行程序的

以上是关于hook ssdt 内核方面的大神来解答下疑惑的主要内容,如果未能解决你的问题,请参考以下文章

SSDT HOOK是啥

09SSDT概述

求英文还凑合,懂ARM嵌入式和Robot机器人方面的大神解答

各位大神速度帮我解答下好么,谢谢了,在线等,C++

SSDT HOOK win7下还能使用吗 进程隐藏相关

什么是单一登录(单应用登录),麻烦大神解答时尽量书面语言?