从Windows可执行文件中识别编译器版本

有没有一种可靠的方法来检测哪个编译器被用来编译和构build给定的Windows可执行文件?

单独这个话题太广泛了,所以我把它缩小了:

  • 我只对C系列的语言感兴趣(C,C ++,C#)
  • 假设可执行文件没有被篡改,以隐藏这些信息。
  • Visual Studio和最显着的GNU编译器就足够了,所以不需要处理非常旧或者不被广泛使用的编译器。

在C#的情况下,很显然它使用了Visual Studio附带的编译器,所以在这种情况下可以获取Studio的版本(年份)和types(快速等)?

编辑:

从答案来看,这似乎是困难的,并不总是可靠的确定,因为启发式必须使用。 那么,是否有任何编译器故意在可执行文件中插入某种“水印”? 我猜是否有,Visual Studio可以是这样一个编译器(如果没有别的,我可以想象他们这样做只是为了知道是否有人使用免费的快递版本,或只是另一个版本,而不是他们正式购买)。 不过,我在Google上找不到任何明确的答案。

对于本地代码,您使用“库指纹识别”。 参见ftp://ftp.cs.wisc.edu/paradyn/papers/Jacobson11Unstrip.pdf

许多签名可在这里: http : //code.google.com/p/flairdatabase/

请参阅http://www.hex-rays.com/products/ida/tech/flirt/in_depth.shtml

这实际上是两个问题,因为C / C ++和C#完全不同。 我将尝试回答C#的问题。

AC#程序集总是为特定的.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寄存器,所以如果你看到这个,代码可能是C ++(而不是C)并使用对象。 更多在这里: http : //en.wikipedia.org/wiki/X86_calling_conventions

C#代码是如此的不同以至于你甚至不需要反汇编器来识别它。

没有官方或标准的方法来识别用于制作二进制或可执行对象的工具。 Windows可执行格式不需要有关工具的信息; 也没有使用的语言。

人们可以通过识别代码模式来区分工具,但这是非常困难的。 人们用不同的工具重写软件是非常困难和耗时的。

顺便说一下,除了Visual Studio和GNU,还有其他的工具。

您可以尝试使用dumpbin工具(称为dumpbin / HEADERS)。 它将列出OPTIONAL HEADERS中的链接器版本,并从中找出可能使用的编译器版本。 请参阅dumpbin帮助页面