Debug 命令 LLDB:Low Lever Debug( 轻量级Debug)
- (lldb)//---------------------内存、寄存器 指令---------------------
(lldb)help memory
(lldb)help register
(lldb)register read :读取寄存器
(lldb)register write pc + 地址 :修改寄存器
(lldb)memory read + 地址 :读取内存
(lldb)x + 地址:(同上) :读取内存
(lldb)memory read list == x list
(lldb)x/100xb list : 查看100个字节,16进制显示
(lldb)x/100xw list : 查看100个字,16进制显示
(lldb)po/x $rip :打印寄存器(rip 指令地址)
(lldb)p/x $rip :打印寄存器(rip 指令地址)
(lldb)p/x $rflags :打印寄存器(rflags 标记寄存器)
(lldb)po $edi
(lldb)po $esi
(lldb)po *Addr
(lldb)po Addr
(lldb)ni :汇编,单步往下走
(lldb)s :进入函数
(lldb)p/x 对象
(lldb)p/x list
(lldb)p/x list->value
x/100xb 这个命令叫什么
读取100个字节
(lldb)help :Debugger commands 查看命令指令
command shfit m + address =memory read
(lldb) x/100xb list
0x10062c640: 0x05 0x00 0x00 0x00 0x00 0x00 0x00 0x00 // 0x05 在左边高地址, 0x00 在右边低地 是小端模式
0x10062c648: 0xf0 0xde 0x62 0x00 0x01 0x00 0x00 0x00 // 01 00 62 de f0 -> 0x010062def0
(lldb) x/100xb 0x010062def0 // 打印指针地址
(lldb) x/100xb list
0x10062c640: 0x00 0x00 0x00 0x05 0x00 0x00 0x00 0x00 // 0x00 在左边高地址, 0x05 在右边低地 是大端模式
(小端模式倒序)f0 de 62 00 01 00 00 00 -> 00 00 00 01 00 62 de f0 -> 0x000000010062def0 == 0x010062def0
//前面是00 就不需要管了,可以直接去掉,再打印地址
高地址 存 高字节
低地址 存 低字节
- //-------------------------------基本使用指令---------------------------------
// 查看所有指令
help
// 查看指令详情:help + 指令
help breakpoint
// 继续往下走(c:continue)
c
// 显示当前线程的调用堆栈(bt:back stack)
bt
// 线程回滚:不再往下走了,下面的代码不会再执行了
thread return
// 单步运行(n:next,把子函数当做整体一步执行)
n
// 单步运行(s:step in,遇到子函数会进去)
s
// 回到上一个函数的调用者
up
// 到下一个函数的调用者
down
// 跳到对应的函数里
frame select 7
// 所有的变量
frame variable
/** 查看堆栈函数(一般奔溃使用:image lookup -a + 内存地址)
* image:Windows叫镜像或库
*/
image lookup -a 0x18a6aafe0
// 查看堆栈对象
image lookup -t Person
// 查看库
image list
指令的:添加、删除、查看(command)
// 添加断点指令
break command add 1
Enter your debugger command(s). Type 'DONE' to end.
> po self
> p self.view
> DONE
// 查看添加的指令
breakpoint command list 1
// 删除添加的指令
breakpoint command delete 1
内存断点
// 查看内存地址
p &p1->_name
结果:(NSString **) $0 = 0x0000000170034f50
// 设置内存断点 ( watchpoint set)
watchpoint set variable p1->_name
// 设置内存断点 (同上)
watchpoint set expression 0x0000000170034f50
//
watchpoint delete 1
watchpoint list
断点:设置、查看、禁用、启用、删除
// 设置断点
breakpoint set
breakpoint set -n test1 //给 test1函数 处 设置一个断点,进入此函数 (-n :--name 的缩写)
// 设置一个断点
breakpoint set -n test1
结果:Breakpoint 2: where = 001--LLDB`test1 + 11 at ViewController.m:81, address = 0x00000001070062fb
breakpoint set -n "-[ViewController touchesBegan:withEvent:]"
结果:Breakpoint 1: where = 001--LLDB`-[ViewController touchesBegan:withEvent:] + 70 at ViewController.m:85, address = 0x000000010c536356
// 同上:(简写)
b -n "-[ViewController touchesBegan:withEvent:]"
// (简写)
(lldb) b -[ViewController hankTest4:]
// (简写)同上
(lldb) b hankTest4:
// 同时设置 多个断点(注意方法要有-[] 和分号:引号" )
breakpoint set -n "-[ViewController save:]" -n "-[ViewController pauseGame:]" -n "-[ViewController continueGame:]"
结果:Breakpoint 6: 3 locations.
// 设置指定文件 中的断点
breakpoint set --file ViewController.m --selector touchesBegan:withEvent:
// 查看断点列表
breakpoint list
// 禁用断点
breakpoint disable 2.1 (对应断点组的子标号)
breakpoint delete 2.1 (效果同上)
breakpoint disable 2 (如果有此组有三个断点:2.1、2.2、2.3,则此指令 禁用此组所有断点)
break dis 2 (简写:效果同上)
// 启用断点
breakpoint enable 2.1 (对应断点组的子标号)
breakpoint enable 2 (如果有此组有三个断点:2.1、2.2、2.3,则此指令 启用此组所有断点)
break en 2 (简写:效果同上)
// 删除断点
breakpoint delete 2 (如果有此组有三个断点:2.1、2.2、2.3,则此指令 删除此组所有断点)
// 是否删除断点,Y
(lldb) breakpoint delete
About to delete all breakpoints, do you want to do that?: [Y/n] Y
// 找到使用过的指令
breakpoint + ↑、↓、←、→
// 设置 所有指定 字符的断点 (如下:暂停、继续 会设置成断点)
(lldb) breakpoint set -r Game
断点:执行、打印
// expression + 代码:(执行代码)
(lldb) expression self.view.subviews
(__NSArrayM *) $0 = 0x000060400025c560 @"3 elements"
// p: 简写 expression
(lldb) p self.view.subviews
(__NSArrayM *) $1 = 0x000060400025c560 @"3 elements"
// po + 代码:(打印代码)
po self.view.subviews
(lldb) p self.models.lastObject
(Person *) $7 = 0x0000600000031920
//------- 错误执行代码 ↓-------
(lldb) p $7.name = @"zm";
error: property 'name' not found on object of type 'id _Nullable'
(lldb) p [$7 setValue:@"zm" forKey:@"name"];
error: no known method '-setValue:forKey:''; cast the message send to the method's return type;
//------- 错误执行代码 ↑-------
// id 类型 必须指出其具体类型,才能正确执行代码
(lldb) p (Person *)self.models.lastObject
(Person *) $8 = 0x0000600000031920
// 赋值
(lldb) p $8.name = @"zm";
(NSTaggedPointerString *) $9 = 0xa00000000006d7a2 @"zm"
// 赋值
(lldb) p $8.age = 18;
(int) $10 = 18
// id 类型,执行代码错误
(lldb) po self.models.lastObject.name
error: property 'name' not found on object of type 'id _Nullable'
// 调出值
(lldb) p $8.name
(NSTaggedPointerString *) $11 = 0xa00000000006d7a2 @"zm"
// 调出
(lldb) p $8.age
(int) $12 = 18
// 执行多行代码
(lldb) p Person *zm = [[Person alloc] init]; zm.name = @"ZM_v587";zm.age = 20; [self.models addObject:zm];
// 同上:执行多行代码:command + return (换行)
(lldb) p Person *zm = [[Person alloc] init];
zm.name = @"ZM_v587";
zm.age = 20;
[self.models addObject:zm];
指令级别 如下图:
普通指令级别
1:显示、隐藏debug
2:是否debug
3:运行、停止debug
4:n 单步运行
5:s 单步运行
6:step out 直接运行当前的函数,返回上一个函数
汇编指令级别:按住control键
1:显示、隐藏debug
2:是否debug
3:运行、停止debug
4:si step over
5:ni step into
6:step out
-
测试代码:如下
------ 测试:数组越界(要真机测试)------
2018-05-13 14:01:59.444424+0800 001--LLDB[5410:2457279] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 4 beyond bounds [0 .. 2]'
*** First throw call stack:
(0x18a6aafe0 0x18910c538 0x18a589200 0x1000c631c 0x19096c01c 0x19096beb8 0x19081017c 0x19080b728 0x1907dc33c 0x190fd6014 0x190fd0770 0x190fd0b9c 0x18a65942c 0x18a658d9c 0x18a6569a8 0x18a586da4 0x18bff0074 0x190841058 0x1000c6550 0x18959559c)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb) image lookup -a 0x18a6aafe0
Address: CoreFoundation[0x0000000181646fe0] (CoreFoundation.__TEXT.__text + 1225360)
Summary: CoreFoundation`__exceptionPreprocess + 124
(lldb) image lookup -a 0x18910c538
Address: libobjc.A.dylib[0x00000001800a8538] (libobjc.A.dylib.__TEXT.__text + 17720)
Summary: libobjc.A.dylib`objc_exception_throw + 56
(lldb) image lookup -a 0x18a589200
Address: CoreFoundation[0x0000000181525200] (CoreFoundation.__TEXT.__text + 38064)
Summary: CoreFoundation`-[__NSArrayM removeObjectAtIndex:]
(lldb) image lookup -a 0x1000c631c
Address: 001--LLDB[0x000000010000631c] (001--LLDB.__TEXT.__text + 1776)
Summary: 001--LLDB`-[ViewController touchesBegan:withEvent:] + 140 at ViewController.m:89
(lldb)
- (void)viewDidLoad {
[super viewDidLoad];
Person * p1 = [[Person alloc] init];
p1.name = @"one";
p1.age = 1;
Person * p2 = [[Person alloc] init];
p2.name = @"two";
p2.age = 2;
Person * p3 = [[Person alloc] init];
p3.name = @"three";
p3.age = 3;
[self.models addObject:p1];
[self.models addObject:p2];
[self.models addObject:p3];
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
id p = self.models[4];
}
------ 测试:内存断点 wachpoint ------
(lldb) frame variable
(ViewController *) self = 0x000000010030bb70
(SEL) _cmd = "viewDidLoad"
(Person *) p1 = 0x0000000170034f40
(Person *) p2 = 0x000000017402ea60
(Person *) p3 = 0x000000016fd520b8
(lldb) p &p1->_name
(NSString **) $0 = 0x0000000170034f50
(lldb) watchpoint set expression 0x0000000170034f50
Watchpoint created: Watchpoint 1: addr = 0x170034f50 size = 8 state = enabled type = w
new value: 4295704824
(lldb) c
Process 5218 resuming
Watchpoint 1 hit:
old value: 4295704824
new value: 4295704952
(lldb) po 4295704824
one
(lldb) po 4295704952
hello
(lldb) watchpoint delete 1
1 watchpoints deleted.
(lldb) watchpoint list
Number of supported hardware watchpoints: 4
No watchpoints currently set.
(lldb)
------ 测试:bt、up、down------
(lldb) b -[ViewController hankTest3:]
Breakpoint 2: where = 001--LLDB`-[ViewController hankTest3:] + 46 at ViewController.m:48, address = 0x000000010485af4e
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
* frame #0: 0x0000000100061f48 001--LLDB`-[ViewController hankTest3:](self=0x000000010030f4f0, _cmd="hankTest3:", str=@"zm") at ViewController.m:48
frame #1: 0x0000000100061efc 001--LLDB`-[ViewController hankTest2:](self=0x000000010030f4f0, _cmd="hankTest2:", str=@"zm") at ViewController.m:45
frame #2: 0x0000000100061e7c 001--LLDB`-[ViewController hankTest1:](self=0x000000010030f4f0, _cmd="hankTest1:", str=@"zm") at ViewController.m:41
frame #3: 0x0000000100062370 001--LLDB`-[ViewController touchesBegan:withEvent:](self=0x000000010030f4f0, _cmd="touchesBegan:withEvent:", touches=1 element, event=0x00000001742e1700) at ViewController.m:91
frame #4: 0x000000019096c01c UIKit`forwardTouchMethod + 336
frame #5: 0x000000019096beb8 UIKit`-[UIResponder touchesBegan:withEvent:] + 60
frame #6: 0x000000019081017c UIKit`-[UIWindow _sendTouchesForEvent:] + 1948
frame #7: 0x000000019080b728 UIKit`-[UIWindow sendEvent:] + 3192
frame #8: 0x00000001907dc33c UIKit`-[UIApplication sendEvent:] + 340
frame #9: 0x0000000190fd6014 UIKit`__dispatchPreprocessedEventFromEventQueue + 2400
frame #10: 0x0000000190fd0770 UIKit`__handleEventQueue + 4268
frame #11: 0x0000000190fd0b9c UIKit`__handleHIDEventFetcherDrain + 148
frame #12: 0x000000018a65942c CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 24
frame #13: 0x000000018a658d9c CoreFoundation`__CFRunLoopDoSources0 + 540
frame #14: 0x000000018a6569a8 CoreFoundation`__CFRunLoopRun + 744
frame #15: 0x000000018a586da4 CoreFoundation`CFRunLoopRunSpecific + 424
frame #16: 0x000000018bff0074 GraphicsServices`GSEventRunModal + 100
frame #17: 0x0000000190841058 UIKit`UIApplicationMain + 208
frame #18: 0x0000000100062560 001--LLDB`main(argc=1, argv=0x000000016fda3aa8) at main.m:14
frame #19: 0x000000018959559c libdyld.dylib`start + 4
(lldb) up
frame #1: 0x0000000100061efc 001--LLDB`-[ViewController hankTest2:](self=0x000000010030f4f0, _cmd="hankTest2:", str=@"zm") at ViewController.m:45
42 }
43 -(void)hankTest2:(NSString *)str{
44 NSLog(@"%@",str);
-> 45 �[4m[�[0mself hankTest3:str];
46 }
47 -(void)hankTest3:(NSString *)str{
48 NSLog(@"%@",str);
(lldb) down
frame #0: 0x0000000100061f48 001--LLDB`-[ViewController hankTest3:](self=0x000000010030f4f0, _cmd="hankTest3:", str=@"zm") at ViewController.m:48
45 [self hankTest3:str];
46 }
47 -(void)hankTest3:(NSString *)str{
-> 48 NSLog(@"%@",�[4ms�[0mtr);
49 [self hankTest4:str];
50 }
51 -(void)hankTest4:(NSString *)str{
(lldb)
------ 测试:源码------
#import "ViewController.h"
#import "Person.h"
@interface ViewController ()
@property(nonatomic,strong)NSMutableArray<Person *> * models;
@end
@implementation ViewController
-(NSMutableArray<Person *> *)models
{
if (!_models) {
_models = [NSMutableArray array];
}
return _models;
}
- (IBAction)save:(id)sender {
NSLog(@"保存");
}
- (IBAction)pauseGame:(id)sender {
NSLog(@"暂停");
}
- (IBAction)continueGame:(id)sender {
NSLog(@"继续");
}
-(void)hankTest1:(NSString *)str{
NSLog(@"%@",str);
[self hankTest2:str];
}
-(void)hankTest2:(NSString *)str{
NSLog(@"%@",str);
[self hankTest3:str];
}
-(void)hankTest3:(NSString *)str{
NSLog(@"%@",str);
[self hankTest4:str];
}
-(void)hankTest4:(NSString *)str{
NSLog(@"%@",str);
}
- (void)viewDidLoad {
[super viewDidLoad];
Person * p1 = [[Person alloc] init];
p1.name = @"one";
p1.age = 1;
Person * p2 = [[Person alloc] init];
p2.name = @"two";
p2.age = 2;
Person * p3 = [[Person alloc] init];
p3.name = @"three";
p3.age = 3;
[self.models addObject:p1];
[self.models addObject:p2];
[self.models addObject:p3];
}
void test1(){
NSLog(@"3");
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
Person * p1 = self.models.firstObject;
p1.name = @"hello";
NSLog(@"---1");
NSLog(@"---2");
test1();
}
-
断点总结:
设置断点
$breakpoint set -n XXX
set 是子命令
-n 是选项 是--name 的缩写!查看断点列表
$breakpoint list删除
$breakpoint delete 组号禁用/启用
$breakpoint disable 禁用
$breakpoint enable 启用遍历整个项目中满足Game:这个字符的所有方法
$breakpoint set -r Game:
流程控制
- 继续执行
$continue c - 单步运行,将子函数当做整体一步执行
$n next - 单步运行,遇到子函数会进去
$s
stop-hook
让你在每次stop的时候去执行一些命令,只对breadpoint,watchpoint
常用命令
- image list
- p
- b -[xxx xxx]
- x
- register read
- po
关于后期的安排(非越狱!)
OC反汇编(MachO文件的东西)
密码学(Base64,HASH,RSA)
苹果签名技术
重签名 Xcode签名 脚本自动签名
动态库(动态库的注入)
HOOK原理