KeServiceDescriptorTableShadow地址的定位
参考:http://hi.baidu.com/175943462/blog/item/f07b6b115dba8e0a203f2e67.html
ULONG g_ServiceTableOffsetInKThread = 0xE0;
VOID GetServiceDescriptorTableShadowAddress() { //遍历线程 ULONG i; NTSTATUS ntStatus; ULONG thread; for(i = 8; i < 32768; i += 4) { ntStatus = PsLookupThreadByThreadId((HANDLE)i, &(PETHREAD)thread); if(NT_SUCCESS(ntStatus)) { if(*(PULONG)(thread + g_ServiceTableOffsetInKThread) != (ULONG)KeServiceDescriptorTable) { g_ServiceDescriptorTableShadow = (PSYSTEM_DESCRIPTOR_TABLE_SHADOW)(*(PULONG)(thread + g_ServiceTableOffsetInKThread)); DbgPrint("Shadow SSDT Address:%p", g_ServiceDescriptorTableShadow); ObDereferenceObject((PETHREAD)thread); break; } ObDereferenceObject((PETHREAD)thread); } } }
g_ServiceTableOffsetInKThread的值,根据系统的不同,值会不同,获取方法
kd> dt _kthread ntdll!_KTHREAD … +0x0de NpxIrql : UChar +0x0df InitialNode : UChar +0x0e0 ServiceTable : Ptr32 Void +0x0e4 Queue : Ptr32 _KQUEUE +0x0e8 ApcQueueLock : Uint4B +0x0f0 Timer : _KTIMER +0x118 QueueListEntry : _LIST_ENTRY …
函数索引(以NtUserSetClipboardData为例)
kd> dd nt!KeServiceDescriptorTableShadow L8 8055a6c0 804e36a8 00000000 0000011c 80513eb8 8055a6d0 bf997600 00000000 0000029b bf998310
bf997600为KeServiceDescriptorTableShadow函数表起始地址。 kd> dds bf997600 L0000029b bf997600 bf934ffe win32k!NtGdiAbortDoc bf997604 bf946a92 win32k!NtGdiAbortPath bf997608 bf8bf295 win32k!NtGdiAddFontResourceW … bf997de4 bf84d0ed win32k!NtUserSetCapture bf997de8 bf8fd95b win32k!NtUserSetClassLong bf997dec bf911a9e win32k!NtUserSetClassWord bf997df0 bf8cd389 win32k!NtUserSetClipboardData bf997df4 bf908b12 win32k!NtUserSetClipboardViewer bf997df8 bf8da65e win32k!NtUserSetConsoleReserveKeys bf997dfc bf81c4af win32k!NtUserSetCursor bf997e00 bf9120a0 win32k!NtUserSetCursorContents …
NtUserSetClipboardData的索引号是 (bf997df0 - bf997600) = 7f0