DerekSelander-LLDB 简介DerekSelander-LLDB 命令详解
__generate_scriptbiofcopyzdclassddddpdumpenviapiblogincludeinfojtoolkeychainlbrlookuplsofmsloverlaydbgpframeworkpmodulesbtsclasssearchsectionsnoopiesystobjectivecxrefyoink
DerekSelander-LLDB 简介
什么是 DerekSelander-LLDB?
DerekSelander-LLDB 是 LLDB 别名、正则表达式、Python 脚本的集合,可帮助开发者进行调试会话,由 DerekSelander(德里克·塞兰德)开发
DerekSelander-LLDB 的安装
将 DerekSelander-LLDB 克隆到本地
~ > sudo mkdir /opt/DerekSelander-LLDB ~ > sudo git clone --recursive https://github.com/DerekSelander/LLDB.git /opt/DerekSelander-LLDB 正克隆到 '/opt/DerekSelander-LLDB'... remote: Enumerating objects: 1479, done. remote: Counting objects: 100% (24/24), done. remote: Compressing objects: 100% (21/21), done. remote: Total 1479 (delta 12), reused 8 (delta 3), pack-reused 1455 接收对象中: 100% (1479/1479), 22.87 MiB | 78.00 KiB/s, 完成. 处理 delta 中: 100% (970/970), 完成.
将以下命令添加到 ~/.lldbinit 文件中
command script import /opt/DerekSelander-LLDB/lldb_commands/dslldb.pyDerekSelander-LLDB 命令详解 __generate_script
(lldb) help __generate_script
# 在与此文件相同的目录中生成一个新的脚本
# 可以生成函数样式的脚本或类样式的脚本
# 期望使用原始输入(请参阅 'help raw-input')
Syntax: __generate_script
# 使用示例:
__generate_script cool_command
reload_lldbinit
cool_command
biof
(lldb) help biof
# 接受两个正则表达式作为输入的正则表达式断点
# 第一个正则表达式在所有匹配的函数上创建一个断点
# 仅当第二个正则表达式断点位于堆栈跟踪中时,第二个正则表达式才会创建一个用于暂停的断点条件
# 期望使用原始输入(请参阅 'help raw-input')
Syntax: biof regex1 [Optional_ModuleName] ||| regex2 ModuleName1
# 使用示例:
# 例如,仅当 "Test" 模块中的代码导致方法 setTintColor: 被调用时,进程才会暂停
# 作为提示,明智的做法是使用只能与少量函数匹配的有限的 regex1,同时将 regex2 保持在任意大小
biof setTintColor: ||| . Test
copyz
(lldb) help copyz
# 期望使用原始输入(请参阅 'help raw-input')
Syntax: copyz
dclass
(lldb) help dclass
# 转储当前进程中所有继承自 NSObject/SwiftObject 的类
# 如果给此命令提供了一个模块参数,则此命令只会转储该模块中的类
# 此命令还支持只过滤某种类型的类,此命令还支持为特定的类生成头文件
# 期望使用原始输入(请参阅 'help raw-input')
Syntax: dclass
# 使用示例:
# 转储当前进程中所有继承自 NSObject/SwiftObject 的类
# 即转储当前进程中所有的 Objective-C 和 Swift 类
(lldb) dclass
# 转储有关 Hello.SomeClass 类的 ObjC/Swift 信息(如果适用的话)
# (与 dclass -i Hello.SomeClass 命令相同)
(lldb) dclass Hello.SomeClass
# 转储当前进程中所有继承自 UIViewController 的类
(lldb) dclass -f UIViewController
# 使用正则表达式不区分大小写地转储当前进程中所有匹配的类
# 在类名中搜索 "viewcontroller"
(lldb) dclass -r (?i)viewControlLer
# 转储 UIKit 模块中的所有类
(lldb) dclass -m UIKit
# 转储名为 CKConfettiEffect 的 NSBundle 中的所有继承自 UIView 的类
(lldb) dclass /System/Library/Messages/iMessageEffects/CKConfettiEffect.bundle/CKConfettiEffect -f UIView
# 为指定的类(UIView)生成头文件
(lldb) dclass -g UIView
# 生成一个可以将对象强制转换为的协议
# 非常适合用于在开发过程中使用私有类
(lldb) dclass -P UIView
# 转储特定模块中的所有类和方法
# 非常适合用于查看框架(framework)随时间发生的变化
(lldb) dclass -o UIKit
# 只转储 superclass 为 NSObject,并且位于 UIKit 模块中的类
# 非常适合用于查看特定的类,比如,继承自 NSObject 的数据源
(lldb) dclass -s NSObject -m UIKit
# 只转储 Swift 类
(lldb) dclass -t swift
# 只转储 Objective-C 类
(lldb) dclass -t objc
# 获取 UIView 类的简化 class-dump
(lldb) dclass -i UIView
# 获取更多关于 UIView 的信息
(lldb) dclass -I UIView
dd
(lldb) help dd
# 用于替代 LLDB 的 disassemble 命令
# 输出彩色的汇编代码,为 x86_64 架构而设计,仅适用于终端
# 期望使用原始输入(请参阅 'help raw-input')
Syntax: dd
ddp
(lldb) help ddp
# 显示当前应用程序的 document 目录
# 包括应用程序可以从共享组中访问的 DataDirectory 和共享目录
# 期望使用原始输入(请参阅 'help raw-input')
Syntax: ddp
dumpenv
(lldb) help dumpenv
# 转储在当前进程中找到的环境变量
# 期望使用原始输入(请参阅 'help raw-input')
Syntax: dumpenv
iap
(lldb) help iap
# iAP 辅助方法
# 期望使用原始输入(请参阅 'help raw-input')
Syntax: iap
# 使用示例:
# iap 至少需要一个参数,当前支持以下参数
# 获取 iAP 收据(如果存在的话)
iap get
# 获取设备上 iAP 收据的状态(如果有的话)
iap stat
iblog
(lldb) help iblog
# 期望使用原始输入(请参阅 'help raw-input')
Syntax: iblog
include
(lldb) help include
# 导入一个独立的 C 头文件
# 期望使用原始输入(请参阅 'help raw-input')
Syntax: include
info
(lldb) help info
# 获取有关内存中指定地址的信息
# 确定指定的地址是什么?堆?栈?MachO?
# 期望使用原始输入(请参阅 'help raw-input')
Syntax: info
jtool
(lldb) help jtool
# 封装 Morpheus(人名:墨菲斯) 的 jtool
# 期望使用原始输入(请参阅 'help raw-input')
Syntax: jtool
keychain
(lldb) help keychain
# 用于操作 iOS 钥匙串的命令,转储与当前进程相关的钥匙串数据库
# 此命令将转储当前进程中所有已知的通用密码和通用互联网密码(仅限 iOS)
# 如果提供了参数,则此命令将只返回与指定的参数(服务名称或帐户名称)匹配的结果
# iOS 设备必须处于打开状态,如果 iOS 设备被锁定,则此命令将不会返回任何结果
# 期望使用原始输入(请参阅 'help raw-input')
Syntax: keychain
# 使用示例:
# 转储当前进程中所有密码的内容
keychain
# 转储当前进程中服务名称或帐户名称包含 tmp 的密码的内容
keychain tmp
lbr
(lldb) help lbr
# 在指定模块的指定文件偏移上创建一个断点,并解析到内存中相应的加载地址
# 期望使用原始输入(请参阅 'help raw-input')
Syntax: lbr ModuleName OffsetAddress
# 使用示例:
lbr UIKit 0x12343
lookup
(lldb) help lookup
# 对可执行文件中的内容执行正则表达式搜索,用于查找函数或变量
# 期望使用原始输入(请参阅 'help raw-input')
Syntax: lookup
# 查找所有包含短语 viewDidLoad 的函数或方法
(lldb) lookup viewDidLoad
# 查找所有模块的摘要,这些模块具有包含短语 viewDidLoad 的函数或方法
(lldb) lookup viewDidLoad -s
# 在剥离的模块中搜索 Objective-C 代码(即在 SpringBoard 中)
(lldb) lookup -x Stocksframework .
# 在剥离的 main bundle 中搜索包含不区分大小写的短语 init 的 Objective-C 代码
(lldb) lookup -X (?i)init
# 在 UIKit 中包含短语 http 的可执行文件中搜索所有硬编码、嵌入的 char *
(lldb) lookup -S http -m UIKit
# 将 libMobileGestalt.dylib 中的所有 md5 键与内存中的地址一起转储
(lldb) lookup -S ^[a-zA-Z0-9+]{22,22}$ -m libMobileGestalt.dylib -l
# 转储 DWARF 引用的所有全局 bss 代码
# 非常适合用于当不在范围内时,访问 static 变量
(lldb) lookup . -g HonoluluArt -l
# 在模块 SwiftTest 中查找短语 nominal (Swift 的 nominal 类型描述符),并获取地址,不要计算符号
(lldb) lookup -G SwiftTest nominal -
lsof
(lldb) help lsof
# 列出当前进程中打开的文件描述符
# 期望使用原始输入(请参阅 'help raw-input')
Syntax: lsof
msl
(lldb) help msl
# 获取地址的堆栈跟踪,需要 MallocStackLogging
# msl(malloc stack logging)将获取地址并尝试获取创建它时的堆栈跟踪
# 需要将环境变量设置为 MallocStackLogging,或在进程处于活动状态时执行 turn_on_stack_logging(1)
# 期望使用原始输入(请参阅 'help raw-input')
Syntax: msl
# 使用示例:
msl 0xadd7E55
overlaydbg
(lldb) help overlaydbg
# 在 iOS 上显示 UIDebuggingInformationOverlay
# 切换 UIDebuggingInformationOverlay,仅限 iOS 9.X - 11.X
# UIDebuggingInformationOverlay 是由 Apple 创建的一个私有的 UIWindow 子类,用于帮助 Apple 的开发工程师和设计师调试 Apple 自己的 iOS App
# 启用后,UIDebuggingInformationOverlay 会浮动在当前 App 的上层
# 期望使用原始输入(请参阅 'help raw-input')
Syntax: overlaydbg
pframework
(lldb) help pframework
# 打印 framework 的位置(磁盘上的)
# 期望使用原始输入(请参阅 'help raw-input')
Syntax: pframework
pmodule
(lldb) help pmodule
# 生成 DTrace 脚本以分析模块
# 创建一个自定义的 DTrace 脚本,根据其内存布局和 ASLR 分析可执行文件中的模块
# 如果想要计算所有模块触发的数量,则请不要提供参数 -a
# 如果想要在方法触发时转储它们,则请提供一个模块
# DTrace 脚本的位置将复制到当前计算机的剪贴板中,因此可以直接将即将执行的 DTrace 脚本粘贴到终端中
# 可以通过 -n 参数选择使用 objc 或非 objc (即 objc$target 或 pid$target)
# 警告: 您必须禁用 rootless 才能使用 DTrace
# 期望使用原始输入(请参阅 'help raw-input')
Syntax: pmodule [[MODULENAME]...]
# 使用示例:
# 在 UIKit 中跟踪所有 Objective-C 代码
pmodule UIKit
# 跟踪 libsystem_kernel.dylib 中的所有非 Objective-C 代码 (即 pid$target:libsystem_kernel.dylib::entry)
pmodule -n libsystem_kernel.dylib
# 转储所有内容
# 仅在结束脚本后显示来自模块的函数调用计数
# 警告: 执行速度很慢
pmodule -a
sbt
(lldb) help sbt
# 进行符号回溯,即重新符号化已剥离的 ObjC 堆栈跟踪
# 如果堆栈跟踪使用的是 Objective-C 代码,则将从可执行文件中重新符号化已剥离的堆栈跟踪
# 目前不适用于 aarch64 架构中已剥离的可执行文件,但是适用于 x64 架构中已剥离的可执行文件
# 期望使用原始输入(请参阅 'help raw-input')
Syntax: sbt
sclass
(lldb) help sclass
# Swizzle Class 辅助方法
# 生成一个 NSObject Category 文件,用于 Swizzle 指定的类
# 期望使用原始输入(请参阅 'help raw-input')
Syntax: sclass
# 使用示例:
# 生成一个类别(Category)来交换(Swizzle)指定类(UIViewController)中所有创建或覆盖的方法
sclass UIViewController
# 生成一个只用于交换(Swizzle)指定方法(viewDidLoad)的类别(Category)
sclass UIViewController -m viewDidLoad
# 生成一个在执行时打印所有函数的类别(Category)
sclass UIViewController -p
# 生成一个每次在命中指定方法(UIViewController)时会暂停的类别(Category)
sclass UIViewController -s
# 生成一个默认启用所有方法交换(Swizzle)的类别(Category)
sclass UIViewController -e
search
(lldb) help search
# 在堆中搜索指定类的所有活动的实例对象
# 指定的类必须是动态的 (也就是继承自 NSObject/SwiftObject 的类)
# 目前不适用于 NSString 或 NSNumber (tagged pointer 类型的实例对象)
# 注意: 此脚本会导致内存泄漏
# 期望使用原始输入(请参阅 'help raw-input')
Syntax: search
Examples:
# 查找所有 UIView 和 UIView 的子类的实例对象
find UIView
# 查找所有 UIStatusBar 和 UIStatusBar 的子类的实例对象
find UIStatusBar
# 查找所有 UIView 的实例对象,忽略 UIView 子类的实例对象
find UIView -e
# 查找 tag == 5 的所有 UIView 的实例对象
# 仅限 Objective-C 语法,可以通过 obj 引用实例对象
find UIView -c "[obj tag] == 5"
# 查找所有 UIView 和 UIView 的子类的实例对象
(lldb) search UIView
# 查找所有 UIView 的实例对象,忽略 UIView 子类的实例对象
(lldb) search UIView -e
# 查找 tag == 5 的所有 UIView 的实例对象
# 仅限 Objective-C 语法,可以通过 obj 引用实例对象
(lldb) search UIView -c "(int)[obj tag]==5"
# 查找在 SpringBoardUI 模块中实现的 UIView 的子类的所有实例
(lldb) search UIView -m SpringBoardUI
# 查找在 Woot 模块中创建的所有 UIView 子类的实例对象,并隐藏它们
(lldb) search UIView -m Woot -p "[obj setHidden:YES]"
# 搜索 UIView 但只打印类描述,不打印对象描述
# (非常适合用于搜索隐藏指针的 Swift)
(lldb) search UIView -b
# 请记住,Swift 将模块名包含在类名中,因此,如果您在模块 WOOT 中有一个名为 TestView 的 Swift UIView,则
(lldb) search WOOT.TestView -b
# 搜索所有包含对指针 0xfeedfacf 的引用的类
(lldb) search -r 0xfeedfacf
section
(lldb) help section
# Mach-O 文件中段(segment)和节(section)的辅助方法
# 显示加载到当前进程中的可执行文件或框架的 Mach-O 的段(segment)和节(section)中的数据
# 期望使用原始输入(请参阅 'help raw-input')
Syntax: section
# 使用示例:
# 转储主可执行文件 (main executable) Mach-O 中的段(segment)
(lldb) section
# 转储 UIKit Mach-O 中的段(segment)
(lldb) section UIKit
# 转储 UIKit Mach-O 中的 __TEXT 段(segment)
(lldb) section UIKit __TEXT
# 获取 UIKit Mach-O 中所有硬编码的 uint8_t * 字符串的加载地址
(lldb) section UIKit __TEXT.__cstring -l
# 获取可执行文件的 entitlements (仅限模拟器,因为实际应用程序的 entitlements 在 __linkEDIT 中)
(lldb) section __TEXT.__entitlements
# 获取主可执行文件(main executable)中所有 lazy symbol stub 的加载地址
(lldb) section __DATA.__la_symbol_ptr -l
snoopie
(lldb) help snoopie
# 使用 DTrace 分析已剥离的 ObjC 方法
# 生成一个 DTrace 脚本,该脚本将只分析在主可执行文件(main executable)中实现的类,而不管二进制文件被是否被剥离
# 这是通过分析 objc_msgSend 完成的
# 期望使用原始输入(请参阅 'help raw-input')
Syntax: snoopie
sys
(lldb) help sys
# 进入 Shell 执行命令
# 请注意,您可以通过 $() 语法执行 LLDB 命令
# 期望使用原始输入(请参阅 'help raw-input')
Syntax: sys
# 使用示例:
# ls 运行 LLDB 的目录
(lldb) sys ls
# 在 UIKit 框架上使用 otool -l
(lldb) sys otool -l $(pframework UIKit)
# 在另一个程序中打开主可执行文件(main executable)
(lldb) sys open -a "Hopper" $(pexecutable)
tobjectivec
(lldb) help tobjectivec
# 生成 DTrace 分析脚本
# 期望使用原始输入(请参阅 'help raw-input')
Syntax: tobjectivec
# 使用示例:
# 创建 DTrace 脚本并复制到剪贴板
sudo dtrace provider:module:function:name / predicate / { action }
xref
(lldb) help xref
# 查找对代码/数据的引用 (非堆)
# 期望使用原始输入(请参阅 'help raw-input')
Syntax: xref
yoink
(lldb) help yoink
# 将远程内容复制到本地计算机
# 将 iOS/tvOS/watchOS 上指定路径的内容写入到本地计算机上的 /tmp/ 目录
# 如果远程内容可以通过 -[NSData dataWithContentsOfFile:] 读取,则其就可以写入本地磁盘
# 期望使用原始输入(请参阅 'help raw-input')
Syntax: yoink
# 使用示例 (iOS 10 device):
yoink /System/Library/Messages/iMessageEffects/CKConfettiEffect.bundle/CKConfettiEffect



