LLDB全称是Low Level Debugger,并非low的调试器,而是轻量级的高性能调试器,xcode默认内置了它,所以咱们不须要再本身安装。笔者最近也是系统的学习了LLDB的用法,在此以前就用过p和po
,哈哈😄。本篇文章主要为了将最近学习的LLDB记录并总结,加深记忆并方便之后查找。git
另外,本篇文章主要有两部分,一个是LLDB的基础用法,另外一个就是对基础LLDB使用插件进行扩展。express
首先就来介绍一下这几个经常使用命令之间的关系吧。 先看看expression
指令。 xcode
expression
指令主要有如下做用:
expression a = 100
,一样这里你能够试试expression self.view.backgroundColor = [UIColor redColor]
,也是能修改背景颜色的。$
符号定义和使用lldb变量,如:expression int $b = 99
。多是p太容易让人联想到print
了,不少人都会认为p是print的缩写,po是print object的缩写
,事实上并非这样。
p 和 print
其实都是expression --
的缩写,可使用help
指令查看。 bash
po
也并非print object(本来也就没这个写法)
的缩写,而是expression -O --
的缩写,一样可使用help
指令查看。 服务器
help expression
看看
expression -O --
是什么意思,以下,能够看到
-O
表明的是对象的
description(描述)
,即打印出变量的描述。
断点调试在平常开发中都常常用到,而且在xcode中咱们也可以很轻易的设置、禁用、删除断点。下面就来看看如何使用LLDB达到而且超越界面化断点。微信
经常使用设置断点的参数及表明的意义。app
缩写 | 全称 | 意义 |
---|---|---|
-f | --file | 文件名称 |
-l | --line | 行数 |
-n | --name | 方法名 |
-S | --selector | SEL |
-r | --func-regex | 方法正则 |
// 举例
breakpoint set -f ViewController.m -l 28
复制代码
click1:
的方法设置断点。breakpoint set -n click1:
复制代码
click2:
的方法设置断点。breakpoint set -S click2:
复制代码
click
的地方设置断点。breakpoint set -r click
复制代码
效果以下: curl
ViewController.m
文件中包含click
的地方设置断点。breakpoint set -f ViewController.m -r click
复制代码
breakpoint set
虽然在拼写时lldb会提示,但感受仍是太长了,怎么办?
直接使用b
便可。 函数
// 缩写:br list
breakpoint list
复制代码
这里须要注意如下,因为这三个断点是使用一条语句设置的,所以它们三个会被分到同一个断点组里面。 oop
这一步就至关于界面操做中,让断点颜色变半透明。
// 设置断点14.1无效
br disable 14.1
// 一样,将无效断点设置为有效
br enable 14.1
复制代码
br delete 14.3
复制代码
是否是感受很666?
其实这些东西基本上用不到,哈哈哈。
正向开发中可使用xcode提供的界面操做设置和删除断点。
而在逆向中,根本就获取不到这些符号(类名,文件名,方法名等)。
不信?看看下图:
上面说了,在逆向中,因为没法获取到符号,是没法直接经过符号设置断点的,而咱们还须要使用断点怎么办?下内存断点。
这里在24行的断点处,获取了_name
指针的地址,而后经过
watchpoint set expression 0x000000014b80b880
复制代码
给_name
变量设置了一个内存断点,接下来c--->continue
过掉断点,点击按钮1,在_name = @"abc";
语句调用时,因_name
指向的空间变化了,就会打印出old value
和new value
。
variable
,效果是同样的,入下:
这里是有点取巧了,变量的内存地址也是直接经过符号获取的,而且这里也只是演示了给变量打内存断点,那么如何给方法打内存断点呢?
假设我如今要给click2:
方法打个断点,那么就须要这样计算:
上面咱们查看MachO
文件的ASLR
时使用了这个命令。这里的image不是图片的意思,而是镜像。
能够理解为每个MachO
都是一个image
,主程序是一个image
,主程序连接的每个动态库也各自是一个image
。
image list
就是打印出App
中所有的image
信息,每一个image
信息的那个地址就是这个image
在内存中的首地址,也即这个image
的ASLR
。
bt命令是用来查看函数调用栈的,以下,我在click1:
中调了click2:
,click2:
中又调用了click3:
,再在click3:
中设置一个断点,点击按钮1
,输入bt
命令,以下:
frame select [调用栈的编号]
复制代码
查看该调用栈的详细信息,包括调用者的内存地址,调用的方法,参数的内存地址等。
up
和
down
命令查看临近的调用栈信息。
这个就简单了,以下图:
上面记录的都是xcode自带的lldb所具备的功能,接下来要说的是使用插件对lldb进行扩展,使得lldb更简单,更强大。
对于chisel
的安装,最方便的仍是使用Homebrew
安装了,使用mac电脑,安装一个Homebrew
是很是有用的,不过这个玩意由于是国外的服务器,因此安装更新都特别慢,甚至很是容易出错,一旦出错就要重来。对此,咱们可使用国内的源。
这里提供一种使用国内源进行安装的方法,终端执行下面的语句便可。若是使用的不是zsh,那么能够尝试将zsh改为bash。
/bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)"
复制代码
安装完Homebrew
以后,直接终端下面的命令便可安装chisel。
brew install chisel
复制代码
完成后在/Users/[username]/.lldbinit
文件里面添加一句(没有就建立一个文件)。
command script import /usr/local/Cellar/chisel/2.0.0/libexec/fblldb.py
复制代码
安装完chisel以后,能够来尝试一下chisel对lldb的扩展。
递归获取所有的视图类对象,而且按照视图的层级结构打印出来。
打印当前所有的控制器对象及层级关系。这里代码进行来一点修改,点击屏幕空白时跳转到NextViewController
。
ViewController
被
NextViewController
盖住了,能够看到控制器对象的
state
,
ViewController 的 state 是 disappeared
。
用来刷新UI,在动态调试时,咱们可能会修改UI控件的布局,此时直接使用caflush
便可刷新视图。
f-->find
,这两个命令是用来查找view
和ViewController
的。
这个就比较厉害了,直接输入taplog,而后你会发现程序正常运行了,此时点击任意一个按钮,那么就会打印出点击的这个按钮的信息。
打印出responder响应链。
打印对象所属的类的继承关系。
经过按钮的内存地址,直接找到按钮响应的actions。
打印对象所属类的所有方法以及属性。相似于class-dump
的功能。
让内存地址对应的控件在手机上闪烁一下。
让内存地址对应的控件变成半透明的红色,而且进入一个编辑模式,使用
还有其余的一些功能,使用help
命令能够进行查看。
这篇文章主要记录了