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

Tim*_*Tim 10 binary programming-languages disassembly

回答了另一个关于用非Objective-C语言开发iPhone的问题,并且我断言使用C#为iPhone写入会让苹果评论家感到错误.我主要谈论的是有关ObjC和C#库之间不同的UI元素,但是一位评论者提出了一个有趣的观点,引出了我这个问题:

是否可以单独从二进制文件中确定程序编写的语言?如果有这样的方法,它们是什么?

我们假设出于问题的目的:

  • 从交互的角度来看(控制台行为,任何GUI外观等)两者是相同的.
  • 该性能不是语言的可靠指标(不比较,比如Java到C).
  • 您没有解释器或您与语言之间的某种东西 - 只是原始的可执行二进制文件.

如果您尽可能与语言无关,则可获得奖励积分.

Kel*_*nch 14

简答:是的

答案很长:

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

抛开这些线索,大多数c/c ++编译器必须将函数的名称插入到二进制文件中,并且存在表中存储的所有函数(或入口点)的列表.C++'破坏'函数名称来编码参数及其类型以支持重载方法.可以对函数名称进行模糊处理,但它们仍然存在.函数签名将包括可用于跟踪系统的参数的数量和类型,或程序中使用的内部调用.在偏移量0x4190处是"SetThreadUILanguage",可以搜索它以找出有关开发环境的很多信息.我找到了偏移量为0x1ED8A的入口点表.我可以很容易地看到像printf,exit和scanf这样的名字; 以及__p__fmode,__ p__commode和__initenv

x86处理器的任何可执行文件都有一个数据段,其中包含程序中包含的任何静态文本.返回cmd.exe(偏移量0x42C8)是文本"Software.Policies.Microsoft.Windows.System".字符串占用的字符数通常是必需的两倍,因为它是使用双宽字符存储的,可能用于国际化.错误代码或消息是这里的主要来源.

在偏移量B1B0是"pushd",然后是mkdir,rmdir,chdir,md,rd和cd; 为了便于阅读,我遗漏了不可打印的字符.这些都是cmd.exe的命令参数.

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

所以,是的,可以从二进制文件中确定源语言.

  • 这一切都依赖于人们链接库。如果这是静态完成的,或者将函数复制/粘贴到源中,会发生什么?这是一个很好的提示(我的+1),但它并不总是可靠的。 (2认同)

Par*_*ppa 7

我不是编译器黑客(有一天,我希望),但我认为你可能能够在二进制文件中找到告诉标志,指示编译器生成它和使用的一些编译器选项,例如指定优化.

但是,严格地说,你要问的是不可能的.可能是有人坐下来用笔和纸制作出与他们想要编写的程序相对应的二进制代码,然后在十六进制编辑器中输入这些东西.基本上,他们在没有汇编工具的情况下进行汇编编程.同样,您可能永远无法确定本机二进制文件是使用直接汇编程序还是使用内联汇编编写的.

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

  • 在我看来,理论上是不可能的,但实际上是不可能的。:) (2认同)