10

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

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

4

3 回答 3

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。

于 2009-04-18T22:43:37.820 回答
2

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

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

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

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

于 2009-04-18T22:46:06.737 回答
1

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

于 2009-04-18T22:21:09.090 回答