【问题标题】:Determining Which Compiler Built a Win32 PE确定哪个编译器构建了 Win32 PE
【发布时间】:2009-04-18 22:10:45
【问题描述】:

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

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

【问题讨论】:

  • 是什么驱使您需要这些信息?
  • 首先,想知道我们使用了什么版本的 VS 来构建我们这里的一些二进制文件。 (我正在考虑使用更新版本的 VS 重新构建它们,以获得几乎免费的性能提升。)我找到了知道这些特定二进制文件答案的人,但我很好奇它是否可以在一般情况下完成。
  • 在这种情况下,答案不就是无论如何都要使用最新的编译器进行重建吗?要么使用相同的编译器重新编译,不做任何更改,要么最终使用更新的编译器,给你提到的优势。
  • 当然可以。但是 1. 你可能在浪费你的一些努力,而且(更重要的是)2. 这并不能平息我的好奇心 :)

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


【解决方案1】:

区分 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。

【讨论】:

  • 嗯,你的版本列表更完整... ;-)
  • 啊,没有编号的 MSVCRT.DLL 是 VC6... 这解释了一些事情。感谢 Dependency Walker 的链接,它看起来非常有用。我希望我可以在你们三个之间分配接受的答案点,但我决定将它们分配给具有 1 个代表的人。
  • Dependencies 是 Dependency Walker 的现代替代品:github.com/lucasg/Dependencies
【解决方案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 领域。还有其他 dll,例如 MFC 和 ATL dll,它们具有类似的版本控制方案。

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

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

    • 是的,我现在使用的是 IDA Pro 5.1。但是,它的分析非常模糊。对于我知道是用 VC6 编译的东西,它说“使用 FLIRT 签名:Microsoft VisualC 2-8/net 运行时”。
    猜你喜欢
    • 1970-01-01
    • 2013-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-17
    • 1970-01-01
    • 1970-01-01
    • 2017-05-11
    相关资源
    最近更新 更多