在iOS开发中,详细大家对Xcode都不陌生,对lldb也不陌生吧,回想大学刚毕业时,第一次出来面试时,面试官问我,在平时的学习和写代码的过程中,是否会使用lldb进行debug,那会还有点懵,貌似没使用过lldb工具吧,殊不知,其实lldb就在我们xcode打断点后,下方弹出的控制台,那个就是lldb,最近一段时间有时间学习,对lldb进行了一次更深层次的了解与学习,lldb是在逆向开发中不可或缺的一样神器。
在正向开发中,我们一般都是通过图形化界面进行断点的置放,在逆向中,通常都是使用lldb来打断点。
通过使用 breakpoint 在lldb环境下,可以对对应的函数名进行断点。
1. breakpoint
breakpoint set -n "objectMothed" (对指定函数设置断点)
breakpoint disable 1.1 (对断点列中1.1断点进行 取消断点操作)
breakpoint enable 1.1 (对断点列中1.1断点进行 重启断点操作)
breakpoint delete 1 (在删除断点时,只能按组删除,如果一组中有多个断点,无法通过1.1方式删除指定断点, 如无指定 目标组数 则删除所有断点)
breakpoint list (可查询当前存在多少组断点,并且显示所有断点详情)
通过上面列举的几个AIP 我们来进行简单的操作,详情,请看下面。
现在来解释一下,上面我标注的三处位置。
1 通过使用 breakpoint set -n "viewDidLoad" 成功为项目中所有viewDidLoad 函数打上断点。并且提示 Breakpoint 1: 343 locations. 这里解释一下:Breakpoint 1 代表一组断点 343 locations 代表 有343处
2 通过使用 breakpoint disable 1.1 成功禁止(关闭)1.1位置的断点。
3 通过使用 breakpoint list 查看所有断点,并且打印出 1: name = 'viewDidLoad', locations = 343, resolved = 342, hit count = 0
此处不难看出 name = 'viewDidLoad' 就是我们刚才用 breakpoint 下断点时的函数名称。locations = 343 (共有343处断点)。但是 resolved = 342 (可生效的断点有 432处)。 此时我们看看图中三指的位置(1.1),在hit count = 0 后面 还跟着 Options: disabled ,其他断点都是没有跟 Options: disabled,这个就是我们上面通过 breakpoint disable 1.1 禁止的断点(也就是未生效断点,可通过 breakpoint enable 1.1 使该断点生效)。
在此顺便提一下 1.1中 address = 0x00000002340c30a8(这是该函数的内存地址,因为xcode在编译时就将该函数加载入内存了)
我们还可以通过 breakpoint help 来获取 breakpoint 相关方法介绍 和 使用。
在下断点时,我们是使用 breakpoint set -n "viewDidLoad"来设置的,我们同样可以使用 help breakpoint set 来查看 set中有多少方法可以使用
一个set 就包含了这么多东西,我靠( ‵o′)凸,还是全英文的,各位有兴趣的就自行了解一下就行了。不过里面的方面是经常会使用到的,后续在使用的时候在跟大家慢慢列举和说明。
breakpoint set -r viewDidLoad 该方法是使用正则表达式,在项目中遍历所有包含有viewDidLoad字段的函数名称,为其打上断点。
Tisp:所有 breakpoint set 都能简写为 b 。例如 breakpoint set -r viewDidLoad 可以简化成 b -r viewDidLoad.
2 bt
使用LLDB能在堆栈中查看信息,在断点后,可以使用bt 来打印堆栈的调用信息。
在查看堆栈时,还能使用 up down 等命令 去到上一个堆栈信息中。
如果 我们要查看当前堆栈中,某个详细堆栈中的信息,我们可以使用 frame select '堆栈编号'
在这个实例中,我定位到当前堆栈的第39行,使用 frame select 39 后,我们能从当中获取到一些信息,在逆向中时候用时,显示的都是汇编语言,在自己项目中时,这里出现的是源码。
Tisp 在我们定位到某个 函数时,可以使用 frame variable 来获取当前函数调用参数信息。
当 我们想给对象的某个属性添加断点时,我们可以使用 watchpoint set expression + 对象属性的内存地址,当该属性发生改变时,就会触发该断点,让我们来详细看看下图。
watchpoint set expression +对象属性的内存地址后,显示已经成功添加一个内存断点。这时我们使用c跳过当前断点后,我们进行对象属性值的改变,这时就会触发已经设置好的内存断点,并且在断点时,还是打印出了 old value 和 new value 并在后面附带出内存地址 ,我们通过常用的lldb命令 PO 打印内存地址中的参数,在此,我们是否想到了跟开发中KVO有点类似??KVO同样有 old value 和 new value
同样的,我们可以为断点添加运行代码,让我们来看看下文。
breakpoint command add + 断点组数 为该断点添加,并提示 Enter your debugger command(s). Type 'DONE' to end.
当你在最后写入DONE时,结束该允许代码添加。
同样的,我们也可以删除我们编写的内存代码,查看断点中内存组数。
使用 breakpoint command list 5 查看 内存断点中相关的代码。
使用 breakpoint command delete 5 删除 内存断点中相关的代码。
3 target stop-hook
在执行断点时,有时,我们需要在触发断点时,顺带打印一些信息,例如函数的参数。这时,我们就可以使用 target stop-hook ,接下来让我们使用help 来了解一下 target stop-hook 有哪些功能呢。
这个 target stop-hook 里面的内容结构跟breakpoint 结构类似, 增删查禁启,细心的小伙伴不难发现,这其中的用法基本都是一样的,在我看来 这里面除了需要仔细研究 add 中是否有其他构造形式,其他几个用法 都比较单一。
这时,我们来试试 target stop-hook add help 看看 add里面有没有更深层次的东西。
当我们在lldb中输入 target stop-hook add help 时 会发现 :Enter your stop hook command(s). Type 'DONE' to end.再次出现内存代码块命令模式。(我在里面一顿操作猛如虎,暂时还不知道如何触发,后期研究到了再回来改写一下。)
从上面得知 target stop-hook add help 不行,那我们就换种写法,help target stop-hook add 此时lldb终于迎来我们熟悉的界面了。
在此就不一一翻译了,有兴趣研究的小伙伴,私下去研究一下。后续,我有用到的也会更新上来。
Tisp:如果有些常用的lldb语句,在每次一次启动后,都要手动敲进去是不是很麻烦。??在此,我们可以使用预加载文件,当我们项目跑起来的时候,就会自动把lldb语句加载入当期项目中,接下来,让我们一起来了解一下。
首先,在我们的系统的根目录下 查找一下 看看是否存在 ".lldbinit" 文件(由于.开头的文件都是隐藏文件,还需打开文件夹隐藏文件显示才能看到),如果没有我们可以使用 终端命令在跟目录下创建一个.
1. touch .lldbinit
2. open .lldbinit 打开.lldbinit文件,然后把 示例代码 target stop-hook add -o "frame variable" 放入文件中 command + S 保存,这是重新运行项目就会发现控制台会自己动把 target stop-hook add -o "frame variable" 添加进入。(注:然后是刚创建 .lldbinit 的 则需要完全关闭Xcode,重新打开才能生效。)
网友评论