驱动开发:内核监控Register注册表回调

在笔者前一篇文章《驱动开发:内核枚举Registry注册表回调》中实现了对注册表的枚举,本章将实现对注册表的监控,不同于32位系统在64位系统中,微软为我们提供了两个针对注册表的专用内核监控函数,通过这两个函数可以在不劫持内核API的前提下实现对注册表增加,删除,创建等事件的有效监控,注册表监视通常会通过CmRegisterCallback创建监控事件并传入自己的回调函数,与该创建对应的是CmUnRegisterCallback当注册表监控结束后可用于注销回调 。

  • CmRegisterCallback 设置注册表回调
  • CmUnRegisterCallback 注销注册表回调
默认情况下CmRegisterCallback需传入三个参数,参数一回调函数地址,参数二空余,参数三回调句柄,微软定义如下 。
// 署名权// right to sign one's name on a piece of work// PowerBy: LyShark// Email: me@lyshark.com// 参数1:回调函数地址// 参数2:无作用// 参数3:回调句柄NTSTATUS CmRegisterCallback([in]PEX_CALLBACK_FUNCTION Function,[in, optional] PVOIDContext,[out]PLARGE_INTEGERCookie);自定义注册表回调函数MyLySharkCallback需要保留三个参数,CallbackContext回调上下文,Argument1是操作类型,Argument2定义详细结构体指针 。
【驱动开发:内核监控Register注册表回调】NTSTATUS MyLySharkCallback(_In_ PVOID CallbackContext, _In_opt_ PVOID Argument1, _In_opt_ PVOID Argument2)在自定义回调函数内Argument1则可获取到操作类型,类型是一个REG_NOTIFY_CLASS枚举结构,微软对其的具体定义如下所示 。
// 署名权// right to sign one's name on a piece of work// PowerBy: LyShark// Email: me@lyshark.comtypedef enum _REG_NOTIFY_CLASS {RegNtDeleteKey,RegNtPreDeleteKey = RegNtDeleteKey,RegNtSetValueKey,RegNtPreSetValueKey = RegNtSetValueKey,RegNtDeleteValueKey,RegNtPreDeleteValueKey = RegNtDeleteValueKey,RegNtSetInformationKey,RegNtPreSetInformationKey = RegNtSetInformationKey,RegNtRenameKey,RegNtPreRenameKey = RegNtRenameKey,RegNtEnumerateKey,RegNtPreEnumerateKey = RegNtEnumerateKey,RegNtEnumerateValueKey,RegNtPreEnumerateValueKey = RegNtEnumerateValueKey,RegNtQueryKey,RegNtPreQueryKey = RegNtQueryKey,RegNtQueryValueKey,RegNtPreQueryValueKey = RegNtQueryValueKey,RegNtQueryMultipleValueKey,RegNtPreQueryMultipleValueKey = RegNtQueryMultipleValueKey,RegNtPreCreateKey,RegNtPostCreateKey,RegNtPreOpenKey,RegNtPostOpenKey,RegNtKeyHandleClose,RegNtPreKeyHandleClose = RegNtKeyHandleClose,//// .Net only//RegNtPostDeleteKey,RegNtPostSetValueKey,RegNtPostDeleteValueKey,RegNtPostSetInformationKey,RegNtPostRenameKey,RegNtPostEnumerateKey,RegNtPostEnumerateValueKey,RegNtPostQueryKey,RegNtPostQueryValueKey,RegNtPostQueryMultipleValueKey,RegNtPostKeyHandleClose,RegNtPreCreateKeyEx,RegNtPostCreateKeyEx,RegNtPreOpenKeyEx,RegNtPostOpenKeyEx,//// new to Windows Vista//RegNtPreFlushKey,RegNtPostFlushKey,RegNtPreLoadKey,RegNtPostLoadKey,RegNtPreUnLoadKey,RegNtPostUnLoadKey,RegNtPreQueryKeySecurity,RegNtPostQueryKeySecurity,RegNtPreSetKeySecurity,RegNtPostSetKeySecurity,//// per-object context cleanup//RegNtCallbackObjectContextCleanup,//// new in Vista SP2//RegNtPreRestoreKey,RegNtPostRestoreKey,RegNtPreSaveKey,RegNtPostSaveKey,RegNtPreReplaceKey,RegNtPostReplaceKey,MaxRegNtNotifyClass //should always be the last enum} REG_NOTIFY_CLASS;其中对于注册表最常用的监控项为以下几种类型,当然为了实现监控则我们必须要使用之前,如果使用之后则只能起到监视而无法做到监控的目的 。
  • RegNtPreCreateKey 创建注册表之前
  • RegNtPreOpenKey打开注册表之前
  • RegNtPreDeleteKey 删除注册表之前
  • RegNtPreDeleteValueKey 删除键值之前
  • RegNtPreSetValueKey 修改注册表之前
如果需要实现监视则,首先

经验总结扩展阅读