Windows与PE版本信息的“不合拍”
作为我目前对Amcache进行研究的一部分(关于Amcache的更多内容将在另一篇文章中探讨),我着手探索Windows PE文件的版本信息以及Windows系统是如何看待这些信息的。这个研究的起因是我最初以为在Velocidex的PE解析模块中发现了一个bug,但实际上,更可能的情况是“Windows有时候会做一些有趣的事情”。
所谓的“bug”是什么?
在检查我Windows 11电脑上某个PE文件的版本信息时,我注意到在某些情况下,Windows显示给你的详情与文件实际嵌入的数据并不匹配。
当时我写了一个Velociraptor工件,用于从Amcache中提取详细信息,同时也用PE模块解析了该二进制文件(这是Velo的强项——将各种不同的线索组合在一起!)。在下图的截屏中,你可以看到二进制文件的“属性”界面显示的信息与手动解析得到的信息的对比。
出于某种原因,根据PE版本信息,该文件是一个自解压的CAB文件,但Windows详情中却没有显示这一点。这里的推测是,在某些情况下,系统API做了一些额外的处理——我猜测这里显示的信息代表了被提取并安装的实际可执行文件。
因此,我决定深入探究一番
你发现了什么?
好吧,我不知道它具体如何工作,也不知道它为何这样做;但在一些Copilot提示的帮助下,我创建了几个二进制文件并做了一些测试。第一个文件,hello.exe,只打印“hello world”,没有嵌入任何元数据。这只是一个用GCC编译的简单C脚本。第二个文件,hello2.exe,有一个.rc文件,嵌入了我指定的元数据。这也很简单。
这就是hello2.exe,它本应包含嵌入的信息,但由于我尚不理解的原因,用于在“详细信息”面板中提取信息的API并没有提取到这些信息。
如果我用pestudio来解析这个文件,信息确实存在(不过值得一提的是,pestudio对之前那个自解压CAB文件的处理也不太正常)。有趣的是,Amcache反映的信息与文件属性中的信息一致,所以它可能使用了相同的API?
接下来,我让Copilot为我编写了另外两个C程序——第一个程序使用Windows API来打印版本信息,第二个程序则手动提取数据。请注意,我对这些程序的具体工作原理持保留态度,因为我20年前上过C语言课,而且我也不完全清楚Windows在做什么(这可能是这些因素的综合结果),但在稍作调整后,Copilot似乎完成了我的要求。
所以,这说明了什么?
基本上,不要假设Windows API返回的属性是完整的,并且要对那些从PE头中提取数据的取证工件(例如Amcache)保持警惕。它可能并不总是完整的,或者正确的(但这又是另一个话题了)。