HKLM \系统\ CurrentControlSet \控制\ TimeZoneInformation \ TimeZoneKeyName腐败?腐败、系统、HKLM、CurrentCont

2023-09-04 02:41:38 作者:离岛茶霏=

我试图确定Windows系统的当前时区。下面code段为(宽松)的基础上对这个线程的答案被@MattJohnson:Getting当操作系统显示语言非英语

I'm trying to determine the current time zone for a Windows system. The following code snippet is (loosely) based on the answer by @MattJohnson on this thread: Getting local timezone identifier when OS display language is non-english

    using (RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(
                                   @"SYSTEM\CurrentControlSet\Control\TimeZoneInformation"))
    {
       if (registryKey != null)
       {
          string windowsTimeZoneId = registryKey.GetValue("TimeZoneKeyName") as string;
          if (string.IsNullOrEmpty(windowsTimeZoneId))
             windowsTimeZoneId = registryKey.GetValue("StandardName") as string;
          if (!string.IsNullOrEmpty(windowsTimeZoneId))
          {
             int i = windowsTimeZoneId.IndexOf('\0');
             if (i != -1)
                windowsTimeZoneId = windowsTimeZoneId.Remove(i);
             return ConvertFromWindowsId(windowsTimeZoneId);
          }
       }
    }

如果我把第一行断点如果(string.IsNullOrEmpty(windowsTimeZoneId)),那么这是我在Visual Studio调试器看到:

If I place a breakpoint on the first line "if (string.IsNullOrEmpty(windowsTimeZoneId))", then this is what I see in Visual Studio debugger:

这是怎么回事呢? RegistryKey.GetValue()返回一个盒装字符串,但为什么它不能检测两个十六进制00字节,并终止字符串呢?

What is going on here? RegistryKey.GetValue() is returning a boxed string, but why does it not detect the two hex 00 bytes and terminate the string there?

到目前为止,我在我的两个电脑测试了这一点。这是从一台运行Windows 7 64位。另外一个,运行Windows 7 32位,是一样的,只是它说,返回的字符串的长度为128个字符,而不是127。

So far I've tested this on two of my PCs. This is from one that runs Windows 7 64-bit. The other one, running Windows 7 32-bit, is the same except that it says that the length of the returned string is 128 characters instead of 127.

当在与REGEDIT.EXE它看起来很好的注册表项看,只显示浪漫标准时间。

When looking at the registry entry with regedit.exe it looks fine, showing only "Romance Standard Time".

谷歌搜索的位打开了这个问题,https://social.msdn.microsoft.com/Forums/sqlserver/en-US/eca7ad76-c910-46be-8fb9-876c7cde5c69/registry-read-time-zone-info-differ-when-$c$c-build-on-40-framework-on-host-system-win-7-64-bit?forum=csharpgeneral否则,我无法找到任何东西。

A bit of Googling turned up this question https://social.msdn.microsoft.com/Forums/sqlserver/en-US/eca7ad76-c910-46be-8fb9-876c7cde5c69/registry-read-time-zone-info-differ-when-code-build-on-40-framework-on-host-system-win-7-64-bit?forum=csharpgeneral Otherwise I can't find anything.

该项目正在建设与Visual Studio 2012,和定位的.Net 2.0。

The program is being built with Visual Studio 2012, and targeting .Net 2.0.

正如你所看到的,我已经添加了code借此腐败的结果考虑在内,但还是我最好的AP preciate,如果有人可以给我解释一下什么是怎么回事,和甚至如何避免整个问题。

As you can see, I've added code to take this "corrupt" result into account, but still I'd appreciate it if someone could explain to me what is going on here, and maybe even how to avoid the whole problem.

编辑:

该项目正在建设与Visual Studio 2012,和定位的.Net 2.0。

The program is being built with Visual Studio 2012, and targeting .Net 2.0.

嗯,情节变稠。这种说法是不完全正确的。的code上面显示的残肢是在是建立在面向.NET 2.0库程序集,但它正在从一个程序,有针对性的.NET 4.0中调用。现在,我已经尝试从一个程序,面向.NET 2.0中调用它,是没有问题的,RegistryKey.GetValue()只返回浪漫标准时间。因此看来,它确实有一些做与.net Framework 4.0中,所隐含MSDN上张贴。

Hmm, the plot thickens. That statement was not totally correct. The stump of code shown above is in a library assembly that is built to target .Net 2.0, but it was being called from a program that targeted .Net 4.0. Now I've tried calling it from a program that targets .Net 2.0, and there is no problem, RegistryKey.GetValue() simply returns "Romance Standard Time". So it appears that it does have something to do with .Net Framework 4.0, as implied by the posting on MSDN.

编辑2 - 开始认为这是正常的

EDIT 2 - beginning to think that this is "normal"

这是一个有点偏离主题SO,但我会AP preciate,如果有人会来看看我的相关帖子在在Superuser.com,因为我没有得到即时的满足感那里,我想获得这个解决,所以我知道我是否仍然应该惊慌失措与否。谢谢你。

This is a bit off-topic for SO, but I'd appreciate it if someone would take a look at my related posting over at Superuser.com, since I'm not getting instant gratification there, and I'd like to get this resolved so I know whether I should still be panicking or not. Thanks.

http://superuser.com/questions/859031/possible-malware-modification-of-windows-registry-entry

推荐答案

在一个字符串或多字符串值在注册表中设置,Windows不检查语义;它提供任何二进制内容,与由程序员指定的长度简单地存储。这意味着,一个字符串可以是prematurely空值终止,或者反过来,不是空终止的。 (这确实有安全隐患,顺便说一句:虽然我不认为premature空终止可能带来的无法处理的情况下的危险,当地code,其中的字符串不是空结尾的可能。)

When a string or multi-string value is set in the registry, Windows does not check the semantics; it simply stores whatever binary content is provided, with the length specified by the programmer. This means that a string can be prematurely null-terminated, or conversely, not null-terminated at all. (This does have security implications, by the way: while I don't think premature null termination is likely to pose a risk, native code that fails to handle the case where the string is not null-terminated might.)

据汉斯(在他被删除的答案).NET之前的4.x版会忽略额外的数据,如果该字符串是prematurely空值终止,而4.x版包含了它的版本。所以这就是为什么你只,一旦你开始使用4.x中发现的问题。

According to Hans (in his deleted answer) versions of .NET prior to 4.x would ignore the extra data if the string is prematurely null-terminated, whereas 4.x includes it. So that's why you only noticed the problem once you started using 4.x.

至于为什么这个值是prematurely空值终止,这似乎是不小心对微软的一部分。如果你删除多余的数据,然后更改时区,额外的数据重新出现。因此它似乎是视窗本身是这样做的。数据看起来是随机的给我,所以我不相信这是故意的。事实上,这可能会在技术上构成了数据泄露的漏洞,虽然有可能是没有实际影响。

As for why this particular value is prematurely null-terminated, that appears to be carelessness on Microsoft's part. If you remove the extra data, and then change the timezone, the extra data reappears. So it appears to be Windows itself that is doing this. The data looks random to me, so I don't believe it is intentional. In fact, this may technically constitute a data exposure vulnerability, though there is probably no practical impact.

我建议你搜索空,如有必要,截断字符串。可能有这样的情况,其中没有一个,例如,如果该条目已经被第三方code修改,或者如果MS最终发布的更新和修复这个问题,或者,当然,如果你是在.NET 2.x中运行所以,你需要处理这两种情况。

I suggest you search for a null and truncate the string if necessary. There might be situations in which there isn't one, e.g., if the entry has been modified by third-party code, or if MS eventually issues an update and fixes the problem, or, of course, if you're running in .NET 2.x. So you'll need to handle both cases.

(如果我有时间,我回去下周上班,我会在虚拟机上安装Windows的全新副本,并确认完全没有第三方软件present存在的问题。如果是这样的,我会考虑它的报告 - 我怀疑MS将发布一个补丁,但它可能会固定在Windows的未来版本)

(If I have time, when I go back to work next week I'll install a clean copy of Windows on a virtual machine and confirm that the issue exists with absolutely no third-party software present. If so, I'll consider reporting it - I doubt MS will issue a patch, but it might get fixed in a future version of Windows.)

 
精彩推荐
图片推荐