Open DianQK opened 4 years ago
_th_dynamic_page:
_th_entry: 原文中这样的写法 为什么_th_dynamic_page对应的是: .rept 2032 mov x13, lr bl _th_entry; .endr
@zhangsuya _th_dynamic_page:
_th_entry: 原文中这样的写法 为什么_th_dynamic_page对应的是: .rept 2032 mov x13, lr bl _th_entry; .endr
文章中 _th_dynamic_page:
放到底下是为了说明 .rept
部分是生成的动态页。但似乎会提高理解难度,是我写错了。晚些时候更正,感谢提醒。
PS. 写到底下也是可以正常运行的,似乎是 vm_remap
做了页对齐修正,结果会正常映射到设计的第二页起始地址。
@zhangsuya _th_dynamic_page:
_th_entry: 原文中这样的写法 为什么_th_dynamic_page对应的是: .rept 2032 mov x13, lr bl _th_entry; .endr
图片、代码已更新,另外增加了标签的介绍。 PS. 网站应用了 PWA,点击右下角的刷新可能才能看到,对此我很后悔看着新鲜的技术就无脑用了。否则一个简单的浏览器刷新就可以看到更新了。
给汇编代码加个注释😊
#if defined(__arm64__)
.text
.align 14
.globl _th_dynamic_page
//dataPage
interceptor:
.quad 0
.align 14
// codePage
_th_dynamic_page:
_th_entry:
nop
nop
nop
nop
nop
sub x12, lr, #0x8
sub x12, x12, #0x4000
mov lr, x13 // 恢复 lr 恢复后的 lr 是返回的地址
ldr x10, [x12] // x10 保存的是原 imp
// q 寄存器入栈
stp q0, q1, [sp, #-32]!
stp q2, q3, [sp, #-32]!
stp q4, q5, [sp, #-32]!
stp q6, q7, [sp, #-32]!
// lr 和 x 寄存器入栈
stp lr, x10, [sp, #-16]!
stp x0, x1, [sp, #-16]!
stp x2, x3, [sp, #-16]!
stp x4, x5, [sp, #-16]!
stp x6, x7, [sp, #-16]!
str x8, [sp, #-16]!
ldr x8, interceptor // interceptor 是自定义 IMP 这里是 static void MTMainThreadChecker(id obj, SEL selector)
blr x8 // 跳转到自定义 IMP 执行 也就是 MTMainThreadChecker
// 恢复lr和x寄存器
ldr x8, [sp], #16
ldp x6, x7, [sp], #16
ldp x4, x5, [sp], #16
ldp x2, x3, [sp], #16
ldp x0, x1, [sp], #16
ldp lr, x10, [sp], #16
// 恢复 q 寄存器
ldp q6, q7, [sp], #32
ldp q4, q5, [sp], #32
ldp q2, q3, [sp], #32
ldp q0, q1, [sp], #32
br x10 // x10 保存的是原 imp 执行原 imp
.rept 2032 // 对应 codePage 的 jumpInstructions[slot] 一个 codePage 可以支持 2032 个 IMP 替换
mov x13, lr // 这是替换的新 IMP 地址,此时 lr 也是返回的地址,需要保存下来 lr 存入寄存器 x13 方便 _th_entry 使用
bl _th_entry;
.endr
#endif
文中这段:[sp], #16 ;从 sp 地址取值,取值完后在把 sp 向高地址偏移 -16 字节,即释放一些栈空间 是不是写错了?出栈不应该是对sp做加法操作么?
此外关于.align指令的那段也有没看明白的地方,我理解的align指令是将下一个指令的地址对齐到2^m整数倍的地方,align 2048就是把下一个指令对齐到后三位是800的地址上,可是反过来知道下一个指令的地址,就一定能计算出align指令前的那条指令的地址吗?读到文章中这一段的时候感到十分困惑,希望作者能解释一下
文中这段:[sp], #16 ;从 sp 地址取值,取值完后在把 sp 向高地址偏移 -16 字节,即释放一些栈空间 是不是写错了?出栈不应该是对sp做加法操作么?
😭写顺手了,应该是 +16 字节。
此外关于.align指令的那段也有没看明白的地方,我理解的align指令是将下一个指令的地址对齐到2^m整数倍的地方,align 2048就是把下一个指令对齐到后三位是800的地址上,可是反过来知道下一个指令的地址,就一定能计算出align指令前的那条指令的地址吗?读到文章中这一段的时候感到十分困惑,希望作者能解释一下
取 .align
伪指令前的地址做不到,但有两个 .align 的伪指令搭配就不一样了,参见:
在本文中,会有一个妙用点,我们在
func_1
也加入 .align 10
: 可以看到 0x8800 - 0x8400 = 0x400
,0x400 刚好是 2^10,这说明我只要知道 func_2
的 ret
指令内存地址,就可以得到 func_1
的 ret
指令地址。
此外关于.align指令的那段也有没看明白的地方,我理解的align指令是将下一个指令的地址对齐到2^m整数倍的地方,align 2048就是把下一个指令对齐到后三位是800的地址上,可是反过来知道下一个指令的地址,就一定能计算出align指令前的那条指令的地址吗?读到文章中这一段的时候感到十分困惑,希望作者能解释一下
取
.align
伪指令前的地址做不到,但有两个 .align 的伪指令搭配就不一样了,参见:在本文中,会有一个妙用点,我们在
func_1
也加入.align 10
: 可以看到0x8800 - 0x8400 = 0x400
,0x400 刚好是 2^10,这说明我只要知道func_2
的ret
指令内存地址,就可以得到func_1
的ret
指令地址。
嗯 这个我是可以理解的,我的意思是,这个图片里的代码让我感到困惑,源码中是先使用一个align指令将下一条指令的地址对齐到2^14整数倍的地址上,也就是64位系统虚拟内存一个page的起始位置,然后再用一个align指令再将下一条指令对齐到下一个page的起始位置。但是你这个图里align 2048我不知道该如何理解,只看图的话,应该指的是将下一条指令对齐到2^11整数倍的地址上。。。
嗯 这个我是可以理解的,我的意思是,这个图片里的代码让我感到困惑,源码中是先使用一个align指令将下一条指令的地址对齐到2^14整数倍的地址上,也就是64位系统虚拟内存一个page的起始位置,然后再用一个align指令再将下一条指令对齐到下一个page的起始位置。但是你这个图里align 2048我不知道该如何理解,只看图的话,应该指的是将下一条指令对齐到2^11整数倍的地址上。。。
图片上似乎漏了点内容:
0000000100008044 align 1024
; ================ B E G I N N I N G O F P R O C E D U R E ================
func_1:
0000000100008400 ret
; endp
0000000100008404 align 2048
; ================ B E G I N N I N G O F P R O C E D U R E ================
func_2:
0000000100008800 ret
; endp
代码对应:
.align 10
_func_1:
ret
.align 10
func_2:
ret
图片的内容是 Hopper Disassembler 生成的,所以这个 align 2048
的含义目前我也不太清楚。
嗯 这个我是可以理解的,我的意思是,这个图片里的代码让我感到困惑,源码中是先使用一个align指令将下一条指令的地址对齐到2^14整数倍的地址上,也就是64位系统虚拟内存一个page的起始位置,然后再用一个align指令再将下一条指令对齐到下一个page的起始位置。但是你这个图里align 2048我不知道该如何理解,只看图的话,应该指的是将下一条指令对齐到2^11整数倍的地址上。。。
图片上似乎漏了点内容:
0000000100008044 align 1024 ; ================ B E G I N N I N G O F P R O C E D U R E ================ func_1: 0000000100008400 ret ; endp 0000000100008404 align 2048 ; ================ B E G I N N I N G O F P R O C E D U R E ================ func_2: 0000000100008800 ret ; endp
代码对应:
.align 10 _func_1: ret .align 10 func_2: ret
图片的内容是 Hopper Disassembler 生成的,所以这个
align 2048
的含义目前我也不太清楚。
这样就能理解了,align 2048在这里应该和align 1024是效果一样的,都是对齐到下一个2^10整数倍的地址上
https://blog.dianqk.org/2020/05/11/trampolinehook-study-notes/