我responded关于用非Objective-C语言开发iPhone的另一个问题,我断言使用C#为iPhone写入会让苹果评论家感到错误。我主要谈论的是有关ObjC和C#库之间不同的UI元素,但是一位评论者提出了一个有趣的观点,引出了我这个问题:
是否可以单独从二进制文件中确定编写程序的语言?如果有这样的方法,它们是什么?
我们假设出于问题的目的:
如果您与语言无关,则获得积分。
答案 0 :(得分: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”,可以搜索它以找出关于development environment的很多信息。我找到了偏移量为0x1ED8A的入口点表。我可以很容易地看到像printf,exit和scanf这样的名字;以及__p__fmode,__ p__commode和__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的命令参数。
对于其他程序,我有时能够找到编译程序的路径。
所以,是,可以从二进制文件中确定源语言。
答案 1 :(得分:7)
我不是编译器黑客(有一天,我希望),但我认为你可以在二进制文件中找到告诉标志,指示编译器生成它和使用的一些编译器选项,例如指定的优化级别。
但是,严格来说,你要问的是不可能的。可能是有人坐下来用笔和纸制作出与他们想要编写的程序相对应的二进制代码,然后在十六进制编辑器中输入这些东西。基本上,他们在没有汇编工具的情况下进行汇编编程。同样,您可能永远无法确定本机二进制文件是用直接汇编程序编写还是用C语言编写内联汇编。对于诸如JVM和.NET之类的虚拟机环境,您应该能够通过二进制可执行文件中的字节代码来识别VM,我希望如此。但是,您可能无法分辨源语言是什么,例如C#与Visual Basic,除非有特定的编译器怪癖提示您。
答案 2 :(得分:1)
我希望您可以,如果您反汇编源代码,或者至少您可能知道编译器,因为并非所有编译器都会使用printf
的相同代码,因此Objective-C和gnu C应该不同这里。
您已排除所有字节代码语言,因此这个问题不如预期的那么常见。
答案 3 :(得分:1)
首先,在某些二进制文件上运行what
并查看输出。 CVS(和SVN)标识符分散在整个二进制图像中。其中大部分来自图书馆。
此外,通常还有各种库功能的“地图”。这也是一个很大的暗示。
当库链接到可执行文件时,通常会有一个包含在名称和偏移量的二进制文件中的映射。这是创建“位置无关代码”的一部分。您不能简单地将各种对象文件“硬链接”在一起。您需要一张地图,并且在将二进制文件加载到内存时必须进行一些查找。
最后,C,C ++(我想象C#)的启动模块对于该编译器的defaiult库集是唯一的。
答案 4 :(得分:1)
答案 5 :(得分:0)
好吧,C最初转换为ASM,因此您可以在ASM中编写所有C代码。
答案 6 :(得分:0)
不,字节码与语言无关。不同的编译器甚至可以使用相同的代码源并生成不同的二进制文件。这就是为什么你没有看到可用于二进制文件的通用反编译器。
答案 7 :(得分:0)
命令'strings'可以用来获得一些关于使用什么语言的提示(例如,我只是在我写的C应用程序的剥离二进制文件上运行它,它找到的第一个条目是由可执行文件)。