目录
一,Xcode动态调试的原理
二,终端动态调试的原理
三,建立连接
四,LLDB常用命令
五,ASLR
一,Xcode动态调试的原理
1,图解
2,说明
-
LLDB
是Xcode自带的调试器
- 在真机调试时,Xcode会自动将
debugserver
安装到iPhone上
- 执行过程
1>
LLDB
将调试命令发送给debugserver
2>debugserver
将调试命令执行到APP上
3>APP将调试信息反馈给debugserver
4>debugserver
将调试信息转发给LLDB
- Xcode只能调试通过Xcode安装的APP
二,终端动态调试的原理
1,图解
2,说明
- 需要手动启动
LLDB
需要手动建立
LLDB
和debugserver
之间的连接需要手动建立
debugserver
和APP之间的连接建立好连接后就可以用终端调试任何APP了
三,建立连接
1,debugserver和APP的连接
- 给
debugserver
授予调试所有APP的权限
1>从iPhone中导出
debugserver
,再从debugserver
中导出权限文件2>在权限文件中添加两个字段:
get-task-allow
,task_for_pid-allow
3>将权限文件重新添加到
debugserver
中4>将授权后的
debugserver
添加到iPhone的/usr/bin
目录下(原目录中的无法替换)
- 连接APP
1>方法一:
debugserver *:[非保留端口号] -a [APP进程名称]
(先手动启动APP)2>方法二:
debugserver -x auto *:[非保留端口号] [APP可执行文件路径]
(会自动启动APP)
2,LLDB和debugserver的连接
- 端口映射(10011是Mac端口,222是iPhone端口)
- 连接debugserver:
process connect connect://localhost:[非保留端口号]
(需要先连接APP)
- 放开断点(连接成功后会自动打一个断点)
3,图解
四,LLDB常用命令
1,frame
-
frame variable
:打印方法内部所有局部变量的信息 -
frame variable [变量名]
:打印方法内部某个局部变量的信息
2,expression
-
expression [表达式]
(简写:p [表达式]
):打印信息或执行代码 -
expression -O -- [表达式]
(简写:po [表达式]
):打印信息或执行代码
3,thread
-
thread backtrace
(简写:bt
):打印当前线程的堆栈信息 -
thread return [返回值]
:让方法直接返回,不执行断点后面的代码
-
thread continue
(简写:continue
或c
):跳过当前断点,继续运行 -
thread step-over
(简写:next
或n
):单步运行,遇到方法不会进入 -
thread step-in
(简写:step
或s
):单步运行,遇到方法会进入 -
thread step-out
(简写:finish
):直接执行完当前方法,回到方法调用的位置
-
thread step-inst-over
(简写:nexti
或ni
):单行汇编运行,遇到函数不会进入 -
thread step-inst
(简写:stepi
或si
):单行汇编运行,遇到函数会进入
4,breakpoint
-
breakpoint set -n [方法名]
:设置断点 -
breakpoint set -a [方法地址]
:设置断点 -
breakpoint set -r [方法关键词]
:设置断点
-
breakpoint list
:列出所有断点
-
breakpoint disable [断点编号]
:禁用断点 -
breakpoint enable [断点编号]
:启用断点 -
breakpoint delete [断点编号]
:删除断点
-
breakpoint command add [断点编号]
:给断点添加命令,当触发断点时,这些命令就会按顺序执行 -
breakpoint command list [断点编号]
:列出所有断点命令 -
breakpoint command delete [断点编号]
:删除断点命令
5,watchpoint
-
watchpoint set variable [变量名]
:给变量设置断点,当变量被修改时触发 -
watchpoint set expression [变量地址]
:给变量设置断点,当变量被修改时触发
6,image
-
image lookup -t [类型]
:查看某个类型的信息 -
image lookup -n [方法名]
:根据方法名查找方法的位置 -
image lookup -a [方法地址]
:根据方法地址查找方法的位置
-
image list
:列出所有已加载的动态库
7,help(查看命令的用法)
五,ASLR
1,Mach-O基本结构
-
Header
:文件类型、架构类型等信息 -
Load commands
:描述文件数据在内存中是如何分布的 -
data
:文件数据在内存中的具体分布
2,Data基本结构
-
_PAGEZERO
:预留的内存空间 -
_TEXT
:代码段,存储编译之后的代码 -
_DATA
:数据段,存储字符串常量、全局变量和静态变量
3,字段介绍
-
VM Address
:在虚拟内存中的位置 -
VM Size
:在虚拟内存中的大小 -
File Offset
:在Mach-O文件中的位置 -
File Size
:在Mach-O文件中的大小
4,使用ASLR前的内存布局
- 图解
- 说明
1>
_PAGEZERO
在Mach-O文件中的大小为0x0,加载进内存后大小为0x100000000(arm64
架构下)
2>Header
和Load commands
都是描述信息,存储在_TEXT
中,所以内存空间从_PAGEZERO
开始分配
3>代码编译完成后,_TEXT
中方法的位置和_DATA
中变量的位置就是固定的,这样很容易进行动态调试,为了增加安全性,从iOS4.3开始就引入了ASLR
技术
5,使用ASLR后的内存布局
- 图解
- 说明
1>
ASLR
是Address Space Layout Randomization
(地址空间布局随机化)的缩写
2>引入ASLR
技术后,当Mach-O文件加载进内存时,会随机生成一个内存地址,然后从该地址开始进行内存空间的分配
3>虽然方法和变量的位置是固定的,但是内存地址就变得随机了,这样就会增加动态调试的难度,从而提高了安全性
6,获取方法的真实内存地址
- 无
ASLR
虚拟内存地址
-
ASLR
随机内存地址(Mach-O文件加载进内存的起始地址)
- 真实内存地址(调试其他APP时,需要用真实内存地址来设置断点,用方法名是无效的)
0x1000055b8 + 0xb4000 = 0x1000b95b8