如何在ARM64中修改这个分支?

逆向工程 拆卸 手臂
2021-06-14 08:28:14

我尝试在二进制文件中修改此反汇编的分支:

SUB             SP, SP, #0x60
STP             X26, X25, [SP,#0x50+var_40]
STP             X24, X23, [SP,#0x50+var_30]
STP             X22, X21, [SP,#0x50+var_20]
STP             X20, X19, [SP,#0x50+var_10]
STP             X29, X30, [SP,#0x50+var_s0]
ADD             X29, SP, #0x50
MOV             X20, X0
MOV             X0, X2
BL              _objc_retain
MOV             X19, X0
ADRP            X8, #selRef_shouldCheckForUpdate@PAGE
LDR             X1, [X8,#selRef_shouldCheckForUpdate@PAGEOFF] ; char *
MOV             X0, X20 ; void *
BL              _objc_msgSend
CBZ             W0, loc_ADCC

基本上,二进制文件正在检查更新并会提示是否应该更新,为了学习,我想实现如何:

  1. 总是去 loc_ADCC 和;

  2. 总是忽略 loc_ADCC(跳过去 loc_ADCC)

这个 ARM64 真的让我感到困惑,但是我可以在 32 位中理解它,但在 64 位中却无法理解。这就像一个新世界。您可以在此处查看屏幕截图以获得更好的可视化效果。

提前致谢!

1个回答

所以,有这些选项:

  1. 要始终采用分支,您需要将CBZ(如果为零则比较和分支)转换为简单B(始终分支)。让我们来看看两者的编码:

乙: 31 30 29 28 27 26 25 .. 0 0 0 0 1 0 1 imm26

CBZ:

31 30 29 28 27 26 25 24 23..5 4..0 sf 0 1 1 0 1 0 0 imm19 Rt

要转换CBZB,您需要修补操作码部分(位 31..26)并将imm19字段(分支偏移量)移动操作码imm26字段B(位 25..0)。由于两个操作码都以相同的方式解释偏移量(乘以 4 并添加到 PC),因此除了符号扩展之外,您不需要进行任何转换。

例如,让我们从我拥有的随机样本中获取此指令:

05088 E0 01 00 34  CBZ W0, loc_50C4

操作码为 32 位值:0x340001E0(AArch64 始终使用小端指令)

二进制:00110100000000000000000111100000

按字段拆分:

0 0110100 0000000000000001111 00000 sf op imm19 Rt

让我们组装B操作码(将 imm19 符号扩展为 26 位):

000101 00000000000000000000001111 op imm26

或者,作为十六进制:0x1400000F

打补丁后:

5088 0F 00 00 14                 B               loc_50C4
  1. 要跳过分支,您可以修补CBZ到一个NOP(无操作)。NOPARM64编码是 0xD503201F 或1F 20 03 D5