#include "stdafx.h" /* 枚举一个进程的句柄信息。 这是一个基本的功能。 一直想做而没有做。 网上也有好多的代码。 今天算是实现了。 本文修改自微软的CppFileHandle工程。 有一定的可信度。 made by correy made at 2014.06.25 homepage:http://correy.webs.com */ #pragma region Includes #include <windows.h> #include <assert.h> #pragma endregion #define STATUS_SUCCESS ((NTSTATUS)0x00000000L) #define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xc0000004L) #include <winternl.h> // Undocumented SYSTEM_INFORMATION_CLASS: SystemHandleInformation const SYSTEM_INFORMATION_CLASS SystemHandleInformation = (SYSTEM_INFORMATION_CLASS)16; // The NtQuerySystemInformation function and the structures that it returns are internal to the operating system and subject to change from one release of Windows to another. // To maintain the compatibility of your application, it is better not to use the function. typedef NTSTATUS (WINAPI * PFN_NTQUERYSYSTEMINFORMATION)( IN SYSTEM_INFORMATION_CLASS SystemInformationClass, OUT PVOID SystemInformation, IN ULONG SystemInformationLength, OUT PULONG ReturnLength OPTIONAL ); typedef NTSTATUS (WINAPI * PFN_ZwQueryObject)( __in_opt HANDLE Handle, __in OBJECT_INFORMATION_CLASS ObjectInformationClass, __out_bcount_opt(ObjectInformationLength) PVOID ObjectInformation, __in ULONG ObjectInformationLength, __out_opt PULONG ReturnLength ); // Undocumented structure: SYSTEM_HANDLE_INFORMATION typedef struct _SYSTEM_HANDLE { ULONG ProcessId; UCHAR ObjectTypeNumber; UCHAR Flags; USHORT Handle; PVOID Object; ACCESS_MASK GrantedAccess; } SYSTEM_HANDLE, *PSYSTEM_HANDLE; typedef struct _SYSTEM_HANDLE_INFORMATION { ULONG NumberOfHandles; SYSTEM_HANDLE Handles[1]; } SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION; ////摘自:\wrk\WindowsResearchKernel-WRK\WRK-v1.2\public\sdk\inc\ntobapi.h //typedef enum _OBJECT_INFORMATION_CLASS { // ObjectBasicInformation, // ObjectNameInformation, // ObjectTypeInformation, // ObjectTypesInformation, // ObjectHandleFlagInformation, // ObjectSessionInformation, // MaxObjectInfoClass // MaxObjectInfoClass should always be the last enum //} OBJECT_INFORMATION_CLASS; //摘自:\wrk\WindowsResearchKernel-WRK\WRK-v1.2\public\sdk\inc\ntobapi.h typedef struct _OBJECT_NAME_INFORMATION { // ntddk wdm nthal UNICODE_STRING Name; // ntddk wdm nthal } OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION; // ntddk wdm nthal BOOL SetPrivilege( //HANDLE hToken, // access token handle LPCTSTR lpszPrivilege, // name of privilege to enable/disable BOOL bEnablePrivilege // to enable or disable privilege ) { TOKEN_PRIVILEGES tp; LUID luid; HANDLE hToken; // Get a token for this process. if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { return( FALSE ); } if ( !LookupPrivilegeValue( NULL, // lookup privilege on local system lpszPrivilege, // privilege to lookup &luid ) ) // receives LUID of privilege { printf("LookupPrivilegeValue error: %u\n", GetLastError() ); return FALSE; } tp.PrivilegeCount = 1; tp.Privileges[0].Luid = luid; if (bEnablePrivilege) tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; else tp.Privileges[0].Attributes = 0; // Enable the privilege or disable all privileges. if ( !AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL) ) { printf("AdjustTokenPrivileges error: %u\n", GetLastError() ); return FALSE; } if (GetLastError() == ERROR_NOT_ALL_ASSIGNED) { printf("The token does not have the specified privilege. \n"); return FALSE; } return TRUE; } /*! * Enumerate all handles of the specified process using undocumented APIs. */ DWORD EnumerateProcessHandles(ULONG pid) { // The functions have no associated import library. // You must use the LoadLibrary and GetProcAddress functions to dynamically link to ntdll.dll. HINSTANCE hNtDll = LoadLibrary(_T("ntdll.dll")); assert(hNtDll != NULL); PFN_NTQUERYSYSTEMINFORMATION NtQuerySystemInformation = (PFN_NTQUERYSYSTEMINFORMATION)GetProcAddress(hNtDll, "NtQuerySystemInformation"); assert(NtQuerySystemInformation != NULL); PFN_ZwQueryObject NtQueryObject = (PFN_ZwQueryObject)GetProcAddress(hNtDll, "NtQueryObject"); assert(NtQueryObject != NULL); // NtQuerySystemInformation does not return the correct required buffer size if the buffer passed is too small. // Instead you must call the function while increasing the buffer size until the function no longer returns STATUS_INFO_LENGTH_MISMATCH. DWORD nSize = 4096, nReturn; PSYSTEM_HANDLE_INFORMATION pSysHandleInfo = (PSYSTEM_HANDLE_INFORMATION)HeapAlloc(GetProcessHeap(), 0, nSize); while (NtQuerySystemInformation(SystemHandleInformation, pSysHandleInfo, nSize, &nReturn) == STATUS_INFO_LENGTH_MISMATCH)// Get system handle information. { HeapFree(GetProcessHeap(), 0, pSysHandleInfo); nSize += 4096; pSysHandleInfo = (SYSTEM_HANDLE_INFORMATION*)HeapAlloc(GetProcessHeap(), 0, nSize); } /* 这个函数已经把整个系统的句柄信息都已经获取了。 当然还有别的信息,如进程等。 下面就是根据这些信息进行分类而已,如进程。 其实这个函数可以显示整个系统的句柄的详细信息。 */ DWORD dwhandles = 0;//一个进程的所有的句柄数量。 // Get the handle of the target process. // The handle will be used to duplicate the handles in the process. HANDLE hProcess = OpenProcess(PROCESS_DUP_HANDLE | PROCESS_QUERY_INFORMATION, FALSE, pid); if (hProcess == NULL) { _tprintf(_T("OpenProcess failed w/err 0x%08lx\n"), GetLastError()); return -1; } /* 打开这个函数需要权限,经测试系统进程提权也打不开。 经测试: 在XP上可以打开系统进程(system)。 在Windows 7上,提权,以管理员(administrator)权限,甚至以服务的权限(NT AUTHORITY\SYSTEM)都不行,估计的会话隔离导致(可服务应该也在会话0,所以还是驱动的权限大)。 */ for (ULONG i = 0; i < pSysHandleInfo->NumberOfHandles; i++) { PSYSTEM_HANDLE pHandle = &(pSysHandleInfo->Handles[i]); //根据进程进行搜索。 if (pHandle->ProcessId == pid) { dwhandles++; // Increase the number of handles /* 经测试发现:EtwRegistration(39)类型的句柄会失败。 0x00000032 不支持该请求。 */ HANDLE hCopy;// Duplicate the handle in the current process if (!DuplicateHandle(hProcess, (HANDLE)pHandle->Handle, GetCurrentProcess(), &hCopy, MAXIMUM_ALLOWED, FALSE, 0)) { wprintf(L"DuplicateHandle fail with 0x%x,HANDLE:0x%x,ObjectTypeNumber:%d file:%s,fun:%s,line:%d\n", GetLastError(),pHandle->Handle, pHandle->ObjectTypeNumber, __FILE__,__FUNCTION__, __LINE__); continue; } /* 在这里可以利用复制的句柄进行一些操作,如查询值。 */ ULONG ObjectInformationLength = sizeof (OBJECT_NAME_INFORMATION) + 512; POBJECT_NAME_INFORMATION poni = (POBJECT_NAME_INFORMATION)HeapAlloc(GetProcessHeap(), 0, ObjectInformationLength); assert(poni != NULL); ULONG ReturnLength; /* 如果句柄的类型是TOKEN,线程,进程等类型的,需要再特殊的处理。 也就是说这个函数是查询不到的。 */ if (NtQueryObject(hCopy, (OBJECT_INFORMATION_CLASS)1, poni, ObjectInformationLength, &ReturnLength) != STATUS_SUCCESS) { wprintf(L"NtQueryObject fail!\n"); HeapFree(GetProcessHeap(), 0, poni); continue; } wprintf(L"HANDLE:0x%x, NAME:%wZ\n", pHandle->Handle, &poni->Name); HeapFree(GetProcessHeap(), 0, poni); CloseHandle(hCopy); } //可以显示整个系统的句柄信息。 //wprintf(L"PID:0x%x\n", pHandle->ProcessId); //wprintf(L"\tHANDLE:0x%x\n", pHandle->Handle); } CloseHandle(hProcess); HeapFree(GetProcessHeap(), 0, pSysHandleInfo);// Clean up. return dwhandles;// Return the number of handles in the process } int _tmain(int argc, _TCHAR* argv[]) { BOOL B = SetPrivilege(SE_DEBUG_NAME, TRUE); DWORD dwFiles = EnumerateProcessHandles(3264);//GetCurrentProcessId() return 0; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #include <ntifs.h> #include <windef.h> /* 内核版的枚举系统/进程的句柄及其信息的代码。 made by correy made at 2014.06.26 homepage:http://correy.webs.com 不当之处,请指正。 */ //这些在WDK 7600.16385.1中没有定义,在WDK8.0中定义了. //以下代码是解决办法之一. #ifndef _In_ #define _Inout_ #define _In_ #define _In_opt_ #define _Out_opt_ #endif //摘自:\wrk\WindowsResearchKernel-WRK\WRK-v1.2\public\sdk\inc\ntexapi.h // System Information Classes. typedef enum _SYSTEM_INFORMATION_CLASS { SystemBasicInformation, SystemProcessorInformation, // obsolete...delete SystemPerformanceInformation, SystemTimeOfDayInformation, SystemPathInformation, SystemProcessInformation, SystemCallCountInformation, SystemDeviceInformation, SystemProcessorPerformanceInformation, SystemFlagsInformation, SystemCallTimeInformation, SystemModuleInformation, SystemLocksInformation, SystemStackTraceInformation, SystemPagedPoolInformation, SystemNonPagedPoolInformation, SystemHandleInformation,//ExpGetHandleInformation处理的。 SystemObjectInformation, SystemPageFileInformation, SystemVdmInstemulInformation, SystemVdmBopInformation, SystemFileCacheInformation, SystemPoolTagInformation, SystemInterruptInformation, SystemDpcBehaviorInformation, SystemFullMemoryInformation, SystemLoadGdiDriverInformation, SystemUnloadGdiDriverInformation, SystemTimeAdjustmentInformation, SystemSummaryMemoryInformation, SystemMirrorMemoryInformation, SystemPerformanceTraceInformation, SystemObsolete0, SystemExceptionInformation, SystemCrashDumpStateInformation, SystemKernelDebuggerInformation, SystemContextSwitchInformation, SystemRegistryQuotaInformation, SystemExtendServiceTableInformation, SystemPrioritySeperation, SystemVerifierAddDriverInformation, SystemVerifierRemoveDriverInformation, SystemProcessorIdleInformation, SystemLegacyDriverInformation, SystemCurrentTimeZoneInformation, SystemLookasideInformation, SystemTimeSlipNotification, SystemSessionCreate, SystemSessionDetach, SystemSessionInformation, SystemRangeStartInformation, SystemVerifierInformation, SystemVerifierThunkExtend, SystemSessionProcessInformation, SystemLoadGdiDriverInSystemSpace, SystemNumaProcessorMap, SystemPrefetcherInformation, SystemExtendedProcessInformation, SystemRecommendedSharedDataAlignment, SystemComPlusPackage, SystemNumaAvailableMemory, SystemProcessorPowerInformation, SystemEmulationBasicInformation, SystemEmulationProcessorInformation, SystemExtendedHandleInformation, SystemLostDelayedWriteInformation, SystemBigPoolInformation, SystemSessionPoolTagInformation, SystemSessionMappedViewInformation, SystemHotpatchInformation, SystemObjectSecurityMode, SystemWatchdogTimerHandler, SystemWatchdogTimerInformation, SystemLogicalProcessorInformation, SystemWow64SharedInformation, SystemRegisterFirmwareTableInformationHandler, SystemFirmwareTableInformation, SystemModuleInformationEx, SystemVerifierTriageInformation, SystemSuperfetchInformation, SystemMemoryListInformation, SystemFileCacheInformationEx, MaxSystemInfoClass // MaxSystemInfoClass should always be the last enum } SYSTEM_INFORMATION_CLASS; //摘自:\wrk\WindowsResearchKernel-WRK\WRK-v1.2\public\sdk\inc\ntexapi.h 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; //摘自:\wrk\WindowsResearchKernel-WRK\WRK-v1.2\public\sdk\inc\ntexapi.h typedef struct _SYSTEM_HANDLE_INFORMATION { ULONG NumberOfHandles; SYSTEM_HANDLE_TABLE_ENTRY_INFO Handles[ 1 ]; } SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION; //摘自:\wrk\WindowsResearchKernel-WRK\WRK-v1.2\public\sdk\inc\ntobapi.h //typedef enum _OBJECT_INFORMATION_CLASS { // ObjectBasicInformation, // ObjectNameInformation, // ObjectTypeInformation, // ObjectTypesInformation, // ObjectHandleFlagInformation, // ObjectSessionInformation, // MaxObjectInfoClass // MaxObjectInfoClass should always be the last enum //} OBJECT_INFORMATION_CLASS; //摘自:\wrk\WindowsResearchKernel-WRK\WRK-v1.2\public\sdk\inc\ntobapi.h //typedef struct _OBJECT_NAME_INFORMATION { // ntddk wdm nthal // UNICODE_STRING Name; // ntddk wdm nthal //} OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION; // ntddk wdm nthal /* 摘自:http://msdn.microsoft.com/en-us/library/windows/desktop/ms724509(v=vs.85).aspx。 有修改。 */ NTSTATUS /* WINAPI NtQuerySystemInformation */ ZwQuerySystemInformation(_In_ SYSTEM_INFORMATION_CLASS SystemInformationClass, _Inout_ PVOID SystemInformation, _In_ ULONG SystemInformationLength, _Out_opt_ PULONG ReturnLength); //摘自:\wrk\WindowsResearchKernel-WRK\WRK-v1.2\public\internal\base\inc\zwapi.h NTSTATUS ZwAdjustPrivilegesToken(IN HANDLE TokenHandle, IN BOOLEAN DisableAllPrivileges, IN PTOKEN_PRIVILEGES NewState OPTIONAL, IN ULONG BufferLength OPTIONAL, OUT PTOKEN_PRIVILEGES PreviousState OPTIONAL, OUT PULONG ReturnLength); #define tag 'tset' //test static NTSTATUS AdjustPrivilege(ULONG Privilege, BOOLEAN Enable) /* 摘自:http://www.osronline.com/article.cfm?article=23 */ { NTSTATUS status; TOKEN_PRIVILEGES privSet; HANDLE tokenHandle; TOKEN_PRIVILEGES tokenPriv; status = ZwOpenProcessTokenEx(NtCurrentProcess(), TOKEN_ALL_ACCESS, OBJ_KERNEL_HANDLE , &tokenHandle);// Open current process token if (!NT_SUCCESS(status)) { DbgPrint("NtOpenProcessToken failed, status 0x%x\n", status); return status; } // Set up the information about the privilege we are adjusting privSet.PrivilegeCount = 1; privSet.Privileges[0].Luid = RtlConvertUlongToLuid(Privilege); if (Enable) { privSet.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; } else { privSet.Privileges[0].Attributes = 0; } status = ZwAdjustPrivilegesToken(tokenHandle, FALSE, // don't disable all privileges &privSet, sizeof(privSet), NULL, // old privileges - don't care NULL); // returned length if (!NT_SUCCESS(status)) { DbgPrint("ZwAdjustPrivilegesToken failed, status 0x%x\n", status); } (void) ZwClose(tokenHandle);// Close the process token handle return status; } DRIVER_UNLOAD Unload; VOID Unload(__in PDRIVER_OBJECT DriverObject) { } NTSTATUS ZwQueryObjectNameByHandle(IN HANDLE Handle, OUT UNICODE_STRING * p_object_name) { unsigned int status = STATUS_UNSUCCESSFUL; PVOID Object; KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); ULONG Length = 1024;//取这个数的原因:参看ObQueryNameString函数的第三个参数的说明:A reasonable size for the buffer to accommodate most object names is 1024 bytes. POBJECT_NAME_INFORMATION pu = 0; status = ObReferenceObjectByHandle( Handle, 0, NULL, PreviousMode, &Object, 0 ); if (!NT_SUCCESS( status )) { return( status ); } Length = 0; status = ObQueryNameString(Object, pu, 0, &Length); if (status != STATUS_INFO_LENGTH_MISMATCH) { KdPrint(("ObQueryNameString fail with 0x%X!\n",status)); ObDereferenceObject(Object); return status; } Length += 512; pu = (POBJECT_NAME_INFORMATION)ExAllocatePoolWithTag(NonPagedPool, Length, tag ); if (pu == 0) { ObDereferenceObject(Object); return status; } RtlZeroMemory(pu, Length); status = ObQueryNameString(Object, pu, Length, &Length); if (status != STATUS_SUCCESS ) { /* 经查此时的返回值是0xC0000001。 即连到系统上的设备没有发挥作用。 此时的句柄的类型是文件。 而且process explorer也是显示的是没有值的。 */ KdPrint(("ObQueryNameString fail with 0x%X!\n",status)); ExFreePoolWithTag(pu, tag ); ObDereferenceObject(Object); return status; } ObDereferenceObject(Object); //有的对象是没有名字的。 if (pu->Name.Length == 0) { status = STATUS_UNSUCCESSFUL; } else { RtlCopyUnicodeString(p_object_name,&pu->Name); //p_object_name->Buffer = pu->Name.Buffer; //p_object_name->Length = pu->Name.Length; //p_object_name->MaximumLength = pu->Name.MaximumLength; } ExFreePoolWithTag(pu, tag ); return status; } NTSTATUS EnumerateProcessHandles(IN HANDLE pid, OUT DWORD * process_handle ) { unsigned int status = STATUS_UNSUCCESSFUL; DWORD nSize = 4096, nReturn; PSYSTEM_HANDLE_INFORMATION pSysHandleInfo; CLIENT_ID ClientId = {0};//不初始化ZwOpenProcess有问题。 HANDLE ProcessHandle; DWORD dwhandles = 0;//一个进程的所有的句柄数量。 ULONG i = 0; OBJECT_ATTRIBUTES ob; pSysHandleInfo = (PSYSTEM_HANDLE_INFORMATION)ExAllocatePoolWithTag( NonPagedPool, nSize, tag); if (pSysHandleInfo == NULL) { KdPrint(("ExAllocatePoolWithTag fail with 0x%x, file:%s,fun:%s,line:%d\n",status, __FILE__,__FUNCTION__, __LINE__)); return STATUS_INSUFFICIENT_RESOURCES; } RtlZeroMemory(pSysHandleInfo, nSize); while (ZwQuerySystemInformation(SystemHandleInformation, pSysHandleInfo, nSize, &nReturn) == STATUS_INFO_LENGTH_MISMATCH)// Get system handle information. { ExFreePoolWithTag( pSysHandleInfo, tag ); nSize += 4096; pSysHandleInfo = (SYSTEM_HANDLE_INFORMATION*)(PSYSTEM_HANDLE_INFORMATION)ExAllocatePoolWithTag( NonPagedPool, nSize, tag); if (pSysHandleInfo == NULL) { KdPrint(("ExAllocatePoolWithTag fail with 0x%x, file:%s,fun:%s,line:%d\n",status, __FILE__,__FUNCTION__, __LINE__)); return STATUS_INSUFFICIENT_RESOURCES; } RtlZeroMemory(pSysHandleInfo, nSize); } ClientId.UniqueProcess = pid ; InitializeObjectAttributes(&ob, 0, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, 0, 0); status = ZwOpenProcess(&ProcessHandle, GENERIC_ALL, &ob, &ClientId); if (!NT_SUCCESS(status)) { KdPrint(("ZwOpenProcess fail with 0x%x, file:%s,fun:%s,line:%d\n",status, __FILE__,__FUNCTION__, __LINE__)); ExFreePoolWithTag( pSysHandleInfo, tag ); return status; } for (; i < pSysHandleInfo->NumberOfHandles; i++) { PSYSTEM_HANDLE_TABLE_ENTRY_INFO pHandle = &(pSysHandleInfo->Handles[i]); //根据进程进行搜索。 if (pHandle->UniqueProcessId == (int)pid) { HANDLE hCopy;// Duplicate the handle in the current process PVOID ObjectInformation = 0; ULONG ObjectInformationLength = 0; ULONG ReturnLength = 0; PPUBLIC_OBJECT_TYPE_INFORMATION ppoti = 0; UNICODE_STRING object_name; dwhandles++; // Increase the number of handles /* 访问系统进程中句柄类型为进程的IDLE句柄会返回0xc0000022.即拒绝访问。 process explorer也是如此。估计是显示的PSYSTEM_HANDLE_TABLE_ENTRY_INFO的内容。 pchunter没有显示句柄为进程和线程的信息。但是process explorer能。 process explorer默认的情况下是不显示没有名字的句柄的MAPPINGS的。但是可以设置和修改。 */ status = ZwDuplicateObject(ProcessHandle, (HANDLE)pHandle->HandleValue, NtCurrentProcess(), &hCopy, PROCESS_ALL_ACCESS , FALSE, DUPLICATE_SAME_ACCESS); if (!NT_SUCCESS(status)) { KdPrint(("ZwDuplicateObject fail with 0x%x, file:%s,fun:%s,line:%d\n",status, __FILE__,__FUNCTION__, __LINE__)); continue; } //status = ZwQueryObject(hCopy, ObjectTypeInformation, ObjectInformation, ObjectInformationLength, &ReturnLength); //if (status == STATUS_BUFFER_OVERFLOW || status == STATUS_BUFFER_TOO_SMALL) //{ // ObjectInformationLength = ReturnLength; //} //else //{ // //continue; // break;//程序发出命令,但命令长度不正确。 C0000004 //} //查询句柄类型,这是字符串。 ObjectInformationLength = sizeof (PUBLIC_OBJECT_TYPE_INFORMATION) * 2;//这个应该再增加点。加个512应该合适点。 ObjectInformation = ExAllocatePoolWithTag( NonPagedPool, ObjectInformationLength, tag); if (ObjectInformation == NULL) { KdPrint(("ExAllocatePoolWithTag fail with 0x%x, file:%s,fun:%s,line:%d\n",status, __FILE__,__FUNCTION__, __LINE__)); ZwClose(hCopy); return STATUS_INSUFFICIENT_RESOURCES; } RtlZeroMemory(ObjectInformation, ObjectInformationLength); status = ZwQueryObject(hCopy, ObjectTypeInformation, ObjectInformation, ObjectInformationLength, &ReturnLength); if (!NT_SUCCESS(status)) { KdPrint(("ZwQueryObject fail with 0x%x, file:%s,fun:%s,line:%d\n",status, __FILE__,__FUNCTION__, __LINE__)); ExFreePoolWithTag( ObjectInformation, tag ); ZwClose(hCopy); return status; } object_name.Buffer = ExAllocatePoolWithTag(NonPagedPool, MAX_PATH, tag ); if (object_name.Buffer == 0) { KdPrint(("ExAllocatePoolWithTag fail with 0x%x, file:%s,fun:%s,line:%d\n",status, __FILE__,__FUNCTION__, __LINE__)); ExFreePoolWithTag( ObjectInformation, tag ); ZwClose(hCopy); return status; } RtlZeroMemory(object_name.Buffer, MAX_PATH); RtlInitEmptyUnicodeString(&object_name, object_name.Buffer,MAX_PATH); ppoti = (PPUBLIC_OBJECT_TYPE_INFORMATION)ObjectInformation; /* 如果要查询句柄的值的名字,可以: 1.用ZwQueryObject的未公开的ObjectNameInformation。其实这是使用ObReferenceObjectByHandle+ObpQueryNameString实现的。 2.ObReferenceObjectByHandle+ObQueryNameString。 */ status = ZwQueryObjectNameByHandle(hCopy, &object_name); if (NT_SUCCESS(status)) { KdPrint(("HANDLE:0x%x, TYPE:%wZ, NAME:%wZ\n",pHandle->HandleValue, &ppoti->TypeName, &object_name)); RtlFreeUnicodeString(&object_name); //ExFreePoolWithTag(object_name.Buffer, tag ); } else { KdPrint(("HANDLE:0x%x, TYPE:%wZ\n",pHandle->HandleValue, &ppoti->TypeName)); } status = ZwClose(hCopy); //if (!NT_SUCCESS(status)) //{//有的句柄保护起来,是不准关闭的。 // KdPrint(("ZwClose fail with 0x%x, file:%s,fun:%s,line:%d\n",status, __FILE__,__FUNCTION__, __LINE__)); // ExFreePoolWithTag( pSysHandleInfo, tag ); // ExFreePoolWithTag( ObjectInformation, tag ); // return status; //} ExFreePoolWithTag( ObjectInformation, tag ); } } status = ZwClose(ProcessHandle); /*if (!NT_SUCCESS(status)) {//可能有的句柄已经释放了。 KdPrint(("ZwClose fail with 0x%x, file:%s,fun:%s,line:%d\n",status, __FILE__,__FUNCTION__, __LINE__)); ExFreePoolWithTag( pSysHandleInfo, tag ); return status; } */ ExFreePoolWithTag( pSysHandleInfo, tag ); * process_handle = dwhandles; return status; } DRIVER_INITIALIZE DriverEntry; NTSTATUS DriverEntry( __in struct _DRIVER_OBJECT * DriverObject, __in PUNICODE_STRING RegistryPath) { unsigned int status = STATUS_UNSUCCESSFUL; DWORD process_handle = 0; HANDLE test_handle = PsGetProcessId(PsInitialSystemProcess);//(HANDLE)1652;//PsGetProcessId(PsInitialSystemProcess);//获取系统进程的id,实用型很强,可以在别处使用,不只是驱动的入口。 KdBreakPoint(); DriverObject->DriverUnload = Unload; status = AdjustPrivilege(SE_DEBUG_PRIVILEGE, TRUE); if (!NT_SUCCESS(status)) { DbgPrint("AdjustPrivilege SE_RESTORE_PRIVILEGE fail!\n"); return status; } status = EnumerateProcessHandles(test_handle, &process_handle); if (!NT_SUCCESS(status)) { KdPrint(("EnumerateProcessHandles fail with 0x%x, file:%s,fun:%s,line:%d\n",status, __FILE__,__FUNCTION__, __LINE__)); return status; } return status;//STATUS_SUCCESS }
2014年6月25日星期三
枚举枚举系统/进程的句柄的信息
订阅:
博文评论 (Atom)
没有评论:
发表评论