如何知道程序入口点是 ARM 模式还是 Thumb 模式

How to know if ARM or Thumb mode at entry point of program

我正在编写 ARMv7 反汇编程序。 ARM和Thumb模式之间切换的方法在ARM参考手册中有明确的描述,但是你怎么知道一个程序中启动的是什么模式呢?

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

mach-o header 中是否有指定入口点指令集的地方?

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

在 iOS 的情况下,这是我假设您的目标,因为您使用的是 Xcode,该代码在 /usr/local/lib/crt0.o 中,在您的 iOS SDK目录。反汇编可以看出符号start是ARM代码。也就是说,iOS 应用始终在 ARM 模式下启动 运行,但它们可以在之后很早的时候更改模式。

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

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

取决于您所说的入口点是什么意思。答案就在那个定义中。操作系统必须有一个定义,因为它必须处于正确的模式。因此,要么操作系统总是定义 arm 模式,然后代码可以根据需要进行切换。或者,如果您使用带有入口点的文件格式(如 elf),那么您可能会以偶数地址为 arm 而奇数地址为 thumb,匹配 bx/blx 指令。

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

如果您只是想反汇编一些通用目标文件,那么您可能无法理解。当你看到很多 0xE(每个单词的开头)可能是 arm 代码、0x6 或 0x7 而不是很多 0xE 或 none(每个半字)时,视觉上就像一个人在看十六进制的 arm 二进制文件那可能是拇指代码。但这不是您可以依赖此任务的东西,因为如果要进行切换,前几条指令可能会切换模式。

另外,如果您可以从块头中分辨出一个 elf 文件,我认为这就是 gnu 工具计算出来的方式,因为它们肯定不会即时检测到它。所以这很可能是您想要执行此操作的方式,请检查 elf 文件。如果这是一个原始二进制文件,只有指令和数据......祝你好运......