首页 > 其他分享 >00000030.ReverseAnalysis.ring0层注册表监控

00000030.ReverseAnalysis.ring0层注册表监控

时间:2024-01-23 20:22:23浏览次数:30  
标签:00000030 ReverseAnalysis INFORMATION PREG KEY 注册表 PVOID REG

00000030.ReverseAnalysis.ring0层注册表监控

links

深入理解注册表监控 从0环监测注册表机制...好像还是有点门槛的

如何监控

注册表是windows的重要数据库,存放了很多重要的信息以及一些应用的设置,对注册表进行监控并防止篡改是十分有必要的。

在64位系统下微软提供了CmRegisterCallback这个回调函数来实时监控注册表的操作,

那么既然这里微软提供了这么一个方便的接口,

病毒木马自然也会利用,这里我们就来探究其实现的原理和如何利用这个回调函数进行对抗

CmRegisterCallback

NTSTATUS CmRegisterCallback(
  [in]           PEX_CALLBACK_FUNCTION Function,//回调函数
  [in, optional] PVOID                 Context,
  [out]          PLARGE_INTEGER        Cookie
);

参数1: 一个回调函数,

参数2: 配置管理器,将作为CallbackContext参数传递给RegistryCallback例程的驱动程序定义的值,所以

参数2为参数1服务

参数3: 指向 LARGE_INTEGER 变量的指针,该变量接收标识回调例程的值。当您取消注册回调例程时,请将此值作为Cookie参数传递给CmUnRegisterCallback

回调函数类型如下

EX_CALLBACK_FUNCTION ExCallbackFunction;

NTSTATUS ExCallbackFunction(
  [in]           PVOID CallbackContext,
  [in, optional] PVOID Argument1,
  [in, optional] PVOID Argument2
)
{
	
}

参数1: 被CmRegisterCallback传递过来的东西

参数2: 一个enum类型,REG_NOTIFY_CLASS, 用于标识正在执行的注册表操作的类型以及注册表操作执行之前还是之后调用RegistryCallback

参数3: 一个结构体,结构体的类型取决于参数2, 指向包含特定于注册表操作类型的信息的结构的指针

可参考官方文档

Argument1对应的枚举值如下

有些Argument1他是一样的,比如enum的RegNtPreDeleteKey和RegNtDeleteKey是一样的

为什么是一样的?因为他们对应的结构体是一样的,所以为了方便,枚举值也是一样的

typedef 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,
    //
    
    //
    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 创建注册表 对应的Argument2PREG_CREATE_KEY_INFORMATION
  • RegNtPreOpenKey 打开注册表 对应的Argument2PREG_CREATE_KEY_INFORMATION
  • RegNtPreDeleteKey 删除键 对应的Argument2PREG_DELETE_KEY_INFORMATION
  • RegNtPreDeleteValueKey 删除键值 对应的Argument2PREG_DELETE_VALUE_KEY_INFORMATION
  • RegNtPreSetValueKey 修改键值 对应的Argument2PREG_SET_VALUE_KEY_INFORMATION

RegNtPreCreateKey RegNtPreOpenKey Argument2都是使用的PREG_CREATE_KEY_INFORMATION这个结构体,

我们看下结构

typedef struct _REG_CREATE_KEY_INFORMATION {
  PUNICODE_STRING CompleteName; //指向路径的指针
  PVOID           RootObject; //指向注册表项的指针
  PVOID           ObjectType;
  ULONG           CreateOptions;
  PUNICODE_STRING Class;
  PVOID           SecurityDescriptor;
  PVOID           SecurityQualityOfService;
  ACCESS_MASK     DesiredAccess;
  ACCESS_MASK     GrantedAccess;
  PULONG          Disposition;
  PVOID           *ResultObject;
  PVOID           CallContext;
  PVOID           RootObjectContext;
  PVOID           Transaction;
  PVOID           Reserved;
} 
REG_CREATE_KEY_INFORMATION, 
REG_OPEN_KEY_INFORMATION, 
*PREG_CREATE_KEY_INFORMATION, 
*PREG_OPEN_KEY_INFORMATION;

再来看看另外一个结构体, RegNtPreDeleteKey 对应PREG_DELETE_KEY_INFORMATION结构体

typedef struct _REG_DELETE_KEY_INFORMATION {
  PVOID Object; //指向要删除注册表的指针
  PVOID CallContext;
  PVOID ObjectContext;
  PVOID Reserved;
} REG_DELETE_KEY_INFORMATION, *PREG_DELETE_KEY_INFORMATION, REG_FLUSH_KEY_INFORMATION, *PREG_FLUSH_KEY_INFORMATION;

然后是RegNtPreDeleteValueKey 对应PREG_DELETE_VALUE_KEY_INFORMATION结构体,

通过名字可以判断这里我们要删除表项里面的值

typedef struct _REG_DELETE_VALUE_KEY_INFORMATION {
  PVOID           Object; //指向要删除的注册表的指针
  PUNICODE_STRING ValueName; //指向具体需要删除的值
  PVOID           CallContext;
  PVOID           ObjectContext;
  PVOID           Reserved;
} REG_DELETE_VALUE_KEY_INFORMATION, *PREG_DELETE_VALUE_KEY_INFORMATION;

RegNtPreSetValueKey 对应的是PREG_SET_VALUE_KEY_INFORMATION结构体

同样是 Object 指向要修改的注册表的指针,而ValueName就是指向具体需要修改的值

typedef struct _REG_SET_VALUE_KEY_INFORMATION {
  PVOID           Object; //指向要修改的注册表的指针
  PUNICODE_STRING ValueName; //就是指向具体需要修改的值
  ULONG           TitleIndex;
  ULONG           Type;
  PVOID           Data;
  ULONG           DataSize;
  PVOID           CallContext;
  PVOID           ObjectContext;
  PVOID           Reserved;
} REG_SET_VALUE_KEY_INFORMATION, *PREG_SET_VALUE_KEY_INFORMATION;

文章<<深入理解注册表监控 >>中,作者对 注册表监控函数 CmRegisterCallback 简单的逆向了一下

了解到CmRegisterCallback其实就是申请了一块空间,保存了一个双向链表、Cookie、Context、回调函数的地址,

那么如果要存放注册表,只可能是放在了双向链表里面,

这里我们就有理由猜测注册表监控的回调函数就是通过一个双向链表连接起来的

在后面的反注册表监控中,,我们也会用到这里的结论

其实...感觉会用就行,,,目前还接触不到那么深的原理

根据作者的讲解 << 深入理解注册表监控 >> 我尝试去复刻他给出的代码....

代码见 https://github.com/redqx/malware_coding/tree/master/ring0-monitor-regedit

代码测试:

windbg输出

我们尝试对计算机\HKEY_CURRENT_USER\SOFTWARE\demo的demo1项进行字符串值得修改

同时驱动文件监控得也是计算机\HKEY_CURRENT_USER\SOFTWARE\demo

加载驱动得时候,修改注册表失败

驱动卸载后,注册表修改无报错,修改值为happy

反监控

通过文章<< 深入理解注册表监控 >>了解到CmRegisterCallback的底层实现,就是通过申请一块内存空间存放双向链表,

那么我们只要定位到这个双向链表删除回调函数即可得到反监控的效果

呃....<< 深入理解注册表监控 >>的作者是从驱动的方式去实现一个反监控,

也就是进入内核层,然后去删除一些信息,,实现反监控

这里的话,,,我就不再深入了解了,,,以后看情况再回来看看吧...

但也还是大概阐述一下,我看懂了什么吧,,,,,,

作者通过硬编码的方式去获取了在注册回调函数时的Cookie

然后调用CmUnRegisterCallback函数,参数是之前获取的Cookie

然后取消回调函数,,实现了一个unhook,从而逃避了注册表的监控

对此..我的比喻是,,,卸掉敌人的刀子,,实现自身的安全,,,,,

标签:00000030,ReverseAnalysis,INFORMATION,PREG,KEY,注册表,PVOID,REG
From: https://www.cnblogs.com/redqx/p/17983350

相关文章

  • Winform中设置程序开机自启动(修改注册表和配置自启动快捷方式)
    场景winform程序需要在启动时自启动,可通过将exe快捷方式添加到自启动目录下,或者通过修改注册表添加启动项的方式。注:博客:https://blog.csdn.net/badao_liumang_qizhi实现使用添加快捷方式到启动目录的方式Windows下怎样使用bat设置Redis和Nginx开机自启动:https://blog.csd......
  • 注册表文件的数据信息保存 改进
    注册表是Windows操作系统中的重要组成部分,它用于存储系统和应用程序的配置信息。在Windows9x/Me版本中,注册表文件的数据信息保存在system.dat和user.dat这两个文件中。system.dat:system.dat是存储系统级别的注册表信息的文件。它包含了操作系统、硬件和驱动程序等方面的配置......
  • 自定义vcpkg注册表(一)
    vcpkg提供自定义注册表的功能,主要用途可以是:公司私有库的注册表,自己对官方port的补充但是目前还不想提交到官方的port以及自己和官方对同一个库有不同的构建意见。在自定义注册表中新建port尽管我经常说vcpkg的本质是git和cmake的组合使用,但其实vcpkg还提供了vcpkg.exe和一整套......
  • Windows用注册表修改键盘映射(扫描码)
    title:Windows用注册表修改键盘映射(扫描码)date:2020-10-18categories:编程tags:-键盘-注册表-Windows前言使用C/C++代码方式修改可见下篇《用C/C++(Win32API)写软件修改键位》据说Qwerty键盘是为了降低打字员打字速度,防止打字机卡机所作出的妥协。那么现在的键盘是......
  • Ajax注册表单用户名实时验证
    Ajax注册表单用户名实时验证 1.1.1摘要很多时候在网站上注册时,我们会发现,注册表单通常需要检查用户名和电子邮件地址的可用性;从而确保用户之间不拥有相同的用户名和电子邮件地址;一些网站喜欢在用户提交填写的用户信息时,做信息可用性的检查,而一些网站会做实时的用户名和电子......
  • 注册表修改后立即生效的命令
    首先,要让修改后的注册表生效通常有三种方法:1、刷新。也就是说修改注册表后可以立即生效(一些修改是可以的)。2、重起explorer进程。这也是通常替代重启的最简单的方法(适用绝大多数)。3、重启。有一些修改是必须要重启计算机的,没有什么其他捷径可言(适用全部)。所以可以看出来,第二......
  • regshot注册表对比工具
    参考:RegShot简介与使用方法-CSDN博客......
  • 什么样的情况,数据写入注册表
    原文链接:https://zhidao.baidu.com/question/21113577.html一般数据都是写入数据库,客户端软件会用到注册表。我看有不少数据写入注册表,就很疑惑,为什么不写入数据库。所以查下什么样的情况下,数据写入注册表。 软件在安装和应用的过程中需要保存一些东西,如路径等,有的还需要加载......
  • 在注册表中设置用户或系统环境变量的值
    12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788......
  • Windows 注册表取证 常用分析项
    Windows注册表取证常用分析项注册表主要单元:SYSTEM:对应的注册表分支为HKEY_LOCAL_MACHINE\SYSTEM,对应的存储文件是\Windows\System32\config\SYSTEM,其作用是存储计算机硬件和系统的信息。NTUSER.DAT:对应的注册表分支是HKEY_CURRENT_USER,存储在用户目录下,与其他注册表文件是分......