4

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

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

mach-o 标头中是否有某处指定入口点的指令集?

4

3 回答 3

9

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

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

于 2015-08-28T21:04:57.780 回答
3

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

对于 iOS,这是我假设您使用 Xcode 时所针对的目标,该代码/usr/local/lib/crt0.o位于您的 iOS SDK 目录中。反汇编显示该符号start是ARM代码。也就是说,iOS 应用程序总是以 ARM 模式开始运行,但之后它们可以很早就改变模式。

于 2015-08-28T20:48:22.133 回答
2

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

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

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

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

于 2015-08-29T00:20:12.580 回答