遍历对象目录

/***************************************************************************************
* 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);
原文地址:https://www.cnblogs.com/yifi/p/6527899.html