獲取指定句柄的類型號.
- 2019 年 10 月 8 日
- 筆記
目錄
一丶簡介
在windows系統下.句柄是很常用的. 騷操作的方法可以通過句柄拷貝方式拷貝到另一個進程讓其佔用句柄.比如獨佔文件. 但是有時候比如驅動想刪除文件.強刪文件的時候就會用到句柄類型. 但是此時一般都是寫死的.網上也很少相關資料.這裡就介紹一下.怎麼通過句柄獲取指定句柄類型(任何內核對象 句柄都可以使用) 下面以文件舉例
二丶原理與程式碼.
2.1原理
原理還是使用未文檔化的API
1.使用 ZwQuerySystemInformation 的16號功能遍歷全局句柄表 2.創建文件(什麼文件都可以)得出 文件句柄 3.遍歷句柄表,判斷文件句柄是否和遍歷出的句柄表中記錄的句柄一樣. 4.如果一樣.獲取句柄表中 objectindex即可.這個則是記錄的文件句柄.
2.2原理偽程式碼講解
主要是兩個結構體.在使用 ** ZwQuerySystemInformation**的時候遍歷的句柄的詳細資訊的結構
如下:
typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO { USHORT UniqueProcessId; USHORT CreatorBackTraceIndex; UCHAR ObjectTypeIndex; UCHAR HandleAttributes; USHORT HandleValue; PVOID Object; ULONG GrantedAccess; } SYSTEM_HANDLE_TABLE_ENTRY_INFO, *PSYSTEM_HANDLE_TABLE_ENTRY_INFO; //全局句柄記錄的個數 typedef struct _SYSTEM_HANDLE_INFORMATION { ULONG NumberOfHandles; SYSTEM_HANDLE_TABLE_ENTRY_INFO Handles[1]; } SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;
第一個結構體記錄的是句柄的詳細資訊 1.UniqueProcessId 記錄的進程ID 2.部落客暫未知. 3.ObjectTypeIndex 記錄的句柄的序號. 主要是獲取他. 4.HandleAttributes記錄的是句柄的屬性 5.HandleValue 記錄的是句柄值我們就是判斷他找objecttypeIndex 6.PVOID Object 記錄的是句柄的EPROCESS 7.GrantedAccess 記錄的句柄訪問許可權.
關於未公開函數直接 loadlibrary + GetProAddress獲取即可.
typedef NTSTATUS(WINAPI * PfnZwQuerySystemInformation)( IN ULONG SysInfoClass, IN OUT PVOID SystemInfroMation, IN ULONG SystemInforMationLength, OUT PULONG RetLen);
3.程式碼實現
核心程式碼如下:
PSYSTEM_HANDLE_INFORMATION pGlobaleHandleInfo = NULL; //全局句柄資訊 SYSTEM_HANDLE_TABLE_ENTRY_INFO HandleInfor = { 0 }; //句柄的詳細資訊. PVOID pBuffer = NULL; HANDLE hFile; DWORD dwNumberOfHandles = 0; //句柄的個數 InitFunction(); hFile = GetFileHandle(); pBuffer = RetSystemHandleInformation(); pGlobaleHandleInfo = reinterpret_cast<PSYSTEM_HANDLE_INFORMATION>(pBuffer); //獲得了句柄的相信資訊.隨便打開個文件句柄.判斷類型是否相等. dwNumberOfHandles = pGlobaleHandleInfo->NumberOfHandles; for (int i = 0; i < dwNumberOfHandles; i++) { HandleInfor = pGlobaleHandleInfo->Handles[i];//獲取句柄的相信資訊 if (GetCurrentProcessId() == HandleInfor.UniqueProcessId) { if (HandleInfor.HandleValue == (USHORT)hFile) { printf("hFile對應的文件類型為 %d rn", HandleInfor.ObjectTypeIndex); } } }
請注意順序.請先打開文件.然後在獲取全局句柄資訊.
總共使用了三個函數.一個是 初始化函數指針.另一個是返回全局句柄表.下一個就是打開自己.
關於打開自己完全可以打開別的文件.別的進程.只不過判斷的時候不能再GetProcessId了.
PfnZwQuerySystemInformation ZwQuerySystemInformation; void InitFunction() { HMODULE hDll = LoadLibrary(TEXT("ntdll.dll")); if (NULL == hDll) { return; } ZwQuerySystemInformation = reinterpret_cast<PfnZwQuerySystemInformation>(GetProcAddress(hDll, "ZwQuerySystemInformation")); if (NULL == ZwQuerySystemInformation) return; } PVOID RetSystemHandleInformation() { //返回系統句柄資訊. PULONG szBuffer = NULL; DWORD dwSize = 0x1000; DWORD dwRetSize = 0; NTSTATUS ntStatus; szBuffer = new ULONG[dwSize]; if (NULL == szBuffer) { return NULL; } //第一遍調用可能不成功.所以獲取返回值. 並且根據DwRetSize的值去重新申請空間 do { ntStatus = ZwQuerySystemInformation(SystemHandleInformation, szBuffer, dwSize, &dwRetSize); if (ntStatus == STATUS_INFO_LENGTH_MISMATCH) //代表空間不足.重新申請空間 { delete[] szBuffer; szBuffer = new ULONG[dwSize *= 2]; } else { if (!NT_SUCCESS(ntStatus)) { delete [] szBuffer; return NULL; } } } while (ntStatus == STATUS_INFO_LENGTH_MISMATCH); //成功返回資訊 return szBuffer; } HANDLE GetFileHandle() { //這裡打開自己 TCHAR tszPath[MAX_PATH] = { 0 }; GetModuleFileName(NULL,tszPath,MAX_PATH ); return CreateFile( tszPath, GENERIC_READ , FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); }
4.用到的結構
#pragma once #include <windows.h> #include <string> using namespace std; #ifdef UNICODE #define CBinString wstring #else #define CBinString string #endif #ifdef _WIN64 #define UBinSize DWORD64 #else #define UBinSize DWORD #endif typedef LONG NTSTATUS; #define STATUS_SUCCESS ((NTSTATUS)0x00000000L) #define STATUS_UNSUCCESSFUL ((NTSTATUS)0xC0000001L) #define STATUS_NOT_IMPLEMENTED ((NTSTATUS)0xC0000002L) #define STATUS_INVALID_INFO_CLASS ((NTSTATUS)0xC0000003L) #define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L) #define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0) //ZwQuerySystemInformation 需要用到的資訊 typedef enum _SYSTEM_INFORMATION_CLASS { SystemBasicInformation, // 0 Y N SystemProcessorInformation, // 1 Y N SystemPerformanceInformation, // 2 Y N SystemTimeOfDayInformation, // 3 Y N SystemNotImplemented1, // 4 Y N SystemProcessesAndThreadsInformation, // 5 Y N SystemCallCounts, // 6 Y N SystemConfigurationInformation, // 7 Y N SystemProcessorTimes, // 8 Y N SystemGlobalFlag, // 9 Y Y SystemNotImplemented2, // 10 Y N SystemModuleInformation, // 11 Y N SystemLockInformation, // 12 Y N SystemNotImplemented3, // 13 Y N SystemNotImplemented4, // 14 Y N SystemNotImplemented5, // 15 Y N SystemHandleInformation, // 16 Y N SystemObjectInformation, // 17 Y N SystemPagefileInformation, // 18 Y N SystemInstructionEmulationCounts, // 19 Y N SystemInvalidInfoClass1, // 20 SystemCacheInformation, // 21 Y Y SystemPoolTagInformation, // 22 Y N SystemProcessorStatistics, // 23 Y N SystemDpcInformation, // 24 Y Y SystemNotImplemented6, // 25 Y N SystemLoadImage, // 26 N Y SystemUnloadImage, // 27 N Y SystemTimeAdjustment, // 28 Y Y SystemNotImplemented7, // 29 Y N SystemNotImplemented8, // 30 Y N SystemNotImplemented9, // 31 Y N SystemCrashDumpInformation, // 32 Y N SystemExceptionInformation, // 33 Y N SystemCrashDumpStateInformation, // 34 Y Y/N SystemKernelDebuggerInformation, // 35 Y N SystemContextSwitchInformation, // 36 Y N SystemRegistryQuotaInformation, // 37 Y Y SystemLoadAndCallImage, // 38 N Y SystemPrioritySeparation, // 39 N Y SystemNotImplemented10, // 40 Y N SystemNotImplemented11, // 41 Y N SystemInvalidInfoClass2, // 42 SystemInvalidInfoClass3, // 43 SystemTimeZoneInformation, // 44 Y N SystemLookasideInformation, // 45 Y N SystemSetTimeSlipEvent, // 46 N Y SystemCreateSession, // 47 N Y SystemDeleteSession, // 48 N Y SystemInvalidInfoClass4, // 49 SystemRangeStartInformation, // 50 Y N SystemVerifierInformation, // 51 Y Y SystemAddVerifier, // 52 N Y SystemSessionProcessesInformation // 53 Y N } SYSTEM_INFORMATION_CLASS; //ZwQuerySystemInformation 遍歷系統所有句柄的句柄資訊 //句柄的詳細資訊 typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO { USHORT UniqueProcessId; USHORT CreatorBackTraceIndex; UCHAR ObjectTypeIndex; UCHAR HandleAttributes; USHORT HandleValue; PVOID Object; ULONG GrantedAccess; } SYSTEM_HANDLE_TABLE_ENTRY_INFO, *PSYSTEM_HANDLE_TABLE_ENTRY_INFO; //全局句柄記錄的個數 typedef struct _SYSTEM_HANDLE_INFORMATION { ULONG NumberOfHandles; SYSTEM_HANDLE_TABLE_ENTRY_INFO Handles[1]; } SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION; //******** typedef struct _LSA_UNICODE_STRING { USHORT Length; USHORT MaximumLength; PWSTR Buffer; } LSA_UNICODE_STRING, *PLSA_UNICODE_STRING, UNICODE_STRING, *PUNICODE_STRING; typedef struct _CLIENT_ID { HANDLE UniqueProcess; HANDLE UniqueThread; } CLIENT_ID; typedef enum _THREAD_STATE { StateInitialized, StateReady, StateRunning, StateStandby, StateTerminated, StateWait, StateTransition, StateUnknown } THREAD_STATE; typedef enum _KWAIT_REASON { Executive, FreePage, PageIn, PoolAllocation, DelayExecution, Suspended, UserRequest, WrExecutive, WrFreePage, WrPageIn, WrPoolAllocation, WrDelayExecution, WrSuspended, WrUserRequest, WrEventPair, WrQueue, WrLpcReceive, WrLpcReply, WrVirtualMemory, WrPageOut, WrRendezvous, Spare2, Spare3, Spare4, Spare5, Spare6, WrKernel } KWAIT_REASON; /*typedef struct _IO_COUNTERS { LARGE_INTEGER ReadOperationCount; //I/O讀操作數目 LARGE_INTEGER WriteOperationCount; //I/O寫操作數目 LARGE_INTEGER OtherOperationCount; //I/O其他操作數目 LARGE_INTEGER ReadTransferCount; //I/O讀數據數目 LARGE_INTEGER WriteTransferCount; //I/O寫數據數目 LARGE_INTEGER OtherTransferCount; //I/O其他操作數據數目 } IO_COUNTERS, *PIO_COUNTERS; */ typedef struct _VM_COUNTERS { ULONG PeakVirtualSize; //虛擬存儲峰值大小 ULONG VirtualSize; //虛擬存儲大小 ULONG PageFaultCount; //頁故障數目 ULONG PeakWorkingSetSize; //工作集峰值大小 ULONG WorkingSetSize; //工作集大小 ULONG QuotaPeakPagedPoolUsage; //分頁池使用配額峰值 ULONG QuotaPagedPoolUsage; //分頁池使用配額 ULONG QuotaPeakNonPagedPoolUsage; //非分頁池使用配額峰值 ULONG QuotaNonPagedPoolUsage; //非分頁池使用配額 ULONG PagefileUsage; //頁文件使用情況 ULONG PeakPagefileUsage; //頁文件使用峰值 } VM_COUNTERS, *PVM_COUNTERS; typedef LONG KPRIORITY; typedef struct _SYSTEM_THREADS { LARGE_INTEGER KernelTime; LARGE_INTEGER UserTime; LARGE_INTEGER CreateTime; ULONG WaitTime; PVOID StartAddress; CLIENT_ID ClientId; KPRIORITY Priority; KPRIORITY BasePriority; ULONG ContextSwitchCount; THREAD_STATE State; KWAIT_REASON WaitReason; } SYSTEM_THREADS, *PSYSTEM_THREADS; typedef struct _SYSTEM_PROCESSES { ULONG NextEntryDelta; ULONG ThreadCount; ULONG Reserved1[6]; LARGE_INTEGER CreateTime; LARGE_INTEGER UserTime; LARGE_INTEGER KernelTime; UNICODE_STRING ProcessName; KPRIORITY BasePriority; ULONG ProcessId; ULONG InheritedFromProcessId; ULONG HandleCount; ULONG Reserved2[2]; VM_COUNTERS VmCounters; IO_COUNTERS IoCounters; SYSTEM_THREADS Threads[1]; } SYSTEM_PROCESSES, *PSYSTEM_PROCESSES; typedef struct _SYSTEM_BASIC_INFORMATION { BYTE Reserved1[24]; PVOID Reserved2[4]; CCHAR NumberOfProcessors; } SYSTEM_BASIC_INFORMATION; typedef struct tagSYSTEM_MODULE_INFORMATION { ULONG Reserved[2]; PVOID Base; ULONG Size; ULONG Flags; USHORT Index; USHORT Unknown; USHORT LoadCount; USHORT ModuleNameOffset; CHAR ImageName[256]; } SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION; //ZwQueryInformationProcess 遍歷進程資訊. typedef enum _PROCESSINFOCLASS { ProcessBasicInformation = 0, ProcessQuotaLimits = 1, ProcessIoCounters = 2, ProcessVmCounters = 3, ProcessTimes = 4, ProcessBasePriority = 5, ProcessRaisePriority = 6, ProcessDebugPort = 7, ProcessExceptionPort = 8, ProcessAccessToken = 9, ProcessLdtInformation = 10, ProcessLdtSize = 11, ProcessDefaultHardErrorMode = 12, ProcessIoPortHandlers = 13, // Note: this is kernel mode only ProcessPooledUsageAndLimits = 14, ProcessWorkingSetWatch = 15, ProcessUserModeIOPL = 16, ProcessEnableAlignmentFaultFixup = 17, ProcessPriorityClass = 18, ProcessWx86Information = 19, ProcessHandleCount = 20, ProcessAffinityMask = 21, ProcessPriorityBoost = 22, ProcessDeviceMap = 23, ProcessSessionInformation = 24, ProcessForegroundInformation = 25, ProcessWow64Information = 26, ProcessImageFileName = 27, ProcessLUIDDeviceMapsEnabled = 28, ProcessBreakOnTermination = 29, ProcessDebugObjectHandle = 30, ProcessDebugFlags = 31, ProcessHandleTracing = 32, ProcessIoPriority = 33, ProcessExecuteFlags = 34, ProcessTlsInformation = 35, ProcessCookie = 36, ProcessImageInformation = 37, ProcessCycleTime = 38, ProcessPagePriority = 39, ProcessInstrumentationCallback = 40, ProcessThreadStackAllocation = 41, ProcessWorkingSetWatchEx = 42, ProcessImageFileNameWin32 = 43, ProcessImageFileMapping = 44, ProcessAffinityUpdateMode = 45, ProcessMemoryAllocationMode = 46, ProcessGroupInformation = 47, ProcessTokenVirtualizationEnabled = 48, ProcessOwnerInformation = 49, ProcessWindowInformation = 50, ProcessHandleInformation = 51, ProcessMitigationPolicy = 52, ProcessDynamicFunctionTableInformation = 53, ProcessHandleCheckingMode = 54, ProcessKeepAliveCount = 55, ProcessRevokeFileHandles = 56, ProcessWorkingSetControl = 57, ProcessHandleTable = 58, ProcessCheckStackExtentsMode = 59, ProcessCommandLineInformation = 60, ProcessProtectionInformation = 61, ProcessMemoryExhaustion = 62, ProcessFaultInformation = 63, ProcessTelemetryIdInformation = 64, ProcessCommitReleaseInformation = 65, ProcessReserved1Information = 66, ProcessReserved2Information = 67, ProcessSubsystemProcess = 68, ProcessInPrivate = 70, ProcessRaiseUMExceptionOnInvalidHandleClose = 71, ProcessSubsystemInformation = 75, ProcessWin32kSyscallFilterInformation = 79, ProcessEnergyTrackingState = 82, MaxProcessInfoClass // MaxProcessInfoClass should always be the last enum } PROCESSINFOCLASS; //ZwQueryinfromation資訊 typedef enum _RFILE_INFORMATION_CLASS { FileDirectoryInformation1 = 1, FileFullDirectoryInformation, FileBothDirectoryInformation, FileBasicInformation, FileStandardInformation, FileInternalInformation, FileEaInformation, FileAccessInformation, FileNameInformation, FileRenameInformation, FileLinkInformation, FileNamesInformation, FileDispositionInformation, FilePositionInformation, FileFullEaInformation, FileModeInformation, FileAlignmentInformation, FileAllInformation, FileAllocationInformation, FileEndOfFileInformation, FileAlternateNameInformation, FileStreamInformation, FilePipeInformation, FilePipeLocalInformation, FilePipeRemoteInformation, FileMailslotQueryInformation, FileMailslotSetInformation, FileCompressionInformation, FileObjectIdInformation, FileCompletionInformation, FileMoveClusterInformation, FileQuotaInformation, FileReparsePointInformation, FileNetworkOpenInformation, FileAttributeTagInformation, FileTrackingInformation, FileIdBothDirectoryInformation, FileIdFullDirectoryInformation, FileValidDataLengthInformation, FileShortNameInformation, FileIoCompletionNotificationInformation, FileIoStatusBlockRangeInformation, FileIoPriorityHintInformation, FileSfioReserveInformation, FileSfioVolumeInformation, FileHardLinkInformation, FileProcessIdsUsingFileInformation, FileNormalizedNameInformation, FileNetworkPhysicalNameInformation, FileIdGlobalTxDirectoryInformation, FileIsRemoteDeviceInformation, FileUnusedInformation, FileNumaNodeInformation, FileStandardLinkInformation, FileRemoteProtocolInformation, FileRenameInformationBypassAccessCheck, FileLinkInformationBypassAccessCheck, FileVolumeNameInformation, FileIdInformation, FileIdExtdDirectoryInformation, FileReplaceCompletionInformation, FileHardLinkFullIdInformation, FileIdExtdBothDirectoryInformation, FileMaximumInformation } RFILE_INFORMATION_CLASS, *PRFILE_INFORMATION_CLASS; typedef _Enum_is_bitflag_ enum _POOL_TYPE { NonPagedPool, NonPagedPoolExecute = NonPagedPool, PagedPool, NonPagedPoolMustSucceed = NonPagedPool + 2, DontUseThisType, NonPagedPoolCacheAligned = NonPagedPool + 4, PagedPoolCacheAligned, NonPagedPoolCacheAlignedMustS = NonPagedPool + 6, MaxPoolType, // // Define base types for NonPaged (versus Paged) pool, for use in cracking // the underlying pool type. // NonPagedPoolBase = 0, NonPagedPoolBaseMustSucceed = NonPagedPoolBase + 2, NonPagedPoolBaseCacheAligned = NonPagedPoolBase + 4, NonPagedPoolBaseCacheAlignedMustS = NonPagedPoolBase + 6, // // Note these per session types are carefully chosen so that the appropriate // masking still applies as well as MaxPoolType above. // NonPagedPoolSession = 32, PagedPoolSession = NonPagedPoolSession + 1, NonPagedPoolMustSucceedSession = PagedPoolSession + 1, DontUseThisTypeSession = NonPagedPoolMustSucceedSession + 1, NonPagedPoolCacheAlignedSession = DontUseThisTypeSession + 1, PagedPoolCacheAlignedSession = NonPagedPoolCacheAlignedSession + 1, NonPagedPoolCacheAlignedMustSSession = PagedPoolCacheAlignedSession + 1, NonPagedPoolNx = 512, NonPagedPoolNxCacheAligned = NonPagedPoolNx + 4, NonPagedPoolSessionNx = NonPagedPoolNx + 32, } _Enum_is_bitflag_ POOL_TYPE; typedef struct _PUBLIC_OBJECT_TYPE_INFORMATION { UNICODE_STRING TypeName; ULONG TotalNumberOfHandles; ULONG TotalNumberOfObjects; WCHAR Unused1[8]; ULONG HighWaterNumberOfHandles; ULONG HighWaterNumberOfObjects; WCHAR Unused2[8]; ACCESS_MASK InvalidAttributes; GENERIC_MAPPING GenericMapping; ACCESS_MASK ValidAttributes; BOOLEAN SecurityRequired; BOOLEAN MaintainHandleCount; USHORT MaintainTypeList; POOL_TYPE PoolType; ULONG DefaultPagedPoolCharge; ULONG DefaultNonPagedPoolCharge; BYTE Unknown2[16]; } PUBLIC_OBJECT_TYPE_INFORMATION, *PPUBLIC_OBJECT_TYPE_INFORMATION; //遍歷系統資訊 typedef NTSTATUS(WINAPI * PfnZwQuerySystemInformation)( IN ULONG SysInfoClass, IN OUT PVOID SystemInfroMation, IN ULONG SystemInforMationLength, OUT PULONG RetLen); typedef enum _OBJECT_INFORMATION_CLASS { ObjectBasicInformation = 0, //如果為1表示獲取名字資訊 ObjectFileInformation = 1, ObjectTypeInformation = 2 //表示獲取類型資訊 } OBJECT_INFORMATION_CLASS; //單獨對象獲取打開句柄的資訊 typedef NTSTATUS(WINAPI * PfnZwQueryObject)( _In_opt_ HANDLE Handle, //句柄 _In_ OBJECT_INFORMATION_CLASS ObjectInformationClass, //要獲取的類型資訊 PVOID ObjectInformation, //緩衝區 用戶模式下使用 NtQueryObject _In_ ULONG ObjectInformationLength, _Out_opt_ //緩衝區大小 PULONG ReturnLength); //返回長度 // NtQueryObject類型為0的資訊結構體 typedef struct _PUBLIC_OBJECT_BASIC_INFORMATION { ULONG Attributes; ACCESS_MASK GrantedAccess; ULONG HandleCount; ULONG PointerCount; ULONG Reserved[10]; } PUBLIC_OBJECT_BASIC_INFORMATION, *PPUBLIC_OBJECT_BASIC_INFORMATION; //查詢句柄資訊. typedef struct _OBJECT_NAME_INformATION { UNICODE_STRING Name; } OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION; //遍歷文件需要的資訊 typedef struct _IO_STATUS_BLOCK { #pragma warning(push) #pragma warning(disable: 4201) // we'll always use the Microsoft compiler union { NTSTATUS Status; PVOID Pointer; } DUMMYUNIONNAME; #pragma warning(pop) ULONG_PTR Information; } IO_STATUS_BLOCK, *PIO_STATUS_BLOCK; typedef struct _FILE_NAME_INFORMATION { ULONG FileNameLength; WCHAR FileName[1]; } FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION; typedef NTSTATUS(WINAPI * PfnNtQueryInformationFile)( HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FileInformation, ULONG Length, RFILE_INFORMATION_CLASS FileInformationClass ); //NtQueryObject類型為1的資訊結構體. //typedef struct __PUBLIC_OBJECT_TYPE_INFORMATION { // UNICODE_STRING TypeName; // ULONG Reserved[22]; //} PUBLIC_OBJECT_TYPE_INFORMATION, *PPUBLIC_OBJECT_TYPE_INFORMATION; //函數指針賦值. //遍歷某個進程的句柄資訊 typedef NTSTATUS(WINAPI* PfnZwQueryInformationProcess)( _In_ HANDLE ProcessHandle, _In_ PROCESSINFOCLASS ProcessInformationClass, //根據類型資訊獲取不同的資訊 _Out_ PVOID ProcessInformation, _In_ ULONG ProcessInformationLength, _Out_opt_ PULONG ReturnLength );
5.程式碼演示截圖.
6.附加
如果獲取句柄了. 還可以使用上面所說的 NtQueryObject來遍歷句柄的 其它資訊.