发新帖

dispatch_async(queue, block)中block代码块的定位

[复制链接]
4407 2
        首先声明,这边文章原是在 bbs.iosre.com上写的一篇文章,问了学习Android逆向,也是蛮拼的,将这篇文章转载到这里,属于原作者转载,应该没啥版权纠纷的。文章链接地址为:(http://bbs.iosre.com/t/dispatch-async-queue-block-block/1234  该论坛id为:hail)。废话不多说,原文如下:
        这几天一直在逆向某个APP,发现该APP很多监控数据都是通过某单例调用dispatch_async(queue, block)在block中同步到服务器上去的。以往某个带有block参数的函数在IDA或者hooper中都会相应地给出__function_invokeblock 这样的汇编代码块。但是在很多次跟dispatch_async这样的方法时,没有(及时)发现相对应的block代码块,搞的自己很郁闷,不知道应该怎么来下断点继续跟踪,于是决定今天研究一下这块的block对应的代码块怎么在内存中获取。
首先看了一下block的声明方式,参考文章Block的实现。文章中说道Block可以理解为一个结构体,结构体的简单表示为:

struct __main_block_impl_0 {  
  struct __block_impl impl;
  struct __main_block_desc_0* Desc;
};

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

static struct __main_block_desc_0 {  
  size_t reserved;
  size_t Block_size;
};
其中我最关注的是 void *FuncPtr; 这个函数指针,因为他可以告诉我当dispatch_async(queue, block)执行之后,下一步的断点应该下在哪一行。看一下调用它的汇编代码吧


dispatch_async(queue, block) 中共有两个参数,第一个queue是r0, 第二个参数是r1,结果r1直接被赋值了一个sp的地址。断点停留在0x2e66c上的时候,查看了一下r1寄存器的情况,如图所示:

表明了r1是一个 NSStackBlock类型的对象(不知道这样描述是否正确),然后读取了一下0xa2fbfc这块的内存数据,如图:


根据上面说的block的结构,第一个数据应该为 block的 isa指针,po一下,如图:

然后依次推导,0xe469d就是block代码块的函数指针。于是从该位置下断点,发现确实程序从该处停下来了。
再次验证,0xe469d - 0xb6000(ASLR) = 0x2e69d

正好也是函数开始的地方。这样整个dispatch_async(queue, block)中block的调用过程算是弄明白了,如何从dispatch_async切入,定位到第二个参数block的实现,也有章可循了。

有什么不对的地方大家多多指出来,一起讨论讨论。





本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

举报 使用道具

回复

精彩评论2

听鬼哥说故事    发表于 2015-10-12 11:11:12 | 显示全部楼层
转正啦~~

举报 使用道具

回复
levis    发表于 2015-10-12 11:15:10 | 显示全部楼层
非常感谢管理员,谢谢!

举报 使用道具

回复 支持 反对
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表