看完第二篇就在动手写hook objc_msg_send的代码,这是学习汇编中记录的一些arm64汇编知识https://github.com/wzpziyi1/Arm64-
有需要的童鞋可以看看。
在学习过程中,发现一个问题(或者说我以为的bug)。
在戴老师的代码中,hook objc_msgSend之前保存个寄存器的状态时,并未保存向量寄存器的状态:
"stp q6, q7, [sp, #-32]!\n" \
"stp q4, q5, [sp, #-32]!\n" \
"stp q2, q3, [sp, #-32]!\n" \
"stp q0, q1, [sp, #-32]!\n" \
"stp x8, x9, [sp, #-16]!\n" \
"stp x6, x7, [sp, #-16]!\n" \
"stp x4, x5, [sp, #-16]!\n" \
"stp x2, x3, [sp, #-16]!\n" \
"stp x0, x1, [sp, #-16]!\n" \
只是保存了通用寄存器x0--x9寄存器的值,在调试代码时,发现这样的c代码:
struct TestOne {
double a;
double b;
double number;
double type;
}TestOne;
void test(struct TestOne x) {
x.a = 10;
x.b = 20;
x.number = 2;
x.type = 11;
}
void call() {
struct TestOne x = {0,0,0,0};
test(x);
}
转成arm64汇编时,结构体的值是保存在向量寄存器d0--d4中的:
_test: ; @test
fmov d4, #11.00000000
fmov d5, #2.00000000
fmov d6, #20.00000000
fmov d7, #10.00000000
str d0, [sp]
str d1, [sp, #8]
str d2, [sp, #16]
str d3, [sp, #24]
str d7, [sp]
str d6, [sp, #8]
str d5, [sp, #16]
str d4, [sp, #24]
add sp, sp, #32 ; =32
ret
_call: ; @call
sub sp, sp, #48 ; =48
stp x29, x30, [sp, #32] ; 8-byte Folded Spill
add x29, sp, #32 ; =32
mov x8, #0
str x8, [sp, #24]
str x8, [sp, #16]
str x8, [sp, #8]
str x8, [sp]
ldr d3, [sp, #24]
ldr d2, [sp, #16]
ldr d1, [sp, #8]
ldr d0, [sp]
bl _test
ldp x29, x30, [sp, #32] ; 8-byte Folded Reload
add sp, sp, #48 ; =48
ret
如果在项目中,有开发童鞋直接这么写:
- (void)doSomething:(struct TestOne)test;
那么hook objc_msgSend时没保存的向量寄存器的状态,会出现问题的吧?
展开