Windows PE文件版本信息解析的陷阱与思考

本文探讨了Windows API获取PE文件版本信息时可能存在的差异,通过对比Velociraptor取证工具和手动解析的结果,揭示了系统接口与文件实际嵌入元数据不一致的现象,对数字取证和文件分析的可靠性提出警示。

作为我研究Amcache(相关内容将另文详述)工作的一部分,我开始探究Windows PE文件的版本信息以及Windows系统如何解读它。起因是我以为在Velocidex的PE解析模块中发现了一个错误,但事实上,这更像是“Windows有时会做些奇怪的事情”。

这个“错误”是什么?

在检查我Windows 11机器上一个PE文件的版本信息时,我注意到在某些情况下,Windows显示给我的细节与文件实际嵌入的内容并不匹配。

我曾编写过一个Velociraptor取证构件(artifact),它从Amcache中提取详细信息,同时也使用PE模块解析二进制文件(这正是Velo的强项——将不同的取证线索结合起来!)。在截图中,你可以看到文件的“属性”信息与手动解析结果的对比。

出于某种原因,根据PE版本信息,该文件是一个自解压的CAB文件,但根据Windows显示的细节来看却不是。这里的推论是,在某些情况下,API可能做了一些额外的工作——我的猜测是,这里显示的细节代表了被提取并安装的可执行文件。

因此我想深入探究一下

我发现了什么?

嗯,我不知道它是如何工作的,也不知道它为什么这样做;但在一些Copilot提示的帮助下,我制作了几个二进制文件并进行了一些测试。第一个是hello.exe,它只打印“Hello World”,没有嵌入任何元数据。只是一个用GCC编译的简单C程序。第二个是hello2.exe,它有一个.rc文件,嵌入了我提供的元数据。很简单。

那么这是hello2,它应该嵌入了信息,但由于我尚不清楚的原因,用于在“详细信息”面板中提取信息的API却没能提取出来。

如果我使用pestudio解析该文件,信息确实存在(顺便一提,pestudio对之前提到的那个自解压CAB文件也没能正常工作)。有趣的是,Amcache反映的信息与文件属性中的一致,所以可能使用了相同的API?

接下来,我让Copilot帮我写了另外两个C程序——第一个使用Windows API来打印版本信息,第二个则手动提取数据。这里需要持保留态度,因为我不完全确定它的工作原理(我20年前上过C语言课,也不完全清楚Windows在做什么,这可能是两者的结合),但经过一些调整,Copilot似乎完成了我的要求。

所以呢?

基本上,不要假定Windows API返回的属性是完整的,并且要对那些从PE头部提取数据的取证构件(例如Amcache)保持警惕。它可能并不总是完整或正确的(但这将是另一个话题了)。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计