反汇编objc分析__block

"You can specify that an imported variable be mutable—that is, read-write— by applying the __block storage type modifier."文档已经清楚说明了它的作用。反汇编就是要看个究竟。

__block类型有着它自己的storage,是blocks编程的一部分,今天先来看一下它如何做storage的。

我们定义如下:

NSString* c = [@"ab" stringByAppendingString:@"c"];
    __block NSInteger bi = 0;
    __block NSString* bc = c;

得到反汇编代码:

0x10699054a <+90>:  movq   0x14bf7(%rip), %rsi       ; "stringByAppendingString:"
    0x106990551 <+97>:  leaq   0x13da8(%rip), %rdi       ; @"ab"
    0x106990558 <+104>: leaq   0x13dc1(%rip), %rdx       ; @"‘c‘"
    0x10699055f <+111>: movq   -0xf0(%rbp), %rcx
    0x106990566 <+118>: movq   %rax, -0xf8(%rbp)
    0x10699056d <+125>: callq  *%rcx
    0x10699056f <+127>: movq   %rax, -0x28(%rbp)
->  0x106990573 <+131>: movq   $0x0, -0x48(%rbp)
    0x10699057b <+139>: leaq   -0x48(%rbp), %rax
    0x10699057f <+143>: movq   %rax, -0x40(%rbp)
    0x106990583 <+147>: movl   $0x20000000, -0x38(%rbp)
    0x10699058a <+154>: movl   $0x20, -0x34(%rbp)
    0x106990591 <+161>: movq   $0x0, -0x30(%rbp)
    0x106990599 <+169>: movq   $0x0, -0x78(%rbp)
    0x1069905a1 <+177>: leaq   -0x78(%rbp), %rax
    0x1069905a5 <+181>: movq   %rax, -0x70(%rbp)
    0x1069905a9 <+185>: movl   $0x52000000, -0x68(%rbp)
    0x1069905b0 <+192>: movl   $0x30, -0x64(%rbp)
    0x1069905b7 <+199>: leaq   -0x21e(%rip), %rax        ; __Block_byref_object_copy_ at ViewController.mm:74
    0x1069905be <+206>: movq   %rax, -0x60(%rbp)
    0x1069905c2 <+210>: leaq   -0x1e9(%rip), %rax        ; __Block_byref_object_dispose_ at ViewController.mm:74
    0x1069905c9 <+217>: movq   %rax, -0x58(%rbp)
    0x1069905cd <+221>: movq   -0x28(%rbp), %rax
    0x1069905d1 <+225>: movq   %rax, -0x50(%rbp)

很容易就看到两处构造对像的地方,没有错就是__block NSInteger bi和__block NSString* bc。这样就可以写出反c++伪代码:

__Block_byref_object_copy_的汇编简单不贴了,_Block_object_assign就是根据最后一个标志参数选择执行_Block_retain,_Block_assign。此方法是被Block定义(就是NSBlock的一种),在构造私有调用栈时调用的。另一个__Block_byref_object_dispose_就是__block在析构里调用的。__block storage的地址被压入NSBlock的私有调用栈,地址不能改变,但是__block storage不在私有栈中,所以被它包装起来的真正的变量可以被修改。例如NSString*, int在NSBlock的私有调用栈中分别是NSString* const, int count, 而__block NSString*, __block int则是__block<NSString*>* const, __block<int>* const。

上一篇介绍了《逆向分析objc,所有类的信息都能在动态调试中获取》。

最后,多谢大家观看本篇文章。下一篇将分析block的反汇编,还会看到__block变量是如何被block使用的。
时间: 2024-11-03 07:58:43

反汇编objc分析__block的相关文章

自制反汇编逆向分析工具 迭代第三版本

将一个函数的分支跳转逆向生成cpp文件,使逆向分析过程从分支跳转的分析中解放出来,工具首要的作用是应当解放生产力. 下面是效果图: 然后附上上面效果图对应的反汇编源代码和工具逆向生成的cpp文件. 有了这个逆向出来的文件,接下来的逆向工作有点像在做填空,但已经帮大忙. 不能上传附件,贴代码. 某比较大的函数的反汇编代码 QuartzCore`CA::Context::commit_transaction: -> <+0>: pushq %rbp <+1>: movq %rsp

自制反汇编逆向分析工具 迭代第五版本 (一)

这个版本添加了几个功能,分开几篇来写. 本篇是关于这样一个功能,显示选定的条件指令与其它条件分支的关系. 它们的关系分别在初版分支形态分布图,和第二版的汇编代码对应图同样展示. 红色表示被选中的目标 蓝色表示被选定的指令的执行位置之前,可能因为条件跳转而直接跳入到被选中的条件分支内(,忽略该条件判断). 绿色表示在被选中的条件分支内,因为其它条件跳转而直接离开目前分支的代码. 紫色表示在被选中的条件分支内,无条件跳转分支并且直接离开目前分支的代码. 浅紫色表示在被选中的条件分支内,无条件跳转分支

自制反汇编逆向分析工具 迭代第四版本

上一个版本,本工具支持的第一个逆向策略,(对反汇编的函数体内的分支控制结构逆向生成cpp代码,)一直都可以正常工作,直到遇上了一个函数.这个使我的逆向策略算法失效的函数,主要的特点是它含有众多无条件跳转指令(,都是在函数体内的跳转). 为什么无条件跳转指令会使得我的第一个逆向算法失效,因为这些无条件跳转指令让函数的执行流变得不易于线性理解. 在一个没有反汇编出来的函数汇编代码中,如果无条件跳转指令很少,特殊地连一条无条件跳转指令也没有时,将汇编代码的执行流当作行文阅读,总可以找到一个特例让所有条

自制反汇编逆向分析工具 迭代第六版本 (五)

本工具从最初版的跳转分布图只为了更直观地分析反汇编代码的分支结构,第三版开始对直观图进行逆向分支代码的输出,第四版对分支输出策略的一些探索,第五版结合之前的探索进行改进.第六版在现在功能的基础上进行增强,利用第六版(一)的基本功能-直译,第六版(二)对条件分支增加条件判断翻译,以及改进在函数调用处附带备选参数参考. 第六版(三)将(一)和(二)组合在一起进行逆向代码输出. 第六版(四),在(三)的基础上增加对原子操作指令的逆向以及c++函数的逆向. 本篇是(五),对待c风格的函数符号调用的翻译,

自制反汇编逆向分析工具 迭代第六版本 (三)

本工具从最初版的跳转分布图只为了更直观地分析反汇编代码的分支结构,第三版开始对直观图进行逆向分支代码的输出,第四版对分支输出策略的一些探索,第五版结合之前的探索进行改进.第六版在现在功能的基础上进行增强,利用第六版(一)的基本功能-直译,第六版(二)对条件分支增加条件判断翻译,以及改进在函数调用处附带备选参数参考. 现在将第六版的(一)和(二)组合在一起进行逆向代码输出. 下面选了三个例子 void prepare_commit(CA::Transaction*) { // 0 pushq %r

C++反汇编代码分析–函数调用

转载:http://shitouer.cn/2010/06/method-called/ 代码如下:#include “stdlib.h” int sum(int a,int b,int m,int n){ return a+b; } void main(){ int result = sum(1,2,3,4); system(“pause”); } 有四个参数的sum函数,接着在main方法中调用sum函数.在debug环境下,单步调试如下: 11:   void main()12:   {0

自制反汇编逆向分析工具 迭代第六版本 (一)

这个版本主要在逆向代码输出上做功夫.首先就是对反汇编代码指令的直译,寻址访问则适配成结构体成员访问或数组访问的方式,使更加直观,效果图如下: 另一图: 接着就是有关SSE指令的直译: 直译中并没有对检测比较和条件跳转进行翻译,因为它们只有在couple成对才有意义(, 一条指令对标志寄存器进行修改,另一条指令根据标志寄存器进行判断).所以检测比较和条件跳转更加适合在带分支结构的逆向代码中翻译,下一篇将介绍.

反汇编看c++引用

继续反汇编系列,本次使用vc2008在x86体系下分析c++中的引用. 定义一个引用类型和将一个变量转换成引用类型一样吗? 引用比指针安全,真的是这样吗,对引用不理解的话比指针还危险. 为什么要用常量引用传参,只是为了只读? 先来说明一下下面使用到的词汇: 对象:不是OO里的对象,而是泛指在c++语言中某种类型(内嵌,结构体,类)的实例,与变量相同的意思. 存储体: "the standard (draft 3225, section [basic.life]) which clearly st

objc反汇编分析,block函数块为何物?

上一篇向大家介绍了__block变量的反汇编和它的伪代码,本篇函数块block,通常定义成原型(^){},它在反汇编中是什么东西. 我们先定义将要反汇编的例子,为减少篇幅例子采用non-arc环境. NSString* a = @"abc"; NSString* b = [NSString stringWithUTF8String:"abc"]; NSString* c = [@"ab" stringByAppendingString:@&quo