Windows注册表的三个简短故事

下午好,亲爱的读者们。

注册表是最可见和最重要的Windows系统之一。 几乎没有人没有听说过他。 在Windows下进行编程已有大约20年的时间,我认为我对他一无所知。 但是,时不时地出现一些新事物,向我展示我是多么的错误。 因此,今天,我想向您介绍研究rootkit时遇到的异常处理注册表的方法,这使我感到惊讶。


第一个故事。 注册表值和键的名称


我们都知道,在Windows中,有一些用于命名对象的规则,无论是文件,目录还是注册表项。 文件名不能包含“ \”字符。 名称不能为空。 名称有一些长度限制,等等。

我们非自愿地将这些限制扩展到所有Windows系统,并在使用注册表时遵守它们。 这就是我们的错误。 创建名称时,注册表上几乎没有什么限制。 例如,在值的名称中,您可以使用字符“ \”


惊讶吗 不行吗 那么,如果我向您显示可以在值的名称中使用符号“ \ 0”,您会怎么说? 是的,是,完全为空字符。 传统上用来指示行尾的那个。

为此,我们需要从ntdll.dll导出的NtSetValueKey函数。

HKEY hKey = 0; RegOpenKeyA( HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\Run", &hKey); UNICODE_STRING uName; uName.Buffer = L"Test\0Zero"; uName.MaxLen = uName.Length = 9 * sizeof(wchar_t); NTSTATUS status = 0; status = NtSetValueKey( hKey, &uName, 0, REG_SZ, (void*)lpData, DataSize); RegCloseKey(hKey); 

要执行NtSetValueKey函数,您需要管理员权限。 结果,一个名称为Test \ 0Zero的值将出现在您的注册表中。

一些Microsoft开发人员也会感到惊讶,因为标准注册表编辑器无法显示这种异常的注册表值。


第二个故事


今天我要告诉您的第二个故事发生在2013年。

起初有一点题外话。 在卡巴斯基实验室,我是创建卡巴斯基救援磁盘的团队成员。 要从Linux下治愈Windows,我们需要自己解析注册表文件。 为了检查此机制的正确运行,我们使用了许多测试。 其中,有一个相当简单:

  • 在Windows下,我们在注册表中写入测试值。
  • 将注册表配置单元文件复制到测试目录。
  • 我们启动执行删除测试值的程序。
  • 我们将修改后的布什加载到注册表中以验证删除。

有一天,我们在Windows测试平台上将其更新到版本8.1,并且测试停止删除测试值。 怎么会,我很惊讶。 我将带有注册表配置单元的文件复制到了我的工作计算机上-没有值! 我的第一个想法:我需要在Flush测试中添加更改的键。 添加了对RegFlushKey的调用,重新启动了测试-没有值!

我认为RegFlushKey无法正常工作。 但是,事实证明,我只是部分正确。

诀窍在于,在Windows 8.1中,Microsoft更改了将更改保存到注册表的机制。 以前,所有注册表更改都存储在内存中,然后,在关闭键,执行RegFlushKey时或一段时间之后,系统会将更改保存到注册表配置单元文件中。 在Windows 8.1中,更改而不是注册表Bush文件保存在具有扩展名.LOG,.LOG1和.LOG2的同名文件中,而我的代码在那时忽略了这些文件。

在这些文件中,更改累积约一个小时。 只有在此之后,Windows才开始将更改集成到主文件中的任务。 此任务称为对帐,它每40分钟启动一次,或者Windows关闭时启动。 调用RegFlushKey函数不会触发对帐任务。 要强制启动更改集成任务,您需要使用未记录的参数SystemRegistryReconciliationInformation调用ZwSetSystemInformation。

 ZwSetSystemInformation( 0x9b, //SystemRegistryReconciliationInformation NULL, 0); 

要执行ZwSetSystemInformation函数,您需要管理员权限。 可执行文件的体系结构必须与系统的体系结构匹配。 在64位Windows上从32位程序调用此函数将失败。

第三故事


前一段时间,我们发现了一个Rootkit,它规定了在注册表中启动其驱动程序。 我们的产品删除了相应的注册表项,但是在重新启动后,注册表项就在其位置。 我想,他似乎将其回调函数用于注册表更改,并在我们进行更改后恢复了密钥。 但是事实证明没有。 更确切地说,是的。 rootkit设置了Callback函数,但它们与密钥恢复任务无关。 一切都变得更加简单和优雅。

rootkit驱动程序在启动时将SYSTEM注册表配置单元文件重命名为HARDWARE。 我创建了SYSTEM文件,并使用RegSaveKey函数定期将HKLM / System分支保存到该文件。 保存时,他恢复了他的钥匙。 重新启动Windows时,系统加载了SYSTEM文件并启动了rootkit驱动程序。 漂亮吗 真好

通缉


PS在这里,我们正在寻找一个团队,他们正在研究反垃圾邮件引擎,并且我们还需要测试工程师

Source: https://habr.com/ru/post/zh-CN415699/


All Articles