【问题标题】:Event IDs don't match what is displayed in Event Viewer事件 ID 与事件查看器中显示的内容不匹配
【发布时间】:2011-03-29 04:18:16
【问题描述】:

系统事件日志中包含以下详细信息的事件:

Source: Kernel-General
Event ID: 1
Details: The system time has changed to ‎2010‎-‎07‎-‎17T02:58:20.285000000Z from ‎2010‎-‎07‎-‎17T02:58:20.285868600Z.

EVENTLOGRECORD 的 EventID 字段也有一个 1,因此它与我们在事件日志查看器中看到的相匹配。

到目前为止一切顺利。

问题是,当您查看 advapi32.dll 时,这是该源获取消息的地方,您会看到:

ID:01000001
String: The system time has changed to %1 from %2.

事件日志查看器如何神奇地知道将这些额外位添加到 ID 以找到正确的字符串?并非所有事件字符串都具有该高位,有些还设置了其他高位。

使用 1 调用 FormatMessage 失败。用 x01000001 调用它成功。但这不是事件日志记录包含的内容...... :(

我找不到任何文档来讨论这个问题(除了描述显示错误/严重性/设施/代码位的 ID 格式之外)。

【问题讨论】:

    标签: windows winapi event-log formatmessage


    【解决方案1】:

    和你一样,我在任何地方都找不到它的文档,但看起来事件查看器将 EVENTLOGRECORD 结构的 EventType 成员映射到消息表标识符的 Severity 位。

    例如,服务控制管理器事件 7035 属于“信息”类型,它映射到 严重性 值 1,产生消息 ID 0x40001B7B,这确实是事件查看器显示的文本netevent.dll:%1 服务已成功发送 %2 控件。

    同样,事件 7000 的类型为“错误”,映射到 严重性 3,消息 ID 为 0xC0001B58:%1 服务由于以下错误而无法启动:%n %2

    当然,这与您的示例不太相符;你确定你把你的 0 和 1 放在了正确的地方吗?

    【讨论】:

    • 嗯,是的,在某些情况下确实有效。不幸的是,据我所知,并非全部。查看 advapi32.dll,有些值的高字节为 0D、76、B5、D4,仅举几例。这似乎表明有时会使用保留位,甚至是设施代码。
    • 那是在哪个平台上?我在 Windows XP 上,advapi32.dll 中的消息表条目都以 0x40 或 0x80 作为最高字节。
    • 你说得很好。我在 Windows 2008 上(我确实知道事情发生了变化)。我已经检查并随机检查了 System32 目录中的大约 50 个 DLL。 CertEnroll 和 AdvApi32 碰巧有各种奇数,但其余的大多数似乎都有上限值 0、1、3、4、5、8、9、B、C。因此使用了 Reserved 和 Customer 位也。也许故事的寓意是,如果查看 Vista/2008 或更新版本,您真的必须使用新的 API。
    • 我已联系 Microsoft 以了解是否有任何关于预测事件 ID 的其他信息。我会回来报告的。
    • 报告——没有来自 MS 的好信息——基本上需要使用新的 Evt API。也找到了这篇文章:grimes.demon.co.uk/workshops/…(第 8.8.1 节)
    【解决方案2】:

    假设在 Windows XP 和更早版本中,事件 ID 直接映射到消息表中的消息 ID。在 Vista 和更高版本中,事件 ID 可以通过两种方式映射到消息 ID。

    1. 事件限定符(这可能是像 Brian 最初提到的那样被掩盖的严重性)
    2. Windows 事件模板资源

    本文更详细地描述了这两种方式: https://github.com/libyal/libevtx/blob/master/documentation/Windows%20XML%20Event%20Log%20(EVTX).asciidoc#message-string-identifier

    对于此“系统时间已更改...”事件,Windows 10 正在使用 Windows 事件模板资源。如果您在注册表中查找 EventMessageFile 键,对于此事件(基于 Event Source = Microsoft-Windows-Kernel-General),您会找到提供程序 DLL。

    Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog\System\Microsoft-Windows-Kernel-General

    然后您可以使用 windows 事件实用程序查看提供程序 dll 的内容(添加 /gm:true 标志将显示消息文本):

    wevtutil gp Microsoft-Windows-Kernel-General /ge:true

    输出显示事件 ID 1 和事件任务 5 的消息 ID = 16777217 (0x01000001)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-09-28
      • 1970-01-01
      • 2012-07-08
      • 2022-12-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多