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, ®istryPath);
KdPrint((" RegNtPreCreateKeyEx %wZ",registryPath));
enumType = REG_TYPE_CREATE;
if( RegFilter(enumType, ®istryPath, &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;
} 不错,加分鼓励一下。 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
不用硬编码啊~可以有函数得到Object名字的~NTSTATUS
ObQueryNameString(
IN PVOIDObject,
OUT POBJECT_NAME_INFORMATIONObjectNameInfo,
IN ULONGLength,
OUT PULONGReturnLength
);
32位元和64位元應該也不一樣才對 學習!! 好東西!
页:
[1]