xiaoc1026 发表于 2012-12-31 16:11:06

CmRegisterCallbacks 获取注册表完整路径

没办法 被逼自己研究了下,特此公开,目前只在WIN2003 SP2 下测试,WIN64 应该也可以
//未公开结构申明
typedef struct _CM_KEY_BODY
{
        ULONG   Type;
        PVOID   KeyControlBlock;
        PVOID   NotifyBlock;
        HANDLEProcessID;      // the owner process
        LIST_ENTRY KeyBodyList;    // key_nodes using the same kcb
} CM_KEY_BODY, *PCM_KEY_BODY;

typedef struct _CM_NAME_CONTROL_BLOCK
{
        USHORT Compressed;
        USHORT RefCount;
        ULONG ConvKey;
        void* NextHash;
        USHORTNameLength;
        USHORT Name;
} CM_NAME_CONTROL_BLOCK, *PCM_NAME_CONTROL_BLOCK;

typedef struct _CM_KEY_CONTROL_BLOCK
{
        ULONG RefCount;
        ULONG ExtFlags: 8;
        ULONG PrivateAlloc: 1;
        ULONG Delete: 1;
        ULONG DelayedCloseIndex: 12;
        ULONG TotalLevels: 10;
        ULONG ConvKey;
        void* NextHash;
        void* KeyHive;
        ULONG KeyCell;
        void* ParentKcb;
        void* NameBlock;
        //...

}CM_KEY_CONTROL_BLOCK, *PCM_KEY_CONTROL_BLOCK;

//RegistryCallback 调用
case RegNtPreCreateKeyEx:
                        {
                                PREG_CREATE_KEY_INFORMATION createKey = (PREG_CREATE_KEY_INFORMATION)Argument2;

                                GetRegObjectCompletePath(createKey->RootObject, createKey->CompleteName, &registryPath);

                                KdPrint((" RegNtPreCreateKeyEx %wZ",registryPath));

                                enumType = REG_TYPE_CREATE;

                                if( RegFilter(enumType, &registryPath, &g_stCreateReg) )
                                {
                                        ntReg = STATUS_ACCESS_DENIED;
                                }

                                break;
                        }

BOOLEAN GetRegObjectCompletePath(PVOID pObject,PUNICODE_STRING pKeyName, PUNICODE_STRING pRootPath)
{
        BOOLEAN bRet = FALSE;
        PCM_KEY_BODY pKeyBody = NULL;
        PCM_KEY_CONTROL_BLOCK pKeyControlBlock = NULL;
        PCM_NAME_CONTROL_BLOCK pNameBlock = NULL;
        ANSI_STRING aniPath;
        char szBuf = {0};
        intnLen = 0;

        do
        {
                if( !pObject || !MmIsAddressValid(pObject) )
                {
                        RtlCopyUnicodeString(pRootPath, pKeyName);
                        RtlAppendUnicodeToString(pRootPath, L"\\");
                        break;
                }

                pKeyBody = (PCM_KEY_BODY)pObject;

                pKeyControlBlock = (PCM_KEY_CONTROL_BLOCK)pKeyBody->KeyControlBlock;

                while(pKeyControlBlock)
                {
                        pNameBlock = (PCM_NAME_CONTROL_BLOCK)pKeyControlBlock->NameBlock;

                        if( nLen + pNameBlock->NameLength + 1 >= MAX_LENGTH )
                        {
                                break;
                        }                       

                        RtlMoveMemory(szBuf + pNameBlock->NameLength + 1, szBuf, nLen);

                        szBuf = '\\';

                        RtlCopyMemory(szBuf + 1, &pNameBlock->Name, pNameBlock->NameLength);

                        nLen += pNameBlock->NameLength + 1;

                        pKeyControlBlock = (PCM_KEY_CONTROL_BLOCK)pKeyControlBlock->ParentKcb;

                        if( !MmIsAddressValid(pKeyControlBlock) )
                        {
                                break;
                        }
                }

                RtlInitAnsiString(&aniPath, szBuf);
                RtlAnsiStringToUnicodeString(pRootPath,&aniPath, FALSE);

                if(pKeyName && pKeyName->Buffer)
                {
                        RtlAppendUnicodeToString(pRootPath, pKeyName);
                        RtlAppendUnicodeToString(pRootPath, L"\\");
                }

                bRet = TRUE;

        } while (FALSE);

        return bRet;
}

Tesla.Angela 发表于 2012-12-31 20:23:17

不错,加分鼓励一下。

xiaoc1026 发表于 2013-1-5 16:26:04

WIN2008和 WIN2003 _CM_KEY_CONTROL_BLOCK 结构居然不一样,坑爹了,肿么办。。。
//win2003
kd> dt nt!pKeyControlBlock
Local var @ 0xfffff880040c1328 Type _CM_KEY_CONTROL_BLOCK*
0xfffff8a0`00022130
   +0x000 RefCount         : 0x23
   +0x004 ExtFlags         : 0y00000000 (0)
   +0x004 PrivateAlloc   : 0y0
   +0x004 Delete         : 0y0
   +0x004 DelayedCloseIndex : 0y000001000000 (0x40)
   +0x004 TotalLevels      : 0y0000000001 (0x1)
   +0x008 ConvKey          : 0x01cb892b`9c18eb70
   +0x010 NextHash         : 0x01cb892b`bd68092e
   +0x018 KeyHive          : (null)
   +0x020 KeyCell          : 0xfffff8a0`0000e010
   +0x028 ParentKcb      : 0x00000000`00000120
   +0x030 NameBlock      : (null)

//win2008
kd> dt nt!_CM_KEY_CONTROL_BLOCK 0xfffff8a0`00022130
   +0x000 RefCount         : 0x23
   +0x004 ExtFlags         : 0y0000000000000000 (0)
   +0x004 PrivateAlloc   : 0y1
   +0x004 Delete         : 0y0
   +0x004 HiveUnloaded   : 0y0
   +0x004 Decommissioned   : 0y0
   +0x004 LockTablePresent : 0y0
   +0x004 TotalLevels      : 0y0000000010 (0x2)
   +0x008 DelayedDeref   : 0y0
   +0x008 DelayedClose   : 0y0
   +0x008 Parking          : 0y0
   +0x010 KeyHash          : _CM_KEY_HASH
   +0x010 ConvKey          : 0xbd68092e
   +0x018 NextHash         : (null)
   +0x020 KeyHive          : 0xfffff8a0`0000e010 _HHIVE
   +0x028 KeyCell          : 0x120
   +0x030 KcbPushlock      : _EX_PUSH_LOCK
   +0x038 Owner            : (null)
   +0x038 SharedCount      : 0
   +0x040 SlotHint         : 0
   +0x048 ParentKcb      : 0xfffff8a0`00022008 _CM_KEY_CONTROL_BLOCK
   +0x050 NameBlock      : 0xfffff8a0`0000a700 _CM_NAME_CONTROL_BLOCK
   +0x058 CachedSecurity   : 0xfffff8a0`00021420 _CM_KEY_SECURITY_CACHE
   +0x060 ValueCache       : _CACHED_CHILD_LIST
   +0x070 IndexHint      : 0x01cb892b`00000007 _CM_INDEX_HINT_BLOCK
   +0x070 HashKey          : 7
   +0x070 SubKeyCount      : 7
   +0x078 KeyBodyListHead: _LIST_ENTRY [ 0xfffff8a0`0153f2f0 - 0xfffff8a0`0253f3e0 ]
   +0x078 FreeListEntry    : _LIST_ENTRY [ 0xfffff8a0`0153f2f0 - 0xfffff8a0`0253f3e0 ]
   +0x088 KeyBodyArray   : 0xfffff8a0`014332e0 _CM_KEY_BODY

wode200910 发表于 2013-2-4 23:14:38

不用硬编码啊~可以有函数得到Object名字的~NTSTATUS
ObQueryNameString(
    IN PVOIDObject,
    OUT POBJECT_NAME_INFORMATIONObjectNameInfo,
    IN ULONGLength,
    OUT PULONGReturnLength
    );

kk1025 发表于 2013-4-7 15:34:37

32位元和64位元應該也不一樣才對

kk1025 发表于 2013-4-8 13:29:10

學習!!

kk1025 发表于 2013-4-9 21:11:34

好東西!
页: [1]
查看完整版本: CmRegisterCallbacks 获取注册表完整路径