ADR x9, sub_xxxxxx 是否调用子程序?为什么代码使用ADR/NOP
Does ADR x9, sub_xxxxxx call a subroutine? Why does code use ADR / NOP
loc_10007390C
SUB X8, X29, #-stuff
LDUR X10, [X8,#-0x100] ;
LDR X0, [X10,#0x10] ;
SUB X8, X29, #-var_1E8
LDUR X2, [X8,#-0x100]
STP X0, XZR, [X2]
SUB X8, X29, #-var_1F0
LDUR X3, [X8,#-0x100]
NOP
LDR X8, =__NSConcreteStackBlock
STR X8, [X3]
STR D8, [X3,#8]
ADD X8, X3, #0x10
ADR X9, sub_100092800
NOP
PACIA X9, X8
ADR X8, unk_1001A2658
NOP
STP X9, X8, [X3,#0x10]
LDUR X8, [X29,#var_B8]
STR X8, [X3,#0x20]
LDUR X8, [X29,#var_C0]
STP X8, X10, [X3,#0x28]
LDUR W8, [X29,#anotherStuff]
STR W8, [X3,#0x38]
SUB X8, X29, #-var_290
LDUR W8, [X8,#-0x100]
STR W8, [X3,#0x3C]
MOV W1, #0
MOV W4, #1
BL do_the_dance
TST W0, #0xFF00
B.EQ loc_1000E8730
我对 ADR X9,sub_100092800 在做什么感到有点困惑。看起来它正在将地址加载到X9中,但是加载后它是否也调用了子程序?
从列表中看,没有来电。它将 PC 相对偏移量加载到寄存器中,然后不对其执行任何操作。但是请看几个地方的 ADR
/NOP
序列。看起来好像 NOP 是要用调用命令修补的 (BL
)。
这里有几种可能性。可能是反汇编程序误读了命令。不太可能,但检查机器代码编码,以防万一。可能有一个重定位指令会在模块加载期间修补这些位置。最后,程序本身可能有一段明确的自我修补逻辑,专门用于阻止像你这样的逆向工程师。自我修补肯定会在模块的其他地方,让你闻风丧胆。
编辑:代码中有一些有趣的地方。我不知道什么是__NSConcreteStackBlock
,但它强烈建议Apple/Cocoa。同时,the PACIA
command is specific to the ARM8.3 instruction set, and has to do with the pointer authentication logic for jump integrity protection. To the best of my knowledge, this is the stuff of the upcoming ptrauth/ARM64E initiative by Apple,最新的 Xcode 和最新的 iDevices 支持,但尚未被 App Store 接受(截至撰写本文时,2020 年 5 月 18 日) .指针身份验证可能很脆弱,Apple 的官方线路是 "try it in dev for now"。我的观点是,它可能是某种函数调用点后处理,它是 ptrauth 感知代码生成管道的一部分。我对 ptrauth 的了解还不够多。 :(
编辑:还有另一种可能性。程序集是否偶然来自反汇编目标文件,而不是链接的可执行文件?然后 NOP 可以作为跨模块调用的占位符。这也可以解释不一致的标签命名。
指令ADR X9, sub_100092800
加载符号sub_100092800
的地址到X9寄存器。它本身不会调用或以其他方式分支到位于那里的代码。
作为安全措施,加载到X9寄存器的地址随后被PACIA指令修改,然后通过以下STP指令存储在内存中。您的代码中没有指示存储在内存中的修改后的值会发生什么,但它很可能在某个时候从内存中加载,恢复到使用 PACIA 指令之前的值,然后被调用。
NOP 指令是一个转移注意力的问题。这是某些伪指令(如 ADRL always generate two real instructions even if it's possible use just one instruction to calculate the same result. The ADR instruction only works with addresses that are within one megabyte of the instruction. For symbols that are farther away two instructions are necessary to calculate the address, ADRP 和 ADD)的结果。在某些时候,汇编器或链接器确定 sub_100092800
的地址在 1M 以内,并将 ADRP 和 ADD 指令替换为 ADR 和 NOP 指令。
loc_10007390C
SUB X8, X29, #-stuff
LDUR X10, [X8,#-0x100] ;
LDR X0, [X10,#0x10] ;
SUB X8, X29, #-var_1E8
LDUR X2, [X8,#-0x100]
STP X0, XZR, [X2]
SUB X8, X29, #-var_1F0
LDUR X3, [X8,#-0x100]
NOP
LDR X8, =__NSConcreteStackBlock
STR X8, [X3]
STR D8, [X3,#8]
ADD X8, X3, #0x10
ADR X9, sub_100092800
NOP
PACIA X9, X8
ADR X8, unk_1001A2658
NOP
STP X9, X8, [X3,#0x10]
LDUR X8, [X29,#var_B8]
STR X8, [X3,#0x20]
LDUR X8, [X29,#var_C0]
STP X8, X10, [X3,#0x28]
LDUR W8, [X29,#anotherStuff]
STR W8, [X3,#0x38]
SUB X8, X29, #-var_290
LDUR W8, [X8,#-0x100]
STR W8, [X3,#0x3C]
MOV W1, #0
MOV W4, #1
BL do_the_dance
TST W0, #0xFF00
B.EQ loc_1000E8730
我对 ADR X9,sub_100092800 在做什么感到有点困惑。看起来它正在将地址加载到X9中,但是加载后它是否也调用了子程序?
从列表中看,没有来电。它将 PC 相对偏移量加载到寄存器中,然后不对其执行任何操作。但是请看几个地方的 ADR
/NOP
序列。看起来好像 NOP 是要用调用命令修补的 (BL
)。
这里有几种可能性。可能是反汇编程序误读了命令。不太可能,但检查机器代码编码,以防万一。可能有一个重定位指令会在模块加载期间修补这些位置。最后,程序本身可能有一段明确的自我修补逻辑,专门用于阻止像你这样的逆向工程师。自我修补肯定会在模块的其他地方,让你闻风丧胆。
编辑:代码中有一些有趣的地方。我不知道什么是__NSConcreteStackBlock
,但它强烈建议Apple/Cocoa。同时,the PACIA
command is specific to the ARM8.3 instruction set, and has to do with the pointer authentication logic for jump integrity protection. To the best of my knowledge, this is the stuff of the upcoming ptrauth/ARM64E initiative by Apple,最新的 Xcode 和最新的 iDevices 支持,但尚未被 App Store 接受(截至撰写本文时,2020 年 5 月 18 日) .指针身份验证可能很脆弱,Apple 的官方线路是 "try it in dev for now"。我的观点是,它可能是某种函数调用点后处理,它是 ptrauth 感知代码生成管道的一部分。我对 ptrauth 的了解还不够多。 :(
编辑:还有另一种可能性。程序集是否偶然来自反汇编目标文件,而不是链接的可执行文件?然后 NOP 可以作为跨模块调用的占位符。这也可以解释不一致的标签命名。
指令ADR X9, sub_100092800
加载符号sub_100092800
的地址到X9寄存器。它本身不会调用或以其他方式分支到位于那里的代码。
作为安全措施,加载到X9寄存器的地址随后被PACIA指令修改,然后通过以下STP指令存储在内存中。您的代码中没有指示存储在内存中的修改后的值会发生什么,但它很可能在某个时候从内存中加载,恢复到使用 PACIA 指令之前的值,然后被调用。
NOP 指令是一个转移注意力的问题。这是某些伪指令(如 ADRL always generate two real instructions even if it's possible use just one instruction to calculate the same result. The ADR instruction only works with addresses that are within one megabyte of the instruction. For symbols that are farther away two instructions are necessary to calculate the address, ADRP 和 ADD)的结果。在某些时候,汇编器或链接器确定 sub_100092800
的地址在 1M 以内,并将 ADRP 和 ADD 指令替换为 ADR 和 NOP 指令。