iOS应用安全7 -- LLDB动态调试
2020/4/28 23:02:55
本文主要是介绍iOS应用安全7 -- LLDB动态调试,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
前言
LLDB全称是Low Level Debugger,并不是low的调试器,而是轻量级的高性能调试器,xcode默认内置了它,因此我们不需要再自己安装。笔者最近也是系统的学习了LLDB的用法,在此之前就用过p和po
,哈哈😄。本篇文章主要为了将最近学习的LLDB记录并总结,加深记忆并方便以后查找。
另外,本篇文章主要有两部分,一个是LLDB的基础用法,另一个就是对基础LLDB使用插件进行扩展。
基础LLDB用法
p、po、print、expression
首先就来介绍一下这几个常用命令之间的关系吧。
先看看expression
指令。
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
指令查看。
po
也并不是print object(原本也就没这个写法)
的缩写,而是expression -O --
的缩写,同样可以使用help
指令查看。
help expression
看看expression -O --
是什么意思,如下,可以看到-O
代表的是对象的description(描述)
,即打印出变量的描述。
breakpoint
断点调试在日常开发中都经常用到,并且在xcode中我们也能够很轻易的设置、禁用、删除断点。下面就来看看如何使用LLDB达到并且超越界面化断点。
设置断点
常用设置断点的参数及代表的意义。
缩写 | 全称 | 意义 |
---|---|---|
-f | --file | 文件名称 |
-l | --line | 行数 |
-n | --name | 方法名 |
-S | --selector | SEL |
-r | --func-regex | 方法正则 |
- 在ViewController.m文件的第28行设置断点。
// 举例 breakpoint set -f ViewController.m -l 28 复制代码
- 给方法名是
click1:
的方法设置断点。
breakpoint set -n click1: 复制代码
- 给SEL是
click2:
的方法设置断点。
breakpoint set -S click2: 复制代码
- 给包含
click
的地方设置断点。
breakpoint set -r click 复制代码
效果如下:
可以看到一次性设置了103个地方,显然想要的不是这样。条件拼接,和第一个例子那样。- 给
ViewController.m
文件中包含click
的地方设置断点。
breakpoint set -f ViewController.m -r click 复制代码
breakpoint set
虽然在拼写时lldb会提示,但感觉还是太长了,怎么办?
直接使用b
即可。
查看当前全部断点
// 缩写:br list breakpoint list 复制代码
这里需要注意以下,由于这三个断点是使用一条语句设置的,因此它们三个会被分到同一个断点组里面。
设置断点无效
这一步就相当于界面操作中,让断点颜色变半透明。
代码设置如下:// 设置断点14.1无效 br disable 14.1 // 同样,将无效断点设置为有效 br enable 14.1 复制代码
删除断点
br delete 14.3 复制代码可以看到,14.3并没有被删除,而只是被设置为了无效。原因就是14.3属于14这个组,不能只删除一个,要删必须将全部都删掉。
是不是感觉很666?
其实这些东西基本上用不到,哈哈哈。
正向开发中可以使用xcode提供的界面操作设置和删除断点。
而在逆向中,根本就获取不到这些符号(类名,文件名,方法名等)。
不信?看看下图:
内存断点
上面说了,在逆向中,由于无法获取到符号,是无法直接通过符号设置断点的,而我们还需要使用断点怎么办?下内存断点。
这里在24行的断点处,获取了_name
指针的地址,然后通过
watchpoint set expression 0x000000014b80b880 复制代码
给_name
变量设置了一个内存断点,接下来c--->continue
过掉断点,点击按钮1,在_name = @"abc";
语句调用时,因_name
指向的空间变化了,就会打印出old value
和new value
。
variable
,效果是一样的,入下:
这里是有点取巧了,变量的内存地址也是直接通过符号获取的,并且这里也只是演示了给变量打内存断点,那么如何给方法打内存断点呢?
假设我现在要给click2:
方法打个断点,那么就需要这样计算:
- 先找到ASLR的值。
- 使用MachOView或者hooper打开App的MachO文件。
- 使用ASLR+方法在MachO文件中的地址 = 方法在内存中的地址。
- 测试以下是不是真的断住了click2:方法。点击按钮2,发现程序停到了这个方法。断点设置成功。
LLDB的其他常用命令
image list
上面我们查看MachO
文件的ASLR
时使用了这个命令。这里的image不是图片的意思,而是镜像。
可以理解为每一个MachO
都是一个image
,主程序是一个image
,主程序链接的每一个动态库也各自是一个image
。
image list
就是打印出App
中全部的image
信息,每个image
信息的那个地址就是这个image
在内存中的首地址,也即这个image
的ASLR
。
bt
bt命令是用来查看函数调用栈的,如下,我在click1:
中调了click2:
,click2:
中又调用了click3:
,再在click3:
中设置一个断点,点击按钮1
,输入bt
命令,如下:
frame select [调用栈的编号] 复制代码
查看该调用栈的详细信息,包括调用者的内存地址,调用的方法,参数的内存地址等。
在此基础上,还能够使用up
和down
命令查看临近的调用栈信息。
c,n,s
这个就简单了,如下图:
LLDB插件扩展
上面记录的都是xcode自带的lldb所具有的功能,接下来要说的是使用插件对lldb进行扩展,使得lldb更简单,更强大。
chisel
对于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的扩展。
pviews
递归获取全部的视图类对象,并且按照视图的层级结构打印出来。
pvc
打印当前全部的控制器对象及层级关系。这里代码进行来一点修改,点击屏幕空白时跳转到NextViewController
。
ViewController
被NextViewController
盖住了,可以看到控制器对象的state
,ViewController 的 state 是 disappeared
。
caflush
用来刷新UI,在动态调试时,我们可能会修改UI控件的布局,此时直接使用caflush
即可刷新视图。
fv 和 fvc
f-->find
,这两个命令是用来查找view
和ViewController
的。
taplog
这个就比较厉害了,直接输入taplog,然后你会发现程序正常运行了,此时点击任意一个按钮,那么就会打印出点击的这个按钮的信息。
这个对于逆向调试是非常有帮助的,直接定位到点击的那个控件的内存地址。有了内存地址,什么都好办了。presponder
打印出responder响应链。
pclass
打印对象所属的类的继承关系。
pactions
通过按钮的内存地址,直接找到按钮响应的actions。
methods
打印对象所属类的全部方法以及属性。类似于class-dump
的功能。
flicker
让内存地址对应的控件在手机上闪烁一下。
vs
让内存地址对应的控件变成半透明的红色,并且进入一个编辑模式,使用
- w:定位到当前视图的父视图。
- s:定位到当前视图的第一个子视图。
- a:定位到当前视图的兄弟视图的前一个。
- d:定位到当前视图的兄弟视图的后一个。
- p:打印定位到的视图的信息。
- q:退出这个编辑模式。
还有其他的一些功能,使用help
命令可以进行查看。
总结
这篇文章主要记录了
- xcode自带的LLDB的使用方法。
- 逆向时如何设置断点。
- 使用插件chisel对LLDB进行功能扩展(更利于逆向)。
本文地址
这篇关于iOS应用安全7 -- LLDB动态调试的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2022-10-05Swift语法学习--基于协议进行网络请求
- 2022-08-17Apple开发_Swift语言地标注释
- 2022-07-24Swift 初见
- 2022-05-22SwiftUI App 支持多语种 All In One
- 2022-05-10SwiftUI 组件参数简写 All In One
- 2022-04-14SwiftUI 学习笔记
- 2022-02-23Swift 文件夹和文件操作
- 2022-02-17Swift中使用KVO
- 2022-02-08Swift 汇编 String array
- 2022-01-30SwiftUI3.0页面反向传值