iOS逆向006--LLDB(Low Lever Debug)

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原理

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 207,248评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,681评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,443评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,475评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,458评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,185评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,451评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,112评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,609评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,083评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,163评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,803评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,357评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,357评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,590评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,636评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,925评论 2 344

推荐阅读更多精彩内容

  • LLDB的Xcode默认的调试器,它与LLVM编译器一起,带给我们更丰富的流程控制和数据检测的调试功能。平时用Xc...
    CoderSC阅读 1,346评论 0 2
  •   LLDB的Xcode默认的调试器,它与LLVM编译器一起,带给我们更丰富的流程控制和数据检测的调试功能。平时用...
    Thinkdifferents阅读 1,506评论 1 4
  • LLDB的Xcode默认的调试器,它与LLVM编译器一起,带给我们更丰富的流程控制和数据检测的调试功能。平时用Xc...
    小笨狼阅读 20,432评论 31 187
  • 断点 设置断点(C语言)$breakpoint set -n XXXset 是子命令-n 是选项 是--name ...
    NextStepPeng阅读 169评论 0 1
  • 【妙妙的月度检视 2017年12月】 没有反思的人生不值得过 -苏格拉底 12月,嘉许自己每一天的认真与热忱,感恩...
    陈妙华阅读 2,188评论 14 41