2013年8月24日星期六

枚举命名的内核对象的类型

#include <ntifs.h>

/*
功能:枚举命名的内核对象的类型.
说明:本代码只适宜于windows server 2008 r2 64位版本.
*/

/*
0: kd> vertarget
Windows 7 Kernel Version 7601 (Service Pack 1) MP (2 procs) Free x64
Product: Server, suite: Enterprise TerminalServer SingleUserTS
Built by: 7601.18205.amd64fre.win7sp1_gdr.130708-1532
Machine Name:
Kernel base = 0xfffff800`0164d000 PsLoadedModuleList = 0xfffff800`018906d0
Debug session time: Fri Aug 23 14:58:58.968 2013 (UTC + 8:00)
System Uptime: 0 days 20:30:10.037
0: kd> dt _OBJECT_DIRECTORY
nt!_OBJECT_DIRECTORY
+0x000 HashBuckets      : [37] Ptr64 _OBJECT_DIRECTORY_ENTRY
+0x128 Lock             : _EX_PUSH_LOCK
+0x130 DeviceMap        : Ptr64 _DEVICE_MAP
+0x138 SessionId        : Uint4B
+0x140 NamespaceEntry   : Ptr64 Void
+0x148 Flags            : Uint4B
0: kd> dt _OBJECT_DIRECTORY_ENTRY
nt!_OBJECT_DIRECTORY_ENTRY
+0x000 ChainLink        : Ptr64 _OBJECT_DIRECTORY_ENTRY
+0x008 Object           : Ptr64 Void
+0x010 HashValue        : Uint4B
1: kd> dt _OBJECT_TYPE
nt!_OBJECT_TYPE
+0x000 TypeList         : _LIST_ENTRY
+0x010 Name             : _UNICODE_STRING
+0x020 DefaultObject    : Ptr64 Void
+0x028 Index            : UChar
+0x02c TotalNumberOfObjects : Uint4B
+0x030 TotalNumberOfHandles : Uint4B
+0x034 HighWaterNumberOfObjects : Uint4B
+0x038 HighWaterNumberOfHandles : Uint4B
+0x040 TypeInfo         : _OBJECT_TYPE_INITIALIZER
+0x0b0 TypeLock         : _EX_PUSH_LOCK
+0x0b8 Key              : Uint4B
+0x0c0 CallbackList     : _LIST_ENTRY
*/

#define TAG 'tset' //test

typedef struct _OBJECT_DIRECTORY_ENTRY {
    struct _OBJECT_DIRECTORY_ENTRY * ChainLink;
    void * Object;
    int HashValue;
} OBJECT_DIRECTORY_ENTRY, *POBJECT_DIRECTORY_ENTRY;

typedef struct _OBJECT_DIRECTORY {
    struct _OBJECT_DIRECTORY_ENTRY *HashBuckets[37];
    struct _OBJECT_DIRECTORY_ENTRY **Lock;
    void * DeviceMap;
    USHORT SessionId;
    void * NamespaceEntry;
    int Flags;
} OBJECT_DIRECTORY, *POBJECT_DIRECTORY;

typedef struct _OBJECT_TYPE {
    LIST_ENTRY TypeList;
    UNICODE_STRING Name;
    //.......
} OBJECT_TYPE;

//一个导出但没有公开的函数
typedef OBJECT_TYPE * (*ObGetObjectType)(IN PVOID pObject);
ObGetObjectType g_pObGetObjectType;

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
    UNICODE_STRING ObjectTypes;
    OBJECT_ATTRIBUTES ObjectAttributes;
    HANDLE Handle = NULL;
    POBJECT_DIRECTORY ObjectTypes_Directory = NULL;
    int i = 0;
    UNICODE_STRING usObGetObjectType;
    OBJECT_TYPE * pot;
    PUNICODE_STRING pu;
    ULONG  Length = 512;
    NTSTATUS status = STATUS_UNSUCCESSFUL;
    OBJECT_DIRECTORY_ENTRY * p = 0;

    KdBreakPoint();//DbgBreakPoint()

    RtlInitUnicodeString( &usObGetObjectType, L"ObGetObjectType" );
    g_pObGetObjectType = MmGetSystemRoutineAddress(&usObGetObjectType);
    if (g_pObGetObjectType == NULL)
    {
        return STATUS_UNSUCCESSFUL;
    }

    RtlInitUnicodeString(&ObjectTypes,L"\\ObjectTypes");//这里也可以直接填写对象空间的根目录,及L"\\".试试看看效果.肯定是不正确的.
    InitializeObjectAttributes(&ObjectAttributes,&ObjectTypes,0,0,0);

    status = ZwOpenDirectoryObject(&Handle, DIRECTORY_QUERY, &ObjectAttributes);
    if (NT_SUCCESS (status))
    {
        status = ObReferenceObjectByHandle(Handle, FILE_READ_ACCESS, NULL, KernelMode, (PVOID *)&ObjectTypes_Directory, NULL);
        if (NT_SUCCESS (status))
        {
            for ( ; i<37 ;i++)
            {
                //__try
                //{
                //    WCHAR w = *(WCHAR *)(ObjectTypes_Directory->HashBuckets[i]->Object);//试探内存是否可访问.MmIsAddressValid要非分页,ProbeForRead 是用户模式.
                //}
                //__except (EXCEPTION_EXECUTE_HANDLER)
                //{
                //    continue;
                //}  

                if (ObjectTypes_Directory->HashBuckets[i] == NULL)
                {
                    continue;
                }

                p = ObjectTypes_Directory->HashBuckets[i];
                for ( ; ; )
                {
                    pot = g_pObGetObjectType(ObjectTypes_Directory->HashBuckets[i]->Object);
                    //KdPrint(("文件路径为:%wZ\n",&(pot->Name)));//这种情况下,得到的值永远是Type.

                    pu = (PUNICODE_STRING)ExAllocatePoolWithTag(NonPagedPool, Length, TAG);
                    if (pu == 0) {
                        return STATUS_UNSUCCESSFUL;
                    }
                    RtlZeroMemory(pu, Length);

                    status = ObQueryNameString(p->Object, (POBJECT_NAME_INFORMATION)pu, Length, &Length);//""
                    if (status != STATUS_SUCCESS )//#define STATUS_INFO_LENGTH_MISMATCH      ((NTSTATUS)0xC0000004L)
                    {
                        //KdPrint(("ObQueryNameString fail 0x%08x",status));
                        ExFreePoolWithTag(pu, TAG);
                        continue;
                    }

                    //估计也可以根据\ObjectTypes\Process这个名字,打开这个对象.

                    KdPrint(("Hash:%d\tAddress:0x%p\tType:%wZ\tName:%wZ\n",i,p->Object,&(pot->Name),pu));
                    ExFreePoolWithTag(pu, TAG);//这两行搞反了是要蓝屏的.

                    if (p->ChainLink == NULL)
                    {
                        break;
                    }

                    p = p->ChainLink;
                }
            }

            ObDereferenceObject(ObjectTypes_Directory);
        }
        ZwClose(Handle);
    }

    return STATUS_UNSUCCESSFUL;
}


看看效果吧!
0: kd> g
Hash:0 Address:0xFFFFFA8003CDC1D0 Type:Type Name:\ObjectTypes\TmTm
Hash:1 Address:0xFFFFFA8003CDB250 Type:Type Name:\ObjectTypes\Desktop
Hash:1 Address:0xFFFFFA8003C8FDE0 Type:Type Name:\ObjectTypes\Process
Hash:3 Address:0xFFFFFA8003C8F8A0 Type:Type Name:\ObjectTypes\DebugObject
Hash:4 Address:0xFFFFFA8003CDC080 Type:Type Name:\ObjectTypes\TpWorkerFactory
Hash:5 Address:0xFFFFFA8003CDCF30 Type:Type Name:\ObjectTypes\Adapter
Hash:5 Address:0xFFFFFA8003C6AAA0 Type:Type Name:\ObjectTypes\Token
Hash:8 Address:0xFFFFFA8003CD08F0 Type:Type Name:\ObjectTypes\EventPair
Hash:9 Address:0xFFFFFA8003FA8200 Type:Type Name:\ObjectTypes\PcwObject
Hash:9 Address:0xFFFFFA8003CF83A0 Type:Type Name:\ObjectTypes\WmiGuid
Hash:11 Address:0xFFFFFA8003CF93A0 Type:Type Name:\ObjectTypes\EtwRegistration
Hash:12 Address:0xFFFFFA8003CDD590 Type:Type Name:\ObjectTypes\Session
Hash:12 Address:0xFFFFFA8003CDB790 Type:Type Name:\ObjectTypes\Timer
Hash:13 Address:0xFFFFFA8003CDB080 Type:Type Name:\ObjectTypes\Mutant
Hash:16 Address:0xFFFFFA8003CDC9F0 Type:Type Name:\ObjectTypes\IoCompletion
Hash:17 Address:0xFFFFFA8003CDB3A0 Type:Type Name:\ObjectTypes\WindowStation
Hash:17 Address:0xFFFFFA8003CDB640 Type:Type Name:\ObjectTypes\Profile
Hash:18 Address:0xFFFFFA8003CDC8A0 Type:Type Name:\ObjectTypes\File
Hash:21 Address:0xFFFFFA8003CDB8E0 Type:Type Name:\ObjectTypes\Semaphore
Hash:23 Address:0xFFFFFA8003CFA3A0 Type:Type Name:\ObjectTypes\EtwConsumer
Hash:25 Address:0xFFFFFA8003CDDF30 Type:Type Name:\ObjectTypes\TmTx
Hash:25 Address:0xFFFFFA8003C6AC90 Type:Type Name:\ObjectTypes\SymbolicLink
Hash:26 Address:0xFFFFFA8003F35880 Type:Type Name:\ObjectTypes\FilterConnectionPort
Hash:26 Address:0xFFFFFA8003CB37A0 Type:Type Name:\ObjectTypes\Key
Hash:26 Address:0xFFFFFA8003CDB4F0 Type:Type Name:\ObjectTypes\KeyedEvent
Hash:26 Address:0xFFFFFA8003CDBF30 Type:Type Name:\ObjectTypes\Callback
Hash:28 Address:0xFFFFFA8003C8FB40 Type:Type Name:\ObjectTypes\UserApcReserve
Hash:28 Address:0xFFFFFA8003C8FF30 Type:Type Name:\ObjectTypes\Job
Hash:29 Address:0xFFFFFA8003CDCDE0 Type:Type Name:\ObjectTypes\Controller
Hash:29 Address:0xFFFFFA8003C8F9F0 Type:Type Name:\ObjectTypes\IoCompletionReserve
Hash:30 Address:0xFFFFFA8003CDCC90 Type:Type Name:\ObjectTypes\Device
Hash:30 Address:0xFFFFFA8003C6ADE0 Type:Type Name:\ObjectTypes\Directory
Hash:31 Address:0xFFFFFA8003CDD6E0 Type:Type Name:\ObjectTypes\Section
Hash:31 Address:0xFFFFFA8003CDDC90 Type:Type Name:\ObjectTypes\TmEn
Hash:31 Address:0xFFFFFA8003C8FC90 Type:Type Name:\ObjectTypes\Thread
Hash:32 Address:0xFFFFFA8003C6AF30 Type:Type Name:\ObjectTypes\Type
Hash:33 Address:0xFFFFFA8003F5FF30 Type:Type Name:\ObjectTypes\FilterCommunicationPort
Hash:33 Address:0xFFFFFA8003CBC7F0 Type:Type Name:\ObjectTypes\PowerRequest
Hash:35 Address:0xFFFFFA8003CDDDE0 Type:Type Name:\ObjectTypes\TmRm
Hash:35 Address:0xFFFFFA8003CD0A40 Type:Type Name:\ObjectTypes\Event
Hash:36 Address:0xFFFFFA8003CB7AC0 Type:Type Name:\ObjectTypes\ALPC Port
Hash:36 Address:0xFFFFFA8003CDCB40 Type:Type Name:\ObjectTypes\Driver

验证一下:
0: kd> !object \ObjectTypes
Object: fffff8a000006930  Type: (fffffa8003c6ade0) Directory
    ObjectHeader: fffff8a000006900 (new version)
    HandleCount: 0  PointerCount: 44
    Directory Object: fffff8a000004c90  Name: ObjectTypes

    Hash Address          Type          Name
    ---- -------          ----          ----
     00  fffffa8003cdc1d0 Type          TmTm
     01  fffffa8003cdb250 Type          Desktop
         fffffa8003c8fde0 Type          Process
     03  fffffa8003c8f8a0 Type          DebugObject
     04  fffffa8003cdc080 Type          TpWorkerFactory
     05  fffffa8003cdcf30 Type          Adapter
         fffffa8003c6aaa0 Type          Token
     08  fffffa8003cd08f0 Type          EventPair
     09  fffffa8003fa8200 Type          PcwObject
         fffffa8003cf83a0 Type          WmiGuid
     11  fffffa8003cf93a0 Type          EtwRegistration
     12  fffffa8003cdd590 Type          Session
         fffffa8003cdb790 Type          Timer
     13  fffffa8003cdb080 Type          Mutant
     16  fffffa8003cdc9f0 Type          IoCompletion
     17  fffffa8003cdb3a0 Type          WindowStation
         fffffa8003cdb640 Type          Profile
     18  fffffa8003cdc8a0 Type          File
     21  fffffa8003cdb8e0 Type          Semaphore
     23  fffffa8003cfa3a0 Type          EtwConsumer
     25  fffffa8003cddf30 Type          TmTx
         fffffa8003c6ac90 Type          SymbolicLink
     26  fffffa8003f35880 Type          FilterConnectionPort
         fffffa8003cb37a0 Type          Key
         fffffa8003cdb4f0 Type          KeyedEvent
         fffffa8003cdbf30 Type          Callback
     28  fffffa8003c8fb40 Type          UserApcReserve
         fffffa8003c8ff30 Type          Job
     29  fffffa8003cdcde0 Type          Controller
         fffffa8003c8f9f0 Type          IoCompletionReserve
     30  fffffa8003cdcc90 Type          Device
         fffffa8003c6ade0 Type          Directory
     31  fffffa8003cdd6e0 Type          Section
         fffffa8003cddc90 Type          TmEn
         fffffa8003c8fc90 Type          Thread
     32  fffffa8003c6af30 Type          Type
     33  fffffa8003f5ff30 Type          FilterCommunicationPort
         fffffa8003cbc7f0 Type          PowerRequest
     35  fffffa8003cddde0 Type          TmRm
         fffffa8003cd0a40 Type          Event
     36  fffffa8003cb7ac0 Type          ALPC Port
         fffffa8003cdcb40 Type          Driver

还可以对照:Winobj(EX).exe或者其他工具查看对比.

made by correy
made at 2013.08.23
email:kouleguan at hotmail dot com
homepage:http://correy.webs.com
不足之处,敬请指出.


一下代码需要改进,不完善:
#include <ntifs.h>

/*
功能:枚举以\为根的整个命名空间的对象.运行的时间长些,需要几分钟.可能有重复,需改进.
说明:本代码只适宜于windows server 2008 r2 64位版本.
*/

#define TAG 'tset' //test

typedef struct _OBJECT_DIRECTORY_ENTRY {
    struct _OBJECT_DIRECTORY_ENTRY * ChainLink;
    void * Object;
    int HashValue;
} OBJECT_DIRECTORY_ENTRY, *POBJECT_DIRECTORY_ENTRY;

typedef struct _OBJECT_DIRECTORY {
    struct _OBJECT_DIRECTORY_ENTRY *HashBuckets[37];
    struct _OBJECT_DIRECTORY_ENTRY **Lock;
    void * DeviceMap;
    USHORT SessionId;
    void * NamespaceEntry;
    int Flags;
} OBJECT_DIRECTORY, *POBJECT_DIRECTORY;

typedef struct _OBJECT_TYPE {
    LIST_ENTRY TypeList;
    UNICODE_STRING Name;
    //.......
} OBJECT_TYPE;

//一个导出但没有公开的函数
typedef OBJECT_TYPE * (*ObGetObjectType)(IN PVOID pObject);
ObGetObjectType g_pObGetObjectType;

UNICODE_STRING us_Directory;

NTSTATUS enum_object(UNICODE_STRING * pus,int n)
{  
    OBJECT_ATTRIBUTES ObjectAttributes;
    HANDLE Handle = NULL;
    POBJECT_DIRECTORY ObjectTypes_Directory = NULL;
    int i = 0;  
    OBJECT_TYPE * pot;
    PUNICODE_STRING pu;
    ULONG  Length = 512;
    NTSTATUS status = STATUS_UNSUCCESSFUL;
    OBJECT_DIRECTORY_ENTRY * p = 0;

    InitializeObjectAttributes(&ObjectAttributes,pus,0,0,0);
    status = ZwOpenDirectoryObject(&Handle, DIRECTORY_QUERY, &ObjectAttributes);
    if (NT_SUCCESS (status))
    {
        status = ObReferenceObjectByHandle(Handle, FILE_READ_ACCESS, NULL, KernelMode, (PVOID *)&ObjectTypes_Directory, NULL);
        if (NT_SUCCESS (status))
        {
            for ( ; i<37 ;i++)
            {
                if (ObjectTypes_Directory->HashBuckets[i] == NULL)
                {
                    continue;
                }

                p = ObjectTypes_Directory->HashBuckets[i];
                for ( ; ; )
                {
                    pot = g_pObGetObjectType(ObjectTypes_Directory->HashBuckets[i]->Object);

                    pu = (PUNICODE_STRING)ExAllocatePoolWithTag(NonPagedPool, Length, TAG);
                    if (pu == 0) {
                        return STATUS_UNSUCCESSFUL;
                    }
                    RtlZeroMemory(pu, Length);

                    status = ObQueryNameString(p->Object, (POBJECT_NAME_INFORMATION)pu, Length, &Length);//""
                    if (status != STATUS_SUCCESS )//#define STATUS_INFO_LENGTH_MISMATCH      ((NTSTATUS)0xC0000004L)
                    {
                        //KdPrint(("ObQueryNameString fail 0x%08x",status));
                        ExFreePoolWithTag(pu, TAG);
                        continue;
                    }

                    //不准重复.
                    // if (RtlEqualUnicodeString(pu,pus,TRUE))
                    // {
                    // break;
                    // }

                    //如果是目录,进行递归的调用.
                    if (RtlEqualUnicodeString(&us_Directory,&(pot->Name),TRUE))
                    {
                        enum_object(pu,n);
                    }

                    // {
                    // int j = 0;
                    // for ( ;j < n; j++)
                    // {
                    // KdPrint(("\t"));
                    // }
                    // }

                    KdPrint(("Address:0x%p\tType:%wZ\tName:%wZ\n",p->Object,&(pot->Name),pu));
                    ExFreePoolWithTag(pu, TAG);//这两行搞反了是要蓝屏的.

                    if (p->ChainLink == NULL)
                    {
                        break;
                    }

                    p = p->ChainLink;
                }
            }

            ObDereferenceObject(ObjectTypes_Directory);
        }
        ZwClose(Handle);
    }

    i++;

    return status;
}

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
    UNICODE_STRING usObGetObjectType;
    UNICODE_STRING ObjectTypes;
    int n = 0;

    KdBreakPoint();//DbgBreakPoint()

    RtlInitUnicodeString( &usObGetObjectType, L"ObGetObjectType" );
    g_pObGetObjectType = MmGetSystemRoutineAddress(&usObGetObjectType);
    if (g_pObGetObjectType == NULL)
    {
        return STATUS_UNSUCCESSFUL;
    }

    RtlInitUnicodeString(&us_Directory, L"Directory");
    RtlInitUnicodeString(&ObjectTypes,L"\\");

    enum_object(&ObjectTypes,n);

    return STATUS_UNSUCCESSFUL;
}

没有评论:

发表评论