LLDB(Low Lever Debug),默认内置于Xcode
中的动态调试工具。标准的 LLDB
提供了一组广泛的命令,旨在与老版本的 GDB
命令兼容。 除了使用标准配置外,还可以很容易地自定义 LLDB
以满足实际需要。
如果逆向别人的代码可以通过暂停程序执行来使程序进入LLDB
状态
LLDB
有很多指令,如果忘了相关指令,我们可以通过help
命令查看
(lldb) help
Debugger commands:
apropos -- List debugger commands related to a word or subject.
breakpoint -- Commands for operating on breakpoints (see 'help b' for
shorthand.)
...
也可以通过apropos
列出与某个单词或主题相关的调试器命令
(lldb) apropos breakpoint
The following commands may relate to 'breakpoint':
_regexp-break -- Set a breakpoint using one of
several shorthand formats.
_regexp-tbreak -- Set a one-shot breakpoint using
one of several shorthand formats.
breakpoint -- Commands for operating on
breakpoints (see 'help b' for
shorthand.)
breakpoint clear -- Delete or disable breakpoints
matching the specified source file
and line.
...
常用命令
- 给所有名为xxx的C函数设置一个断点
(lldb) breakpoint set -name xxx
(lldb) br s -n xxx
(lldb) b xxx
- 给一个OC函数[objc msgSend:]设置一个断点
(lldb) breakpoint set -n "[objc msgSend:]"
(lldb) b -n "[objc msgSend:]"
- 给所有名为xxx的OC方法设置一个断点
(lldb) breakpoint set -selector xxx:
- 给指定文件的某个OC方法设置一个断点
(lldb) breakpoint set --file ViewController.m --selector touchesBegan:withEvent:
- 给所有包含xxx的字段设置断点
(lldb) breakpoint set -r xxx
- 给指定文件F的某一行L设置一个断点
(lldb) breakpoint set --file F -line L
- 断点查看
(lldb) breakpoint list
(lldb) br l
- 断点删除
(lldb) breakpoint delete index//index是组号
(lldb) breakpoint delete //删除所有断点
(lldb) br del index
- 禁用/开启断点
(lldb) breakpoint disable index
(lldb) breakpoint enable index
断点的流程控制
- 继续
(lldb) process continue
(lldb) continue
(lldb) c
- 单步运行,将子函数当做整体一步执行
(lldb) thread step -over
(lldb) next
(lldb) n
(lldb) ni //单步运行汇编级别
- 单步运行,遇到子函数会进去
(lldb) thread step -in
(lldb) step
(lldb) s
(lldb) si //单步运行可跳转指令内部,汇编级别
- 跳出方法,返回上层调用栈
(lldb) thread step -out
(lldb) finish
(lldb) f
expression
expression
其实是p
的缩写,它的主要作用是在当前线程执行一个表达式,并将结果按照LLDB的默认格式返回。
(lldb) help p
Evaluate an expression on the current thread. Displays any returned value
with LLDB's default formatting. Expects 'raw' input (see 'help
raw-input'.)
Syntax: p <expr>
Command Options Usage:
p <expr>
'p' is an abbreviation for 'expression --'
下面是这个例子,可以看到expression
执行了表达式,给属性变量name
赋值,并返回了新赋的值,它可以动态的修改变量在内存中的值。
(lldb) po self.name
xiaoli
(lldb) p self.name = @"David"
(NSTaggedPointerString *) $5 = 0xc2f9f48bff645c0d @"David"
(lldb) p self.name
(NSTaggedPointerString *) $6 = 0xc2f9f48bff645c0d @"David"
(lldb)
查看堆栈信息
在一个函数的断点出,输入bt可查看调用堆栈信息
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
* frame #0: 0x000000010056e1c0 002--LLDB调试`-[ViewController test3:](self=0x0000000151e07750, _cmd="test3:", str=@"hook") at ViewController.m:64:20
frame #1: 0x000000010056e180 002--LLDB调试`-[ViewController test2:](self=0x0000000151e07750, _cmd="test2:", str=@"hook") at ViewController.m:60:5
frame #2: 0x000000010056e11c 002--LLDB调试`-[ViewController test1:](self=0x0000000151e07750, _cmd="test1:", str=@"hook") at ViewController.m:56:5
frame #3: 0x000000010056e258 002--LLDB调试`-[ViewController touchesBegan:withEvent:](self=0x0000000151e07750, _cmd="touchesBegan:withEvent:", touches=1 element, event=0x00000002806d0fa0) at ViewController.m:71:5
frame #4: 0x0000000193692b64 UIKitCore`forwardTouchMethod + 328
frame #5: 0x0000000193692a08 UIKitCore`-[UIResponder touchesBegan:withEvent:] + 60
frame #6: 0x00000001936a0af0 UIKitCore`-[UIWindow _sendTouchesForEvent:] + 1692
frame #7: 0x00000001936a20a8 UIKitCore`-[UIWindow sendEvent:] + 3352
frame #8: 0x000000019367eae8 UIKitCore`-[UIApplication sendEvent:] + 336
frame #9: 0x00000001936f623c UIKitCore`__dispatchPreprocessedEventFromEventQueue + 5880
frame #10: 0x00000001936f8798 UIKitCore`__handleEventQueueInternal + 4924
frame #11: 0x00000001936f160c UIKitCore`__handleHIDEventFetcherDrain + 108
frame #12: 0x000000018f5d67e0 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 24
frame #13: 0x000000018f5d6738 CoreFoundation`__CFRunLoopDoSource0 + 80
frame #14: 0x000000018f5d5ed0 CoreFoundation`__CFRunLoopDoSources0 + 180
frame #15: 0x000000018f5d101c CoreFoundation`__CFRunLoopRun + 1080
frame #16: 0x000000018f5d08bc CoreFoundation`CFRunLoopRunSpecific + 464
frame #17: 0x000000019943c328 GraphicsServices`GSEventRunModal + 104
frame #18: 0x00000001936666d4 UIKitCore`UIApplicationMain + 1936
frame #19: 0x000000010056e518 002--LLDB调试`main(argc=1, argv=0x000000016f8978c8) at main.m:14:16
frame #20: 0x000000018f45b460 libdyld.dylib`start + 4
可以通过up和down指令跟进堆栈的调用信息
(lldb) up
frame #1: 0x000000010056e180 002--LLDB调试`-[ViewController test2:](self=0x0000000151e07750, _cmd="test2:", str=@"hook") at ViewController.m:60:5
57 }
58
59 -(void)test2:(NSString *)str{
-> 60 [self test3:str];
^
61 }
62
63 -(void)test3:(NSString *)str{
(lldb) down
frame #0: 0x000000010056e1c0 002--LLDB调试`-[ViewController test3:](self=0x0000000151e07750, _cmd="test3:", str=@"hook") at ViewController.m:64:20
61 }
62
63 -(void)test3:(NSString *)str{
-> 64 NSLog(@"!!!%@",str);
^
65 }
也可以通过frame select index(堆栈的序号)命令来查看具体序号堆栈的调用信息
(lldb) frame select 3
frame #3: 0x000000010056e258 002--LLDB调试`-[ViewController touchesBegan:withEvent:](self=0x0000000151e07750, _cmd="touchesBegan:withEvent:", touches=1 element, event=0x00000002806d0fa0) at ViewController.m:71:5
68
69 -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
70 {
-> 71 [self test1:@"hook"];
^
72 //Person * p1 = self.models.firstObject;
73 }
74 - (IBAction)save:(id)sender {
通过frame variable命令查看具体序号堆栈的参数
(lldb) frame variable
(ViewController *) self = 0x0000000151e07750
(SEL) _cmd = "touchesBegan:withEvent:"
(__NSSetM *) touches = 0x00000002837f34a0 1 element
(UITouchesEvent *) event = 0x00000002806d0fa0
回滚thread return命令,会回到上一层调用堆栈,但是不会向下继续执行
(lldb) thread return
2019-10-26 16:24:54.495174+0800 002--LLDB调试[13707:437713] XPC connection interrupted
内存断点watchpoint
watchpoint
可以对方法或者对象的内存地址设置断点,如果对属性操作,类似KVO
观察者,如下是对一个属性变量设置的内存断点,如果属性变量的值发生改变了,程序就会自动中断
(lldb) po self
<ViewController: 0x1033040d0>
(lldb) n
(lldb) watchpoint set variable self->_name
Watchpoint created: Watchpoint 1: addr = 0x103304428 size = 8 state = enabled type = w
watchpoint spec = 'self->_name'
new value: 0x0000000102c10098
(lldb) c
Process 14669 resuming
Watchpoint 1 hit:
old value: 0x0000000102c10098
new value: 0x0000000102c10158
2019-10-28 10:52:01.935109+0800 002--LLDB调试[14669:514790] !!!hook
(lldb) po 0x0000000102c10098
lilei
(lldb) po 0x0000000102c10158
David
也可以通过如下方式操作
(lldb) p &self->_name
(NSString **) $0 = 0x0000000103303b48
(lldb) watchpoint set expression 0x0000000103303b48
Watchpoint created: Watchpoint 1: addr = 0x103303b48 size = 8 state = enabled type = w
new value: 4343234712
(lldb) c
Process 14731 resuming
Watchpoint 1 hit:
old value: 4343234712
new value: 4343234872
(lldb) po 4343234712
lilei
(lldb) po 4343234872
David
watchpoint
类似breakpoint
也有list
、delete
等相关命令,可以通过help watchpoint
命令来熟悉
(lldb) help watchpoint
Commands for operating on watchpoints.
Syntax: watchpoint <subcommand> [<command-options>]
The following subcommands are supported:
command -- Commands for adding, removing and examining LLDB commands
executed when the watchpoint is hit (watchpoint 'commands').
delete -- Delete the specified watchpoint(s). If no watchpoints are
specified, delete them all.
disable -- Disable the specified watchpoint(s) without removing it/them.
If no watchpoints are specified, disable them all.
enable -- Enable the specified disabled watchpoint(s). If no watchpoints
are specified, enable all of them.
ignore -- Set ignore count on the specified watchpoint(s). If no
watchpoints are specified, set them all.
list -- List all watchpoints at configurable levels of detail.
modify -- Modify the options on a watchpoint or set of watchpoints in
the executable. If no watchpoint is specified, act on the
last created watchpoint. Passing an empty argument clears the
modification.
set -- Commands for setting a watchpoint.
For more help on any particular subcommand, type 'help <command> <subcommand>'.
command
command
可以用来给一个断点添加命令,如下所示,先给test1
方法设置断点,然后用command
添加命令,当再一次调用test1
方法的时候,程序就会执行test1
方法添加的指令
(lldb) breakpoint set -n "[ViewController test1:]"
Breakpoint 3: where = 002--LLDB调试`-[ViewController test1:] + 48 at ViewController.m:57:6, address = 0x0000000104b86100
(lldb) breakpoint command add 3
Enter your debugger command(s). Type 'DONE' to end.
> po self
> p self.view
> DONE
(lldb) c
Process 14830 resuming
po self
<ViewController: 0x105107580>
p self.view
(UIView *) $1 = 0x0000000105209550
(lldb) breakpoint command list 3
Breakpoint 3:
Breakpoint commands:
po self
p self.view
(lldb) breakpoint command delete 3
(lldb) breakpoint command list 3
Breakpoint 3 does not have an associated command.
target stop-hook
target stop-hook
让每个断点都去执行一些命令,可以把它当作初始化的配置,如下所示,在每个断点处添加target stop-hook add -o "frame variable"
查看每个断点的参数信息,当断点触发的时候,该断点的参数信息就会打印出来
(lldb) breakpoint list
Current breakpoints:
1: file = '/Users/niujf/Desktop/ios逆向/007--LLDB/代码/002--LLDB调试/002--LLDB调试/ViewController.m', line = 56, exact_match = 0, locations = 1, resolved = 1, hit count = 0
1.1: where = 002--LLDB调试`-[ViewController test1:] + 48 at ViewController.m:57:6, address = 0x00000001027ba100, resolved, hit count = 0
2: file = '/Users/niujf/Desktop/ios逆向/007--LLDB/代码/002--LLDB调试/002--LLDB调试/ViewController.m', line = 70, exact_match = 0, locations = 1, resolved = 1, hit count = 0
2.1: where = 002--LLDB调试`-[ViewController touchesBegan:withEvent:] + 80 at ViewController.m:72:6, address = 0x00000001027ba240, resolved, hit count = 0
(lldb) target stop-hook add -o "frame variable" //查看每个断点的参数信息
Stop hook #1 added.
(lldb) c
Process 14962 resuming
(ViewController *) self = 0x0000000143e06f90
(SEL) _cmd = "touchesBegan:withEvent:"
(__NSSetM *) touches = 0x00000002800e5a20 1 element
(UITouchesEvent *) event = 0x00000002831f8c80
(lldb) c
Process 14962 resuming
(ViewController *) self = 0x0000000143e06f90
(SEL) _cmd = "test1:"
(__NSCFConstantString *) str = 0x00000001027bc138 @"hook"
image
image lookup -t xxxx
可以查看文件的详细信息
(lldb) image lookup -t ViewController
Best match found in /Users/niujf/Library/Developer/Xcode/DerivedData/002--LLDB调试-hblhlghervytczgywjtrdblfcdga/Build/Products/Debug-iphoneos/002--LLDB调试.app/002--LLDB调试:
id = {0x10000002b}, name = "ViewController", byte-size = 24, decl = ViewController.h:11, compiler_type = "@interface ViewController : UIViewController{
NSMutableArray * _models;
NSString * _name;
}
@property ( getter = models,setter = setModels:,readwrite,nonatomic ) NSMutableArray * models;
@property ( getter = name,setter = setName:,readwrite,copy,nonatomic ) NSString * name;
@end"
image list
查看调用的库
(lldb) image list
[ 0] EE92FCA2-C78B-31CC-8C2C-C7A123E92F28 0x00000001029b8000 /Users/niujf/Library/Developer/Xcode/DerivedData/002--LLDB调试-hblhlghervytczgywjtrdblfcdga/Build/Products/Debug-iphoneos/002--LLDB调试.app/002--LLDB调试
[ 1] 571392A7-E1E6-369F-8805-C1A141F3C1C5 0x0000000102cdc000 /Users/niujf/Library/Developer/Xcode/iOS DeviceSupport/13.1.3 (17A878)/Symbols/usr/lib/dyld
...
网友评论