谈谈 block Part 2

前面看过的 NSConcreteGobalBlock 其实在实际应用里是并不是太多的情况,相对来说,接下来要提到的 NSConcreteStackBlock 则是会经常遇到的情况。

从源码看 NSConcreteStackBlock

还是先从代码来看:


#include <stdio.h>

int main(){
    int a = 1;
    int (^block)(void) = ^{printf("%d\n", a);
    	return a;
    };
    int b = block();
    printf("%d\n", b);
    return 0;
}

翻译成 C++ 代码则是:


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

struct __main_block_impl_0 {
  struct __block_impl impl;
  struct __main_block_desc_0* Desc;
  int a;
  __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, int _a, int flags=0) : a(_a) {
    impl.isa = &_NSConcreteStackBlock;
    impl.Flags = flags;
    impl.FuncPtr = fp;
    Desc = desc;
  }
};

static int __main_block_func_0(struct __main_block_impl_0 *__cself) {int a = __cself->a; // bound by copy

    printf("%d\n", a);
    return a;
}

static struct __main_block_desc_0 {
  size_t reserved;
  size_t Block_size;
} __main_block_desc_0_DATA = {0, sizeof(struct __main_block_impl_0)};

int main(){
    int a = 1;
    int (*block)(void) = (int (*)())&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA, a);
    int b = ((int (*)(__block_impl *))((__block_impl *)block)->FuncPtr)((__block_impl *)block);
    printf("%d\n", b);
    return 0;
}

代码具体和 NSConcreteGobalBlock 相比还是有一些变化,如,由于使用局部变量 a,在 block 中则是对 a 变量进行了拷贝,也就是说,在 block 中修改某一变量并不会影响 block 之外的相同变量。另外一个是关于返回值的定义,对函数的强制类型转化而来,关于这一块的东西,会在逆向分析时在进行对比。对于调用传入的指针 cself,则是在对 main_block_impl_0 结构的转化,注意在定义时,添加了 a 的传入参数,从而获取到参数内容。

从逆向看 NSConcreteStackBlock

x86_64:


__text:0000000100000E60 _main           proc near
__text:0000000100000E60
__text:0000000100000E60 var_4C          = dword ptr -4Ch
__text:0000000100000E60 var_48          = qword ptr -48h
__text:0000000100000E60 var_3C          = dword ptr -3Ch
__text:0000000100000E60 var_38          = qword ptr -38h
__text:0000000100000E60 var_30          = dword ptr -30h
__text:0000000100000E60 var_2C          = dword ptr -2Ch
__text:0000000100000E60 var_28          = qword ptr -28h
__text:0000000100000E60 var_20          = qword ptr -20h
__text:0000000100000E60 var_18          = dword ptr -18h
__text:0000000100000E60 var_10          = qword ptr -10h
__text:0000000100000E60 var_8           = dword ptr -8
__text:0000000100000E60 var_4           = dword ptr -4
__text:0000000100000E60
__text:0000000100000E60                 push    rbp
__text:0000000100000E61                 mov     rbp, rsp
__text:0000000100000E64                 sub     rsp, 50h
__text:0000000100000E68                 lea     rdi, aD         ; "%d\n"
__text:0000000100000E6F                 lea     rax, [rbp+var_38]
__text:0000000100000E73                 lea     rcx, ___block_descriptor_tmp
__text:0000000100000E7A                 lea     rdx, ___main_block_invoke
__text:0000000100000E81                 mov     rsi, cs:__NSConcreteStackBlock_ptr
__text:0000000100000E88                 mov     [rbp+var_4], 0
__text:0000000100000E8F                 mov     [rbp+var_8], 1
__text:0000000100000E96                 mov     [rbp+var_38], rsi
__text:0000000100000E9A                 mov     [rbp+var_30], 40000000h
__text:0000000100000EA1                 mov     [rbp+var_2C], 0
__text:0000000100000EA8                 mov     [rbp+var_28], rdx
__text:0000000100000EAC                 mov     [rbp+var_20], rcx
__text:0000000100000EB0                 mov     r8d, [rbp+var_8]
__text:0000000100000EB4                 mov     [rbp+var_18], r8d
__text:0000000100000EB8                 mov     [rbp+var_10], rax
__text:0000000100000EBC                 mov     rax, [rbp+var_10]
__text:0000000100000EC0                 mov     rcx, rax
__text:0000000100000EC3                 mov     [rbp+var_48], rdi
__text:0000000100000EC7                 mov     rdi, rcx
__text:0000000100000ECA                 call    qword ptr [rax+10h]
__text:0000000100000ECD                 mov     [rbp+var_3C], eax
__text:0000000100000ED0                 mov     esi, [rbp+var_3C]
__text:0000000100000ED3                 mov     rdi, [rbp+var_48] ; char *
__text:0000000100000ED7                 mov     al, 0
__text:0000000100000ED9                 call    _printf
__text:0000000100000EDE                 mov     esi, 0
__text:0000000100000EE3                 mov     [rbp+var_4C], eax
__text:0000000100000EE6                 mov     eax, esi
__text:0000000100000EE8                 add     rsp, 50h
__text:0000000100000EEC                 pop     rbp
__text:0000000100000EED                 retn
__text:0000000100000EED _main           endp

ARM:


__text:00002F0C _main
__text:00002F0C
__text:00002F0C var_34          = -0x34
__text:00002F0C var_30          = -0x30
__text:00002F0C var_2C          = -0x2C
__text:00002F0C var_28          = -0x28
__text:00002F0C var_24          = -0x24
__text:00002F0C var_20          = -0x20
__text:00002F0C var_1C          = -0x1C
__text:00002F0C var_18          = -0x18
__text:00002F0C var_14          = -0x14
__text:00002F0C var_10          = -0x10
__text:00002F0C var_C           = -0xC
__text:00002F0C var_8           = -8
__text:00002F0C
__text:00002F0C                 PUSH            {R4,R7,LR}
__text:00002F0E                 ADD             R7, SP, #4
__text:00002F10                 SUB             SP, SP, #0x30
__text:00002F12                 MOV             R0, #(aD - 0x2F1E) ; "%d\n"
__text:00002F1A                 ADD             R0, PC  ; "%d\n"
__text:00002F1C                 ADD             R1, SP, #0x34+var_28
__text:00002F1E                 MOV             R2, #(___block_descriptor_tmp - 0x2F2A) ; ___block_descriptor_tmp
__text:00002F26                 ADD             R2, PC ; ___block_descriptor_tmp
__text:00002F28                 MOV             R3, #(___main_block_invoke+1 - 0x2F34) ; ___main_block_invoke
__text:00002F30                 ADD             R3, PC ; ___main_block_invoke
__text:00002F32                 MOV             R9, #0
__text:00002F3A                 MOV             R12, #0x40000000
__text:00002F42                 MOV             LR, #(__NSConcreteStackBlock_ptr - 0x2F4E) ; __NSConcreteStackBlock_ptr
__text:00002F4A                 ADD             LR, PC ; __NSConcreteStackBlock_ptr
__text:00002F4C                 LDR.W           LR, [LR] ; __NSConcreteStackBlock
__text:00002F50                 MOVS            R4, #1
__text:00002F56                 STR.W           R9, [SP,#0x34+var_8]
__text:00002F5A                 STR             R4, [SP,#0x34+var_C]
__text:00002F5C                 STR.W           LR, [SP,#0x34+var_28]
__text:00002F60                 STR.W           R12, [SP,#0x34+var_24]
__text:00002F64                 STR.W           R9, [SP,#0x34+var_20]
__text:00002F68                 STR             R3, [SP,#0x34+var_1C]
__text:00002F6A                 STR             R2, [SP,#0x34+var_18]
__text:00002F6C                 LDR             R2, [SP,#0x34+var_C]
__text:00002F6E                 STR             R2, [SP,#0x34+var_14]
__text:00002F70                 STR             R1, [SP,#0x34+var_10]
__text:00002F72                 LDR             R1, [SP,#0x34+var_10]
__text:00002F74                 MOV             R2, R1
__text:00002F76                 LDR             R1, [R1,#0xC]
__text:00002F78                 STR             R0, [SP,#0x34+var_30]
__text:00002F7A                 MOV             R0, R2
__text:00002F7C                 BLX             R1
__text:00002F7E                 STR             R0, [SP,#0x34+var_2C]
__text:00002F80                 LDR             R1, [SP,#0x34+var_2C]
__text:00002F82                 LDR             R0, [SP,#0x34+var_30] ; char *
__text:00002F84                 BLX             _printf
__text:00002F88                 MOVS            R1, #0
__text:00002F8E                 STR             R0, [SP,#0x34+var_34]
__text:00002F90                 MOV             R0, R1
__text:00002F92                 ADD             SP, SP, #0x30
__text:00002F94                 POP             {R4,R7,PC}
__text:00002F94 ; End of function _main
Built with Hugo
主题 StackJimmy 设计