这里整理一下常用的,我会慢慢添加并总结一些经验,iOS调试中。各位还是逐步放弃GDB吧,这已经成为定局了(虽然我含泪写下这段)~~~

lldb命令支持缩写,自己慢慢研究吧

 

优雅人生飘云原创整理,转载请注明出处!

http://www.dllhook.com

http://www.chinapyg.com

 

官方文档:http://lldb.llvm.org/


2014-12-02增加:

调试本地文件方法(Mac OS X):(lldb) target create "/Users/piaoyun/Desktop/xx.app/Contents/MacOS/xxxx"


远程调试方法:

设备端:

#附加进程:

./debugserver *:1234 -a "YourAPPName"


直接启动进程:

debugserver -x backboard *:1234 /path/to/app/executable

例:

debugserver -x backboard *:1234 /Applications/MobileNotes.app/MobileNotes

此命令会启动记事本,并断在dyld的第一条指令上


在Mac终端运行lldb命令后,输入以下2条命令:
platform select remote-ios
process connect connect://你的设备IP地址:1234


用USB连接方法:

////////////////////////////////////////////////////////////////////////////////////////

wget http://cgit.sukimashita.com/usbmuxd.git/snapshot/usbmuxd-1.0.8.tar.bz2
tar xjfv usbmuxd-1.0.8.tar.bz2
cd usbmuxd-1.0.8/python-client/
python tcprelay.py -t 1234:1234


在Mac终端运行lldb命令后,输入以下2条命令:

platform select remote-ios

process connect connect://localhost:1234

////////////////////////////////////////////////////////////////////////////////////////


-(void)loginWithUserName:(NSString *)username password:(NSString *)password

{

    NSLog(@"login.... username:%@   password:%@", username, password);  // 假设我们在此下断点

}


1.expression(或者缩写expr)  表达式 

例子:

expression $r6 = 1   // 设置r6寄存器的值

expression $r6       // 查看r6寄存器的值

expression username(源代码中变量) = @"www.dllhook.com"

expression [self btnTest]     // 调用某类某方法

 

2.po 表达式

例子:

po $r6

po username

po [[NSString alloc] initWithData:$r2 encoding:4]   // 打印$r2寄存器的明文数据

po [$r5 base64EncodedStringWithOptions:0];          // 打印$r5寄存器(NSData)类型的base64明文数据


3.print (type)表达式

例子:

print (int)$r6

print username


4.bt [all]   --- 打印调用堆栈

例子:

bt

返回如下:

* thread #1: tid = 0x1ee09, 0x00035e80 debug`-[ViewController loginWithUserName:password:](self=0x15d7be60, _cmd=0x00036441, username=0x15db0120, password=0x0003768c) + 168 at ViewController.m:34, queue = 'com.apple.main-thread', stop reason = breakpoint 2.1

  * frame #0: 0x00035e80 debug`-[ViewController loginWithUserName:password:](self=0x15d7be60, _cmd=0x00036441, username=0x15db0120, password=0x0003768c) + 168 at ViewController.m:34

.

.

.


5.breakpoint list     //打印断点列表

例子:

br l

返回如下:

Current breakpoints:

1: file = '/Users/piao/Desktop/debug/debug/main.m', line = 16, locations = 1, resolved = 1, hit count = 1

  1.1: where = debug`main + 54 at main.m:16, address = 0x00036232, resolved, hit count = 1 


2: file = '/Users/piao/Desktop/debug/debug/ViewController.m', line = 34, locations = 1, resolved = 1, hit count = 1

  2.1: where = debug`-[ViewController loginWithUserName:password:] + 168 at ViewController.m:34, address = 0x00035e80, resolved, hit count = 1 


下断:

breakpoint set -a 函数地址   --常规断点


breakpoint set --func-regex 函数关键字   --飘云提示:这个非常有用!我也是最近才研究发现的-虽然官方文档一直有,但是没重视

这样下断的优势:


比如再某动态库中有 testA函数,那么常规做法是先 image list -o -f 查看模块基址 然后 image lookup -r -n 函数关键字找到偏移   然后再 br s -a 基址+偏移!

用上面这个命令下端就简洁方便了!!!lldb会自动帮你下断所有匹配特征字的断点,可以模糊匹配哦


再来一个对动态库函数下断的:

breakpoint set --shlib foo.dylib --name foo


对某个方法下断:

breakpoint set --method/--name "-[TSRegistWinCtrl showRegister]"


在每个viewDidLoad方法设置断点:

breakpoint set --selector viewDidLoad


这个也非常有用,可以进行断点过程中的一些自动化处理:

breakpoint command add 断点序号


这个也非常有用,对C函数下断非常好 / 貌似是模糊匹配

breakpoint set -F isTest   / 可以简写为 b isTest


6.c

继续执行


7.s 

源码级别单步执行,遇到子函数则进入


8.si

单步执行,遇到子函数则进入


9.n 

源码级别单步执行,遇到子函数不进入,直接步过


10.ni

单步执行,遇到子函数不进入,直接步过


11.finish/f

退出子函数


12.thread list

 

打印线程列表

 

13.image lookup -a 表达式、image list

例子:

image lookup -a $pc

返回如下:

      Address: debug[0x0000b236] (debug.__TEXT.__text + 1254)

      Summary: debug`main + 58 at main.m:16

 

 

打印加载模块列表

image list [-f -o 通常带这两个参数使用]

返回如下:

[  0] 40E417A4-F966-3DB4-B028-B0272DC016A7 0x000a0000 /Users/piao/Library/Developer/Xcode/DerivedData/debug-bdkhskdqykkoqmhjedilckzvpuls/Build/Products/Debug-iphoneos/debug.app/debug 

      /Users/piao/Library/Developer/Xcode/DerivedData/debug-bdkhskdqykkoqmhjedilckzvpuls/Build/Products/Debug-iphoneos/debug.app.dSYM/Contents/Resources/DWARF/debug

[  1] 011601C0-F561-3306-846B-94A7C8C841DA 0x2d9e6000 /Users/piao/Library/Developer/Xcode/iOS DeviceSupport/7.1.2 (11D257)/Symbols/System/Library/Frameworks/CoreGraphics.framework/CoreGraphics


查找某个函数:


对于有调试符号的这样使用

image lookup -r -n <FUNC_REGEX>

对于无调试符号的这样使用:

image lookup -r -s <FUNC_REGEX>


 

14.disassemble -a 地址

例子:

dis -a $pc

debug`main at main.m:14:

   0xa71fc:  push   {r7, lr}

   0xa71fe:  mov    r7, sp

   0xa7200:  sub    sp, #0x24

   0xa7202:  movs   r2, #0x0

   0xa7204:  movt   r2, #0x0

   0xa7208:  str    r2, [sp, #0x20]

   0xa720a:  str    r0, [sp, #0x1c]

   0xa720c:  str    r1, [sp, #0x18]

   0xa720e:  blx    0xa7fe0                   ; symbol stub for: 

.

.

.

2015-04-29 添加

disassemble -A thumb    

可选:

thumbv4t

thumbv5

thumbv5e

thumbv6

thumbv6m

thumbv7

thumbv7f

thumbv7s

thumbv7k

thumbv7m

thumbv7em


///////////////////////////////////////////////

 

15.memory read [起始地址 结束地址]/寄存器 -outfile 输出路径

例子:

memory read $pc

0x00035ebe: 0e 98 07 99 09 68 08 9a 90 47 0c 99 03 90 08 46  .....h...G.....F

0x00035ece: 03 99 01 f0 80 e8 02 22 c0 f2 00 02 41 f2 52 10  ......."....A.R.


memory read 0x35f1c 0x35f46 -outfile /tmp/test.txt  // 将内存区域保存到文件


2015-04-29添加:

默认情况下,memory read 只能读取 1024字节数据

例如:

memory read 0x1000 0x3000 -outfile /tmp/test.txt 就会报错

error: Normally, 'memory read' will not read over 1024 bytes of data.

解决方法:加-force参数


memory read 0x1000 0x3000 -outfile /tmp/test.txt -force

或者:

memory read 0x1000 -outfile /tmp/test.txt -count 0x2000 -force

memory read $x0(寄存器) -outfile /tmp/test.txt -count 0x2000 -force


--binary // 二进制输出

例:

memory read 0x1000 0x3000 -outfile /tmp/test.bin --binary -force


写内存:

memory write $rip 0xc3

memory write $rip+1 0x90


16.register read/格式、register write 寄存器名称 数值

例子:

register read/x

返回如下:

General Purpose Registers:

        r0 = 0x1599e028

        r1 = 0x38131621  libobjc.A.dylib`objc_msgSend + 1

        r2 = 0x000a85cc  "class"

        r3 = 0x000a85d4  (void *)0x000a8618: AppDelegate

        r4 = 0x00000000

        r5 = 0x000a71fd  debug`main + 1 at main.m:14

        r6 = 0x00000000

        r7 = 0x27d63c80

        r8 = 0x27d63c98

        r9 = 0x00000002

       r10 = 0x00000000

       r11 = 0x00000000

       r12 = 0x3a3ff1c8  (void *)0x3875cc19: _Unwind_SjLj_Unregister + 1

        sp = 0x27d63c5c

        lr = 0x38136eaf  libobjc.A.dylib`objc_autoreleasePoolPush + 311

        pc = 0x000a7236  debug`main + 58 at main.m:16

      cpsr = 0x20000030


// 改写r9寄存器例子:

register write r9 2

 


17.display 表达式     undisplay 序号
例子:

display $R0

undisplay 1

 

18 内存断点 watchpoint set expression 地址    /  watchpoint set variable 变量名称 -- (源码调试用到,略过)

例子:

watchpoint set expression 0x1457fa70

命中后得到结果:

Watchpoint 3 hit:

old value: 3

new value: 4


18.2 内存访问断点 watchpoint set expression -w read -- 内存地址

watchpoint set expression -w read -- 0x16b9dd91


18.2 内存写入断点 watchpoint set expression -w write -- 内存地址

watchpoint set expression -w read -- 0x16b9dd91


18.3 条件断点 watchpoint modify -c 表达式

例子:

watchpoint modify -c '*(int *)0x1457fa70 == 20'

命中后得到结果:

Watchpoint 3 hit:

old value: 15

new value: 20


19.找按钮事件 po [按钮名称/内存地址 allTargets]

例子:

(lldb) po [[self btnTest] allTargets]
{(
    <ViewController: 0x166af1f0>
)}

(lldb) po [[self btnTest] actionsForTarget:(id)0x166af1f0 forControlEvent:0]
<__NSArrayM 0x165b8950>(
testAction:
)

// 在机器上实战一下:
(lldb) po [[[UIApplication sharedApplication] keyWindow] recursiveDescription]
<UIWindow:
 0x15e771c0; frame = (0 0; 320 568); gestureRecognizers = <NSArray: 
0x15e96210>; layer = <UIWindowLayer: 0x15e988e0>>
   | <UIView: 0x15eb4180; frame = (0 0; 320 568); autoresize = W+H; layer = <CALayer: 0x15eb4300>>
  
 |    | <UIButton: 0x15eb32d0; frame = (277 285; 46 30); opaque = NO;
 autoresize = RM+BM; layer = <CALayer: 0x15eb2e30>>
   |    
|    | <UIButtonLabel: 0x15db5220; frame = (0 6; 46 18); text = 
'Button'; opaque = NO; userInteractionEnabled = NO; layer = 
<_UILabelLayer: 0x15db5410>>
   |    | <_UILayoutGuide: 0x15eb4360; frame = (0 0; 0 20); hidden = YES; layer = <CALayer: 0x15eb4540>>
   |    | <_UILayoutGuide: 0x15eb4af0; frame = (0 568; 0 0); hidden = YES; layer = <CALayer: 0x15eb4b70>>

(lldb) po [(UIButton *)0x15eb32d0 allTargets]
{(
    <ViewController: 0x15e93250>
)}

(lldb) po [(UIButton *)0x15eb32d0 allTargets]
{(
    <ViewController: 0x15e93250>
)}

(lldb) po [(UIButton *)0x15eb32d0 actionsForTarget:(id)0x15e93250 forControlEvent:0]
<__NSArrayM 0x15dbfc50>(
testAction:
)
// 调用--
(lldb) po [0x15e93250 testAction:nil]
0x00210c18


// 再来一发,对按钮属性操作

(lldb) po [[[UIApplication sharedApplication] keyWindow] recursiveDescription]
<UIWindow: 0x15e771c0; frame = (0 0; 320 568); gestureRecognizers = <NSArray: 0x15e96210>; layer = <UIWindowLayer: 0x15e988e0>>
   | <UIView: 0x15eb4180; frame = (0 0; 320 568); autoresize = W+H; layer = <CALayer: 0x15eb4300>>
   |    | <UIButton: 0x15eb32d0; frame = (277 285; 46 30); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x15eb2e30>>
   |    |    | <UIButtonLabel: 0x15db5220; frame = (0 6; 46 18); text = 'Button'; opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x15db5410>>
   |    | <_UILayoutGuide: 0x15eb4360; frame = (0 0; 0 20); hidden = YES; layer = <CALayer: 0x15eb4540>>
   |    | <_UILayoutGuide: 0x15eb4af0; frame = (0 568; 0 0); hidden = YES; layer = <CALayer: 0x15eb4b70>>

(lldb) expression UIButton *$btn = (UIButton *)0x15eb32d0
(lldb) expression [$btn setHidden:YES]



带参数运行:

(lldb) target create "/bin/ls"
Current executable set to '/bin/ls' (x86_64).
(lldb) set set target.run-args  $(python \-c 'print "a"*200')
(lldb) run
Process 40752 launched: '/bin/ls' (x86_64)
ls: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: No such file or directory
Process 40752 exited with status = 1 (0x00000001)
(lldb)


std::string 读取方式:从内存+8的地方开始  64bit自行变通

例:

(lldb) x $r0+8      
0x02db9248: 20 82 e3 14 71 00 00 00 61 00 00 00 c0 82 d3 14   .惝q...a...喇赢
0x02db9258: 71 00 00 00 2b 00 00 00 20 f9 e6 14 61 00 00 00  q...+... .a...
(lldb) x/s 0x14e38220
0x14e38220: "hello!piaoyun"


你可能感兴趣的文章

评论区

发表评论

必填

选填

选填

必填

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。