/*************************************************************************************** * AUTHOR : yifi * DATE : 2016-10-8 * MODULE : ObjectDir.C * * Command: * Source of IOCTRL Sample Driver * * Description: * Demonstrates communications between USER and KERNEL. * **************************************************************************************** * Copyright (C) 2010 yifi. ****************************************************************************************/ //####################################################################################### //# I N C L U D E S //####################################################################################### #ifndef CXX_OBJECTDIR_H # include "ObjectDir.h" #endif #define NO_USE(a) (a) #define MAX_TABLE 37 #define MAX_OBJECT_COUNT 0x10000 //global RTL_OSVERSIONINFOW glpVersionInformation; VOID GetObpRootDirectoryObject(PVOID* pObpRootDirectoryObject)//通过_kpcr 结构来获取 ObpRootDirectoryObject的地址 { PVOID KdVersionBlock; PKDDEBUGGER_DATA64 KdDebuggerData64; KeSetSystemAffinityThread(1); __asm { mov eax, fs:[0x34]//KdVersionBlock’s offset in KPCR is 0x34 mov KdVersionBlock, eax } KdDebuggerData64 = (PKDDEBUGGER_DATA64)((ULONG_PTR)KdVersionBlock + sizeof(DBGKD_GET_VERSION64)); *pObpRootDirectoryObject = (PVOID)KdDebuggerData64->ObpRootDirectoryObject; KeRevertToUserAffinityThread(); } VOID MyUnLoad(PDRIVER_OBJECT DriverObject) { NO_USE(DriverObject); //------------- } void EnumObjectDirectory(POBJECT_DIRECTORY ObpRootDirectoryObject) { ULONG u_Index; ULONG u_ObType; ULONG* uObTypeIndexTable; POBJECT_DIRECTORY_ENTRY pObEntry; UNICODE_STRING usType; UNICODE_STRING usNamedType; UNICODE_STRING usObGetObjectType; RtlInitUnicodeString(&usObGetObjectType, L"ObGetObjectType"); RtlInitUnicodeString(&usType, L"Directory"); RtlInitUnicodeString(&usNamedType, L"Type"); for (u_Index = 0; u_Index < MAX_TABLE; u_Index++) { pObEntry = (POBJECT_DIRECTORY_ENTRY)(ObpRootDirectoryObject->HashBuckets[u_Index]); if (!MmIsAddressValid(pObEntry)) { continue; } do { u_ObType = (ULONG)(pObEntry->Object); //这样写纯粹是出于空间换效率考虑所以才会重复的这么厉害,原因么?递归太慢,复制粘贴比较方便 if (glpVersionInformation.dwMajorVersion == 6)//版本号判断 { ////通过硬编码获得表的地址,然后通过表的地址 获得 对象类型,不过这个 函数本身似乎具有这样的功能,可能这里 只用个函数指针就能搞定 //uObTypeIndexTable = (PULONG)*(ULONG*)((ULONG)MmGetSystemRoutineAddress(&usObGetObjectType) + 0xF); //KdPrint(("0x%X", uObTypeIndexTable)); //POBJECT_TYPE_WIN7 pObjType = (POBJECT_TYPE_WIN7)uObTypeIndexTable[(*(UCHAR*)(u_ObType - 0xC))]; //if (RtlCompareUnicodeString(&usNamedType, &pObjType->Name, FALSE) == 0) //{ // KdPrint(("%X----%wZ----%wZ ", pObEntry, &((POBJECT_TYPE_WIN7)u_ObType)->Name, &pObjType->Name)); //} //else //{ // KdPrint(("%X----%wZ----%wZ ", pObEntry, &((POBJECT_HEADER_NAME_INFO)(u_ObType - 0x28))->Name, &pObjType->Name)); //} //if (RtlCompareUnicodeString(&usType, &pObjType->Name, FALSE) == 0) //{ // KdPrint(("//////////////////////////////////////////// ")); // EnumObjectDirectory((POBJECT_DIRECTORY)u_ObType);//递归开始!! // KdPrint(("============================================ ")); //} } else//Xp { POBJECT_TYPE_XP pObjType = (POBJECT_TYPE_XP)(*(ULONG*)(u_ObType - 0x10)); if (RtlCompareUnicodeString(&usNamedType, &pObjType->Name, FALSE) == 0) { KdPrint(("%X----%wZ----%wZ ", pObEntry, &((POBJECT_TYPE_XP)u_ObType)->Name, &pObjType->Name)); } else { KdPrint(("%X----%wZ----%wZ ", pObEntry, &((POBJECT_HEADER_NAME_INFO)(u_ObType - 0x28))->Name, &pObjType->Name)); } if (RtlCompareUnicodeString(&usType, &pObjType->Name, FALSE) == 0) { KdPrint(("//////////////////////////////////////////// ")); EnumObjectDirectory((POBJECT_DIRECTORY)u_ObType);//递归开始! KdPrint(("============================================ ")); } } pObEntry = pObEntry->ChainLink; } while (pObEntry != NULL); } } NTSTATUS DriverEntry( PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath ) { //NO_USE(RegistryPath); /* 基本驱动框架结构 */ POBJECT_DIRECTORY* ObpRootDirectoryObject; GetObpRootDirectoryObject(&(PVOID)ObpRootDirectoryObject); RtlGetVersion(&glpVersionInformation); if (!MmIsAddressValid(ObpRootDirectoryObject)) { KdPrint(("ObpRootDirectoryObject is null")); return STATUS_UNSUCCESSFUL; } EnumObjectDirectory(*ObpRootDirectoryObject); DriverObject->DriverUnload = (PDRIVER_UNLOAD)MyUnLoad; return STATUS_SUCCESS; } /*************************************************************************************** * AUTHOR : yifi * DATE : 2016-10-8 * MODULE : ObjectDir.H * * IOCTRL Sample Driver * * Description: * Demonstrates communications between USER and KERNEL. * **************************************************************************************** * Copyright (C) 2010 yifi. ****************************************************************************************/ #ifndef CXX_OBJECTDIR_H #define CXX_OBJECTDIR_H #include <ntifs.h> // // This structure is used by the debugger for all targets // It is the same size as DBGKD_DATA_HEADER on all systems // typedef struct _DBGKD_DEBUG_DATA_HEADER64 { // // Link to other blocks // LIST_ENTRY64 List; // // This is a unique tag to identify the owner of the block. // If your component only uses one pool tag, use it for this, too. // ULONG OwnerTag; // // This must be initialized to the size of the data block, // including this structure. // ULONG Size; } DBGKD_DEBUG_DATA_HEADER64, *PDBGKD_DEBUG_DATA_HEADER64; typedef struct _KDDEBUGGER_DATA64 { DBGKD_DEBUG_DATA_HEADER64 Header; // // Base address of kernel image // ULONG64 KernBase; // // DbgBreakPointWithStatus is a function which takes an argument // and hits a breakpoint. This field contains the address of the // breakpoint instruction. When the debugger sees a breakpoint // at this address, it may retrieve the argument from the first // argument register, or on x86 the eax register. // ULONG64 BreakpointWithStatus; // address of breakpoint // // Address of the saved context record during a bugcheck // // N.B. This is an automatic in KeBugcheckEx's frame, and // is only valid after a bugcheck. // ULONG64 SavedContext; // // help for walking stacks with user callbacks: // // // The address of the thread structure is provided in the // WAIT_STATE_CHANGE packet. This is the offset from the base of // the thread structure to the pointer to the kernel stack frame // for the currently active usermode callback. // USHORT ThCallbackStack; // offset in thread data // // these values are offsets into that frame: // USHORT NextCallback; // saved pointer to next callback frame USHORT FramePointer; // saved frame pointer // // pad to a quad boundary // USHORT PaeEnabled : 1; // // Address of the kernel callout routine. // ULONG64 KiCallUserMode; // kernel routine // // Address of the usermode entry point for callbacks. // ULONG64 KeUserCallbackDispatcher; // address in ntdll // // Addresses of various kernel data structures and lists // that are of interest to the kernel debugger. // ULONG64 PsLoadedModuleList; ULONG64 PsActiveProcessHead; ULONG64 PspCidTable; ULONG64 ExpSystemResourcesList; ULONG64 ExpPagedPoolDescriptor; ULONG64 ExpNumberOfPagedPools; ULONG64 KeTimeIncrement; ULONG64 KeBugCheckCallbackListHead; ULONG64 KiBugcheckData; ULONG64 IopErrorLogListHead; ULONG64 ObpRootDirectoryObject; ULONG64 ObpTypeObjectType; ULONG64 MmSystemCacheStart; ULONG64 MmSystemCacheEnd; ULONG64 MmSystemCacheWs; ULONG64 MmPfnDatabase; ULONG64 MmSystemPtesStart; ULONG64 MmSystemPtesEnd; ULONG64 MmSubsectionBase; ULONG64 MmNumberOfPagingFiles; ULONG64 MmLowestPhysicalPage; ULONG64 MmHighestPhysicalPage; ULONG64 MmNumberOfPhysicalPages; ULONG64 MmMaximumNonPagedPoolInBytes; ULONG64 MmNonPagedSystemStart; ULONG64 MmNonPagedPoolStart; ULONG64 MmNonPagedPoolEnd; ULONG64 MmPagedPoolStart; ULONG64 MmPagedPoolEnd; ULONG64 MmPagedPoolInformation; ULONG64 MmPageSize; ULONG64 MmSizeOfPagedPoolInBytes; ULONG64 MmTotalCommitLimit; ULONG64 MmTotalCommittedPages; ULONG64 MmSharedCommit; ULONG64 MmDriverCommit; ULONG64 MmProcessCommit; ULONG64 MmPagedPoolCommit; ULONG64 MmExtendedCommit; ULONG64 MmZeroedPageListHead; ULONG64 MmFreePageListHead; ULONG64 MmStandbyPageListHead; ULONG64 MmModifiedPageListHead; ULONG64 MmModifiedNoWritePageListHead; ULONG64 MmAvailablePages; ULONG64 MmResidentAvailablePages; ULONG64 PoolTrackTable; ULONG64 NonPagedPoolDescriptor; ULONG64 MmHighestUserAddress; ULONG64 MmSystemRangeStart; ULONG64 MmUserProbeAddress; ULONG64 KdPrintCircularBuffer; ULONG64 KdPrintCircularBufferEnd; ULONG64 KdPrintWritePointer; ULONG64 KdPrintRolloverCount; ULONG64 MmLoadedUserImageList; // NT 5.1 Addition ULONG64 NtBuildLab; ULONG64 KiNormalSystemCall; // NT 5.0 hotfix addition ULONG64 KiProcessorBlock; ULONG64 MmUnloadedDrivers; ULONG64 MmLastUnloadedDriver; ULONG64 MmTriageActionTaken; ULONG64 MmSpecialPoolTag; ULONG64 KernelVerifier; ULONG64 MmVerifierData; ULONG64 MmAllocatedNonPagedPool; ULONG64 MmPeakCommitment; ULONG64 MmTotalCommitLimitMaximum; ULONG64 CmNtCSDVersion; // NT 5.1 Addition ULONG64 MmPhysicalMemoryBlock; ULONG64 MmSessionBase; ULONG64 MmSessionSize; ULONG64 MmSystemParentTablePage; // Server 2003 addition ULONG64 MmVirtualTranslationBase; USHORT OffsetKThreadNextProcessor; USHORT OffsetKThreadTeb; USHORT OffsetKThreadKernelStack; USHORT OffsetKThreadInitialStack; USHORT OffsetKThreadApcProcess; USHORT OffsetKThreadState; USHORT OffsetKThreadBStore; USHORT OffsetKThreadBStoreLimit; USHORT SizeEProcess; USHORT OffsetEprocessPeb; USHORT OffsetEprocessParentCID; USHORT OffsetEprocessDirectoryTableBase; USHORT SizePrcb; USHORT OffsetPrcbDpcRoutine; USHORT OffsetPrcbCurrentThread; USHORT OffsetPrcbMhz; USHORT OffsetPrcbCpuType; USHORT OffsetPrcbVendorString; USHORT OffsetPrcbProcStateContext; USHORT OffsetPrcbNumber; USHORT SizeEThread; ULONG64 KdPrintCircularBufferPtr; ULONG64 KdPrintBufferSize; ULONG64 KeLoaderBlock; USHORT SizePcr; USHORT OffsetPcrSelfPcr; USHORT OffsetPcrCurrentPrcb; USHORT OffsetPcrContainedPrcb; USHORT OffsetPcrInitialBStore; USHORT OffsetPcrBStoreLimit; USHORT OffsetPcrInitialStack; USHORT OffsetPcrStackLimit; USHORT OffsetPrcbPcrPage; USHORT OffsetPrcbProcStateSpecialReg; USHORT GdtR0Code; USHORT GdtR0Data; USHORT GdtR0Pcr; USHORT GdtR3Code; USHORT GdtR3Data; USHORT GdtR3Teb; USHORT GdtLdt; USHORT GdtTss; USHORT Gdt64R3CmCode; USHORT Gdt64R3CmTeb; ULONG64 IopNumTriageDumpDataBlocks; ULONG64 IopTriageDumpDataBlocks; // Longhorn addition ULONG64 VfCrashDataBlock; ULONG64 MmBadPagesDetected; ULONG64 MmZeroedPageSingleBitErrorsDetected; // Windows 7 addition ULONG64 EtwpDebuggerData; USHORT OffsetPrcbContext; // Windows 8 addition USHORT OffsetPrcbMaxBreakpoints; USHORT OffsetPrcbMaxWatchpoints; ULONG OffsetKThreadStackLimit; ULONG OffsetKThreadStackBase; ULONG OffsetKThreadQueueListEntry; ULONG OffsetEThreadIrpList; USHORT OffsetPrcbIdleThread; USHORT OffsetPrcbNormalDpcState; USHORT OffsetPrcbDpcStack; USHORT OffsetPrcbIsrStack; USHORT SizeKDPC_STACK_FRAME; } KDDEBUGGER_DATA64, *PKDDEBUGGER_DATA64; typedef struct _DBGKD_GET_VERSION64 { USHORT MajorVersion; USHORT MinorVersion; UCHAR ProtocolVersion; UCHAR KdSecondaryVersion; // Cannot be 'A' for compat with dump header USHORT Flags; USHORT MachineType; // // Protocol command support descriptions. // These allow the debugger to automatically // adapt to different levels of command support // in different kernels. // // One beyond highest packet type understood, zero based. UCHAR MaxPacketType; // One beyond highest state change understood, zero based. UCHAR MaxStateChange; // One beyond highest state manipulate message understood, zero based. UCHAR MaxManipulate; // Kind of execution environment the kernel is running in, // such as a real machine or a simulator. Written back // by the simulation if one exists. UCHAR Simulation; USHORT Unused[1]; ULONG64 KernBase; ULONG64 PsLoadedModuleList; // // Components may register a debug data block for use by // debugger extensions. This is the address of the list head. // // There will always be an entry for the debugger. // ULONG64 DebuggerDataList; } DBGKD_GET_VERSION64, *PDBGKD_GET_VERSION64; // // Object Directory Entry Structure // typedef struct _OBJECT_DIRECTORY_ENTRY { struct _OBJECT_DIRECTORY_ENTRY *ChainLink; PVOID Object; } OBJECT_DIRECTORY_ENTRY, *POBJECT_DIRECTORY_ENTRY; // begin_ntosp // // Push lock definitions // //typedef struct _EX_PUSH_LOCK { // // // // // LOCK bit is set for both exclusive and shared acquires // // //#define EX_PUSH_LOCK_LOCK_V ((ULONG_PTR)0x0) //#define EX_PUSH_LOCK_LOCK ((ULONG_PTR)0x1) // // // // // Waiting bit designates that the pointer has chained waiters // // // //#define EX_PUSH_LOCK_WAITING ((ULONG_PTR)0x2) // // // // // Waking bit designates that we are either traversing the list // // to wake threads or optimizing the list // // // //#define EX_PUSH_LOCK_WAKING ((ULONG_PTR)0x4) // // // // // Set if the lock is held shared by multiple owners and there are waiters // // // //#define EX_PUSH_LOCK_MULTIPLE_SHARED ((ULONG_PTR)0x8) // // // // // Total shared Acquires are incremented using this // // //#define EX_PUSH_LOCK_SHARE_INC ((ULONG_PTR)0x10) //#define EX_PUSH_LOCK_PTR_BITS ((ULONG_PTR)0xf) // // union { // struct { // ULONG_PTR Locked : 1; // ULONG_PTR Waiting : 1; // ULONG_PTR Waking : 1; // ULONG_PTR MultipleShared : 1; // ULONG_PTR Shared : sizeof(ULONG_PTR) * 8 - 4; // }; // ULONG_PTR Value; // PVOID Ptr; // }; //} EX_PUSH_LOCK, *PEX_PUSH_LOCK; // // Object Directory Structure // #define NUMBER_HASH_BUCKETS 37 #define OBJ_INVALID_SESSION_ID 0xFFFFFFFF typedef struct _OBJECT_DIRECTORY { struct _OBJECT_DIRECTORY_ENTRY *HashBuckets[NUMBER_HASH_BUCKETS]; EX_PUSH_LOCK Lock; struct _DEVICE_MAP *DeviceMap; ULONG SessionId; } OBJECT_DIRECTORY, *POBJECT_DIRECTORY; // end_ntosp // begin_ntosp typedef struct _OBJECT_HEADER_NAME_INFO { POBJECT_DIRECTORY Directory; UNICODE_STRING Name; ULONG QueryReferences; #if DBG ULONG Reserved2; LONG DbgDereferenceCount; #ifdef _WIN64 ULONG64 Reserved3; // Win64 requires these structures to be 16 byte aligned. #endif #endif } OBJECT_HEADER_NAME_INFO, *POBJECT_HEADER_NAME_INFO; // end_ntosp typedef struct _OBJECT_TYPE_INITIALIZER { USHORT Length; BOOLEAN UseDefaultObject; BOOLEAN CaseInsensitive; ULONG InvalidAttributes; GENERIC_MAPPING GenericMapping; ULONG ValidAccessMask; BOOLEAN SecurityRequired; BOOLEAN MaintainHandleCount; BOOLEAN MaintainTypeList; POOL_TYPE PoolType; ULONG DefaultPagedPoolCharge; ULONG DefaultNonPagedPoolCharge; PVOID DumpProcedure; PVOID OpenProcedure; PVOID CloseProcedure; PVOID DeleteProcedure; PVOID ParseProcedure; PVOID SecurityProcedure; PVOID QueryNameProcedure; PVOID OkayToCloseProcedure; } OBJECT_TYPE_INITIALIZER, *POBJECT_TYPE_INITIALIZER; typedef struct _OBJECT_TYPE_XP { ERESOURCE Mutex; LIST_ENTRY TypeList; UNICODE_STRING Name; // Copy from object header for convenience PVOID DefaultObject; ULONG Index; ULONG TotalNumberOfObjects; ULONG TotalNumberOfHandles; ULONG HighWaterNumberOfObjects; ULONG HighWaterNumberOfHandles; OBJECT_TYPE_INITIALIZER TypeInfo; #ifdef POOL_TAGGING ULONG Key; #endif //POOL_TAGGING } OBJECT_TYPE_XP, *POBJECT_TYPE_XP; typedef struct _OBJECT_TYPE_WIN7 { //ERESOURCE Mutex;//在Win7系统中没有这个结构 LIST_ENTRY TypeList; UNICODE_STRING Name; // Copy from object header for convenience PVOID DefaultObject; ULONG Index; ULONG TotalNumberOfObjects; ULONG TotalNumberOfHandles; ULONG HighWaterNumberOfObjects; ULONG HighWaterNumberOfHandles; OBJECT_TYPE_INITIALIZER TypeInfo; #ifdef POOL_TAGGING ULONG Key; #endif //POOL_TAGGING } OBJECT_TYPE_WIN7, *POBJECT_TYPE_WIN7; #endif VOID GetObpRootDirectoryObject(PVOID* pObpRootDirectoryObject);//通过_kpcr 结构来获取 ObpRootDirectoryObject的地址; void EnumObjectDirectory(POBJECT_DIRECTORY ObpRootDirectoryObject);