100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > IDA反汇编/反编译静态分析iOS模拟器程序(九)block

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

时间:2019-05-13 03:21:01

相关推荐

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

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

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

Block介绍(一)基础

Block介绍(二)内存管理与其他特性

block介绍(三)揭开神秘面纱(上)

block介绍(四)揭开神秘面纱(下)

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

[cpp]

@implementationViewController

-(void)later

{

[selfpresentViewController:selfanimated:NOcompletion:^{

NSLog(@"woyun");

[selfdidReceiveMemoryWarning];

}];

[UIViewtransitionFromView:self.viewtoView:self.viewduration:1options:UIViewAnimationOptionTransitionCurlUpcompletion:^(BOOLfinished){

NSLog(@"%d",finished);

}];

}

在IDA中出现的名字分别为:

[cpp]

___23__ViewController_later__block_invoke

___23__ViewController_later__block_invoke6

全局型block:

[cpp]

int(^nimei)(int,id)=^(intp1,idp2){

p1++;

[p2release];

return0;

};

显示为:

[cpp]

_nimei_block_invoke

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

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

[cpp]

__text:00001F30;===============SUBROUTINE=======================================

__text:00001F30

__text:00001F30;ViewController-(void)later

__text:00001F30;Attributes:bp-basedframe

__text:00001F30

__text:00001F30;void__cdecl-[ViewControllerlater](structViewController*self,SEL)

__text:00001F30__ViewController_later_procnear;DATAXREF:__objc_const:00005590o

__text:00001F30

__text:00001F30var_30=dwordptr-30h

__text:00001F30var_2C=dwordptr-2Ch

__text:00001F30var_28=dwordptr-28h

__text:00001F30var_24=dwordptr-24h

__text:00001F30var_20=dwordptr-20h

__text:00001F30var_1C=dwordptr-1Ch

__text:00001F30var_18=dwordptr-18h

__text:00001F30var_14=dwordptr-14h

__text:00001F30self=dwordptr8

__text:00001F30

__text:00001F30pushebp

__text:00001F31movebp,esp

__text:00001F33pushebx

__text:00001F34pushedi

__text:00001F35pushesi

__text:00001F36subesp,4Ch

__text:00001F39call$+5

__text:00001F3Epopedi

__text:00001F3Fmoveax,ds:(__NSConcreteStackBlock_ptr-1F3Eh)[edi]

__text:00001F45mov[ebp+var_28],eax

__text:00001F48mov[ebp+var_24],42000000h

__text:00001F4Fmov[ebp+var_20],0

__text:00001F56leaeax,(___23__ViewController_later__block_invoke-1F3Eh)[edi]

__text:00001F5Cmov[ebp+var_1C],eax

__text:00001F5Fleaeax,(___block_descriptor_tmp-1F3Eh)[edi]

__text:00001F65mov[ebp+var_18],eax

__text:00001F68movebx,[ebp+self]

__text:00001F6Bmov[ebp+var_14],ebx

__text:00001F6Emoveax,ds:(selRef_presentViewController_animated_completion_-1F3Eh)[edi]

__text:00001F74leaecx,[ebp+var_28]

__text:00001F77mov[esp+10h],ecx

__text:00001F7Bmov[esp+8],ebx

__text:00001F7Fmov[esp+4],eax

__text:00001F83mov[esp],ebx

__text:00001F86movdwordptr[esp+0Ch],0

__text:00001F8Ecall_objc_msgSend

__text:00001F93moveax,ds:(classRef_UIView-1F3Eh)[edi]

__text:00001F99mov[ebp+var_2C],eax

__text:00001F9Cmovesi,ds:(selRef_view-1F3Eh)[edi]

__text:00001FA2mov[esp+4],esi

__text:00001FA6mov[esp],ebx

__text:00001FA9call_objc_msgSend

__text:00001FAEmov[ebp+var_30],eax

__text:00001FB1mov[esp+4],esi

__text:00001FB5mov[esp],ebx

__text:00001FB8call_objc_msgSend

__text:00001FBDmovecx,ds:(selRef_transitionFromView_toView_duration_options_completion_-1F3Eh)[edi]

__text:00001FC3leaedx,(___block_literal_global-1F3Eh)[edi]

__text:00001FC9mov[esp+1Ch],edx

__text:00001FCDmov[esp+0Ch],eax

__text:00001FD1moveax,[ebp+var_30]

__text:00001FD4mov[esp+8],eax

__text:00001FD8mov[esp+4],ecx

__text:00001FDCmoveax,[ebp+var_2C]

__text:00001FDFmov[esp],eax

__text:00001FE2movdwordptr[esp+14h],3FF00000h

__text:00001FEAmovdwordptr[esp+10h],0

__text:00001FF2movdwordptr[esp+18h],300000h

__text:00001FFAcall_objc_msgSend

__text:00001FFFaddesp,4Ch

__text:00002002popesi

__text:0000popedi

__text:0000popebx

__text:0000popebp

__text:0000retn

__text:0000__ViewController_later_endp

这两个block都是在栈上创建的,用到了_NSConcreteStackBlock来传参,在0x1F3F处开始的好几行代码是无法一下子看懂的,需要了解局部变量的空间里对应的意义。实际上,我还没碰到需要看懂这部分代码的实战情况,因为block函数也会得到传参,与普通的C/C++类似,所以还不如在xcode里加断点做动态分析的好。这里也就不深入了。

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

源码:

[cpp]

int(^nimei)(int,id)=^(intp1,idp2){

p1++;

[p2release];

return0;

};

[cpp]

-(void)setParam1:(CGRect)p1para2:(CGFloat)p2

{

nimei(3,nil);

}

其中调用block处的反汇编为:

[cpp]

__text:000023FAmoveax,ds:(_nimei-23F9h)[esi]

__text:00002400mov[esp],eax

__text:00002403movdwordptr[esp+8],0

__text:0000240Bmovdwordptr[esp+4],3

__text:00002413calldwordptr[eax+0Ch]

可见block是直接call相对地址的,这个相对地址就是block结构体

[cpp]

struct__block_impl{

void*isa;

intFlags;

intReserved;

void*FuncPtr;

};

中的FuncPtr,偏移就是0Ch。

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

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

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

转载请注明出处:/hursing

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。