Programming languages 从二进制文件确定源语言?

Programming languages 从二进制文件确定源语言?,programming-languages,binary,disassembly,Programming Languages,Binary,Disassembly,我回答了另一个关于用非目标C语言为iPhone开发的问题,我断言,用C#为iPhone编写代码会让苹果的评论员大吃一惊。我主要谈论的是ObjC和C#库之间不同的UI元素,但一位评论者提出了一个有趣的观点,将我引向了这个问题: 是否可以仅从二进制文件确定程序所用的语言?如果有这样的方法,它们是什么 为了问题的目的,让我们假设: 从交互角度(控制台行为、任何GUI外观等)来看,两者是相同的 这种性能不是语言的可靠指标(比如说,Java和C之间没有比较) 在你和语言之间没有解释器或其他东西——只有原

我回答了另一个关于用非目标C语言为iPhone开发的问题,我断言,用C#为iPhone编写代码会让苹果的评论员大吃一惊。我主要谈论的是ObjC和C#库之间不同的UI元素,但一位评论者提出了一个有趣的观点,将我引向了这个问题:

是否可以仅从二进制文件确定程序所用的语言?如果有这样的方法,它们是什么

为了问题的目的,让我们假设:

  • 从交互角度(控制台行为、任何GUI外观等)来看,两者是相同的
  • 这种性能不是语言的可靠指标(比如说,Java和C之间没有比较)
  • 在你和语言之间没有解释器或其他东西——只有原始的可执行二进制文件

如果你尽可能不懂语言,那么你就可以获得额外的积分。

好吧,C最初是转换为ASM的,因此你可以在ASM中编写所有C代码。

我希望你可以,如果你反汇编源代码,或者至少你可能知道编译器,因为不是所有编译器都会使用相同的代码,例如,
printf
,所以Objective-C和GNUC在这里应该有所不同

您已经排除了所有字节码语言,因此此问题将不像预期的那样常见。

我不是编译器黑客(我希望有一天),但我认为您可能能够在二进制文件中找到指示编译器生成了什么以及使用了哪些编译器选项的指示符号,例如指定的优化级别

然而,严格地说,你所要求的是不可能的。可能有人拿着纸和笔坐下来,计算出与他们想要编写的程序相对应的二进制代码,然后在十六进制编辑器中键入这些内容。基本上,他们不用汇编工具就可以在汇编中编程。类似地,您可能永远无法确定本机二进制文件是用直接汇编语言编写的,还是用C语言编写的,并带有内联汇编


对于JVM和.NET等虚拟机环境,我希望您能够通过二进制可执行文件中的字节码来识别VM。但是,您可能无法分辨源语言是什么,例如C#还是Visual Basic,除非有特殊的编译器怪癖提示您。

首先,在一些二进制文件上运行
what
,并查看输出。CV(和SVN)标识符分散在整个二进制图像中。其中大部分来自图书馆

此外,通常还有一个指向各种库函数的“映射”。这也是一个很大的暗示

当库链接到可执行文件时,通常会在二进制文件中包含一个带有名称和偏移量的映射。这是创建“位置独立代码”的一部分。您不能简单地将各种对象文件“硬链接”在一起。您需要一个映射,并且在将二进制文件加载到内存时必须进行一些查找


<>最后,C、C++的启动模块(和我想象的C)是编译器的DeFault库集合中唯一的。

< P>不,字节码是语言不可知的。不同的编译器甚至可以获取相同的代码源并生成不同的二进制文件。这就是为什么你看不到能在二进制文件上工作的通用反编译程序。

可以使用命令“strings”来获得一些关于所用语言的提示(例如,我刚刚在我编写的C应用程序的剥离二进制文件上运行了它,它找到的第一个条目是由可执行文件链接的库).

简短回答:

长答覆:

如果查看二进制文件,可以找到已链接到的库的名称。在TextPad中打开cmd.exe很容易在十六进制偏移量0x270处找到以下内容:msvcrt.dll、KERNEL32.dll、NTDLL.dll、USER32.dll等。msvcrt是Microsoft“C”运行时支持函数。KERNEL32、NTDLL和USER32.dll是特定于操作系统的库,它们告诉您目标平台或构建目标平台的平台,具体取决于跨平台开发环境将两者分离的程度

抛开这些线索不谈,大多数c/c++编译器都必须将函数名插入到二进制文件中,表中存储了所有函数(或入口点)的列表。C++函数“Mangle”函数名来编码参数及其类型,以支持重载方法。可以混淆函数名,但它们仍然存在。函数签名将包括可用于跟踪系统或程序中使用的内部调用的参数的数量和类型。在偏移量0x4190处是“SetThreadUILanguage”,可以搜索它以了解有关的许多信息。我在偏移量0x1ED8A处找到入口点表。我可以很容易地看到printf、exit和scanf等名称;以及uuu p_ufmode,uu p_ucommode和uu initenv

x86处理器的任何可执行文件都将有一个数据段,其中包含程序中包含的任何静态文本。返回cmd.exe(偏移量0x42C8)是文本“S.o.f.t.w.a.r.e..P.o.l.i.c.i.e.S..M.i.c.r.o.S.o.f.t..w.i.n.d.o.w.S..S.y.S.t.e.M.”。字符串所需的字符数是通常需要的两倍,因为它是使用双宽字符存储的,可能是为了国际化。错误代码或消息是这里的主要来源

在偏移量B1B0处,为“p.u.s.h.d”,其后为mkdir、rmdir、chdir、md、rd和cd;为了便于阅读,我省略了不可打印的字符。这些都是cmd.exe的命令参数

对于其他程序,我有时能够找到编译程序的路径


因此,,可以从二进制文件中确定源语言。

这些工具如何:

两者都是PE标识符。好的,他们是波