确定哪个编译器构建了Win32 PE

如何确定使用哪个C或C ++编译器来构建特定的Windows可执行文件或DLL? 有些编译器在最终的可执行文件中留下了版本字符串,但这在Windows上似乎比在Linux上更少见。

具体来说,我有兴趣区分Visual C ++和各种MinGW编译器(通常很容易从函数签名),然后在Visual C ++版本之间(6,2002 / 2003,2005,2008;更难做)。 有没有一种工具能够以半可靠的方式进行区分?

区分VC版本的提示的一个来源是链接的特定C运行时库。 由于默认情况(至少在现代版本中)链接到DLL,这很容易做到。 实用程序Dependency Walker几乎不可或缺,用于validation您是否知道正在加载的DLL,并且它将告诉您正在使用哪个C运行时DLL。 尽管Dependency Walker包含在Microsoft Platform SDK中,但它已经独立扩展,我链接的站点是其当前开发的主页。

VC6和MinGW默认都链接到MSVCRT.DLL,因此不区分它们。 通过一些努力,MinGW也可以链接到后来的C运行时版本,因此您需要独立排除MinGW。

Runtime VC Version ---------- ------------- MSVCRT.DLL VC6 MSCVR80.DLL VC8 (VS 2005) MSCVR90.DLL VC9 (VS 2008) 

其他运行时DLL也是很好的线索,例如对Delphi运行时的引用可能表明EXE实际上是从Delphi构建的,而不是C工具链。

如果尚未从.EXE文件中删除符号,则可能会找到一些内部符号存在的线索。 例如,对_sjlj_init类的_sjlj_init可能表示在某些时候涉及为setjmp / longjmpexception处理配置的MinGW GCC 3.x.

另一种选择是使用depends.exe检查dll链接到哪个CRT库
MinGW和Cygwin有他们自己的dll,很明显可以识别。
VC6通常使用MSVCRT.dll
任何较新版本的VS的版本都在dll的文件名旁边:
MSVCR90.dll – VS2008
MSVCR80.dll – VS2005
MSVCR71.dll – VS2003
MSVCR70.dll – VS2002

不要将此列表作为权威指南,因为这些名称往往有奇怪的变化,特别是在VS2002-2003领域。 还有其他类似MFC和ATL dll的dll具有类似的版本控制方案。

只要PE实际上依赖于CRT并且它没有静态地链接到它,这将起作用。

我认为Delphi也有一些它链接到的DLL,但我不确定它是什么。

IDA-Pro执行的部分分析包含一些编译器识别。 打开PE进行分析后,查看输出日志。 它通常埋在那里的某个地方。