是否有可靠的方法来检测使用哪个编译器来编译和构建给定的 Windows 可执行文件?
单独这个话题太宽泛,所以我缩小范围:
在 C# 的情况下,很明显使用了 Visual Studio 附带的编译器,因此在这种情况下是否可以获得 Studio 的版本(年份)和类型(express 等)?
编辑:
从答案来看,确定起来似乎很困难而且并不总是可靠,因为必须使用启发式方法。 那么,是否有编译器故意在可执行文件中插入某种“水印”?我猜测是否有,Visual Studio 可能是这样的编译器(如果没有别的原因,我可以想象他们这样做只是为了知道是否有人使用免费的 Express 版本,或者只是他们正式购买的另一个版本)。然而,我在谷歌上找不到任何明确的答案。
这实际上是两个问题,因为 C/C++ 和 C# 完全不同。我将尝试回答 C# 问题。
C# 程序集始终是为特定的 .NET Framework 版本构建的。通过检查程序集的版本,您可以确定使用的是哪个版本的编译器。每个版本的框架都有自己的编译器。
无法从编译后的程序集中找到有关 Visual Studio 的详细信息,因为编译器不是 VS 的一部分。您可以假设 .NET 4 程序集是使用 VS 2010 构建的,但仅此而已。据我们所知,它可以用记事本编写。
也有可能使用了除 csc 之外的编译器,但这种情况并不经常发生,除了 Mono,所以我会忽略它。
至于母语:
没有可靠的方法可以知道使用的是哪个编译器。甚至没有办法确定使用的是哪种语言。您所需要使用的只是机器代码和二进制数据,因此您必须根据已知的编译器模式做出有根据的猜测。
IDA 反汇编器能够识别静态编译的编译器标准库:
http://www.hex-rays.com/products/ida/index.shtml
http://www.hex-rays.com/products/ida/tech/flirt/in_depth.shtml
如果只谈论 MSVC,它会在 ECX 寄存器中传递 this 指针,所以如果你看到这个,代码可能是 C++(而不是 C)并使用对象。更多信息请参见:http://en.wikipedia.org/wiki/X86_calling_conventions
C# 代码是如此不同,您甚至不需要反汇编程序来识别它。
没有官方或标准方法来识别用于制作二进制或可执行对象的工具。 Windows 可执行格式不需要有关工具的信息;也没有使用的语言。
人们也许能够通过识别代码模式来区分工具,但这非常困难。 人们使用不同的工具重写软件是如此困难和耗时。
顺便说一句,除了 Visual Studio 和 GNU 之外,还有其他工具。
您可以尝试 dumpbin 工具(将其称为 dumpbin /HEADERS)。它将在可选标头中列出链接器版本,从中您可以找出可能使用的编译器版本。 请参阅 dumpbin 帮助页面