嘿嘿老規矩先上OC原始碼:
- (void)viewDidLoad {
[super viewDidLoad];
void(^block)(void) = ^(){
NSLog(@"111");
};
block();
}
複製程式碼
彙編:
03-彙編-Block`-[ViewController viewDidLoad]:
...
0x1002a6764 <+68>: adrp x8, 2
0x1002a6768 <+72>: add x8, x8, #0x88 ; =0x88
0x1002a676c <+76>: mov x0, x8
0x1002a6770 <+80>: bl 0x1002a6ba4 ; symbol stub for: objc_retainBlock
0x1002a6774 <+84>: str x0, [sp, #0x8]
-> 0x1002a6778 <+88>: ldr x8, [sp, #0x8]
0x1002a677c <+92>: mov x0, x8
0x1002a6780 <+96>: ldr x8, [x8, #0x10]
0x1002a6784 <+100>: blr x8
.....
複製程式碼
首先分析通過adrp指令計算出 block的地址 block的地址 = 2 << 12 + 0x1002a6000 + 0x88 = 0x1002a8088 通過LLDB:檢視該記憶體地址
(lldb) memory read --format x --size 8 0x1002a8088
0x1002a8088: 0x00000001b5791288 0x0000000050000000
0x1002a8098: 0x00000001002a67a8 0x00000001002a8068
0x1002a80a8: 0x00000001b5798610 0x00000000000007c8
0x1002a80b8: 0x00000001002a7685 0x0000000000000003
(lldb) po 0x00000001b5791288
__NSGlobalBlock__
複製程式碼
首先我們可以通過Block的isa指標知道這貨是啥?就是個__NSGlobalBlock__ 然後我們還能從Block+0x10的位置獲取到Block的入口看下圖
使用IDA檢視會更加方便,後面會用到擴充套件: