2015年3月18日星期三

查看64位系统的ssdt里面的函数

1: kd> .for (r $t0=0;@$t0<poi(nt!KeServiceDescriptorTable + 0x10);r $t0=@$t0+1){.printf "index:%d, %y\n", $t0, ((dwo(nt!KiServiceTable + 4*(@$t0)) >> 4) + nt!KiServiceTable) & ffffffff0FFFFFFf}
index:0, nt!NtMapUserPhysicalPagesScatter (fffff800`01cdaca0)
index:1, nt!NtWaitForSingleObject (fffff800`01bc28c0)
index:2, nt!NtCallbackReturn (fffff800`018c41a0)
index:3, nt!NtReadFile (fffff800`01bb5a80)
index:4, nt!NtDeviceIoControlFile (fffff800`01be77a0)
index:5, nt!NtWriteFile (fffff800`01bde9a0)
index:6, nt!NtRemoveIoCompletion (fffff800`01b88c90)
index:7, nt!NtReleaseSemaphore (fffff800`01b82220)
index:8, nt!NtReplyWaitReceivePort (fffff800`01bdffc4)
index:9, nt!NtReplyPort (fffff800`01caaa40)
index:10, nt!NtSetInformationThread (fffff800`01b95770)
index:11, nt!NtSetEvent (fffff800`01bb5010)
index:12, nt!NtClose (fffff800`01bc3b10)
index:13, nt!NtQueryObject (fffff800`01bad530)
index:14, nt!NtQueryInformationFile (fffff800`01baa360)
index:15, nt!NtOpenKey (fffff800`01ba6910)
index:16, nt!NtEnumerateValueKey (fffff800`01bac760)
index:17, nt!NtFindAtom (fffff800`01bbeb60)
index:18, nt!NtQueryDefaultLocale (fffff800`01b7a350)
index:19, nt!NtQueryKey (fffff800`01b9c2e0)
index:20, nt!NtQueryValueKey (fffff800`01b9d4d0)
index:21, nt!NtAllocateVirtualMemory (fffff800`01bc3c90)
index:22, nt!NtQueryInformationProcess (fffff800`01bdd410)
index:23, nt!NtWaitForMultipleObjects32 (fffff800`01bf0fa0)
index:24, nt!NtWriteFileGather (fffff800`01d22f30)
index:25, nt!NtSetInformationProcess (fffff800`01bba59c)
index:26, nt!NtCreateKey (fffff800`01b80170)
index:27, nt!NtFreeVirtualMemory (fffff800`018b94d0)
index:28, nt!NtImpersonateClientOfPort (fffff800`01d09580)
index:29, nt!NtReleaseMutant (fffff800`01bc2404)
index:30, nt!NtQueryInformationToken (fffff800`01b925c0)
index:31, nt!NtRequestWaitReplyPort (fffff800`01bdf9c0)
index:32, nt!NtQueryVirtualMemory (fffff800`01ba6930)
index:33, nt!NtOpenThreadToken (fffff800`01ba0338)
index:34, nt!NtQueryInformationThread (fffff800`01bb9a30)
index:35, nt!NtOpenProcess (fffff800`01b9f2ec)
index:36, nt!NtSetInformationFile (fffff800`01baacb0)
index:37, nt!NtMapViewOfSection (fffff800`01be59e0)
index:38, nt!NtAccessCheckAndAuditAlarm (fffff800`01bb00a0)
index:39, nt!NtUnmapViewOfSection (fffff800`01be3ad4)
index:40, nt!NtReplyWaitReceivePortEx (fffff800`01bdffe0)
index:41, nt!NtTerminateProcess (fffff800`01b855a4)
index:42, nt!NtSetEventBoostPriority (fffff800`01cdf980)
index:43, nt!NtReadFileScatter (fffff800`01b346c4)
index:44, nt!NtOpenThreadTokenEx (fffff800`01b9fd80)
index:45, nt!NtOpenProcessTokenEx (fffff800`01ba7c40)
index:46, nt!NtQueryPerformanceCounter (fffff800`01b7d150)
index:47, nt!NtEnumerateKey (fffff800`01b84670)
index:48, nt!NtOpenFile (fffff800`01bb50dc)
index:49, nt!NtDelayExecution (fffff800`01bc29d4)
index:50, nt!NtQueryDirectoryFile (fffff800`01bb57b0)
index:51, nt!NtQuerySystemInformation (fffff800`01bd68fc)
index:52, nt!NtOpenSection (fffff800`01be5d80)
index:53, nt!NtQueryTimer (fffff800`01cdf520)
index:54, nt!NtFsControlFile (fffff800`01ba6870)
index:55, nt!NtWriteVirtualMemory (fffff800`01b73850)
index:56, nt!NtCloseObjectAuditAlarm (fffff800`01ba2c3c)
index:57, nt!NtDuplicateObject (fffff800`01ba5c10)
index:58, nt!NtQueryAttributesFile (fffff800`01ba7e20)
index:59, nt!NtClearEvent (fffff800`01bb6588)
index:60, nt!NtReadVirtualMemory (fffff800`01b739c0)
index:61, nt!NtOpenEvent (fffff800`01bade44)
index:62, nt!NtAdjustPrivilegesToken (fffff800`01b81334)
index:63, nt!NtDuplicateToken (fffff800`01b72b08)
index:64, nt!NtContinue (fffff800`018ce140)
index:65, nt!NtQueryDefaultUILanguage (fffff800`01c77450)
index:66, nt!NtQueueApcThread (fffff800`01bb0efc)
index:67, nt!NtYieldExecution (fffff800`0189b568)
index:68, nt!NtAddAtom (fffff800`01b1f06c)
index:69, nt!NtCreateEvent (fffff800`01b91e60)
index:70, nt!NtQueryVolumeInformationFile (fffff800`01be0fc0)
index:71, nt!NtCreateSection (fffff800`01ba79b0)
index:72, nt!NtFlushBuffersFile (fffff800`01b6b700)
index:73, nt!NtApphelpCacheControl (fffff800`01baca34)
index:74, nt!NtCreateProcessEx (fffff800`01d3cf20)
index:75, nt!NtCreateThread (fffff800`01caab70)
index:76, nt!NtIsProcessInJob (fffff800`01cdffd0)
index:77, nt!NtProtectVirtualMemory (fffff800`01be4b2c)
index:78, nt!NtQuerySection (fffff800`01be8db0)
index:79, nt!NtResumeThread (fffff800`01bbd1c8)
index:80, nt!NtTerminateThread (fffff800`01ba2530)
index:81, nt!NtReadRequestData (fffff800`01d30a10)
index:82, nt!NtCreateFile (fffff800`01bd4400)
index:83, nt!NtQueryEvent (fffff800`01b66284)
index:84, nt!NtWriteRequestData (fffff800`01d30990)
index:85, nt!NtOpenDirectoryObject (fffff800`01be6900)
index:86, nt!NtAccessCheckByTypeAndAuditAlarm (fffff800`01b6dba4)
index:87, nt!NtQuerySystemTime (fffff800`01c53ea0)
index:88, nt!NtWaitForMultipleObjects (fffff800`01bc2f58)
index:89, nt!NtSetInformationObject (fffff800`01b6896c)
index:90, nt!NtCancelIoFile (fffff800`01cdee10)
index:91, nt!NtTraceEvent (fffff800`018b1c2c)
index:92, nt!NtPowerInformation (fffff800`01b88e3c)
index:93, nt!NtSetValueKey (fffff800`01b801b0)
index:94, nt!NtCancelTimer (fffff800`0188146c)
index:95, nt!NtSetTimer (fffff800`018b90a4)
index:96, nt!NtAcceptConnectPort (fffff800`01b862e0)
index:97, nt!NtAccessCheck (fffff800`01892ad4)
index:98, nt!NtAccessCheckByType (fffff800`018a74d4)
index:99, nt!NtAccessCheckByTypeResultList (fffff800`019e1e20)
index:100, nt!NtAccessCheckByTypeResultListAndAuditAlarm (fffff800`01cf1560)
index:101, nt!NtAccessCheckByTypeResultListAndAuditAlarmByHandle (fffff800`01cf14a0)
index:102, nt!NtAddBootEntry (fffff800`01d0e030)
index:103, nt!NtAddDriverEntry (fffff800`01d0dd90)
index:104, nt!NtAdjustGroupsToken (fffff800`01b4c2e0)
index:105, nt!NtAlertResumeThread (fffff800`01cf3080)
index:106, nt!NtAlertThread (fffff800`01bb3d4c)
index:107, nt!NtAllocateLocallyUniqueId (fffff800`01b63d80)
index:108, nt!NtAllocateReserveObject (fffff800`01caa020)
index:109, nt!NtAllocateUserPhysicalPages (fffff800`01d21480)
index:110, nt!NtAllocateUuids (fffff800`01b19b20)
index:111, nt!NtAlpcAcceptConnectPort (fffff800`01ba9730)
index:112, nt!NtAlpcCancelMessage (fffff800`01b3415c)
index:113, nt!NtAlpcConnectPort (fffff800`01bae5dc)
index:114, nt!NtAlpcCreatePort (fffff800`01bb4428)
index:115, nt!NtAlpcCreatePortSection (fffff800`01b697a4)
index:116, nt!NtAlpcCreateResourceReserve (fffff800`01bb4870)
index:117, nt!NtAlpcCreateSectionView (fffff800`01b68a10)
index:118, nt!NtAlpcCreateSecurityContext (fffff800`01b6d524)
index:119, nt!NtAlpcDeletePortSection (fffff800`01b60b44)
index:120, nt!NtAlpcDeleteResourceReserve (fffff800`01c9b2d0)
index:121, nt!NtAlpcDeleteSectionView (fffff800`01b857fc)
index:122, nt!NtAlpcDeleteSecurityContext (fffff800`01b6d6f0)
index:123, nt!NtAlpcDisconnectPort (fffff800`01b85290)
index:124, nt!NtAlpcImpersonateClientOfPort (fffff800`01b9fb50)
index:125, nt!NtAlpcOpenSenderProcess (fffff800`01baf32c)
index:126, nt!NtAlpcOpenSenderThread (fffff800`01b887a0)
index:127, nt!NtAlpcQueryInformation (fffff800`01b5d180)
index:128, nt!NtAlpcQueryInformationMessage (fffff800`01b9f6c0)
index:129, nt!NtAlpcRevokeSecurityContext (fffff800`01c9b150)
index:130, nt!NtAlpcSendWaitReceivePort (fffff800`01bd96c0)
index:131, nt!NtAlpcSetInformation (fffff800`01bb3490)
index:132, nt!NtAreMappedFilesTheSame (fffff800`01b19850)
index:133, nt!NtAssignProcessToJobObject (fffff800`01b83cd4)
index:134, nt!NtCancelIoFileEx (fffff800`01beffd0)
index:135, nt!NtCancelSynchronousIoFile (fffff800`01cf3e70)
index:136, nt!NtCommitComplete (fffff800`01cf5470)
index:137, nt!NtCommitEnlistment (fffff800`01d1c000)
index:138, nt!NtCommitTransaction (fffff800`01b5a220)
index:139, nt!NtCompactKeys (fffff800`01cf8ef0)
index:140, nt!NtCompareTokens (fffff800`01b91730)
index:141, nt!FsRtlSyncVolumes (fffff800`01b56a00)
index:142, nt!NtCompressKey (fffff800`01d4a1f0)
index:143, nt!NtConnectPort (fffff800`01b7a148)
index:144, nt!NtCreateDebugObject (fffff800`01ca9da0)
index:145, nt!NtCreateDirectoryObject (fffff800`01b637c0)
index:146, nt!NtCreateEnlistment (fffff800`01b52d78)
index:147, nt!NtCreateEventPair (fffff800`01ca9f20)
index:148, nt!NtCreateIoCompletion (fffff800`01baed30)
index:149, nt!NtCreateJobObject (fffff800`01caa6a0)
index:150, nt!NtCreateJobSet (fffff800`01cef350)
index:151, nt!NtCreateKeyTransacted (fffff800`01b558e8)
index:152, nt!NtCreateKeyedEvent (fffff800`01b7f28c)
index:153, nt!NtCreateMailslotFile (fffff800`01b40450)
index:154, nt!NtCreateMutant (fffff800`01b72e40)
index:155, nt!NtCreateNamedPipeFile (fffff800`01b8dfe0)
index:156, nt!NtCreatePagingFile (fffff800`01d341c0)
index:157, nt!NtCreatePort (fffff800`01b8873c)
index:158, nt!NtCreatePrivateNamespace (fffff800`01b3dcc4)
index:159, nt!NtCreateProcess (fffff800`01d3cfb0)
index:160, nt!NtCreateProfile (fffff800`01cf1360)
index:161, nt!NtCreateProfileEx (fffff800`01cf1430)
index:162, nt!NtCreateResourceManager (fffff800`01b56bf8)
index:163, nt!NtCreateSemaphore (fffff800`01b73344)
index:164, nt!NtCreateSymbolicLinkObject (fffff800`01b63e00)
index:165, nt!NtCreateThreadEx (fffff800`01bbc128)
index:166, nt!NtCreateTimer (fffff800`01b61038)
index:167, nt!NtCreateToken (fffff800`01b62d5c)
index:168, nt!NtCreateTransaction (fffff800`01b4ffe0)
index:169, nt!NtCreateTransactionManager (fffff800`01b55ff0)
index:170, nt!NtCreateUserProcess (fffff800`01b774a0)
index:171, nt!NtCreateWaitablePort (fffff800`01cead60)
index:172, nt!NtCreateWorkerFactory (fffff800`01baee38)
index:173, nt!NtDebugActiveProcess (fffff800`01d1a1f0)
index:174, nt!NtDebugContinue (fffff800`01cf1b90)
index:175, nt!NtDeleteAtom (fffff800`01d03f00)
index:176, nt!NtDeleteBootEntry (fffff800`01cbcfa0)
index:177, nt!NtDeleteDriverEntry (fffff800`01cbca80)
index:178, nt!NtDeleteFile (fffff800`01b26780)
index:179, nt!NtDeleteKey (fffff800`01b4d1d0)
index:180, nt!NtDeleteObjectAuditAlarm (fffff800`01cf06d0)
index:181, nt!NtDeletePrivateNamespace (fffff800`01becef0)
index:182, nt!NtDeleteValueKey (fffff800`01b4bb1c)
index:183, nt!NtDisableLastKnownGood (fffff800`01c9aec0)
index:184, nt!NtDisplayString (fffff800`01d23890)
index:185, nt!NtDrawText (fffff800`019e92b0)
index:186, nt!NtEnableLastKnownGood (fffff800`01ce7770)
index:187, nt!NtEnumerateBootEntries (fffff800`01d293a0)
index:188, nt!NtEnumerateDriverEntries (fffff800`01d28980)
index:189, nt!NtEnumerateSystemEnvironmentValuesEx (fffff800`01d29960)
index:190, nt!NtEnumerateTransactionObject (fffff800`01ceee00)
index:191, nt!NtExtendSection (fffff800`01cfbc70)
index:192, nt!NtFilterToken (fffff800`01bf036c)
index:193, nt!NtFlushInstallUILanguage (fffff800`01cff6a0)
index:194, nt!NtFlushInstructionCache (fffff800`01b3d8c4)
index:195, nt!NtFlushKey (fffff800`01b6c6ac)
index:196, nt!NtFlushProcessWriteBuffers (fffff800`0186c898)
index:197, nt!NtFlushVirtualMemory (fffff800`01b31370)
index:198, nt!NtFlushWriteBuffer (fffff800`01c38e50)
index:199, nt!NtFreeUserPhysicalPages (fffff800`01cf5b60)
index:200, nt!NtFreezeRegistry (fffff800`019c3cb0)
index:201, nt!NtFreezeTransactions (fffff800`01cf2f90)
index:202, nt!NtGetContextThread (fffff800`01b1bae8)
index:203, nt!NtGetCurrentProcessorNumber (fffff800`01b5c1e0)
index:204, nt!NtGetDevicePowerState (fffff800`01ceddb0)
index:205, nt!NtGetMUIRegistryInfo (fffff800`01b7f0a0)
index:206, nt!NtGetNextProcess (fffff800`01cfc2a0)
index:207, nt!NtGetNextThread (fffff800`01cfbfb0)
index:208, nt!NtGetNlsSectionPtr (fffff800`01cfaef0)
index:209, nt!NtGetNotificationResourceManager (fffff800`01cf2e10)
index:210, nt!NtGetPlugPlayEvent (fffff800`01b37320)
index:211, nt!NtGetWriteWatch (fffff800`0186c8a8)
index:212, nt!NtImpersonateAnonymousToken (fffff800`01b61220)
index:213, nt!NtImpersonateThread (fffff800`01b736d4)
index:214, nt!NtInitializeNlsFiles (fffff800`01b74228)
index:215, nt!NtInitializeRegistry (fffff800`01b25740)
index:216, nt!NtInitiatePowerAction (fffff800`01d15140)
index:217, nt!NtIsSystemResumeAutomatic (fffff800`01c37620)
index:218, nt!NtIsUILanguageComitted (fffff800`01b8cd10)
index:219, nt!NtListenPort (fffff800`01cf92b0)
index:220, nt!NtLoadDriver (fffff800`01d454f0)
index:221, nt!NtLoadKey (fffff800`01b4a594)
index:222, nt!NtLoadKey2 (fffff800`01d4a9a0)
index:223, nt!NtLoadKeyEx (fffff800`01b495a4)
index:224, nt!NtLockFile (fffff800`01b40b9c)
index:225, nt!NtLockProductActivationKeys (fffff800`01ce0ad0)
index:226, nt!NtLockRegistryKey (fffff800`01cf85e0)
index:227, nt!NtLockVirtualMemory (fffff800`019de1d0)
index:228, nt!NtMakePermanentObject (fffff800`01d018d0)
index:229, nt!NtMakeTemporaryObject (fffff800`01b65b58)
index:230, nt!NtMapCMFModule (fffff800`01b75610)
index:231, nt!NtMapUserPhysicalPages (fffff800`01cdb4b0)
index:232, nt!NtModifyBootEntry (fffff800`01d0e000)
index:233, nt!NtModifyDriverEntry (fffff800`01d0dd60)
index:234, nt!NtNotifyChangeDirectoryFile (fffff800`01b3220c)
index:235, nt!NtNotifyChangeKey (fffff800`01b82144)
index:236, nt!NtNotifyChangeMultipleKeys (fffff800`01b81884)
index:237, nt!NtNotifyChangeSession (fffff800`01cf3ab0)
index:238, nt!NtOpenEnlistment (fffff800`01cebe90)
index:239, nt!NtOpenEventPair (fffff800`01cb1d90)
index:240, nt!NtOpenIoCompletion (fffff800`01cb1a10)
index:241, nt!NtOpenJobObject (fffff800`01cb1f00)
index:242, nt!NtOpenKeyEx (fffff800`01b9dc90)
index:243, nt!NtOpenKeyTransacted (fffff800`01cef8a0)
index:244, nt!NtOpenKeyTransactedEx (fffff800`01b55d00)
index:245, nt!NtOpenKeyedEvent (fffff800`01cb1ce0)
index:246, nt!NtOpenMutant (fffff800`01be5e04)
index:247, nt!NtOpenObjectAuditAlarm (fffff800`01cf07e0)
index:248, nt!NtOpenPrivateNamespace (fffff800`01b64e74)
index:249, nt!NtOpenProcessToken (fffff800`01b72f70)
index:250, nt!NtOpenResourceManager (fffff800`01bef8ec)
index:251, nt!NtOpenSemaphore (fffff800`01b33f68)
index:252, nt!NtOpenSession (fffff800`01cb1980)
index:253, nt!NtOpenSymbolicLinkObject (fffff800`01b73060)
index:254, nt!NtOpenThread (fffff800`01bbe73c)
index:255, nt!NtOpenTimer (fffff800`01cb1e50)
index:256, nt!NtOpenTransaction (fffff800`01cebbf0)
index:257, nt!NtOpenTransactionManager (fffff800`01ceeae0)
index:258, nt!NtPlugPlayControl (fffff800`01b90b3c)
index:259, nt!NtPrePrepareComplete (fffff800`01cf55d0)
index:260, nt!NtPrePrepareEnlistment (fffff800`01d1c0b0)
index:261, nt!NtPrepareComplete (fffff800`01cf5680)
index:262, nt!NtPrepareEnlistment (fffff800`01d1c160)
index:263, nt!NtPrivilegeCheck (fffff800`01b66040)
index:264, nt!NtPrivilegeObjectAuditAlarm (fffff800`01cf0fd0)
index:265, nt!NtPrivilegedServiceAuditAlarm (fffff800`01b36764)
index:266, nt!NtPropagationComplete (fffff800`01d225e0)
index:267, nt!NtPropagationFailed (fffff800`01cf3600)
index:268, nt!NtPulseEvent (fffff800`01b311c0)
index:269, nt!NtQueryBootEntryOrder (fffff800`01d29100)
index:270, nt!NtQueryBootOptions (fffff800`01cbcc80)
index:271, nt!NtQueryDebugFilterState (fffff800`01907720)
index:272, nt!NtQueryDirectoryObject (fffff800`01be6344)
index:273, nt!NtQueryDriverEntryOrder (fffff800`01d28e60)
index:274, nt!NtQueryEaFile (fffff800`01d31780)
index:275, nt!NtQueryFullAttributesFile (fffff800`01b5e0d4)
index:276, nt!NtQueryInformationAtom (fffff800`01cbe9e0)
index:277, nt!NtQueryInformationEnlistment (fffff800`01cea150)
index:278, nt!NtQueryInformationJobObject (fffff800`01d0b710)
index:279, nt!NtQueryInformationPort (fffff800`01c9adf0)
index:280, nt!NtQueryInformationResourceManager (fffff800`01ce9820)
index:281, nt!NtQueryInformationTransaction (fffff800`01ce9a90)
index:282, nt!NtQueryInformationTransactionManager (fffff800`01bef460)
index:283, nt!NtQueryInformationWorkerFactory (fffff800`019e0510)
index:284, nt!NtQueryInstallUILanguage (fffff800`01b8b1c0)
index:285, nt!NtQueryIntervalProfile (fffff800`01c490a0)
index:286, nt!NtQueryIoCompletion (fffff800`01cdf110)
index:287, nt!NtQueryLicenseValue (fffff800`01bb0f28)
index:288, nt!NtQueryMultipleValueKey (fffff800`01b80d44)
index:289, nt!NtQueryMutant (fffff800`01cdf690)
index:290, nt!NtQueryOpenSubKeys (fffff800`01d16ed0)
index:291, nt!NtQueryOpenSubKeysEx (fffff800`01d16ae0)
index:292, nt!NtQueryPortInformationProcess (fffff800`01c373c0)
index:293, nt!NtQueryQuotaInformationFile (fffff800`01d30a90)
index:294, nt!NtQuerySecurityAttributesToken (fffff800`01b90940)
index:295, nt!NtQuerySecurityObject (fffff800`01b61350)
index:296, nt!NtQuerySemaphore (fffff800`01cdf840)
index:297, nt!NtQuerySymbolicLinkObject (fffff800`01b7727c)
index:298, nt!NtQuerySystemEnvironmentValue (fffff800`01d0e3d0)
index:299, nt!NtQuerySystemEnvironmentValueEx (fffff800`01d329a0)
index:300, nt!NtQuerySystemInformationEx (fffff800`01baec90)
index:301, nt!NtQueryTimerResolution (fffff800`01b3281c)
index:302, nt!NtQueueApcThreadEx (fffff800`01bb0dc0)
index:303, nt!NtRaiseException (fffff800`018ce380)
index:304, nt!NtRaiseHardError (fffff800`01cfb2a0)
index:305, nt!NtReadOnlyEnlistment (fffff800`01cf5520)
index:306, nt!NtRecoverEnlistment (fffff800`01d1b050)
index:307, nt!NtRecoverResourceManager (fffff800`01b53828)
index:308, nt!NtRecoverTransactionManager (fffff800`01b53410)
index:309, nt!NtRegisterProtocolAddressInformation (fffff800`01d226f0)
index:310, nt!NtRegisterThreadTerminatePort (fffff800`01ce00c0)
index:311, nt!NtReleaseKeyedEvent (fffff800`01bb3820)
index:312, nt!NtReleaseWorkerFactoryWorker (fffff800`018b8aac)
index:313, nt!NtRemoveIoCompletionEx (fffff800`01b6b324)
index:314, nt!NtRemoveProcessDebug (fffff800`01cdf3b0)
index:315, nt!NtRenameKey (fffff800`01d1d440)
index:316, nt!NtRenameTransactionManager (fffff800`01d0b540)
index:317, nt!NtReplaceKey (fffff800`01d49ab0)
index:318, nt!NtReplacePartitionUnit (fffff800`019eee90)
index:319, nt!NtReplyWaitReplyPort (fffff800`01cbacd0)
index:320, nt!NtRequestPort (fffff800`01bbe8e0)
index:321, nt!NtResetEvent (fffff800`01cdfa00)
index:322, nt!NtResetWriteWatch (fffff800`0186c440)
index:323, nt!NtRestoreKey (fffff800`01d49d90)
index:324, nt!NtResumeProcess (fffff800`01d18560)
index:325, nt!NtRollbackComplete (fffff800`01cf36a0)
index:326, nt!NtRollbackEnlistment (fffff800`01d143a0)
index:327, nt!NtRollbackTransaction (fffff800`01d1a6f0)
index:328, nt!NtRollforwardTransactionManager (fffff800`01d1c210)
index:329, nt!NtSaveKey (fffff800`01d47d00)
index:330, nt!NtSaveKeyEx (fffff800`01d47a50)
index:331, nt!NtSaveMergedKeys (fffff800`01d47880)
index:332, nt!NtSecureConnectPort (fffff800`01b785f4)
index:333, nt!NtSerializeBoot (fffff800`01c9ec10)
index:334, nt!NtSetBootEntryOrder (fffff800`01d0ddc0)
index:335, nt!NtSetBootOptions (fffff800`01cbf040)
index:336, nt!NtSetContextThread (fffff800`01b1b410)
index:337, nt!NtSetDebugFilterState (fffff800`01c9afc0)
index:338, nt!NtSetDefaultHardErrorPort (fffff800`01c9f150)
index:339, nt!NtSetDefaultLocale (fffff800`01c774d0)
index:340, nt!NtSetDefaultUILanguage (fffff800`01c78bb0)
index:341, nt!NtSetDriverEntryOrder (fffff800`01d0db20)
index:342, nt!NtSetEaFile (fffff800`01d31300)
index:343, nt!NtSetHighEventPair (fffff800`01cf29a0)
index:344, nt!NtSetHighWaitLowEventPair (fffff800`01cf3150)
index:345, nt!NtSetInformationDebugObject (fffff800`01cef6d0)
index:346, nt!NtSetInformationEnlistment (fffff800`01cef0a0)
index:347, nt!NtSetInformationJobObject (fffff800`01d171f0)
index:348, nt!NtSetInformationKey (fffff800`01b6e4c0)
index:349, nt!NtSetInformationResourceManager (fffff800`01d222c0)
index:350, nt!NtSetInformationToken (fffff800`01b617b8)
index:351, nt!NtSetInformationTransaction (fffff800`01d23a60)
index:352, nt!NtSetInformationTransactionManager (fffff800`01d0b4a0)
index:353, nt!NtSetInformationWorkerFactory (fffff800`018bbdf0)
index:354, nt!NtSetIntervalProfile (fffff800`01c74af0)
index:355, nt!NtSetIoCompletion (fffff800`01b5e010)
index:356, nt!NtSetIoCompletionEx (fffff800`01cdefd0)
index:357, nt!xKdReleasePciDeviceForDebugging (fffff800`01951210)
index:358, nt!NtSetLowEventPair (fffff800`01cf2a10)
index:359, nt!NtSetLowWaitHighEventPair (fffff800`01cf31d0)
index:360, nt!NtSetQuotaInformationFile (fffff800`01d330c0)
index:361, nt!NtSetSecurityObject (fffff800`01b68538)
index:362, nt!NtSetSystemEnvironmentValue (fffff800`01d0e060)
index:363, nt!NtSetSystemEnvironmentValueEx (fffff800`01d32680)
index:364, nt!NtSetSystemInformation (fffff800`01d401a0)
index:365, nt!NtSetSystemPowerState (fffff800`01b15450)
index:366, nt!NtSetSystemTime (fffff800`01ce62b0)
index:367, nt!NtSetThreadExecutionState (fffff800`01d10650)
index:368, nt!NtSetTimerEx (fffff800`0187a7c4)
index:369, nt!NtSetTimerResolution (fffff800`01cf17a0)
index:370, nt!NtSetUuidSeed (fffff800`01d21f00)
index:371, nt!NtSetVolumeInformationFile (fffff800`01bef040)
index:372, nt!NtShutdownSystem (fffff800`01d4bdb0)
index:373, nt!NtShutdownWorkerFactory (fffff800`01b82dd8)
index:374, nt!NtSignalAndWaitForSingleObject (fffff800`019daee0)
index:375, nt!NtSinglePhaseReject (fffff800`01d1bf50)
index:376, nt!NtStartProfile (fffff800`01d2aab0)
index:377, nt!NtStopProfile (fffff800`01cf6360)
index:378, nt!NtSuspendProcess (fffff800`01d19c30)
index:379, nt!NtSuspendThread (fffff800`01b1b930)
index:380, nt!NtSystemDebugControl (fffff800`01b5dab0)
index:381, nt!NtTerminateJobObject (fffff800`01b2a890)
index:382, nt!NtTestAlert (fffff800`01bbe76c)
index:383, nt!NtThawRegistry (fffff800`019c3f40)
index:384, nt!NtThawTransactions (fffff800`01ca05c0)
index:385, nt!NtTraceControl (fffff800`01b720a0)
index:386, nt!NtTranslateFilePath (fffff800`01cf03c0)
index:387, nt!NtUmsThreadYield (fffff800`01c51310)
index:388, nt!NtUnloadDriver (fffff800`01cb2dc0)
index:389, nt!NtUnloadKey (fffff800`01b58b40)
index:390, nt!NtUnloadKey2 (fffff800`01b50ea4)
index:391, nt!NtUnloadKeyEx (fffff800`01d1b730)
index:392, nt!NtUnlockFile (fffff800`01b407fc)
index:393, nt!NtUnlockVirtualMemory (fffff800`019da410)
index:394, nt!NtVdmControl (fffff800`01d2fcd0)
index:395, nt!NtWaitForDebugEvent (fffff800`01d033d0)
index:396, nt!NtWaitForKeyedEvent (fffff800`01bb3ab4)
index:397, nt!NtWaitForWorkViaWorkerFactory (fffff800`018b82a0)
index:398, nt!NtWaitHighEventPair (fffff800`01ce9600)
index:399, nt!NtWaitLowEventPair (fffff800`01ce9690)
index:400, nt!NtWorkerFactoryWorkerReady (fffff800`018c0750)

2015年3月17日星期二

获取32位系统上内核没有导出的SSDT函数的地址‏

#include <ntifs.h>
#include <windef.h>
#include <Aux_klib.h> //source里面要有TARGETLIBS=$(DDK_LIB_PATH)\Aux_klib.lib


/*
功能:获取内核中没有导出的SSDT函数的地址/ID。
思路:因为在NTDLL.DLL里必定有,而且必定是对应的关系。
      而且NTDLL.DLL的地址在内核中是可以查询到的。
      导出的函数是肯定能查询到的。
      ID是根据一个宏获取的。
      相应的套入SSDT即可获取那个函数的地址。注意是NT开头的。

注意:试验证明ZwCreateMutant,ZwOpenMutant,NtCreateMutant,NtOpenMutant在内核中都没有导出,用MmGetSystemRoutineAddress是获取不到地址的。

本文测试环境是32位系统,64位系统没有测试,可能需要稍微修改代码。

made by correy
made at 2015.03.16
*/


#define TAG  'tset' //test


#pragma pack(1)
typedef struct ServiceDescriptorEntry{
    unsigned int *ServiceTableBase;
    unsigned int *ServiceCounterTableBase; //Used only in checked build
    unsigned int NumberOfServices;
    unsigned char *ParamTableBase;
} ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;
#pragma pack()

extern __declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable;

#define SYSCALL_INDEX(_Function) (*(PULONG)((PUCHAR)_Function+1)) //获取SSDT函数的ID,X64没有测试和观察。

#define SYSTEMSERVICE(index) KeServiceDescriptorTable.ServiceTableBase[index]



DRIVER_UNLOAD Unload;
VOID Unload(__in PDRIVER_OBJECT DriverObject)
{

}


PVOID RtlImageDirectoryEntryToData (IN PVOID Base, IN BOOLEAN MappedAsImage, IN USHORT DirectoryEntry, OUT PULONG Size);
/*++
Routine Description:
    This function locates a Directory Entry within the image header and returns either the virtual address or seek address of the data the Directory describes.
Arguments:
    Base - Supplies the base of the image or data file.
    MappedAsImage - FALSE if the file is mapped as a data file.
                  - TRUE if the file is mapped as an image.
    DirectoryEntry - Supplies the directory entry to locate.
    Size - Return the size of the directory.
Return Value:
    NULL - The file does not contain data for the specified directory entry.
    NON-NULL - Returns the address of the raw data the directory describes.
--*/
//{
//    PIMAGE_NT_HEADERS NtHeaders;
//
//    if (LDR_IS_DATAFILE(Base)) {
//        Base = LDR_DATAFILE_TO_VIEW(Base);
//        MappedAsImage = FALSE;
//    }
//
//    NtHeaders = RtlImageNtHeader(Base);
//
//    if (!NtHeaders)
//        return NULL;
//
//    if (NtHeaders->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
//        return (RtlpImageDirectoryEntryToData32(Base, MappedAsImage, DirectoryEntry, Size, (PIMAGE_NT_HEADERS32)NtHeaders));
//    } else if (NtHeaders->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
//        return (RtlpImageDirectoryEntryToData64(Base, MappedAsImage, DirectoryEntry, Size, (PIMAGE_NT_HEADERS64)NtHeaders));
//    } else {
//        return (NULL);
//    }
//}


PVOID MiFindExportedRoutineByName (IN PVOID DllBase, IN PANSI_STRING AnsiImageRoutineName)
/*++
Routine Description:
    This function searches the argument module looking for the requested exported function name.
Arguments:
    DllBase - Supplies the base address of the requested module.
    AnsiImageRoutineName - Supplies the ANSI routine name being searched for.
Return Value:
    The virtual address of the requested routine or NULL if not found.
--*/
{
    USHORT OrdinalNumber;
    PULONG NameTableBase;
    PUSHORT NameOrdinalTableBase;
    PULONG Addr;
    LONG High;
    LONG Low;
    LONG Middle;
    LONG Result;
    ULONG ExportSize;
    PVOID FunctionAddress = 0;
    PIMAGE_EXPORT_DIRECTORY ExportDirectory;

    PAGED_CODE();

    __try
    {
        FunctionAddress = *(PVOID *)DllBase;
        FunctionAddress = 0;
    }
    __except(EXCEPTION_EXECUTE_HANDLER)
    {
        return FunctionAddress;
    }

    //确保DllBase可以访问。否则蓝屏。
    ExportDirectory = (PIMAGE_EXPORT_DIRECTORY) RtlImageDirectoryEntryToData (DllBase, TRUE, IMAGE_DIRECTORY_ENTRY_EXPORT, &ExportSize);
    if (ExportDirectory == NULL) {
        return NULL;
    }
   
    NameTableBase = (PULONG)((PCHAR)DllBase + (ULONG)ExportDirectory->AddressOfNames);// Initialize the pointer to the array of RVA-based ansi export strings.  
    NameOrdinalTableBase = (PUSHORT)((PCHAR)DllBase + (ULONG)ExportDirectory->AddressOfNameOrdinals);// Initialize the pointer to the array of USHORT ordinal numbers.  
    Low = 0;
    Middle = 0;
    High = ExportDirectory->NumberOfNames - 1;

    while (High >= Low) // Lookup the desired name in the name table using a binary search.
    {      
        Middle = (Low + High) >> 1;// Compute the next probe index and compare the import name with the export name entry.
        Result = strcmp (AnsiImageRoutineName->Buffer, (PCHAR)DllBase + NameTableBase[Middle]);
        if (Result < 0) {
            High = Middle - 1;
        } else if (Result > 0) {
            Low = Middle + 1;
        } else {
            break;
        }
    }

    // If the high index is less than the low index, then a matching table entry was not found.
    // Otherwise, get the ordinal number from the ordinal table.
    if (High < Low) {
        return NULL;
    }

    OrdinalNumber = NameOrdinalTableBase[Middle];

    // If the OrdinalNumber is not within the Export Address Table,then this image does not implement the function.
    // Return not found.
    if ((ULONG)OrdinalNumber >= ExportDirectory->NumberOfFunctions) {
        return NULL;
    }

    // Index into the array of RVA export addresses by ordinal number.
    Addr = (PULONG)((PCHAR)DllBase + (ULONG)ExportDirectory->AddressOfFunctions);
    FunctionAddress = (PVOID)((PCHAR)DllBase + Addr[OrdinalNumber]);

    // Forwarders are not used by the kernel and HAL to each other.
    ASSERT ((FunctionAddress <= (PVOID)ExportDirectory) || (FunctionAddress >= (PVOID)((PCHAR)ExportDirectory + ExportSize)));

    return FunctionAddress;
}


PVOID get_module_image_base(__in UCHAR * name)
{
    NTSTATUS status = 0;
    ULONG  modulesSize;
    AUX_MODULE_EXTENDED_INFO * modules;
    ULONG  numberOfModules;
    ULONG i;
    PIMAGE_EXPORT_DIRECTORY pied = 0;
    PVOID ImageBase = 0;

    status = AuxKlibInitialize();
    if (!NT_SUCCESS( status ))
    {
        KdPrint(( "AuxKlibInitialize fail %d\n", status));
        return ImageBase;
    }  
   
    status = AuxKlibQueryModuleInformation(&modulesSize, sizeof(AUX_MODULE_EXTENDED_INFO), NULL);// Get the required array size.
    if (!NT_SUCCESS(status) || modulesSize == 0) {
        return ImageBase;
    }
   
    numberOfModules = modulesSize / sizeof(AUX_MODULE_EXTENDED_INFO);// Calculate the number of modules.
       
    modules = (AUX_MODULE_EXTENDED_INFO*) ExAllocatePoolWithTag(PagedPool, modulesSize, TAG);// Allocate memory to receive data.
    if (modules == NULL) {
        status = STATUS_INSUFFICIENT_RESOURCES;
        return ImageBase;
    }
    RtlZeroMemory(modules, modulesSize);
   
    status = AuxKlibQueryModuleInformation(&modulesSize, sizeof(AUX_MODULE_EXTENDED_INFO), modules);// Obtain the module information.
    if (!NT_SUCCESS(status)) {
        ExFreePoolWithTag(modules,TAG);
        return ImageBase;
    }

    for (i = 0;i<numberOfModules;i++)
    {
        UCHAR * pfilename = modules[i].FullPathName + modules[i].FileNameOffset;

        if (_stricmp(pfilename, name) == 0)
        {
            ImageBase = modules[i].BasicInfo.ImageBase;
            break;
        }
    }

    ExFreePoolWithTag(modules,TAG);

    return ImageBase;
}


DRIVER_INITIALIZE DriverEntry;
NTSTATUS DriverEntry( __in struct _DRIVER_OBJECT  * DriverObject, __in PUNICODE_STRING  RegistryPath)
{
    NTSTATUS status = STATUS_UNSUCCESSFUL;
    PVOID ImageBase = 0;
    PVOID FunctionAddress;
    //ANSI_STRING EngCreateBitmap  = RTL_CONSTANT_STRING("EngCreateBitmap");//NT开头的函数竟然一个也没有导出。
    ANSI_STRING test  = RTL_CONSTANT_STRING("NtCreateMutant");
    int index = 0;
    PVOID p_NtCreateMutant = 0;

    KdBreakPoint();

    DriverObject->DriverUnload = Unload;  

    //ImageBase = get_module_image_base("WIN32k.sys");//注意这个的环境:有的线程不可以访问。不然地址不可访问。
    ImageBase = get_module_image_base("ntdll.dll");
    if (ImageBase == 0)
    {
        return status;
    }

    FunctionAddress = MiFindExportedRoutineByName (ImageBase, &test);
    if (FunctionAddress == 0)
    {
        return status;
    }

    index = SYSCALL_INDEX(FunctionAddress);
    KdPrint(( "NtCreateMutant ID: %d\n", index));

    p_NtCreateMutant = (PVOID)SYSTEMSERVICE(index);
    KdPrint(( "NtCreateMutant: %p\n", p_NtCreateMutant));

    return status;  
}


/*
结果如下:
0: kd> g
Mon Mar 16 18:16:28.216 2015 (UTC + 8:00): NtCreateMutant ID: 43
Mon Mar 16 18:16:28.216 2015 (UTC + 8:00):
Mon Mar 16 18:16:28.220 2015 (UTC + 8:00): NtCreateMutant: 80618822
分析如下:
0: kd> u nt!NtCreateMutant
nt!NtCreateMutant:
80618822 6a2c            push    2Ch
80618824 6890e44d80      push    offset nt!ExpLuidIncrement+0x108 (804de490)
80618829 e81245f2ff      call    nt!_SEH_prolog (8053cd40)
8061882e 33db            xor     ebx,ebx
80618830 895dfc          mov     dword ptr [ebp-4],ebx
80618833 64a124010000    mov     eax,dword ptr fs:[00000124h]
80618839 8945d0          mov     dword ptr [ebp-30h],eax
8061883c 8a8040010000    mov     al,byte ptr [eax+140h]
看来获取的地址是对的。
0: kd> u nt!ZwCreateMutant
nt!ZwCreateMutant:
805010e4 b82b000000      mov     eax,2Bh
805010e9 8d542404        lea     edx,[esp+4]
805010ed 9c              pushfd
805010ee 6a08            push    8
805010f0 e81c150400      call    nt!KiSystemService (80542611)
805010f5 c21000          ret     10h
nt!ZwCreateNamedPipeFile:
805010f8 b82c000000      mov     eax,2Ch
805010fd 8d542404        lea     edx,[esp+4]
0: kd> ?2b
Evaluate expression: 43 = 0000002b
看来获取的ID是正确的。
0: kd> !process 0 0 explorer.exe
PROCESS 81b49020  SessionId: 0  Cid: 0694    Peb: 7ffdb000  ParentCid: 0654
    DirBase: 02940200  ObjectTable: e1d1b3b8  HandleCount: 523.
    Image: explorer.exe

PROCESS 82054620  SessionId: 0  Cid: 059c    Peb: 7ffd6000  ParentCid: 0694
    DirBase: 029402e0  ObjectTable: e1604900  HandleCount: 312.
    Image: explorer.exe

0: kd> .process /r /p 82054620
Implicit process is now 82054620
.cache forcedecodeuser done
Loading User Symbols
................................................................
.......................
0: kd> u ntdll!ZwCreateMutant
ntdll!NtCreateMutant:
7c92d10e b82b000000      mov     eax,2Bh
7c92d113 ba0003fe7f      mov     edx,offset SharedUserData!SystemCallStub (7ffe0300)
7c92d118 ff12            call    dword ptr [edx]
7c92d11a c21000          ret     10h
7c92d11d 90              nop
ntdll!ZwCreateNamedPipeFile:
7c92d11e b82c000000      mov     eax,2Ch
7c92d123 ba0003fe7f      mov     edx,offset SharedUserData!SystemCallStub (7ffe0300)
7c92d128 ff12            call    dword ptr [edx]
0: kd> u ntdll!NtCreateMutant
ntdll!NtCreateMutant:
7c92d10e b82b000000      mov     eax,2Bh
7c92d113 ba0003fe7f      mov     edx,offset SharedUserData!SystemCallStub (7ffe0300)
7c92d118 ff12            call    dword ptr [edx]
7c92d11a c21000          ret     10h
7c92d11d 90              nop
ntdll!ZwCreateNamedPipeFile:
7c92d11e b82c000000      mov     eax,2Ch
7c92d123 ba0003fe7f      mov     edx,offset SharedUserData!SystemCallStub (7ffe0300)
7c92d128 ff12            call    dword ptr [edx]
*/


/*
1: kd> uf nt!Zwcreatefile
Flow analysis was incomplete, some code may be missing
nt!ZwCreateFile:
fffff800`018d8680 488bc4          mov     rax,rsp
fffff800`018d8683 fa              cli
fffff800`018d8684 4883ec10        sub     rsp,10h
fffff800`018d8688 50              push    rax
fffff800`018d8689 9c              pushfq
fffff800`018d868a 6a10            push    10h
fffff800`018d868c 488d05dd270000  lea     rax,[nt!KiServiceLinkage (fffff800`018dae70)]
fffff800`018d8693 50              push    rax
fffff800`018d8694 b852000000      mov     eax,52h 注意这个。
fffff800`018d8699 e9225f0000      jmp     nt!KiServiceInternal (fffff800`018de5c0)

nt!KiServiceInternal:
fffff800`018de5c0 4883ec08        sub     rsp,8
fffff800`018de5c4 55              push    rbp
fffff800`018de5c5 4881ec58010000  sub     rsp,158h
fffff800`018de5cc 488dac2480000000 lea     rbp,[rsp+80h]
fffff800`018de5d4 48899dc0000000  mov     qword ptr [rbp+0C0h],rbx
fffff800`018de5db 4889bdc8000000  mov     qword ptr [rbp+0C8h],rdi
fffff800`018de5e2 4889b5d0000000  mov     qword ptr [rbp+0D0h],rsi
fffff800`018de5e9 fb              sti
fffff800`018de5ea 65488b1c2588010000 mov   rbx,qword ptr gs:[188h]
fffff800`018de5f3 0f0d8bd8010000  prefetchw [rbx+1D8h]
fffff800`018de5fa 0fb6bbf6010000  movzx   edi,byte ptr [rbx+1F6h]
fffff800`018de601 40887da8        mov     byte ptr [rbp-58h],dil
fffff800`018de605 c683f601000000  mov     byte ptr [rbx+1F6h],0
fffff800`018de60c 4c8b93d8010000  mov     r10,qword ptr [rbx+1D8h]
fffff800`018de613 4c8995b8000000  mov     qword ptr [rbp+0B8h],r10
fffff800`018de61a 4c8d1d3d010000  lea     r11,[nt!KiSystemServiceStart (fffff800`018de75e)]
fffff800`018de621 41ffe3          jmp     r11
1: kd> !process 0 0 explorer.exe
PROCESS fffffa801ad91910
    SessionId: 1  Cid: 06a4    Peb: 7fffffdd000  ParentCid: 0680
    DirBase: 66ef5000  ObjectTable: fffff8a0011323b0  HandleCount: 755.
    Image: explorer.exe

1: kd> .process /p /r fffffa801ad91910
Implicit process is now fffffa80`1ad91910
.cache forcedecodeuser done
Loading User Symbols
................................................................
................................................................
...........
1: kd> uf ntdll!NtCreateFile
ntdll!ZwCreateFile:
00000000`77051860 4c8bd1          mov     r10,rcx
00000000`77051863 b852000000      mov     eax,52h 注意这个
00000000`77051868 0f05            syscall
00000000`7705186a c3              ret
知道64位SSDT的结构及地址,根据上面的示例不难写出X64的相应的例子。

*/

2015年3月13日星期五

遍历32位系统的SSDT函数

#include <ntifs.h>
#include <windef.h>


/*
好久不玩SSDT了,因为微软不建议,甚至抵触,特别是在64位系统上。
但是有时候,知道原理对于分析问题和解决功能还是有好处的,

所以有此文。

SSDT再分析。

首先这是系统的一个机制。

其次是32位的系统导出了一个变量。
0: kd> x nt!_KeServiceDescriptorTable
8055d700          nt!KeServiceDescriptorTable = <no type information>

这个变量是啥类型呢?
REGMON的一个版本的代码,声明如下:
typedef struct _SRVTABLE {
PVOID           *ServiceTable;
ULONG           LowCall;      
ULONG           HiCall;
PVOID    *ArgTable;
} SRVTABLE, *PSRVTABLE;

不过我们可以这样看:
0: kd> dps 8055d700 L 8
8055d700  80505570 nt!KiServiceTable
8055d704  00000000
8055d708  0000011c
8055d70c  805059e4 nt!KiArgumentTable
8055d710  00000000
8055d714  00000000
8055d718  00000000
8055d71c  00000000

再下就是这样看:
0: kd> dps 80505570 L 11c
80505570  805a5664 nt!NtAcceptConnectPort
80505574  805f23ea nt!NtAccessCheck
80505578  805f5c20 nt!NtAccessCheckAndAuditAlarm
8050557c  805f241c nt!NtAccessCheckByType
80505580  805f5c5a nt!NtAccessCheckByTypeAndAuditAlarm
80505584  805f2452 nt!NtAccessCheckByTypeResultList
80505588  805f5c9e nt!NtAccessCheckByTypeResultListAndAuditAlarm
8050558c  805f5ce2 nt!NtAccessCheckByTypeResultListAndAuditAlarmByHandle
80505590  80616e80 nt!NtAddAtom
...

再下就是本文了。

功能:枚举SSDT。有的是分析PE文件的,觉得不太好。

made by correy
made at 2014.11.22


再看看一个宏:
#define SYSCALL_INDEX(_Function) (*(PULONG)((PUCHAR)_Function+1))
这是求一个函数的INDEX,输入是函数名/函数地址,不过这个函数特殊必须是SSDT。
0: kd> u nt!ZwQuerySystemInformation
nt!ZwQuerySystemInformation:
80501b0c b8ad000000      mov     eax,0ADh
80501b11 8d542404        lea     edx,[esp+4]
80501b15 9c              pushfd
80501b16 6a08            push    8
80501b18 e8f40a0400      call    nt!KiSystemService (80542611)
80501b1d c21000          ret     10h
nt!ZwQuerySystemTime:
80501b20 b8ae000000      mov     eax,0AEh
80501b25 8d542404        lea     edx,[esp+4]
也就是说函数的地址前移一个字节就是函数INDEX。这个宏的定义是一样的。

made at 2015.03.13
*/


#define TAG 'tset' //test


#if defined(_WIN64)
//啥也没有。
#else
//这里的内容摘自:REGMON的某个版本的代码。


// Definition for system call service table
typedef struct _SRVTABLE {
PVOID           *ServiceTable;
ULONG           LowCall;      
ULONG           HiCall;
PVOID    *ArgTable;
} SRVTABLE, *PSRVTABLE;


extern PSRVTABLE KeServiceDescriptorTable;// Pointer to the image of the system service table

// Macro for easy hook/unhook.
// On X86 implementations of Zw* functions, the DWORD following the first byte is the system call number, so we reach into the Zw function passed as a parameter, and pull the number out.
// This makes system call hooking dependent ONLY on the Zw* function implementation not changing.
//#if defined(_ALPHA_)
//#define SYSCALL(_function)  KeServiceDescriptorTable->ServiceTable[ (*(PULONG)_function)  & 0x0000FFFF ]
//#else
//#define SYSCALL(_function)  KeServiceDescriptorTable->ServiceTable[ *(PULONG)((PUCHAR)_function+1)]
//#endif

#endif


DRIVER_UNLOAD Unload;
VOID Unload(__in PDRIVER_OBJECT DriverObject)
{
 
 
}


VOID enumerate_SSDT()
{
    ULONG i = 0;

    for ( ; i < KeServiceDescriptorTable->HiCall ;i++ )
    {
        KdPrint(("第%d个函数的地址是:0x%p.\n", i, KeServiceDescriptorTable->ServiceTable[i]));

        /*
        这里要做的还有更多,如参数的个数,函数的名字,函数所在的模块(区分是不是被劫持)。
        根据函数的名字找到ID等。
        */
    }
}


DRIVER_INITIALIZE DriverEntry;
NTSTATUS DriverEntry( __in struct _DRIVER_OBJECT  * DriverObject, __in PUNICODE_STRING  RegistryPath)
{
    KdBreakPoint();

    DriverObject->DriverUnload = Unload;

    enumerate_SSDT();

    return 0;
}


-------------------------------------------------------------------------------------------------------------------------

#include <ntifs.h>
#include <windef.h>
#include <Aux_klib.h> //source里面要有TARGETLIBS=$(DDK_LIB_PATH)\Aux_klib.lib

/*
made by correy
made at 2015.04.11
*/

#define TAG  'tset' //test
#pragma pack(1)
typedef struct ServiceDescriptorEntry{
    unsigned int *ServiceTableBase;
    unsigned int *ServiceCounterTableBase; //Used only in checked build
    unsigned int NumberOfServices;
    unsigned char *ParamTableBase;
} ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;
#pragma pack()
extern __declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable;
#define SYSCALL_INDEX(_Function) (*(PULONG)((PUCHAR)_Function+1)) //获取SSDT函数的ID,X64没有测试和观察。
#define SYSTEMSERVICE(index) KeServiceDescriptorTable.ServiceTableBase[index]

DRIVER_UNLOAD Unload;
VOID Unload(__in PDRIVER_OBJECT DriverObject)
{
}

PVOID RtlImageDirectoryEntryToData (IN PVOID Base, IN BOOLEAN MappedAsImage, IN USHORT DirectoryEntry, OUT PULONG Size);

PVOID MiFindExportedRoutineByName (IN PVOID DllBase, IN PANSI_STRING AnsiImageRoutineName)
/*++
Routine Description:
    This function searches the argument module looking for the requested exported function name.
Arguments:
    DllBase - Supplies the base address of the requested module.
    AnsiImageRoutineName - Supplies the ANSI routine name being searched for.
Return Value:
    The virtual address of the requested routine or NULL if not found.
--*/
{
    USHORT OrdinalNumber;
    PULONG NameTableBase;
    PUSHORT NameOrdinalTableBase;
    PULONG Addr;
    LONG High;
    LONG Low;
    LONG Middle;
    LONG Result;
    ULONG ExportSize;
    PVOID FunctionAddress = 0;
    PIMAGE_EXPORT_DIRECTORY ExportDirectory;
    PAGED_CODE();
    __try
    {
        FunctionAddress = *(PVOID *)DllBase;
        FunctionAddress = 0;
    }
    __except(EXCEPTION_EXECUTE_HANDLER)
    {
        return FunctionAddress;
    } 
    //确保DllBase可以访问。否则蓝屏。
    ExportDirectory = (PIMAGE_EXPORT_DIRECTORY) RtlImageDirectoryEntryToData (DllBase, TRUE, IMAGE_DIRECTORY_ENTRY_EXPORT, &ExportSize);
    if (ExportDirectory == NULL) {
        return NULL;
    }
   
    NameTableBase = (PULONG)((PCHAR)DllBase + (ULONG)ExportDirectory->AddressOfNames);// Initialize the pointer to the array of RVA-based ansi export strings.   
    NameOrdinalTableBase = (PUSHORT)((PCHAR)DllBase + (ULONG)ExportDirectory->AddressOfNameOrdinals);// Initialize the pointer to the array of USHORT ordinal numbers.   
    Low = 0;
    Middle = 0;
    High = ExportDirectory->NumberOfNames - 1;
    while (High >= Low) // Lookup the desired name in the name table using a binary search.
    {       
        Middle = (Low + High) >> 1;// Compute the next probe index and compare the import name with the export name entry.
        Result = strcmp (AnsiImageRoutineName->Buffer, (PCHAR)DllBase + NameTableBase[Middle]);
        if (Result < 0) {
            High = Middle - 1;
        } else if (Result > 0) {
            Low = Middle + 1;
        } else {
            break;
        }
    }
    // If the high index is less than the low index, then a matching table entry was not found.
    // Otherwise, get the ordinal number from the ordinal table.
    if (High < Low) {
        return NULL;
    }
    OrdinalNumber = NameOrdinalTableBase[Middle];
    // If the OrdinalNumber is not within the Export Address Table,then this image does not implement the function.
    // Return not found.
    if ((ULONG)OrdinalNumber >= ExportDirectory->NumberOfFunctions) {
        return NULL;
    }
    // Index into the array of RVA export addresses by ordinal number.
    Addr = (PULONG)((PCHAR)DllBase + (ULONG)ExportDirectory->AddressOfFunctions);
    FunctionAddress = (PVOID)((PCHAR)DllBase + Addr[OrdinalNumber]);
    // Forwarders are not used by the kernel and HAL to each other.
    ASSERT ((FunctionAddress <= (PVOID)ExportDirectory) || (FunctionAddress >= (PVOID)((PCHAR)ExportDirectory + ExportSize)));
    return FunctionAddress;
}

PVOID get_module_image_base(__in UCHAR * name)
{
    NTSTATUS status = 0;
    ULONG  modulesSize;
    AUX_MODULE_EXTENDED_INFO * modules;
    ULONG  numberOfModules;
    ULONG i;
    PIMAGE_EXPORT_DIRECTORY pied = 0;
    PVOID ImageBase = 0;
    status = AuxKlibInitialize();
    if (!NT_SUCCESS( status ))
    {
        KdPrint(( "AuxKlibInitialize fail %d\n", status));
        return ImageBase;
    }   
   
    status = AuxKlibQueryModuleInformation(&modulesSize, sizeof(AUX_MODULE_EXTENDED_INFO), NULL);// Get the required array size.
    if (!NT_SUCCESS(status) || modulesSize == 0) {
        return ImageBase;
    }
   
    numberOfModules = modulesSize / sizeof(AUX_MODULE_EXTENDED_INFO);// Calculate the number of modules.
       
    modules = (AUX_MODULE_EXTENDED_INFO*) ExAllocatePoolWithTag(PagedPool, modulesSize, TAG);// Allocate memory to receive data.
    if (modules == NULL) {
        status = STATUS_INSUFFICIENT_RESOURCES;
        return ImageBase;
    }
    RtlZeroMemory(modules, modulesSize);
   
    status = AuxKlibQueryModuleInformation(&modulesSize, sizeof(AUX_MODULE_EXTENDED_INFO), modules);// Obtain the module information.
    if (!NT_SUCCESS(status)) {
        ExFreePoolWithTag(modules,TAG);
        return ImageBase;
    }
    for (i = 0;i<numberOfModules;i++)
    {
        UCHAR * pfilename = modules[i].FullPathName + modules[i].FileNameOffset;
        if (_stricmp(pfilename, name) == 0)
        {
            ImageBase = modules[i].BasicInfo.ImageBase;
            break;
        }
    }
    ExFreePoolWithTag(modules,TAG);
    return ImageBase;
}

ULONG get_ssdt_function_index(IN char * function_name)
    /*
    功能:获取SSDT函数的调用号。
          这里支持内核没有导出的SSDT的函数,即ntoskrnl.exe没有导出,而ntdll.dll导出的,在SSDT里有的函数。
    */
{
    PVOID ImageBase = 0;
    PVOID FunctionAddress;
    ANSI_STRING test  = RTL_CONSTANT_STRING(function_name);
    ImageBase = get_module_image_base("ntdll.dll");
    if (ImageBase == 0)
    {
        return -1;
    }
    FunctionAddress = MiFindExportedRoutineByName (ImageBase, &test);
    if (FunctionAddress == 0)
    {
        return -1;
    }      
    return SYSCALL_INDEX(FunctionAddress);
}

BOOL get_function_name_by_ssdt_index  (int index, OUT PANSI_STRING AnsiImageRoutineName)
/*++
--*/
{
    PULONG NameTableBase;
    PUSHORT NameOrdinalTableBase;
    ULONG Ordinals = 0;
    ULONG ExportSize;
    PIMAGE_EXPORT_DIRECTORY ExportDirectory;
    PVOID DllBase = 0;
    BOOL B = FALSE ;
    PAGED_CODE();
    if (AnsiImageRoutineName == NULL || AnsiImageRoutineName->Buffer == NULL)
    {
        return FALSE;
    }
    DllBase = get_module_image_base("ntdll.dll");
    if (DllBase == 0)
    {
        return FALSE;
    }
    //确保DllBase可以访问。否则蓝屏。
    ExportDirectory = (PIMAGE_EXPORT_DIRECTORY) RtlImageDirectoryEntryToData (DllBase, TRUE, IMAGE_DIRECTORY_ENTRY_EXPORT, &ExportSize);
    if (ExportDirectory == NULL) {
        return FALSE;
    }
   
    NameTableBase = (PULONG)((PCHAR)DllBase + (ULONG)ExportDirectory->AddressOfNames);// Initialize the pointer to the array of RVA-based ansi export strings.   
    NameOrdinalTableBase = (PUSHORT)((PCHAR)DllBase + (ULONG)ExportDirectory->AddressOfNameOrdinals);// Initialize the pointer to the array of USHORT ordinal numbers.   
    while (Ordinals < ExportDirectory->NumberOfNames) // Lookup the desired name in the name table using a binary search.
    {   
        PCHAR RoutineName = (PCHAR)DllBase + NameTableBase[Ordinals];
        //如果是Nt开头的函数。
        if (_strnicmp(RoutineName, "nt", 2) == 0)// || _strnicmp(RoutineName, "zw", 2) == 0
        {
            USHORT OrdinalNumber = NameOrdinalTableBase[Ordinals];
            // Index into the array of RVA export addresses by ordinal number.
            PULONG Addr = (PULONG)((PCHAR)DllBase + (ULONG)ExportDirectory->AddressOfFunctions);
            PVOID FunctionAddress = (PVOID)((PCHAR)DllBase + Addr[OrdinalNumber]);
            //这个函数的地址的第二个字节的INT等于index,就退出,并返回返函数的名字。
            if (SYSCALL_INDEX(FunctionAddress) == index)
            {
                RtlCopyMemory(AnsiImageRoutineName->Buffer, RoutineName, strlen(RoutineName));
                //KdPrint(("function_name:%s.\n", RoutineName));
                B = TRUE;
                break;
            }
        }
        Ordinals++;
    }   
    return B;
}

VOID enumerate_SSDT_32()
{
    ULONG i = 0;
    for ( ; i < KeServiceDescriptorTable.NumberOfServices ;i++ )
    {
        CHAR RoutineName[MAX_PATH] = {0};
        ANSI_STRING AnsiImageRoutineName = {0};
        AnsiImageRoutineName.Buffer = RoutineName;
        AnsiImageRoutineName.MaximumLength = MAX_PATH;
        get_function_name_by_ssdt_index  (i, &AnsiImageRoutineName);
        RtlInitAnsiString(&AnsiImageRoutineName, AnsiImageRoutineName.Buffer);
        KdPrint(("index:%d, address:0x%p, name:%Z.\n", i, KeServiceDescriptorTable.ServiceTableBase[i], &AnsiImageRoutineName));
        /*
        这里要做的还有更多,如参数的个数,函数的名字,函数所在的模块,原始的地址。
        */
    }
}

DRIVER_INITIALIZE DriverEntry;
NTSTATUS DriverEntry( __in struct _DRIVER_OBJECT  * DriverObject, __in PUNICODE_STRING  RegistryPath)
{
    NTSTATUS status = STATUS_UNSUCCESSFUL; 
    ULONG index = 0;
    PVOID p_NtCreateMutant = 0;
    KdBreakPoint();
    DriverObject->DriverUnload = Unload;   
    //index = get_ssdt_function_index("NtCreateMutant");
    //p_NtCreateMutant = (PVOID)SYSTEMSERVICE(index);//注意这个是Nt*的函数。
    enumerate_SSDT_32();
    return status;   
}

/*
0: kd> !process 0 0 explorer.exe
PROCESS 81d4d588  SessionId: 0  Cid: 0658    Peb: 7ffde000  ParentCid: 0604
    DirBase: 02940200  ObjectTable: e149da90  HandleCount: 379.
    Image: explorer.exe
0: kd> .process /r /p 81d4d588 
Implicit process is now 81d4d588
.cache forcedecodeuser done
Loading User Symbols
................................................................
........................
0: kd> u ntdll!ntcreatefile
ntdll!ZwCreateFile:
7c92d0ae b825000000      mov     eax,25h
7c92d0b3 ba0003fe7f      mov     edx,offset SharedUserData!SystemCallStub (7ffe0300)
7c92d0b8 ff12            call    dword ptr [edx]
7c92d0ba c22c00          ret     2Ch
*/

/*
1: kd> uf nt!Zwcreatefile
Flow analysis was incomplete, some code may be missing
nt!ZwCreateFile:
fffff800`018d8680 488bc4          mov     rax,rsp
fffff800`018d8683 fa              cli
fffff800`018d8684 4883ec10        sub     rsp,10h
fffff800`018d8688 50              push    rax
fffff800`018d8689 9c              pushfq
fffff800`018d868a 6a10            push    10h
fffff800`018d868c 488d05dd270000  lea     rax,[nt!KiServiceLinkage (fffff800`018dae70)]
fffff800`018d8693 50              push    rax
fffff800`018d8694 b852000000      mov     eax,52h 注意这个。
fffff800`018d8699 e9225f0000      jmp     nt!KiServiceInternal (fffff800`018de5c0)
nt!KiServiceInternal:
fffff800`018de5c0 4883ec08        sub     rsp,8
fffff800`018de5c4 55              push    rbp
fffff800`018de5c5 4881ec58010000  sub     rsp,158h
fffff800`018de5cc 488dac2480000000 lea     rbp,[rsp+80h]
fffff800`018de5d4 48899dc0000000  mov     qword ptr [rbp+0C0h],rbx
fffff800`018de5db 4889bdc8000000  mov     qword ptr [rbp+0C8h],rdi
fffff800`018de5e2 4889b5d0000000  mov     qword ptr [rbp+0D0h],rsi
fffff800`018de5e9 fb              sti
fffff800`018de5ea 65488b1c2588010000 mov   rbx,qword ptr gs:[188h]
fffff800`018de5f3 0f0d8bd8010000  prefetchw [rbx+1D8h]
fffff800`018de5fa 0fb6bbf6010000  movzx   edi,byte ptr [rbx+1F6h]
fffff800`018de601 40887da8        mov     byte ptr [rbp-58h],dil
fffff800`018de605 c683f601000000  mov     byte ptr [rbx+1F6h],0
fffff800`018de60c 4c8b93d8010000  mov     r10,qword ptr [rbx+1D8h]
fffff800`018de613 4c8995b8000000  mov     qword ptr [rbp+0B8h],r10
fffff800`018de61a 4c8d1d3d010000  lea     r11,[nt!KiSystemServiceStart (fffff800`018de75e)]
fffff800`018de621 41ffe3          jmp     r11
1: kd> !process 0 0 explorer.exe
PROCESS fffffa801ad91910
    SessionId: 1  Cid: 06a4    Peb: 7fffffdd000  ParentCid: 0680
    DirBase: 66ef5000  ObjectTable: fffff8a0011323b0  HandleCount: 755.
    Image: explorer.exe
1: kd> .process /p /r fffffa801ad91910
Implicit process is now fffffa80`1ad91910
.cache forcedecodeuser done
Loading User Symbols
................................................................
................................................................
...........
1: kd> uf ntdll!NtCreateFile
ntdll!ZwCreateFile:
00000000`77051860 4c8bd1          mov     r10,rcx
00000000`77051863 b852000000      mov     eax,52h 注意这个
00000000`77051868 0f05            syscall
00000000`7705186a c3              ret
知道64位SSDT的结构及地址,根据上面的示例不难写出X64的相应的例子。
*/