IDA反汇编/反编译静态分析iOS模拟器程序(九)block

在第三节 函数表示与搜索函数 提到block函数和普通的OC函数不同。

反汇编分析前需要理解block的实现原理,故推荐先看看这几篇文章及其所引用的参考资料:

Block介绍(一)基础
Block介绍(二)内存管理与其他特性
block介绍(三)揭开神秘面纱(上)
block介绍(四)揭开神秘面纱(下)


block函数的命名与上文提到类似。函数内部定义的block会以scope命名,如:

@implementation ViewController

- (void)later
{
    [self presentViewController:self animated:NO completion:^{
        NSLog(@"wo yun");
        [self didReceiveMemoryWarning];
    }];
    
    [UIView transitionFromView:self.view toView:self.view duration:1 options:UIViewAnimationOptionTransitionCurlUp completion:^(BOOL finished) {
        NSLog(@"%d", finished);
    }];
}
在IDA中出现的名字分别为:

___23__ViewController_later__block_invoke
___23__ViewController_later__block_invoke6
全局型block:

int (^nimei)(int, id) = ^(int p1, id p2) {
    p1++;
    [p2 release];
    return 0;
};
显示为:

_nimei_block_invoke


由于block的实质是用一些结构体来保存调用信息,而结构体信息在release版的C++编译结果中是无明文的,所以在反汇编中block的传参看起来就是直接传到一块内存区域中,需要自己理解其排放顺序是参照那些结构体的。

以下是上面的源码- [ViewController later]函数的反汇编(Mac IDA):

__text:00001F30 ; =============== S U B R O U T I N E =======================================
__text:00001F30
__text:00001F30 ; ViewController - (void)later
__text:00001F30 ; Attributes: bp-based frame
__text:00001F30
__text:00001F30 ; void __cdecl -[ViewController later](struct ViewController *self, SEL)
__text:00001F30 __ViewController_later_ proc near       ; DATA XREF: __objc_const:00005590o
__text:00001F30
__text:00001F30 var_30          = dword ptr -30h
__text:00001F30 var_2C          = dword ptr -2Ch
__text:00001F30 var_28          = dword ptr -28h
__text:00001F30 var_24          = dword ptr -24h
__text:00001F30 var_20          = dword ptr -20h
__text:00001F30 var_1C          = dword ptr -1Ch
__text:00001F30 var_18          = dword ptr -18h
__text:00001F30 var_14          = dword ptr -14h
__text:00001F30 self            = dword ptr  8
__text:00001F30
__text:00001F30                 push    ebp
__text:00001F31                 mov     ebp, esp
__text:00001F33                 push    ebx
__text:00001F34                 push    edi
__text:00001F35                 push    esi
__text:00001F36                 sub     esp, 4Ch
__text:00001F39                 call    $+5
__text:00001F3E                 pop     edi
__text:00001F3F                 mov     eax, ds:(__NSConcreteStackBlock_ptr - 1F3Eh)[edi]
__text:00001F45                 mov     [ebp+var_28], eax
__text:00001F48                 mov     [ebp+var_24], 42000000h
__text:00001F4F                 mov     [ebp+var_20], 0
__text:00001F56                 lea     eax, (___23__ViewController_later__block_invoke - 1F3Eh)[edi]
__text:00001F5C                 mov     [ebp+var_1C], eax
__text:00001F5F                 lea     eax, (___block_descriptor_tmp - 1F3Eh)[edi]
__text:00001F65                 mov     [ebp+var_18], eax
__text:00001F68                 mov     ebx, [ebp+self]
__text:00001F6B                 mov     [ebp+var_14], ebx
__text:00001F6E                 mov     eax, ds:(selRef_presentViewController_animated_completion_ - 1F3Eh)[edi]
__text:00001F74                 lea     ecx, [ebp+var_28]
__text:00001F77                 mov     [esp+10h], ecx
__text:00001F7B                 mov     [esp+8], ebx
__text:00001F7F                 mov     [esp+4], eax
__text:00001F83                 mov     [esp], ebx
__text:00001F86                 mov     dword ptr [esp+0Ch], 0
__text:00001F8E                 call    _objc_msgSend
__text:00001F93                 mov     eax, ds:(classRef_UIView - 1F3Eh)[edi]
__text:00001F99                 mov     [ebp+var_2C], eax
__text:00001F9C                 mov     esi, ds:(selRef_view - 1F3Eh)[edi]
__text:00001FA2                 mov     [esp+4], esi
__text:00001FA6                 mov     [esp], ebx
__text:00001FA9                 call    _objc_msgSend
__text:00001FAE                 mov     [ebp+var_30], eax
__text:00001FB1                 mov     [esp+4], esi
__text:00001FB5                 mov     [esp], ebx
__text:00001FB8                 call    _objc_msgSend
__text:00001FBD                 mov     ecx, ds:(selRef_transitionFromView_toView_duration_options_completion_ - 1F3Eh)[edi]
__text:00001FC3                 lea     edx, (___block_literal_global - 1F3Eh)[edi]
__text:00001FC9                 mov     [esp+1Ch], edx
__text:00001FCD                 mov     [esp+0Ch], eax
__text:00001FD1                 mov     eax, [ebp+var_30]
__text:00001FD4                 mov     [esp+8], eax
__text:00001FD8                 mov     [esp+4], ecx
__text:00001FDC                 mov     eax, [ebp+var_2C]
__text:00001FDF                 mov     [esp], eax
__text:00001FE2                 mov     dword ptr [esp+14h], 3FF00000h
__text:00001FEA                 mov     dword ptr [esp+10h], 0
__text:00001FF2                 mov     dword ptr [esp+18h], 300000h
__text:00001FFA                 call    _objc_msgSend
__text:00001FFF                 add     esp, 4Ch
__text:00002002                 pop     esi
__text:00002003                 pop     edi
__text:00002004                 pop     ebx
__text:00002005                 pop     ebp
__text:00002006                 retn
__text:00002006 __ViewController_later_ endp
这两个block都是在栈上创建的,用到了_NSConcreteStackBlock来传参,在0x1F3F处开始的好几行代码是无法一下子看懂的,需要了解局部变量的空间里对应的意义。实际上,我还没碰到需要看懂这部分代码的实战情况,因为block函数也会得到传参,与普通的C/C++类似,所以还不如在xcode里加断点做动态分析的好。这里也就不深入了。


上面的代码是关于block创建和传递,下面的是调用block。

源码:

int (^nimei)(int, id) = ^(int p1, id p2) {
    p1++;
    [p2 release];
    return 0;
};
- (void)setParam1:(CGRect)p1 para2:(CGFloat)p2
{
    nimei(3, nil); 
}
其中调用block处的反汇编为:
__text:000023FA                 mov     eax, ds:(_nimei - 23F9h)[esi]
__text:00002400                 mov     [esp], eax
__text:00002403                 mov     dword ptr [esp+8], 0
__text:0000240B                 mov     dword ptr [esp+4], 3
__text:00002413                 call    dword ptr [eax+0Ch]
可见block是直接call相对地址的,这个相对地址就是block结构体

struct __block_impl {
  void *isa;
  int Flags;
  int Reserved;
  void *FuncPtr;
};

中的FuncPtr,偏移就是0Ch。


对含有block的函数进行反编译是没意义的(至少在windows版IDA是这样),因为既然没有表示block结构体的信息,IDA就不能分析出调用的意义。

因为对block反汇编静态分析的场景不多(欢迎留下评论来举例),这里没再做更完全的阐述。如果想自行研究,可以自己写一些block例子来让IDA分析,就能知道各种block的创建、传递和调用方法是怎样被编译出来的了。

上一篇:IDA反汇编/反编译静态分析iOS模拟器程序(八)IDA for Mac

转载请注明出处:http://blog.csdn.net/hursing

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hursing

来一个五羊香芋甜筒~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值