如何在程序的入口点知道ARM或Thumb模式

时间:2015-08-28 19:19:25

标签: assembly arm disassembly mach-o thumb

我正在编写一个ARMv7反汇编程序。 在ARM参考手册中清楚地描述了在ARM和Thumb模式之间切换的方法,但是如何知道程序启动的模式?

我正在使用默认编译为拇指的Xcode,所以我知道我所有自己的程序都将在Thumb中启动,除非我强制编译为ARM模式。但是,我希望能够获取任意的mach-o可执行文件,并在代码的开头找出指令集模式。

mach-o标题中是否有某个地方指定了入口点的指令集?

3 个答案:

答案 0 :(得分:7)

处理器通过打开程序计数器的最低有效位来确定它处于拇指模式,从而导致程序计数器具有奇数值。为了取指令,该位被忽略,您可以通过切换该位在ARM和拇指模式之间切换。

创建ARM二进制文件时,链接器将设置符号地址的最低有效位,具体取决于此符号是指向ARM还是缩略图代码,以便处理器在程序启动时自动选择正确的模式。你不需要关心这个。

答案 1 :(得分:2)

大多数操作系统在应用程序的入口点(C运行时支持)之前插入一些代码。他们将以编写代码的任何模式启动您的应用程序。然后,当调用main()或其他入口点时,该代码将根据需要进行模式更改。

对于iOS,我假设您使用Xcode进行定位,因此该代码位于iOS SDK目录中的/usr/local/lib/crt0.o。反汇编表明符号start是ARM代码。也就是说,iOS应用程序始终以ARM模式运行,但它们可以在此后很早就改变模式。

答案 2 :(得分:1)

取决于您的入口点的含义。答案就在那个定义中。操作系统必须具有定义,因为它必须处于正确的模式。因此,操作系统将始终定义例如arm模式,然后代码可以根据需要进行切换。或者,如果您使用带有入口点的精灵等文件格式,那么您可能会使用偶数地址为arm而奇数地址为拇指,与bx / blx指令匹配。

如果您正在谈论其中一个核心,那么armv7m将始终启动并且必须保持在拇指模式下。 armv7a和r将以arm模式启动(重置,其他在arm文档中定义,可能是arm模式),然后代码可以切换。

如果您只是想要反汇编某些通用对象文件,那么您可能无法弄清楚它。当你看到很多0xE(每个单词的开头)很可能是arm代码,0x6或0x7而不是很多0xE或者没有(每个半字)时,可视化地看着十六进制的arm二进制文件然后那可能是拇指码。但这不是你可以依赖的任务,因为如果有一个开关发生,前几条指令可能会切换模式。

如果你可以从块头中判断一个elf文件,我认为这就是gnu工具如何解决这个问题,因为他们肯定不会在运行中检测到它。所以很有可能你想要这样做,检查精灵文件。如果这是一个原始的二进制文件,只需要说明和数据......祝你好运......