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

时间:2009-04-18 22:10:45

标签: c++ c compiler-construction executable disassembly

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

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

3 个答案:

答案 0 :(得分:11)

区分VC版本的提示的一个来源是链接的特定C运行时库。由于默认情况(至少在现代版本中)链接到DLL,这很容易做到。实用程序Dependency Walker几乎是必不可少的,用于验证您是否知道正在加载的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之类的引用可能表示在某些时候涉及为setjmp / longjmp异常处理配置的MinGW GCC 3.x.

答案 1 :(得分:2)

另一种选择是使用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,但我不确定它是什么。

答案 2 :(得分:1)

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