驱动开发笔记3—SSDT表详解

SSDT表

SSDT的全称是"System Services Descriptor Table",即系统服务描述表,在内核中的实际名称是KeServiceDescriptorTable,这个表由ntoskrnl.exe导出(在x64里不导出)。

SSDT用于处理应用层通过Kernel32.dll下发的各个API操作请求。ntdll.dll中的API是一个简单的包装函数,当Kernel32.dll中的API通过Ntdll.dll时,会先完成对参数的检查,再调用一个中断(int 2Eh 或者 SysEnter指令),从而实现从Ring3层进入Ring0层,并将要调用的服务号(也就是SSDT数组中的索引号index值)存放到寄存器EAX中,最后根据存放在EAX中的索引值在SSDT数组中调用指定的服务(Nt系列函数)。
在这里插入图片描述

KeServiceDescriptorTable变量是在NTOS模块中导出的一个全局变量,声明一下就可以用
3: kd> dd KeServiceDescriptorTable
849acb00 848c143c 00000000 00000191 848c1a84
(其中,848c143c就是SSDT表的基地址,00000191是SSDT表中服务函数的个数)

extern PSYSTEM_SERVICE_DESCRIPTOR_TABLE	KeServiceDescriptorTable;

typedef struct _SYSTEM_SERVICE_DESCRIPTOR_TABLE
{
    
    
	PVOID		ServiceTableBase;			//SSDT表的基地址
	PVOID		ServiceCounterTableBase;
	ULONG_PTR	NumberOfServices;			//SSDT表中服务函数的个数
	PVOID		ParameterTableBase;
}SYSTEM_SERVICE_DESCRIPTOR_TABLE, *PSYSTEM_SERVICE_DESCRIPTOR_TABLE;

知道了SSDT表的基地址(数组的首地址)和SSDT函数的索引号(Index),就可以求出对应的服务函数的地址。
在x86平台上: FuncAddress = KeServiceDescriptorTable + 4 * Index
在x64平台上:FuncAddress = [KeServiceDescriptorTable+4*Index]>>4 + KeServiceDescriptorTable
在这里插入图片描述

获得SSDT表中Nt函数索引的方法:

先获得Zw函数的地址,然后加一个字节得到Nt函数的索引
注意:
ntkrnlpa.exe的物理内存是映射到Ring0层内存空间的,和我们的进程(xxx.sys)是在一片内存空间中,因此可以直接访问。
ntdll.dll的物理内存是映射在Ring3层内存空间的(映射到每一个应用程序的内存中),我们的进程(xxx.sys)若想要访问ntdll.dll的数据,需要先把它的物理内存映射到自己(xxx.sys)的内存空间,然后才能访问。

1. 直接访问ntkrnlpa.exe中的SSDT表

UNICODE_STRING v1;
RtlInitUnicodeString(&v1, L"ZwOpenProcess");
ZwOpenProcess = MmGetSystemRoutineAddress(&v1);

#define SSDT_INDEX(ZwFunctionAddress)	*(PULONG)(ZwFunctionAddress + 1)
/*
	3: kd> u ZwOpenProcess
	nt!ZwOpenProcess:
	8487ecd8  b8be000000      mov     eax,0BEh

	3: kd> dd 8487ecd8
	8487ecd8  0000beb8 24548d00 086a9c04 0019d5e8

	3: kd> dd 8487ecd9
	8487ecd9  000000be 0424548d e8086a9c 000019d5

*/
//ZwFunctionAddress + 1,加一个字节,越过那个b8,就能得到索引

2. 通过访问Ntdll.dll模块的导出表
首先通过Ntdll.dll的路径获得文件句柄,然后通过文件句柄获得映射句柄,然后映射Ntdll.dll物理内存到当前进程的内存空间,得到映射内存的首地址和映射内存大小。
通过模块基地址,访问ntdll.dll模块的导出表,利用那三个数组,来获得Zw函数地址,最后加一个字节得到Nt函数索引。

NTSTATUS MyGetSSDTFunctionIndex(char* ZwFunctionName, ULONG* NtFunctionIndex)
{
    
    
	NTSTATUS Status = STATUS_UNSUCCESSFUL;
	WCHAR FileFullPath[] = L"\\SystemRoot\\System32\\ntdll.dll";
	PVOID MappedFileVA = NULL;
	ULONG MappedFileSize = 0;
	PIMAGE_NT_HEADERS ImageNtHeaders = NULL;
	PIMAGE_EXPORT_DIRECTORY ImageExportDirectory = NULL;
	ULONG* AddressOfFunctions = NULL;
	ULONG* AddressOfNames = NULL;
	USHORT* AddressOfNameOrdinals = NULL;
	ULONG i = 0;
	char* FunctionName = NULL;
	PUCHAR FunctionAddress = NULL;
	ULONG Offset = 1;

	if (!ZwFunctionName)
	{
    
    
		return Status;
	}
	//将Ntdll.dll文件映射到系统空间中
	if (!NT_SUCCESS(MyMappingPEFileInRing0Space(FileFullPath, &MappedFileVA, &MappedFileSize)))
	{
    
    
		return Status;
	}
	__try
	{
    
    
		//通过Dos头获得Nt头
		ImageNtHeaders = RtlImageNtHeader(MappedFileVA);
		if (ImageNtHeaders && ImageNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress)
		{
    
    
			ImageExportDirectory = (IMAGE_EXPORT_DIRECTORY*)((ULONG_PTR)MappedFileVA + 
				ImageNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);

			AddressOfFunctions = (ULONG*)((ULONG_PTR)MappedFileVA + ImageExportDirectory->AddressOfFunctions);
			AddressOfNames = (ULONG*)((ULONG_PTR)MappedFileVA + ImageExportDirectory->AddressOfNames);
			AddressOfNameOrdinals = (USHORT*)((ULONG_PTR)MappedFileVA + ImageExportDirectory->AddressOfNameOrdinals);

			for (i = 0; i < ImageExportDirectory->NumberOfNames; i++)
			{
    
    
				FunctionName = (char*)((ULONG_PTR)MappedFileVA + AddressOfNames[i]);
				if (!_stricmp(FunctionName, ZwFunctionName))
				{
    
    
					FunctionAddress = (PUCHAR)((ULONG_PTR)MappedFileVA + AddressOfFunctions[AddressOfNameOrdinals[i]]);
					*NtFunctionIndex = *(ULONG*)(FunctionAddress + 1);	//加1个字节,即越过b8,得到索引be000000
					Status = STATUS_SUCCESS;
					break;
				}	
			}
		}
	}
	__except (EXCEPTION_EXECUTE_HANDLER)
	{
    
    

	}
	//回收内存
	ZwUnmapViewOfSection(NtCurrentProcess(), MappedFileVA);
	if (*NtFunctionIndex == -1)
	{
    
    
		return STATUS_UNSUCCESSFUL;
	}
	return Status;
}
NTSTATUS MyMappingPEFileInRing0Space(WCHAR* FileFullPath, PVOID* MappedFileVA, ULONG* MappedFileSize)
{
    
    
	NTSTATUS Status = STATUS_UNSUCCESSFUL;
	UNICODE_STRING v1;
	OBJECT_ATTRIBUTES ObjectAttributes;
	IO_STATUS_BLOCK IoStatusBlock;
	HANDLE FileHandle = NULL;
	HANDLE SectionHandle = NULL;
	if (!FileFullPath || !MappedFileVA)
	{
    
    
		return Status;
	}
	RtlInitUnicodeString(&v1, FileFullPath);
	InitializeObjectAttributes(&ObjectAttributes, &v1, 
		OBJ_CASE_INSENSITIVE, NULL, NULL);	 //OBJ_CASE_INSENSITIVE表示忽略大小写
	
	//获得文件句柄
	Status = ZwCreateFile(&FileHandle,
		SYNCHRONIZE,
		&ObjectAttributes,
		&IoStatusBlock,
		NULL,
		FILE_ATTRIBUTE_NORMAL,
		FILE_SHARE_READ,
		FILE_OPEN,
		FILE_SYNCHRONOUS_IO_NONALERT,
		NULL,
		0);
	if (!NT_SUCCESS(Status))
	{
    
    
		return Status;
	}

	//通过文件句柄创建一个映射对象
	ObjectAttributes.ObjectName = NULL;
	Status = ZwCreateSection(&SectionHandle,
		SECTION_QUERY | SECTION_MAP_READ,
		&ObjectAttributes,
		NULL,
		PAGE_WRITECOPY,	//写拷贝
		SEC_IMAGE,		//内存对齐
		FileHandle);
	ZwClose(FileHandle);
	if (!NT_SUCCESS(Status))
	{
    
    
		return Status;
	}

	//通过映射句柄获得虚拟地址空间
	Status = ZwMapViewOfSection(SectionHandle,
		NtCurrentProcess(),	//映射到当前进程的内存空间中
		MappedFileVA,
		0, 0, 0,
		MappedFileSize,
		ViewUnmap, 0, 
		PAGE_WRITECOPY);
	ZwClose(SectionHandle);
	if (!NT_SUCCESS(Status))
	{
    
    
		return Status;
	}
	return Status;
}

SSDT表中的函数列表

SSDT表中共有0x191个函数,分别是:

NtAcceptConnectPort
NtAccessCheck
NtAccessCheckAndAuditAlarm
NtAccessCheckByType
NtAccessCheckByTypeAndAuditAlarm
NtAccessCheckByTypeResultList
NtAccessCheckByTypeResultListAndAuditAlarm
NtAccessCheckByTypeResultListAndAuditAlarmByHandle
NtAddAtom
NtAddBootEntry
NtAddDriverEntry
NtAdjustGroupsToken
NtAdjustPrivilegesToken
NtAlertResumeThread
NtAlertThread
NtAllocateLocallyUniqueId
NtAllocateReserveObject
NtAllocateUserPhysicalPages
NtAllocateUuids
NtAllocateVirtualMemory
NtAlpcAcceptConnectPort
NtAlpcCancelMessage
NtAlpcConnectPort
NtAlpcCreatePort
NtAlpcCreatePortSection
NtAlpcCreateResourceReserve
NtAlpcCreateSectionView
NtAlpcCreateSecurityContext
NtAlpcDeletePortSection
NtAlpcDeleteResourceReserve
NtAlpcDeleteSectionView
NtAlpcDeleteSecurityContext
NtAlpcDisconnectPort
NtAlpcImpersonateClientOfPort
NtAlpcOpenSenderProcess
NtAlpcOpenSenderThread
NtAlpcQueryInformation
NtAlpcQueryInformationMessage
NtAlpcRevokeSecurityContext
NtAlpcSendWaitReceivePort
NtAlpcSetInformation
NtApphelpCacheControl
NtAreMappedFilesTheSame
NtAssignProcessToJobObject
NtCallbackReturn
NtCancelIoFile
NtCancelIoFileEx
NtCancelSynchronousIoFile
NtCancelTimer
NtClearEvent
NtClose
NtCloseObjectAuditAlarm
NtCommitComplete
NtCommitEnlistment
NtCommitTransaction
NtCompactKeys
NtCompareTokens
NtCompleteConnectPort
NtCompressKey
NtConnectPort
NtContinue
NtCreateDebugObject
NtCreateDirectoryObject
NtCreateEnlistment
NtCreateEvent
NtCreateEventPair
NtCreateFile
NtCreateIoCompletion
NtCreateJobObject
NtCreateJobSet
NtCreateKey
NtCreateKeyedEvent
NtCreateKeyTransacted
NtCreateMailslotFile
NtCreateMutant
NtCreateNamedPipeFile
NtCreatePagingFile
NtCreatePort
NtCreatePrivateNamespace
NtCreateProcess
NtCreateProcessEx
NtCreateProfile
NtCreateProfileEx
NtCreateResourceManager
NtCreateSection
NtCreateSemaphore
NtCreateSymbolicLinkObject
NtCreateThread
NtCreateThreadEx
NtCreateTimer
NtCreateToken
NtCreateTransaction
NtCreateTransactionManager
NtCreateUserProcess
NtCreateWaitablePort
NtCreateWorkerFactory
NtDebugActiveProcess
NtDebugContinue
NtDelayExecution
NtDeleteAtom
NtDeleteBootEntry
NtDeleteDriverEntry
NtDeleteFile
NtDeleteKey
NtDeleteObjectAuditAlarm
NtDeletePrivateNamespace
NtDeleteValueKey
NtDeviceIoControlFile
NtDisableLastKnownGood
NtDisplayString
NtDrawText
NtDuplicateObject
NtDuplicateToken
NtEnableLastKnownGood
NtEnumerateBootEntries
NtEnumerateDriverEntries
NtEnumerateKey
NtEnumerateSystemEnvironmentValuesEx
NtEnumerateTransactionObject
NtEnumerateValueKey
NtExtendSection
NtFilterToken
NtFindAtom
NtFlushBuffersFile
NtFlushInstallUILanguage
NtFlushInstructionCache
NtFlushKey
NtFlushProcessWriteBuffers
NtFlushVirtualMemory
NtFlushWriteBuffer
NtFreeUserPhysicalPages
NtFreeVirtualMemory
NtFreezeRegistry
NtFreezeTransactions
NtFsControlFile
NtGetContextThread
NtGetCurrentProcessorNumber
NtGetDevicePowerState
NtGetMUIRegistryInfo
NtGetNextProcess
NtGetNextThread
NtGetNlsSectionPtr
NtGetNotificationResourceManager
NtGetPlugPlayEvent
NtGetWriteWatch
NtImpersonateAnonymousToken
NtImpersonateClientOfPort
NtImpersonateThread
NtInitializeNlsFiles
NtInitializeRegistry
NtInitiatePowerAction
NtIsProcessInJob
NtIsSystemResumeAutomatic
NtIsUILanguageComitted
NtListenPort
NtLoadDriver
NtLoadKey
NtLoadKey2
NtLoadKeyEx
NtLockFile
NtLockProductActivationKeys
NtLockRegistryKey
NtLockVirtualMemory
NtMakePermanentObject
NtMakeTemporaryObject
NtMapCMFModule
NtMapUserPhysicalPages
NtMapUserPhysicalPagesScatter
NtMapViewOfSection
NtModifyBootEntry
NtModifyDriverEntry
NtNotifyChangeDirectoryFile
NtNotifyChangeKey
NtNotifyChangeMultipleKeys
NtNotifyChangeSession
NtOpenDirectoryObject
NtOpenEnlistment
NtOpenEvent
NtOpenEventPair
NtOpenFile
NtOpenIoCompletion
NtOpenJobObject
NtOpenKey
NtOpenKeyEx
NtOpenKeyedEvent
NtOpenKeyTransacted
NtOpenKeyTransactedEx
NtOpenMutant
NtOpenObjectAuditAlarm
NtOpenPrivateNamespace
NtOpenProcess
NtOpenProcessToken
NtOpenProcessTokenEx
NtOpenResourceManager
NtOpenSection
NtOpenSemaphore
NtOpenSession
NtOpenSymbolicLinkObject
NtOpenThread
NtOpenThreadToken
NtOpenThreadTokenEx
NtOpenTimer
NtOpenTransaction
NtOpenTransactionManager
NtPlugPlayControl
NtPowerInformation
NtPrepareComplete
NtPrepareEnlistment
NtPrePrepareComplete
NtPrePrepareEnlistment
NtPrivilegeCheck
NtPrivilegedServiceAuditAlarm
NtPrivilegeObjectAuditAlarm
NtPropagationComplete
NtPropagationFailed
NtProtectVirtualMemory
NtPulseEvent
NtQueryAttributesFile
NtQueryBootEntryOrder
NtQueryBootOptions
NtQueryDebugFilterState
NtQueryDefaultLocale
NtQueryDefaultUILanguage
NtQueryDirectoryFile
NtQueryDirectoryObject
NtQueryDriverEntryOrder
NtQueryEaFile
NtQueryEvent
NtQueryFullAttributesFile
NtQueryInformationAtom
NtQueryInformationEnlistment
NtQueryInformationFile
NtQueryInformationJobObject
NtQueryInformationPort
NtQueryInformationProcess
NtQueryInformationResourceManager
NtQueryInformationThread
NtQueryInformationToken
NtQueryInformationTransaction
NtQueryInformationTransactionManager
NtQueryInformationWorkerFactory
NtQueryInstallUILanguage
NtQueryIntervalProfile
NtQueryIoCompletion
NtQueryKey
NtQueryLicenseValue
NtQueryMultipleValueKey
NtQueryMutant
NtQueryObject
NtQueryOpenSubKeys
NtQueryOpenSubKeysEx
NtQueryPerformanceCounter
NtQueryPortInformationProcess
NtQueryQuotaInformationFile
NtQuerySection
NtQuerySecurityAttributesToken
NtQuerySecurityObject
NtQuerySemaphore
NtQuerySymbolicLinkObject
NtQuerySystemEnvironmentValue
NtQuerySystemEnvironmentValueEx
NtQuerySystemInformation
NtQuerySystemInformationEx
NtQuerySystemTime
NtQueryTimer
NtQueryTimerResolution
NtQueryValueKey
NtQueryVirtualMemory
NtQueryVolumeInformationFile
NtQueueApcThread
NtQueueApcThreadEx
NtRaiseException
NtRaiseHardError
NtReadFile
NtReadFileScatter
NtReadOnlyEnlistment
NtReadRequestData
NtReadVirtualMemory
NtRecoverEnlistment
NtRecoverResourceManager
NtRecoverTransactionManager
NtRegisterProtocolAddressInformation
NtRegisterThreadTerminatePort
NtReleaseKeyedEvent
NtReleaseMutant
NtReleaseSemaphore
NtReleaseWorkerFactoryWorker
NtRemoveIoCompletion
NtRemoveIoCompletionEx
NtRemoveProcessDebug
NtRenameKey
NtRenameTransactionManager
NtReplaceKey
NtReplacePartitionUnit
NtReplyPort
NtReplyWaitReceivePort
NtReplyWaitReceivePortEx
NtReplyWaitReplyPort
NtRequestPort
NtRequestWaitReplyPort
NtResetEvent
NtResetWriteWatch
NtRestoreKey
NtResumeProcess
NtResumeThread
NtRollbackComplete
NtRollbackEnlistment
NtRollbackTransaction
NtRollforwardTransactionManager
NtSaveKey
NtSaveKeyEx
NtSaveMergedKeys
NtSecureConnectPort
NtSerializeBoot
NtSetBootEntryOrder
NtSetBootOptions
NtSetContextThread
NtSetDebugFilterState
NtSetDefaultHardErrorPort
NtSetDefaultLocale
NtSetDefaultUILanguage
NtSetDriverEntryOrder
NtSetEaFile
NtSetEvent
NtSetEventBoostPriority
NtSetHighEventPair
NtSetHighWaitLowEventPair
NtSetInformationDebugObject
NtSetInformationEnlistment
NtSetInformationFile
NtSetInformationJobObject
NtSetInformationKey
NtSetInformationObject
NtSetInformationProcess
NtSetInformationResourceManager
NtSetInformationThread
NtSetInformationToken
NtSetInformationTransaction
NtSetInformationTransactionManager
NtSetInformationWorkerFactory
NtSetIntervalProfile
NtSetIoCompletion
NtSetIoCompletionEx
NtSetLdtEntries
NtSetLowEventPair
NtSetLowWaitHighEventPair
NtSetQuotaInformationFile
NtSetSecurityObject
NtSetSystemEnvironmentValue
NtSetSystemEnvironmentValueEx
NtSetSystemInformation
NtSetSystemPowerState
NtSetSystemTime
NtSetThreadExecutionState
NtSetTimer
NtSetTimerEx
NtSetTimerResolution
NtSetUuidSeed
NtSetValueKey
NtSetVolumeInformationFile
NtShutdownSystem
NtShutdownWorkerFactory
NtSignalAndWaitForSingleObject
NtSinglePhaseReject
NtStartProfile
NtStopProfile
NtSuspendProcess
NtSuspendThread
NtSystemDebugControl
NtTerminateJobObject
NtTerminateProcess
NtTerminateThread
NtTestAlert
NtThawRegistry
NtThawTransactions
NtTraceControl
NtTraceEvent
NtTranslateFilePath
NtUmsThreadYield
NtUnloadDriver
NtUnloadKey
NtUnloadKey2
NtUnloadKeyEx
NtUnlockFile
NtUnlockVirtualMemory
NtUnmapViewOfSection
NtVdmControl
NtWaitForDebugEvent
NtWaitForKeyedEvent
NtWaitForMultipleObjects
NtWaitForMultipleObjects32
NtWaitForSingleObject
NtWaitForWorkViaWorkerFactory
NtWaitHighEventPair
NtWaitLowEventPair
NtWorkerFactoryWorkerReady
NtWriteFile
NtWriteFileGather
NtWriteRequestData
NtWriteVirtualMemory
NtYieldExecution

猜你喜欢

转载自blog.csdn.net/qq_42814021/article/details/120680268