哇,看到很多人找SSDT/SSSDT名称很蛋疼,读ntdll啊什么的,最后index还很乱,github上也有相关的工具,关键字是syscall,也是用ntdll的方式..
这里科普下吧
以win10为例
x86下
找到ssdt表很简单,ida打开找到后交叉下 会找到KiInitSystem
INIT:00998E8E A3 48 93 64 00 mov ds:dword_649348, eax
INIT:00998E93 B8 40 93 64 00 mov eax, offset _KeServiceDescriptorTable
INIT:00998E98 59 pop ecx
INIT:00998E99 6A 08 push 8
INIT:00998E9B C7 05 40 93 64 00 B0 73 52 00 mov ds:_KeServiceDescriptorTable, offset _KiServiceTable
INIT:00998EA5 8B F0 mov esi, eax
INIT:00998EA7 C7 05 4C 93 64 00 BC 7A 52 00 mov ds:dword_64934C, offset _KiArgumentTable
INIT:00998EB1 89 1D 58 93 64 00 mov ds:dword_649358, ebx
INIT:00998EB7 F3 A5 rep movsd
INIT:00998EB9 59 pop ecx
INIT:00998EBA 8B F0 mov esi, eax
看下KiServiceTable 哇,这不就是名字吗,index都给我们摆好了~
.text:005273B0 6C 1B 47 00 _KiServiceTable dd offset _NtAccessCheck@32
.text:005273B0 ; DATA XREF: KiInitSystem
()+9Do
.text:005273B0 ; NtAccessCheck
(x,x,x,x,x,x,x,x)
.text:005273B4 04 E8 4D 00 dd offset _NtWorkerFactoryWorkerReady@4 ;
NtWorkerFactoryWorkerReady(x)
.text:005273B8 32 AF 74 00 dd offset _NtAcceptConnectPort@24 ;
NtAcceptConnectPort(x,x,x,x,x,x)
.text:005273BC D0 1C 43 00 dd offset _NtYieldExecution@0 ; NtYieldExecution()
.text:005273C0 EA 30 71 00 dd offset _NtWriteVirtualMemory@20 ;
NtWriteVirtualMemory(x,x,x,x,x)
.text:005273C4 68 6F 88 00 dd offset _NtWriteRequestData@24 ;
NtWriteRequestData(x,x,x,x,x,x)
.text:005273C8 6A 36 73 00 dd offset _NtWriteFileGather@36 ; NtWriteFileGather
(x,x,x,x,x,x,x,x,x)
.text:005273CC 10 7F 71 00 dd offset _NtWriteFile@36 ; NtWriteFile
(x,x,x,x,x,x,x,x,x)
.text:005273D0 86 8E 7A 00 dd offset _NtSetHighWaitLowEventPair@4 ;
NtSetHighWaitLowEventPair(x)
.text:005273D4 86 8E 7A 00 dd offset _NtSetHighWaitLowEventPair@4 ;
NtSetHighWaitLowEventPair(x)
.text:005273D8 50 BD 44 00 dd offset _NtWaitForWorkViaWorkerFactory@20 ;
NtWaitForWorkViaWorkerFactory(x,x,x,x,x)
.text:005273DC 20 0D 6A 00 dd offset _NtWaitForSingleObject@12 ;
NtWaitForSingleObject(x,x,x)
.text:005273E0 F9 59 89 00 dd offset _NtWaitForMultipleObjects32@20 ;
NtWaitForMultipleObjects32(x,x,x,x,x)
.text:005273E4 00 B7 69 00 dd offset _NtWaitForMultipleObjects@20 ;
NtWaitForMultipleObjects(x,x,x,x,x)
.text:005273E8 54 D9 74 00 dd offset _NtWaitForKeyedEvent@16 ;
NtWaitForKeyedEvent(x,x,x,x)
.text:005273EC E3 69 85 00 dd offset _NtWaitForDebugEvent@16 ;
NtWaitForDebugEvent(x,x,x,x)
.text:005273F0 98 21 73 00 dd offset _NtWaitForAlertByThreadId@8 ;
NtWaitForAlertByThreadId(x,x)
.text:005273F4 90 49 8C 00 dd offset _NtVdmControl@8 ; NtVdmControl(x,x)
.text:005273F8 2C 50 73 00 dd offset _NtUnsubscribeWnfStateChange@4 ;
NtUnsubscribeWnfStateChange(x)
.text:005273FC 6A 8C 70 00 dd offset _NtUpdateWnfStateData@28 ;
NtUpdateWnfStateData(x,x,x,x,x,x,x)
.text:00527400 76 49 71 00 dd offset _NtUnmapViewOfSection@8 ;
NtUnmapViewOfSection(x,x)
.text:00527404 B0 4C 71 00 dd offset _NtUnmapViewOfSectionEx@12 ;
NtUnmapViewOfSectionEx(x,x,x)
.text:00527408 80 0D 49 00 dd offset _NtUnlockVirtualMemory@16 ;
NtUnlockVirtualMemory(x,x,x,x)
.text:0052740C E2 AC 73 00 dd offset _NtUnlockFile@20 ; NtUnlockFile(x,x,x,x,x)
.text:00527410 DC 99 6F 00 dd offset _NtUnloadKeyEx@8 ; NtUnloadKeyEx(x,x)
.text:00527414 A2 80 77 00 dd offset _NtUnloadKey2@8 ; NtUnloadKey2(x,x)
.text:00527418 DA 89 7A 00 dd offset _NtUnloadKey@4 ; NtUnloadKey(x)
.text:0052741C 4C 2B 86 00 dd offset _NtUnloadDriver@4 ; NtUnloadDriver(x)
.text:00527420 61 4C 88 00 dd offset _NtUmsThreadYield@4 ; NtUmsThreadYield(x)
.text:00527424 FE EC 8D 00 dd offset _NtTranslateFilePath@16 ;
NtTranslateFilePath(x,x,x,x)
.text:00527428 80 0B 43 00 dd offset _NtTraceEvent@16 ; NtTraceEvent(x,x,x,x)
.text:0052742C 30 28 69 00 dd offset _NtTraceControl@24 ; NtTraceControl
(x,x,x,x,x,x)
.text:00527430 62 28 42 00 dd offset _NtThawTransactions@0 ; NtThawTransactions
()
.text:00527434 8D E4 58 00 dd offset _NtThawRegistry@0 ; NtThawRegistry()
看下KiArgumentTable ,跟函数的参数个数对一下~哇
text:00527ABC 20 _KiArgumentTable db 20h ; DATA XREF: KiInitSystem
()+A9o
.text:00527ABD 04 db 4
.text:00527ABE 18 db 18h
.text:00527ABF 00 db 0
.text:00527AC0 14 db 14h
.text:00527AC1 18 db 18h
.text:00527AC2 24 db 24h
.text:00527AC3 24 db 24h ; $
.text:00527AC4 04 db 4
.text:00527AC5 04 db 4
.text:00527AC6 14 db 14h
.text:00527AC7 0C db 0Ch
.text:00527AC8 14 db 14h
.text:00527AC9 14 db 14h
.text:00527ACA 10 db 10h
.text:00527ACB 10 db 10h
.text:00527ACC 08 db 8
.text:00527ACD 08 db 8
.text:00527ACE 04 db 4
.text:00527ACF 1C db 1Ch
.text:00527AD0 08 db 8
.text:00527AD1 0C db 0Ch
x86 win32k
找到W32pServiceTable
.data:00030000 _W32pServiceTable dd offset _NtUserGetOwnerTransformedMonitorRect@16
.data:00030000 ; DATA XREF: SysEntryGetW32pServiceTable()o
.data:00030000 ; NtUserGetOwnerTransformedMonitorRect(x,x,x,x)
.data:00030004 dd offset _NtUserYieldTask@0 ; NtUserYieldTask()
.data:00030008 dd offset _NtUserSetSensorPresence@4 ; NtUserSetSensorPresence(x)
.data:0003000C dd offset _NtGdiWidenPath@4 ; NtGdiWidenPath(x)
.data:00030010 dd offset _NtGdiUpdateColors@4 ; NtGdiUpdateColors(x)
.data:00030014 dd offset _NtGdiUnrealizeObject@4 ; NtGdiUnrealizeObject(x)
.data:00030018 dd offset _NtGdiUnmapMemFont@4 ; NtGdiUnmapMemFont(x)
.data:0003001C dd offset _NtGdiUnloadPrinterDriver@8 ; NtGdiUnloadPrinterDriver(x,x)
.data:00030020 dd offset _NtGdiTransparentBlt@44 ; NtGdiTransparentBlt(x,x,x,x,x,x,x,x,x,x,x)
.data:00030024 dd offset _NtGdiTransformPoints@20 ; NtGdiTransformPoints(x,x,x,x,x)
.data:00030028 dd offset _NtGdiScaleRgn@8 ; NtGdiScaleRgn(x,x)
.data:0003002C dd offset _NtGdiScaleValues@12 ; NtGdiScaleValues(x,x,x)
.data:00030030 dd offset _NtGdiGetDCDpiScaleValue@4 ; NtGdiGetDCDpiScaleValue(x)
.data:00030034 dd offset _NtGdiGetBitmapDpiScaleValue@4 ; NtGdiGetBitmapDpiScaleValue(x)
.data:00030038 dd offset _NtGdiSwapBuffers@4 ; NtGdiSwapBuffers(x)
.data:0003003C dd offset _NtGdiStrokePath@4 ; NtGdiStrokePath(x)
.data:00030040 dd offset _NtGdiStrokeAndFillPath@4 ; NtGdiStrokeAndFillPath(x)
.data:00030044 dd offset _NtGdiStretchDIBitsInternal@64 ; NtGdiStretchDIBitsInternal
(x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x)
.data:00030048 dd offset _NtGdiStretchBlt@48 ; NtGdiStretchBlt(x,x,x,x,x,x,x,x,x,x,x,x)
.data:0003004C dd offset _NtGdiStartPage@4 ; NtGdiStartPage(x)
.data:00030050 dd offset _NtGdiStartDoc@16 ; NtGdiStartDoc(x,x,x,x)
.data:00030054 dd offset _NtGdiSetSizeDevice@12 ; NtGdiSetSizeDevice(x,x,x)
.data:00030058 dd offset _NtGdiSetVirtualResolution@20 ; NtGdiSetVirtualResolution(x,x,x,x,x)
W32pArgumentTable:
.data:00031628 _W32pArgumentTable db 10h ; DATA XREF: SysEntryGetW32pArgumentTable()o
.data:00031629 db 0
.data:0003162A db 4
.data:0003162B db 4
.data:0003162C db 4
.data:0003162D db 4
.data:0003162E db 4
.data:0003162F db 8
.data:00031630 db 2Ch
.data:00031631 db 14h
.data:00031632 db 8
.data:00031633 db 0Ch
.data:00031634 db 4
.data:00031635 db 4
.data:00031636 db 4
.data:00031637 db 4
.data:00031638 db 4
.data:00031639 db 40h ; @
.data:0003163A db 30h ; 0
.data:0003163B db 4
.data:0003163C db 10h
.data:0003163D db 0Ch
x64下:
KiInitSystem:
INIT:000000014075DC47 mov cs:KiSwapEvent.Header.WaitListHead.Flink, rax
INIT:000000014075DC4E lea rax, KiServiceTable
INIT:000000014075DC55 mov qword ptr cs:KeServiceDescriptorTable, rax
INIT:000000014075DC5C mov eax, cs:KiServiceLimit
INIT:000000014075DC62 movaps xmm0, cs:KeServiceDescriptorTable
INIT:000000014075DC69 mov cs:dword_14037F790, eax
INIT:000000014075DC6F lea rax, KiArgumentTable
INIT:000000014075DC76 mov cs:qword_14037F798, rax
INIT:000000014075DC7D lea rax, KiBalanceSetManagerDeferredRoutine
INIT:000000014075DC84 movaps xmm1, xmmword ptr cs:dword_14037F790
KiServiceTable:
.rdata:00000001402C2310 KiServiceTable dq offset NtAccessCheck ; DATA XREF: KiInitializeKernel+5F1o
.rdata:00000001402C2310 ; KiInitSystem+BEo
.rdata:00000001402C2318 dq offset NtWorkerFactoryWorkerReady
.rdata:00000001402C2320 dq offset NtAcceptConnectPort
.rdata:00000001402C2328 dq offset NtMapUserPhysicalPagesScatter
.rdata:00000001402C2330 dq offset NtWaitForSingleObject
.rdata:00000001402C2338 dq offset NtCallbackReturn
.rdata:00000001402C2340 dq offset NtReadFile
.rdata:00000001402C2348 dq offset NtDeviceIoControlFile
.rdata:00000001402C2350 dq offset NtWriteFile
.rdata:00000001402C2358 dq offset NtRemoveIoCompletion
.rdata:00000001402C2360 dq offset NtReleaseSemaphore
.rdata:00000001402C2368 dq offset NtReplyWaitReceivePort
.rdata:00000001402C2370 dq offset NtReplyPort
.rdata:00000001402C2378 dq offset NtSetInformationThread
.rdata:00000001402C2380 dq offset NtSetEvent
.rdata:00000001402C2388 dq offset NtClose
.rdata:00000001402C2390 dq offset NtQueryObject
.rdata:00000001402C2398 dq offset NtQueryInformationFile
.rdata:00000001402C23A0 dq offset NtOpenKey
.rdata:00000001402C23A8 dq offset NtEnumerateValueKey
.rdata:00000001402C23B0 dq offset NtFindAtom
.rdata:00000001402C23B8 dq offset NtQueryDefaultLocale
.rdata:00000001402C23C0 dq offset NtQueryKey
.rdata:00000001402C23C8 dq offset NtQueryValueKey
KiArgumentTable
.rdata:00000001402C30F4 KiArgumentTable db 10h ; DATA XREF: KiInitializeKernel+5EAo
.rdata:00000001402C30F4 ; KiInitSystem+DFo
.rdata:00000001402C30F5 db 0
.rdata:00000001402C30F6 db 8
.rdata:00000001402C30F7 db 0
.rdata:00000001402C30F8 db 0
.rdata:00000001402C30F9 db 0
.rdata:00000001402C30FA db 14h
.rdata:00000001402C30FB db 18h
.rdata:00000001402C30FC db 14h
.rdata:00000001402C30FD db 4
.rdata:00000001402C30FE db 0
.rdata:00000001402C30FF db 0
.rdata:00000001402C3100 db 0
.rdata:00000001402C3101 db 0
.rdata:00000001402C3102 db 0
.rdata:00000001402C3103 db 0
.rdata:00000001402C3104 db 4
.rdata:00000001402C3105 db 4
.rdata:00000001402C3106 db 0
.rdata:00000001402C3107 db 8
.rdata:00000001402C3108 db 0
#pragma pack(1) //SSDT表的结构
typedef struct ServiceDescriptorEntry {
// SSDT
unsigned int *ServiceTableBase;
unsigned int *ServiceCounterTableBase; //Used only in checked build
unsigned int NumberOfServices; //ServiceLimit
unsigned char *ParamTableBase; //SSPT
/*
SSSDT....
*/
} ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;
#pragma pack()
for (i = 0; i< SSDT_FUNC_COUNT; i++)
{
g_aCurrentKiServiceTable[i] = ((PULONG)(pServiceTable[0]))[i];
//获得ssdt 参数个数
g_KiArgumentTable[i] = ( ((BYTE *)(pServiceTable[0+3]))[i] ) / 4;
}
ULONG j;
for (j = 0; j < SSDTSHADOW_FUNC_COUNT; j++)
{
g_aCurrentW32pServiceTable[j] = ((PULONG)(pServiceTable[4]))[j];
//获得shadow 参数个数
g_W32pArgumentTable[j] = ( ((BYTE *)(pServiceTable[4+3]))[j] ) / 4;
}
KeUnstackDetachProcess(&sExplorerApcState);
//获得ssdt的地址 获得ssdtshadow的地址
g_dwKiServiceTable = pServiceTable[0];
g_dwW32pServiceTable = pServiceTable[4];