网上关于SSDT的有很多的博客可以参考,我就不啰嗦了直接上码
#include <ntddk.h>
//SSDT服务表中,各项对应的函数名称,@num 代表参数*4的大小
char* funcName[] = {
"NtAcceptConnectPort@24 ",
"NtAccessCheck@32 ",
"ZwAccessCheckAndAuditAlarm@44 ",
"NtAccessCheckByType@44 ",
"NtAccessCheckByTypeAndAuditAlarm@64 ",
"NtAccessCheckByTypeResultList@44 ",
"NtAccessCheckByTypeResultListAndAuditAla ",
"ZwAccessCheckByTypeResultListAndAuditAla ",
"NtAddAtom@12 ",
"ZwAddBootEntry@8 ",
"ZwAdjustGroupsToken@24 ",
"ZwAdjustPrivilegesToken@24 ",
"NtAlertResumeThread@8 ",
"NtAlertThread@4 ",
"ZwAllocateLocallyUniqueId@4 ",
"NtAllocateUserPhysicalPages@12 ",
"NtAllocateUuids@16 ",
"NtAllocateVirtualMemory@24 ",
"ZwAreMappedFilesTheSame@8 ",
"ZwAssignProcessToJobObject@8 ",
"ZwCallbackReturn@12 ",
"NtCancelDeviceWakeupRequest@4 ",
"ZwCancelIoFile@8 ",
"ZwCancelTimer@8 ",
"NtClearEvent@4 ",
"NtClose@4 ",
"ZwCloseObjectAuditAlarm@12 ",
"NtCompactKeys@8 ",
"ZwCompareTokens@12 ",
"NtCompleteConnectPort@4 ",
"ZwCompressKey@4 ",
"NtConnectPort@32 ",
"ZwContinue@8 ",
"ZwCreateDebugObject@16 ",
"ZwCreateDirectoryObject@12 ",
"NtCreateEvent@20 ",
"NtCreateEventPair@12 ",
"NtCreateFile@44 ",
"NtCreateIoCompletion@16 ",
"ZwCreateJobObject@12 ",
"NtCreateJobSet@12 ",
"ZwCreateKey@28 ",
"ZwCreateMailslotFile@32 ",
"ZwCreateMutant@16 ",
"ZwCreateNamedPipeFile@56 ",
"NtCreatePagingFile@16 ",
"ZwCreatePort@20 ",
"ZwCreateProcess@32 ",
"ZwCreateProcessEx@36 ",
"ZwCreateProfile@36 ",
"NtCreateSection@28 ",
"NtCreateSemaphore@20 ",
"ZwCreateSymbolicLinkObject@16 ",
"NtCreateThread@32 ",
"ZwCreateTimer@16 ",
"NtCreateToken@52 ",
"ZwCreateWaitablePort@20 ",
"NtDebugActiveProcess@8 ",
"ZwDebugContinue@12 ",
"ZwDelayExecution@8 ",
"ZwDeleteAtom@4 ",
"NtDeleteBootEntry@4 ",
"NtDeleteFile@4 ",
"ZwDeleteKey@4 ",
"NtDeleteObjectAuditAlarm@12 ",
"NtDeleteValueKey@8 ",
"ZwDeviceIoControlFile@40 ",
"NtDisplayString@4 ",
"ZwDuplicateObject@28 ",
"NtDuplicateToken@24 ",
"ZwEnumerateBootEntries@8 ",
"ZwEnumerateKey@24 ",
"ZwEnumerateSystemEnvironmentValuesEx@12 ",
"NtEnumerateValueKey@24 ",
"ZwExtendSection@8 ",
"NtFilterToken@24 ",
"NtFindAtom@12 ",
"ZwFlushBuffersFile@8 ",
"ZwFlushInstructionCache@12 ",
"NtFlushKey@4 ",
"ZwFlushVirtualMemory@16 ",
"NtFlushWriteBuffer@0 ",
"NtFreeUserPhysicalPages@12 ",
"NtFreeVirtualMemory@16 ",
"NtFsControlFile@40 ",
"NtGetContextThread@8 ",
"NtGetDevicePowerState@8 ",
"ZwGetPlugPlayEvent@16 ",
"NtGetWriteWatch@28 ",
"NtImpersonateAnonymousToken@4 ",
"ZwImpersonateClientOfPort@8 ",
"ZwImpersonateThread@12 ",
"ZwInitializeRegistry@4 ",
"NtInitiatePowerAction@16 ",
"ZwIsProcessInJob@8 ",
"NtIsSystemResumeAutomatic@0 ",
"ZwListenPort@8 ",
"NtLoadDriver@4 ",
"NtLoadKey@8 ",
"NtLoadKey2@12 ",
"NtLockFile@40 ",
"ZwLockProductActivationKeys@8 ",
"NtLockRegistryKey@4 ",
"ZwLockVirtualMemory@16 ",
"ZwMakePermanentObject@4 ",
"NtMakeTemporaryObject@4 ",
"NtMapUserPhysicalPages@12 ",
"ZwMapUserPhysicalPagesScatter@12 ",
"ZwMapViewOfSection@40 ",
"NtModifyBootEntry@4 ",
"NtNotifyChangeDirectoryFile@36 ",
"NtNotifyChangeKey@40 ",
"NtNotifyChangeMultipleKeys@48 ",
"ZwOpenDirectoryObject@12 ",
"NtOpenEvent@12 ",
"NtOpenEventPair@12 ",
"NtOpenFile@24 ",
"ZwOpenIoCompletion@12 ",
"ZwOpenJobObject@12 ",
"ZwOpenKey@12 ",
"NtOpenMutant@12 ",
"ZwOpenObjectAuditAlarm@48 ",
"ZwOpenProcess@16 ",
"ZwOpenProcessToken@12 ",
"ZwOpenProcessTokenEx@16 ",
"NtOpenSection@12 ",
"NtOpenSemaphore@12 ",
"NtOpenSymbolicLinkObject@12 ",
"ZwOpenThread@16 ",
"NtOpenThreadToken@16 ",
"NtOpenThreadTokenEx@20 ",
"ZwOpenTimer@12 ",
"NtPlugPlayControl@12 ",
"ZwPowerInformation@20 ",
"ZwPrivilegeCheck@12 ",
"ZwPrivilegeObjectAuditAlarm@24 ",
"NtPrivilegedServiceAuditAlarm@20 ",
"ZwProtectVirtualMemory@20 ",
"ZwPulseEvent@8 ",
"ZwQueryAttributesFile@8 ",
"ZwQueryBootEntryOrder@8 ",
"ZwQueryBootOptions@8 ",
"NtQueryDebugFilterState@8 ",
"NtQueryDefaultLocale@8 ",
"ZwQueryDefaultUILanguage@4 ",
"ZwQueryDirectoryFile@44 ",
"ZwQueryDirectoryObject@28 ",
"ZwQueryEaFile@36 ",
"NtQueryEvent@20 ",
"ZwQueryFullAttributesFile@8 ",
"NtQueryInformationAtom@20 ",
"ZwQueryInformationFile@20 ",
"ZwQueryInformationJobObject@20 ",
"ZwQueryInformationPort@20 ",
"ZwQueryInformationProcess@20 ",
"NtQueryInformationThread@20 ",
"ZwQueryInformationToken@20 ",
"NtQueryInstallUILanguage@4 ",
"NtQueryIntervalProfile@8 ",
"NtQueryIoCompletion@20 ",
"ZwQueryKey@20 ",
"NtQueryMultipleValueKey@24 ",
"NtQueryMutant@20 ",
"NtQueryObject@20 ",
"NtQueryOpenSubKeys@8 ",
"NtQueryPerformanceCounter@8 ",
"ZwQueryQuotaInformationFile@36 ",
"ZwQuerySection@20 ",
"NtQuerySecurityObject@20 ",
"ZwQuerySemaphore@20 ",
"ZwQuerySymbolicLinkObject@12 ",
"ZwQuerySystemEnvironmentValue@16 ",
"ZwQuerySystemEnvironmentValueEx@20 ",
"NtQuerySystemInformation@16 ",
"NtQuerySystemTime@4 ",
"ZwQueryTimer@20 ",
"NtQueryTimerResolution@12 ",
"ZwQueryValueKey@24 ",
"NtQueryVirtualMemory@24 ",
"NtQueryVolumeInformationFile@20 ",
"NtQueueApcThread@20 ",
"ZwRaiseException@12 ",
"ZwRaiseHardError@24 ",
"NtReadFile@36 ",
"NtReadFileScatter@36 ",
"ZwReadRequestData@24 ",
"NtReadVirtualMemory@20 ",
"ZwRegisterThreadTerminatePort@4 ",
"ZwReleaseMutant@8 ",
"NtReleaseSemaphore@12 ",
"ZwRemoveIoCompletion@20 ",
"ZwRemoveProcessDebug@8 ",
"ZwRenameKey@8 ",
"ZwReplaceKey@12 ",
"ZwReplyPort@8 ",
"NtReplyWaitReceivePort@16 ",
"NtReplyWaitReceivePortEx@20 ",
"NtReplyWaitReplyPort@8 ",
"ZwRequestDeviceWakeup@4 ",
"ZwRequestPort@8 ",
"NtRequestWaitReplyPort@12 ",
"ZwRequestWakeupLatency@4 ",
"NtResetEvent@8 ",
"ZwResetWriteWatch@12 ",
"NtRestoreKey@12 ",
"ZwResumeProcess@4 ",
"ZwResumeThread@8 ",
"NtSaveKey@8 ",
"NtSaveKeyEx@12 ",
"NtSaveMergedKeys@12 ",
"NtSecureConnectPort@36 ",
"ZwSetBootEntryOrder@8 ",
"ZwSetBootOptions@8 ",
"ZwSetContextThread@8 ",
"NtSetDebugFilterState@12 ",
"NtSetDefaultHardErrorPort@4 ",
"NtSetDefaultLocale@8 ",
"ZwSetDefaultUILanguage@4 ",
"ZwSetEaFile@16 ",
"NtSetEvent@8 ",
"NtSetEventBoostPriority@4 ",
"NtSetHighEventPair@4 ",
"NtSetHighWaitLowEventPair@4 ",
"ZwSetInformationDebugObject@20 ",
"ZwSetInformationFile@20 ",
"ZwSetInformationJobObject@16 ",
"ZwSetInformationKey@16 ",
"ZwSetInformationObject@16 ",
"ZwSetInformationProcess@16 ",
"ZwSetInformationThread@16 ",
"ZwSetInformationToken@16 ",
"NtSetIntervalProfile@8 ",
"NtSetIoCompletion@20 ",
"ZwSetLdtEntries@24 ",
"ZwSetLowEventPair@4 ",
"ZwSetLowWaitHighEventPair@4 ",
"ZwSetQuotaInformationFile@16 ",
"NtSetSecurityObject@12 ",
"ZwSetSystemEnvironmentValue@8 ",
"ZwSetSystemEnvironmentValueEx@20 ",
"ZwSetSystemInformation@12 ",
"ZwSetSystemPowerState@12 ",
"ZwSetSystemTime@8 ",
"ZwSetThreadExecutionState@8 ",
"ZwSetTimer@28 ",
"NtSetTimerResolution@12 ",
"ZwSetUuidSeed@4 ",
"ZwSetValueKey@24 ",
"NtSetVolumeInformationFile@20 ",
"ZwShutdownSystem@4 ",
"ZwSignalAndWaitForSingleObject@16 ",
"NtStartProfile@4 ",
"ZwStopProfile@4 ",
"ZwSuspendProcess@4 ",
"ZwSuspendThread@8 ",
"NtSystemDebugControl@24 ",
"ZwTerminateJobObject@8 ",
"ZwTerminateProcess@8 ",
"ZwTerminateThread@8 ",
"NtTestAlert@0 ",
"NtTraceEvent@16 ",
"NtTranslateFilePath@16 ",
"ZwUnloadDriver@4 ",
"NtUnloadKey@4 ",
"ZwUnloadKeyEx@8 ",
"ZwUnlockFile@20 ",
"NtUnlockVirtualMemory@16 ",
"NtUnmapViewOfSection@8 ",
"NtVdmControl@8 ",
"NtWaitForDebugEvent@16 ",
"NtWaitForMultipleObjects@20 ",
"ZwWaitForSingleObject@12 ",
"ZwWaitHighEventPair@4 ",
"NtWaitLowEventPair@4 ",
"NtWriteFile@36 ",
"NtWriteFileGather@36 ",
"NtWriteRequestData@24 ",
"NtWriteVirtualMemory@20 ",
"ZwYieldExecution@0 ",
"ZwCreateKeyedEvent@16 ",
"NtOpenKeyedEvent@12 ",
"NtReleaseKeyedEvent@16 ",
"NtWaitForKeyedEvent@16 ",
"ZwQueryPortInformationProcess@0 ",
};
typedef struct _KSYSTEM_SERVICE_TABLE{
PULONG ServiceTableBase;
ULONG counter;
ULONG numberOfService;
PULONG paramTableBase;
}KSYSTEM_SERVICE_TABLE, *PKSYSTEM_SERVICE_TABLE;
typedef struct _KSERVICE_TABLE_DESCRIPTOR{
KSYSTEM_SERVICE_TABLE ntoskrnl;
KSYSTEM_SERVICE_TABLE win32k;
KSYSTEM_SERVICE_TABLE notUsed1;
KSYSTEM_SERVICE_TABLE notUsed2;
}KSERVICE_TABLE_DESCRIPTOR, *PKSERVICE_TABLE_DESCRIPTOR;
//内核导出KeServiceDescriptorTable指针,结构如上,
extern PKSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTable;
//用于枚举内核模块所用的结构体
typedef struct _LDR_DATA_TABLE_ENTRY{
LIST_ENTRY InLoadOrderLinks; //+0x000 InLoadOrderLinks : _LIST_ENTRY
LIST_ENTRY InMemoryOrderLinks; //+ 0x008 InMemoryOrderLinks : _LIST_ENTRY
LIST_ENTRY InInitializationOrderLinks; //+ 0x010 InInitializationOrderLinks : _LIST_ENTRY
ULONG DllBase; //+ 0x018 DllBase : Ptr32 Void
ULONG EntryPoint; //+ 0x01c EntryPoint : Ptr32 Void
ULONG SizeOfImage; //+ 0x020 SizeOfImage : Uint4B
UNICODE_STRING FullDllName; //+ 0x024 FullDllName : _UNICODE_STRING
UNICODE_STRING BaseDllName; //+ 0x02c BaseDllName : _UNICODE_STRING
ULONG Flags; //+ 0x034 Flags : Uint4B
USHORT LoadCount; //+ 0x038 LoadCount : Uint2B
USHORT TlsIndex; //+ 0x03a TlsIndex : Uint2B
LIST_ENTRY HashLinks; //+ 0x03c HashLinks : _LIST_ENTRY
ULONG SectionPointer; //+ 0x03c SectionPointer : Ptr32 Void
ULONG CheckSum; //+ 0x040 CheckSum : Uint4B
ULONG TimeDateStamp; //+ 0x044 TimeDateStamp : Uint4B
ULONG LoadedImports; //+ 0x044 LoadedImports : Ptr32 Void
ULONG EntryPointActivationContext;//+ 0x048 EntryPointActivationContext : Ptr32 Void
ULONG PatchInformation; //+ 0x04c PatchInformation : Ptr32 Void
}LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
//显示给定地址所在的内核模块,返回该模块的PUNICODE_STRING形式的 名称
PUNICODE_STRING FindKernelModule(PDRIVER_OBJECT pDriverObj, ULONG funcAddr){
PLDR_DATA_TABLE_ENTRY p = (PLDR_DATA_TABLE_ENTRY)pDriverObj->DriverSection;
PLIST_ENTRY pList, pStartList;
pList = pStartList = (PLIST_ENTRY)p;
do{
p = (PLDR_DATA_TABLE_ENTRY)pList;
if (p->DllBase != 0){//排除模块链表头,windbg中观察头部,此为0
if (p->DllBase <= funcAddr
&&
(p->DllBase + p->SizeOfImage) > funcAddr){
return &p->BaseDllName;
}
}
pList = pList->Flink;
} while (pList != pStartList);
return NULL;
}
VOID DriverUnload(PDRIVER_OBJECT pDriverObj){
return;
}
//DbgView中打印SSDT系统服务表中数据
VOID ShowNtoskrnlSSDTFunc(PDRIVER_OBJECT pDriverObj){
KSYSTEM_SERVICE_TABLE p = KeServiceDescriptorTable->ntoskrnl;
PULONG funcArray = (PULONG)p.ServiceTableBase;
UINT32 index = 0;
while (index<p.numberOfService){
KdPrint(("[%d]%s: 0X%08X module :%wZ\n", index,
funcName[index], funcArray[index], FindKernelModule(pDriverObj, funcArray[index])));
index++;
}
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegPath){
pDriverObj->DriverUnload = DriverUnload;
ShowNtoskrnlSSDTFunc(pDriverObj);
return STATUS_SUCCESS;
}
为什么还有这篇的存在呢?只为总结下一些资料容易忽略掉的2个方面,方便今后查阅:
【1】
typedef struct _KSYSTEM_SERVICE_TABLE{
PULONG ServiceTableBase;
ULONG counter;
ULONG numberOfService;
PULONG paramTableBase;
}KSYSTEM_SERVICE_TABLE, *PKSYSTEM_SERVICE_TABLE;
typedef struct _KSERVICE_TABLE_DESCRIPTOR{
KSYSTEM_SERVICE_TABLE ntoskrnl;
KSYSTEM_SERVICE_TABLE win32k;
KSYSTEM_SERVICE_TABLE notUsed1;
KSYSTEM_SERVICE_TABLE notUsed2;
}KSERVICE_TABLE_DESCRIPTOR, *PKSERVICE_TABLE_DESCRIPTOR;
//内核导出KeServiceDescriptorTable指针,结构如上,
extern PKSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTable;
因为KeServiceDescriptorTableShaddow也是同样 64BYTE 大小的结构体的指针,只不过,它没有被导出,而KeServiceDescriptorTable被ntoskrnl.exe导出了
【2】
ServiceTableBase指向的地址是传说中的SSDT服务函数的地址,那么,地址和服务函数名称是如何做到的呢?
这个是本篇的关键
【正文】
ntdll.dll 中有这些服务函数的桩函数,形式如下
mov eax, INDEX
mov edx, 7FFE0300h
call dword ptr [edx]
下两句都是重复的,用ida BYTE序列搜索 对应的 16进制 BA 00 03 FE 7F FF 12
PCHunter上的数据
经过对比发现,搜索得到的桩函数,是一句 INDEX 从小到大 逐一增加 排布的,这样就可以直接在IDA 上复制粘贴了,而不用苦逼的手打了。。。
附加:Shaddow SSDT中的名称如何得到?
如此,上述搜索,SSDT只有284项目,(32BIT-XP SP3),而有 Shaddow SSDT 上667项目(PCHunter上显示),你可能听说过KERNEL32.dll的函数走ntdll.dll,而USER32.dll, GDI32.dll 直接与win32K.sys通信,那么按照之前的序列搜索,USER32.DLL 和 GDI32.dll 你可能 发现数量对不上,而且,都错号的,难不成要我,一个一个的手打?还要忍受数量不齐(约差 3,40个 ),有什么办法,得到,这些服务的名称呢?
用IDA 加载 WIN32.sys并 链接到 微软符号服务器上,文本搜索 W32pServiceTable
根据偏移算算个数 (C6EC-BC80)/4 = 667 ,项目和PCHUnter中一样