前篇博客中,使用 杨君的小黑屋 提供的工具恢复二进制文件的符号表,只恢复了函数的符号表,本篇讲述如何恢复block符号表,杨君的博客中使用IDA分析二进制文件,本篇则使用MacOS系统上体验也不错的Hopper来作分析。

使用工具:

  Hopper 4.0.8

block的类型有3种:

  • _NSConcreteGlobalBlock(全局)
  • _NSConcreteStackBlock(栈)
  • _NSConcreteMallocBlock(堆)--> 不会出现在二进制文件中

block编译后在二进制文件中的布局,查看 Block_private.h 文件

struct Block_layout {
  /* 指向所属类型 __NSConcreteGlobalBlock,__NSConcreteStackBlock */
void *isa;
int flags;
int reserved;
  
  /* 函数指针,指向block的实现地址 */
void (*invoke)(void *, ...);
struct Block_descriptor *descriptor;
/* Imported variables. */
};

使用Hopper查看二进制文件(CrashTest)

  • __NSConcreteGlobalBlock 存在于全局静态区 Segment __DATA 的 Section __const , 使用Hopper查看GlobalBlock如图:

__NSConcreteGlobalBlock位置即为 isa指针地址0x10000c2f0,后跟2个int型的值,接着是函数指针地址0x10000c300, 它指向地址 0x1000081b0 即为block的实现函数地址。

  • _NSConcreteStackBlock则与代码指令在一起,如图

恢复Block符号表

根据以上特性,以及Hopper提供的脚本接口,写一段python脚本收集block函数地址与名字的对应关系,再将此关系恢复到二进制文件中。

脚本已上传github

原理:

全局的Block比较容易找到函数入口,isa指针向后偏移固定字节即可找到,栈区Block相对复杂,笔者是通过扩大搜索地址区域到 ±24字节的范围内搜索函数指针 

在Hopper中运行脚本,会得到一个block_sym.json文件,此json文件将用于恢复block的符号。使用符号表恢复工具的的 -j 选项

./restore-symbol -o CrashTest-sym -j block_sym.json CrashTest-arm64

得到恢复符号的二进制文件 CrashTest-sym,于是就可以用atos命令解析block中的崩溃了

atos -arch arm64 -o CrashTest-sym -l 0x1000d0000 0x1000d84ac 0x1000d83a4 0x1000d8108

// 输出
-[PersonInfo haveChilren:]_block_invoke (in CrashTest-sym) +
-[PersonInfo haveChilren:] (in CrashTest-sym) +
-[ViewController printStaff] (in CrashTest-sym) +

附件:

本篇使用的DEMO

参考 & 感谢

  杨君的小黑屋 http://blog.imjun.net/posts/restore-symbol-of-iOS-app/

本文地址:http://www.cnblogs.com/ciml/p/7698271.html

恢复二进制文件中的block符号表的更多相关文章

  1. 如何恢复oracle中已删除的表

    在9i中Oracle引入了flashback的概念,可以将数据返回到某个时间点,但对于诸如drop/truncate等DDL语句却尚不支持.进入Oracle10g,这一缺陷得到了弥补.可以将丢失掉的表 ...

  2. iOS 符号表恢复 & 逆向支付宝

    推荐序 本文介绍了恢复符号表的技巧,并且利用该技巧实现了在 Xcode 中对目标程序下符号断点调试,该技巧可以显著地减少逆向分析时间.在文章的最后,作者以支付宝为例,展示出通过在 UIAlertVie ...

  3. windbg加载符号表

    0x00 前言 在使用windbg调试windows中的程序时会经常碰到一些系统的dll里面的一些函数调用,有些函数是没有具体函数名的,这对于调试非常不利,基于此,微软针对windows也发布了很多系 ...

  4. 恢复oracle中误删除drop掉的表

    查看回收站中表 select object_name,original_name,partition_name,type,ts_name,createtime,droptime from recycl ...

  5. 从MySQL全库备份中恢复某个库和某张表【转】

    从MySQL全库备份中恢复某个库和某张表 一.全库备份-A [root@mha2 backup]#mysqldump -uroot -p123456 --default-character-set=u ...

  6. C++编译连接过程中关于符号表的报错分析

    是这样的,在学习郑莉老师的多文件结构和编译预处理命令章节时候,看到书里有这么一张图描述如下:#include指令作用是将指定的文件嵌入到当前源文件中#include指令所在的位置. 然后我就想5_10 ...

  7. 恢复oracle中误删除drop掉的表 闪回的方法

    恢复oracle中误删除drop掉的表   查看回收站中表 --需要在其所在用户下查询 回收站对象 select object_name,original_name,partition_name,ty ...

  8. 从MySQL全库备份中恢复某个库和某张表

    在Mysqldump官方工具中,如何只恢复某个库呢? 全库备份 [root@HE1 ~]# mysqldump -uroot -p --single-transaction -A --master-d ...

  9. Mysql误删表中数据与误删表的恢复方法

    由于头两天面试时被问了这样一个问题,如果某同事误删了某个表,你该怎么恢复? 当时想了一下,因为博主没有遇到过这个问题,但是也多少了解一些,所以就回答通过mysql的binlog日志进行恢复. 面试官当 ...

随机推荐

  1. 二十二、springboot之监控管理Actuator

    1.新增spring-boot-starter-actuator的依赖 gradle: compile('org.springframework.boot:spring-boot-actuator') ...

  2. Python匿名函数详解

    python 使用 lambda 来创建匿名函数. lambda这个名称来自于LISP,而LISP则是从lambda calculus(一种符号逻辑形式)取这个名称的. 在Python中,lambda ...

  3. JavaScript 中的回调函数

    原文:http://javascriptissexy.com/ 翻译:http://blog.csdn.net/luoweifu/article/details/41466537 [建议阅读原文,以下 ...

  4. [java笔记]父类设计法则

    1.父类通常情况下都设计为抽象类或接口,其中优先考虑接口,如接口不能满足才考虑抽象类. 2.一个具体的类尽可能不去继承另一个具体类,这样的好处是无需检查对象是否为父类的对象.

  5. TObject、TPersisent 、TComponent、TControl、TGraphicControl、TWinControl 关系图

    VCL的类图结构               TObject                 |               TPersisent                 |         ...

  6. C#socket编程序(一)

    在讲socket编程之前,我们先看一下最常用的一些类和方法,相信这些能让你事半功倍. 一.IP地址操作类 1.IPaddress类 a.在该类中有一个 parse()方法,能够把点分十进制IP地址 转 ...

  7. 两类for循环

    九.两类for循环 (一)穷举 1.格式 for (初始条件;循环条件 ;循环改变) { for (初始条件;循环条件;循环改变) { for (初始条件;循环条件;循环改变) { if (判断条件) ...

  8. Kylin使用笔记-0: kylin介绍

    APACHE KYLIN™ 概览 Apache Kylin™是一个开源的分布式分析引擎,提供Hadoop之上的SQL查询接口及多维分析(OLAP)能力以支持超大规模数据,最初由eBay Inc. 开发 ...

  9. 【LOJ】#2069. 「SDOI2016」齿轮

    题解 我一开始还努力想这道题是不是有坑,被SDOI折磨到我觉得不能有那么水的题在-- 就是带权并查集维护一下两点间距离,如果新加一条边两个点在同一集合,看看已有的路径和新加的路径是否相等 乘积可以在模 ...

  10. Django第一步

    对于一个web框架,掌握了三部分的内容,就可以说是迈出了第一步. 1. 准备开发环境 2. 创建一个工程,并运行 3. 开发hello world应用 1. 准备环境 首先应该是安装python和dj ...