WindowsAPI编程核心技术-注册表监控
WindowsAPI编程核心技术-注册表监控
前置芝士
CmRegisterCallback
注册注册表监控例程。卸载用CmUnRegisterCallback
。
1 | NTSTATUS CmRegisterCallback( |
PEX_CALLBACK_FUNCTION
回调函数。
1 | NTSTATUS RegistryCallback( |
Argument1的结构如下:
1 | typedef enum _REG_NOTIFY_CLASS { |
实现方法
设置注册表回调函数时会拿到Cookie:
1 | // 设置回调函数 |
删除注册表回调函数时直接用Cookie删就好啦:
1 | // 删除回调函数 |
当要拒绝注册表指定键操作时,回调函数直接除STATUS_SUCCESS以外的错误码,如STATUS_ACCESS_DENIED等。
回调函数的第一个参数判断操作类型,RegNtPreCreateKey将要创建注册表,RegNtPreOpenKey将要打开注册表,RegNtPreDeleteKey将要删除注册表,RegNtPreDeleteValueKey将要删除注册表键值,RegNtPreSetValueKey将要修改键值。
第二个参数获取操作类型对应结构体数据,从中获取注册表路径对象,用ObQueryNameString
获取字符串路径。不同操作结构体不同。
1 | // 回调函数 |
附上拦截注册表删除方法:
1 | // 反注册表删除回调 |
还有拦截创建操作:
1 | // 拦截创建操作 |
源代码
Driver.h:
1 |
|
NotifyRoutine.h:
1 |
|
Driver.c:
1 |
|
NotifyRoutine.c:
1 |
|
反注册表监控
基本原理
系统里所有通过CmRegisterCallback
设置的注册表回调函数地址和Cookie都存储在以CallbackListHead
为表头的双向链表中。这个CallbackListHead
双向链表指向的数据结构是:
1 | typedef struct _CM_NOTIFY_ENTRY { |
获取CallbackListHead
表头地址方法:最简单从删除注册表回调函数CmUnRegisterCallback
获取:
1 | ;Windows 10 x64 |
扫描特征码即可,在x86下获取表头地址,在x64下获取表头偏移地址。
Windows 7 | Windows 8.1 | Windows 10 | |
---|---|---|---|
x86 | BF | BE | B9 |
x64 | 488D54(488D0D出现次数太多) | 488D0D | 488D0D |
获取表头地址具体实现代码如下:
1 | // 根据特征码获取 CallbackListHead 链表地址 |
枚举系统注册表回调函数:
1 | // 遍历回调 |
删除注册表回调函数:
1 | // 移除回调 |
源代码
Driver.h:
1 |
|
EnumRemove.h:
1 |
|
Driver.c:
1 |
|
EnumRemove.c:
1 |
|
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 The Blog of Monoceros406!