如何识别编译的应用程序的编程语言?
How to identify the programming language of an application which is compiled?
我刚刚下载了一个应用程序,我想知道他们是用什么编程语言编写的。
如果它是 Java,那么后台会有一个 JVM 进程 运行,对吗?
我做到了:
% sudo ps -A | grep -i java
没有结果。
我记得 Linux 有一个工具可以在编译后的源代码中搜索字符串,但我不记得这个名字了,你知道类似的东西吗?
对我如何找到编程语言有什么建议吗?
编译是将程序从一种语言翻译成另一种语言的过程。对于计算机语言,就像自然语言的翻译一样,通常无法分辨从翻译成哪种语言,只能知道翻译成哪种语言.
例如,与您问题中的示例保持一致,如果 Java 程序被编译为 ECMAScript 然后 运行,将不会有 java
过程 运行宁。关于该程序,您只能说它是当前 用 ECMAScript 编写的,但您无法分辨它以前是用什么编写的。同样,如果你把一个Java程序编译成本地机器码,你之前无法判断它是一个Java程序,你只能判断它是一个本地可执行文件。如果你把Java编译成CIL字节码,你只能看出它是一个CLI程序,而不是之前的样子。
另一方面,如果您将 Ruby 编译为 JVM 字节码,然后 运行 它, 将 成为一个 java
进程运行宁。但这确实 而不是 意味着原始程序是用 Java 编写的。只是表示运行ning程序在JVM字节码中是"written"。但是,该程序可以用 任何 语言编写,存在编译器可以编译为 JVM 字节码。或者,它可能是用 JVM 字节代码本身编写的,尽管这种可能性极小。存在编译为 JVM 字节码的编译器的多种语言:Scala、Groovy、Clojure、Fantom、Kotlin、Ceylon、Ruby、Python、ECMAScript、C、PHP, Scheme, CommonLisp, x86 native machine code, Frege, Ioke, Seph, …我相信有超过500种语言在JVM上实现。
现在,这并不完全正确:有时,根据所使用的确切编译器,编译器会在编译后的代码中留下某些可检测的残留痕迹或模式,让您至少猜测源语言。例如,主线 Scala-to-JVM 编译器将在编译的 .class
文件中留下一个 ScalaSig
属性,其中包含无法在有限的 JVM 类型系统中清楚地表示的签名和类型信息。许多 X-to-ECMAScript 编译器实际上会在编译输出的顶部放置一个注释,其中包含原始源文件的名称以及编译器的名称和版本。等等。具体来说,需要保留一定数量的 运行 有关原始程序的时间信息的语言,例如对于动态类型、动态调度、动态反射、动态优化等,将比能够擦除几乎所有类型和名称的语言更容易识别。
但这不是你可以依赖的。
I remember from Linux that there was a tool which would search for strings in a compiled source but I don't remember the name anymore, do you know something like that?
它简称为 strings
,预装在大多数类 Unix 操作系统上,包括 OSX。
我刚刚下载了一个应用程序,我想知道他们是用什么编程语言编写的。
如果它是 Java,那么后台会有一个 JVM 进程 运行,对吗?
我做到了:
% sudo ps -A | grep -i java
没有结果。
我记得 Linux 有一个工具可以在编译后的源代码中搜索字符串,但我不记得这个名字了,你知道类似的东西吗?
对我如何找到编程语言有什么建议吗?
编译是将程序从一种语言翻译成另一种语言的过程。对于计算机语言,就像自然语言的翻译一样,通常无法分辨从翻译成哪种语言,只能知道翻译成哪种语言.
例如,与您问题中的示例保持一致,如果 Java 程序被编译为 ECMAScript 然后 运行,将不会有 java
过程 运行宁。关于该程序,您只能说它是当前 用 ECMAScript 编写的,但您无法分辨它以前是用什么编写的。同样,如果你把一个Java程序编译成本地机器码,你之前无法判断它是一个Java程序,你只能判断它是一个本地可执行文件。如果你把Java编译成CIL字节码,你只能看出它是一个CLI程序,而不是之前的样子。
另一方面,如果您将 Ruby 编译为 JVM 字节码,然后 运行 它, 将 成为一个 java
进程运行宁。但这确实 而不是 意味着原始程序是用 Java 编写的。只是表示运行ning程序在JVM字节码中是"written"。但是,该程序可以用 任何 语言编写,存在编译器可以编译为 JVM 字节码。或者,它可能是用 JVM 字节代码本身编写的,尽管这种可能性极小。存在编译为 JVM 字节码的编译器的多种语言:Scala、Groovy、Clojure、Fantom、Kotlin、Ceylon、Ruby、Python、ECMAScript、C、PHP, Scheme, CommonLisp, x86 native machine code, Frege, Ioke, Seph, …我相信有超过500种语言在JVM上实现。
现在,这并不完全正确:有时,根据所使用的确切编译器,编译器会在编译后的代码中留下某些可检测的残留痕迹或模式,让您至少猜测源语言。例如,主线 Scala-to-JVM 编译器将在编译的 .class
文件中留下一个 ScalaSig
属性,其中包含无法在有限的 JVM 类型系统中清楚地表示的签名和类型信息。许多 X-to-ECMAScript 编译器实际上会在编译输出的顶部放置一个注释,其中包含原始源文件的名称以及编译器的名称和版本。等等。具体来说,需要保留一定数量的 运行 有关原始程序的时间信息的语言,例如对于动态类型、动态调度、动态反射、动态优化等,将比能够擦除几乎所有类型和名称的语言更容易识别。
但这不是你可以依赖的。
I remember from Linux that there was a tool which would search for strings in a compiled source but I don't remember the name anymore, do you know something like that?
它简称为 strings
,预装在大多数类 Unix 操作系统上,包括 OSX。