神秘的 ARM 指令评估结果为 0xfe 而不是 0xff

逆向工程 调试 反调试 ios arm64
2021-07-01 20:33:38

我在调试用于教育目的的 iOS 应用程序时遇到了一些问题。这是在 App Store 上找到的 iOS 应用程序,并且内置了一些反调试功能。

借口: 您在下面看到的汇编指令是应用程序完成的反调试检查的片段。以下说明将执行以下操作:

  1. 使用(当前 PC 寄存器 - 0xa70)的内存地址加载寄存器 X8
  2. 无操作
  3. 从寄存器 X8 加载字节到 w8
  4. 比较寄存器 w8 是否等于 0xff

在 IDA 中看到的指令的确切代码块

ADR X8, __cB5JgDa_QrhRN_ ; +[cB5JgDa QrhRN] NOP LDRB W8, [X8] CMP W8, #0xFF

相同指令集对应的字节码块

88 AC FF 10 1F 20 03 D5 08 01 40 39 1F FD 03 71

反调试检查的组装说明

现在,让我们开枪看看当它尝试从寄存器 x8 int w8 加载字节时会发生什么。如您所见,我对 w8 和 X8 进行了寄存器读取。理论上,根据X8的内存内容,这条指令应该已经通过汇编指令ldrb w8, [x8]将0xff加载到了w8中

有问题的组装说明

面临的问题:在评估指令时,w8 中的实际内存内容是 0xfe 而不是 0xff。这确实是一种意外行为,因为我的 ARM 知识告诉我该评估的正确值应该是 0xff 而不是 0xfe。

评估结果是 0xfe 而不是 0xff

我尝试过但未能解释这种行为的事情

  1. 创建迷你 Xcode iOS 应用程序并尝试复制相同的指令集和内存状态
  2. 设置观察点以观察程序的任何部分是否正在编辑中间的内存
  3. 如果他们修改了该内存区域,则寻找诸如 mprotect 之类的内存保护

我将非常感谢任何能够为我指明任何正确方向或方式的人,以便我能够更好地理解这种神秘的行为。如果是我对ARM指令的误解,也请告诉我。谢谢大家!谢谢。

1个回答

认为代码应该检查钩子。

adr指令设置x8为函数的开头,因此如果钩子库在那里放置了断点或跳转,则那里的字节将与原始值不同FF

一种可能性是那里有一个断点,但调试器通过向您显示原始代码来屏蔽它。如果您确实在那里放置了一个断点,请在逐步读取之前尝试将其删除。您也可以尝试使用一次性断点,这些断点在被击中后会自动删除。