Xcode Debugging

Xcode Debugging

你的代碼器予,或者任何人的代碼中總會(huì)有bug存在偿枕,你可以把調(diào)試看做是更好地理解代碼的一種方式 —— By Advanced_Apple_Debugging_&_Reverse_Engineering_v0.9.5

The Debugging Process

  1. Reproduce the problem

if you cannot reproduce the problem, then you (probably) do not understand it.

  1. Gather Debug Information

Logs, program, state,...
What is the value of a variable?
What kind of error?(ex.EXC_BAD_ACCESS)
What line of code caused the error?
Which functions or methods led to the error?

  1. Form a Hypothesis
  1. Try a fix

Maximize the information gained per fix!

image

Print Debugging

image

TOOL

LLDB

Use commands to debugging, save your time in rebuild and make breakpoints.

常用命令

po —— call the description method on an object.
p —— print the value of 數(shù)量級(jí) values

Print variable frame

frame variable
fr v

Expression命令

expression命令的作用是執(zhí)行一個(gè)表達(dá)式陌凳,并將表達(dá)式返回的結(jié)果輸出充岛。expression的完整語(yǔ)法是這樣的:

Objective-C

expression <cmd-options> -- <expr>
1
expression <cmd-options> -- <expr>

說(shuō)expression是LLDB里面最重要的命令都不為過(guò)蒜魄。因?yàn)樗軐?shí)現(xiàn)2個(gè)功能伞鲫。

執(zhí)行某個(gè)表達(dá)式撒会。 我們?cè)诖a運(yùn)行過(guò)程中怔檩,可以通過(guò)執(zhí)行某個(gè)表達(dá)式來(lái)動(dòng)態(tài)改變程序運(yùn)行的軌跡闸英。 假如我們?cè)谶\(yùn)行過(guò)程中辙喂,突然想把self.view顏色改成紅色灸蟆,看看效果城看。我們不必寫下代碼谒主,重新run,只需暫停程序搪柑,用expression改變顏色,再刷新一下界面焦读,就能看到效果
Objective-C

// 改變顏色
(lldb) expression -- self.view.backgroundColor = [UIColor redColor]
// 刷新界面
(lldb) expression -- (void)[CATransaction flush]
將返回值輸出贫奠。 也就是說(shuō)我們可以通過(guò)expression來(lái)打印東西骇窍。 假如我們想打印self.view:
Objective-C

(lldb) expression -- self.view
(UIView *) $1 = 0x00007fe322c18a10

(lldb) expression -- self.view
(UIView *) $1 = 0x00007fe322c18a10

expression 可以支持多行輸入,輸入expression后回車畦浓,會(huì)顯示行號(hào)宴倍,每行輸入后換行张症,雙擊回車代表完成輸入,過(guò)掉斷言即刻看到表達(dá)式的效果鸵贬。

image

BreakPoint

image
breakpoint command add給斷點(diǎn)添加命令

e.g: 假設(shè)我們需要在ViewController的viewDidLoad中查看self.view的值
我們首先給-[ViewController viewDidLoad]添加一個(gè)斷點(diǎn)

(lldb) breakpoint set -n "-[ViewController viewDidLoad]"
'breakpoint 3': where = TLLDB`-[ViewController viewDidLoad] + 20 at ViewController.m:23, address = 0x00000001055e6004

可以看到添加成功之后俗他,這個(gè)breakpoint的id為3,然后我們給他增加一個(gè)命令:po self.view
(lldb) breakpoint command add -o "po self.view" 3

-o完整寫法是--one-liner阔逼,表示增加一條命令兆衅。3表示對(duì)id為3的breakpoint增加命令。
添加完命令之后嗜浮,每次程序執(zhí)行到這個(gè)斷點(diǎn)就可以自動(dòng)打印出self.view的值了

如果我們一下子想增加多條命令羡亩,比如我想在viewDidLoad中打印當(dāng)前frame的所有變量,但是我們不想讓他中斷危融,也就是在打印完成之后畏铆,需要繼續(xù)執(zhí)行。我們可以這樣玩:

(lldb) breakpoint command add 3
Enter your debugger command(s). Type 'DONE' to end.

frame variable
continue
DONE
輸入breakpoint command add 3對(duì)斷點(diǎn)3增加命令吉殃。他會(huì)讓你輸入增加哪些命令辞居,輸入'DONE'表示結(jié)束。這時(shí)候你就可以輸入多條命令了

多次對(duì)同一個(gè)斷點(diǎn)添加命令寨腔,后面命令會(huì)將前面命令覆蓋

breakpoints添加通過(guò)條件
image

breakpoint

調(diào)試過(guò)程中速侈,我們用得最多的可能就是斷點(diǎn)了。LLDB中的斷點(diǎn)命令也非常強(qiáng)大

breakpoint set

breakpoint set命令用于設(shè)置斷點(diǎn)迫卢,LLDB提供了很多種設(shè)置斷點(diǎn)的方式:

使用-n根據(jù)方法名設(shè)置斷點(diǎn):

e.g: 我們想給所有類中的viewWillAppear:設(shè)置一個(gè)斷點(diǎn):

(lldb) breakpoint set -n viewWillAppear:
Breakpoint 13: 33 locations.

使用-f指定文件

e.g: 我們只需要給ViewController.m文件中的viewDidLoad設(shè)置斷點(diǎn):

(lldb) breakpoint set -f ViewController.m -n viewDidLoad
Breakpoint 22: where = TLLDB`-[ViewController viewDidLoad] + 20 at ViewController.m:22, address = 0x000000010272a6f4

這里需要注意倚搬,如果方法未寫在文件中(比如寫在category文件中,或者父類文件中)乾蛤,指定文件之后每界,將無(wú)法給這個(gè)方法設(shè)置斷點(diǎn)。

使用-l指定文件某一行設(shè)置斷點(diǎn)

e.g: 我們想給ViewController.m第38行設(shè)置斷點(diǎn)

(lldb) breakpoint set -f ViewController.m -l 38
Breakpoint 23: where = TLLDB`-[ViewController text:] + 37 at ViewController.m:38, address = 0x000000010272a7d5
使用-c設(shè)置條件斷點(diǎn)

e.g: text:方法接受一個(gè)ret的參數(shù)家卖,我們想讓ret == YES的時(shí)候程序中斷:

(lldb) breakpoint set -n text: -c ret == YES
Breakpoint 7: where = TLLDB`-[ViewController text:] + 30 at ViewController.m:37, address = 0x0000000105ef37ce
使用-o設(shè)置單次斷點(diǎn)

e.g: 如果剛剛那個(gè)斷點(diǎn)我們只想讓他中斷一次:

(lldb) breakpoint set -n text: -o
'breakpoint 3': where = TLLDB`-[ViewController text:] + 30 at ViewController.m:37, address = 0x000000010b6f97ce
breakpoint command

有的時(shí)候我們可能需要給斷點(diǎn)添加一些命令眨层,比如每次走到這個(gè)斷點(diǎn)的時(shí)候,我們都需要打印self對(duì)象上荡。我們只需要給斷點(diǎn)添加一個(gè)po self命令趴樱,就不用每次執(zhí)行斷點(diǎn)再自己輸入po self了

breakpoint command add

breakpoint command add命令就是給斷點(diǎn)添加命令的命令馒闷。

e.g: 假設(shè)我們需要在ViewController的viewDidLoad中查看self.view的值
我們首先給-[ViewController viewDidLoad]添加一個(gè)斷點(diǎn)

(lldb) breakpoint set -n "-[ViewController viewDidLoad]"
'breakpoint 3': where = TLLDB`-[ViewController viewDidLoad] + 20 at ViewController.m:23, address = 0x00000001055e6004
可以看到添加成功之后,這個(gè)breakpoint的id為3叁征,然后我們給他增加一個(gè)命令:po self.view

(lldb) breakpoint command add -o "po self.view" 3
-o完整寫法是--one-liner纳账,表示增加一條命令。3表示對(duì)id為3的breakpoint增加命令捺疼。
添加完命令之后疏虫,每次程序執(zhí)行到這個(gè)斷點(diǎn)就可以自動(dòng)打印出self.view的值了

如果我們一下子想增加多條命令,比如我想在viewDidLoad中打印當(dāng)前frame的所有變量啤呼,但是我們不想讓他中斷卧秘,也就是在打印完成之后,需要繼續(xù)執(zhí)行官扣。我們可以這樣玩:

(lldb) breakpoint command add 3
Enter your debugger command(s). Type 'DONE' to end.

frame variable
continue
DONE
輸入breakpoint command add 3對(duì)斷點(diǎn)3增加命令翅敌。他會(huì)讓你輸入增加哪些命令,輸入'DONE'表示結(jié)束惕蹄。這時(shí)候你就可以輸入多條命令了

多次對(duì)同一個(gè)斷點(diǎn)添加命令哼御,后面命令會(huì)將前面命令覆蓋
breakpoint command list

如果想查看某個(gè)斷點(diǎn)已有的命令,可以使用breakpoint command list焊唬。
e.g: 我們查看一下剛剛的斷點(diǎn)3已有的命令

(lldb) breakpoint command list 3
'breakpoint 3':
Breakpoint commands:
frame variable
continue
可以看到一共有2條命令,分別為frame variable和continue

breakpoint command delete

有增加就有刪除看靠,breakpoint command delete可以讓我們刪除某個(gè)斷點(diǎn)的命令
e.g: 我們將斷點(diǎn)3中的命令刪除:

(lldb) breakpoint command delete 3
(lldb) breakpoint command list 3
Breakpoint 3 does not have an associated command.
可以看到刪除之后赶促,斷點(diǎn)3就沒有命令了

breakpoint list

如果我們想查看已經(jīng)設(shè)置了哪些斷點(diǎn),可以使用breakpoint list
e.g:

(lldb) breakpoint list
Current breakpoints:
4: name = '-[ViewController viewDidLoad]', locations = 1, resolved = 1, hit count = 0
4.1: where = TLLDB`-[ViewController viewDidLoad] + 20 at ViewController.m:23, address = 0x00000001055e6004, resolved, hit count = 0
我們可以看到當(dāng)前只有一個(gè)斷點(diǎn)挟炬,打在-[ViewController viewDidLoad]上鸥滨,id是4

breakpoint disable/enable

有的時(shí)候我們可能暫時(shí)不想要某個(gè)斷點(diǎn),可以使用breakpoint disable讓某個(gè)斷點(diǎn)暫時(shí)失效
e.g: 我們來(lái)讓剛剛的斷點(diǎn)4失效

(lldb) breakpoint disable 4
1 breakpoints disabled.
輸入完命令之后谤祖,顯示斷點(diǎn)已經(jīng)失效

當(dāng)我們又需要這個(gè)斷點(diǎn)的時(shí)候婿滓,可以使用breakpoint enable再次讓他生效
e.g: 重新啟用斷點(diǎn)4

(lldb) breakpoint enable 4
1 breakpoints enabled.
breakpoint delete

如果我們覺得這個(gè)斷點(diǎn)以后再也用不上了,可以用breakpoint delete直接刪除斷點(diǎn).
e.g: 刪除斷點(diǎn)4

(lldb) breakpoint delete 4
1 breakpoints deleted; 0 breakpoint locations disabled.
如果我們想刪除所有斷點(diǎn)粥喜,只需要不指定breakpoint delete參數(shù)即可

(lldb) breakpoint delete
About to delete all breakpoints, do you want to do that?: [Y/n] y
All breakpoints removed. (1 breakpoint)
刪除的時(shí)候他會(huì)提示你凸主,是不是真的想刪除所有斷點(diǎn),需要你再次輸入Y確認(rèn)额湘。如果想直接刪除卿吐,不需要他的提示,使用-f命令選項(xiàng)即可

(lldb) breakpoint delete -f
All breakpoints removed. (1 breakpoint)
實(shí)際平時(shí)我們真正使用breakpoint命令反而比較少锋华,因?yàn)閄code已經(jīng)內(nèi)置了斷點(diǎn)工具嗡官。我們可以直接在代碼上打斷點(diǎn),可以在斷點(diǎn)工具欄里面查看編輯斷點(diǎn)毯焕,這比使用LLDB命令方便很多衍腥。不過(guò)了解LLDB相關(guān)命令可以讓我們對(duì)斷點(diǎn)理解更深刻。
如果你想了解怎么使用Xcode設(shè)置斷點(diǎn),可以閱讀這篇文章《Xcode中斷點(diǎn)的威力》

非重寫方法的符號(hào)斷點(diǎn)

非重寫方法的符號(hào)斷點(diǎn)
假設(shè)你想知道 -[MyViewController viewDidAppear:] 什么時(shí)候被調(diào)用婆咸。如果這個(gè)方法并沒有在MyViewController 中實(shí)現(xiàn)竹捉,而是在其父類中實(shí)現(xiàn)的,該怎么辦呢擅耽?試著設(shè)置一個(gè)斷點(diǎn)活孩,會(huì)出現(xiàn)以下結(jié)果:

(lldb) b -[MyViewController viewDidAppear:]
Breakpoint 1: no locations (pending).
WARNING:  Unable to resolve breakpoint to any actual locations.

因?yàn)?LLDB 會(huì)查找一個(gè)符號(hào),但是實(shí)際在這個(gè)類上卻找不到乖仇,所以斷點(diǎn)也永遠(yuǎn)不會(huì)觸發(fā)憾儒。你需要做的是為斷點(diǎn)設(shè)置一個(gè)條件 [self isKindOfClass:[MyViewController class]],然后把斷點(diǎn)放在 UIViewController 上乃沙。正常情況下這樣設(shè)置一個(gè)條件可以正常工作起趾。但是這里不會(huì),因?yàn)槲覀儧]有父類的實(shí)現(xiàn)警儒。

viewDidAppear: 是蘋果實(shí)現(xiàn)的方法训裆,因此沒有它的符號(hào);在方法內(nèi)沒有 self 蜀铲。如果想在符號(hào)斷點(diǎn)上使用 self边琉,你必須知道它在哪里 (它可能在寄存器上,也可能在棧上记劝;在 x86 上变姨,你可以在 $esp+4 找到它)。但是這是很痛苦的厌丑,因?yàn)楝F(xiàn)在你必須至少知道四種體系結(jié)構(gòu) (x86定欧,x86-64,armv7怒竿,armv64)砍鸠。想象你需要花多少時(shí)間去學(xué)習(xí)命令集以及它們每一個(gè)的調(diào)用約定,然后正確的寫一個(gè)在你的超類上設(shè)置斷點(diǎn)并且條件正確的命令耕驰。幸運(yùn)的是爷辱,這個(gè)在 facebook的Chisel 被解決了。這被成為 bmessage

(lldb) bmessage -[MyViewController viewDidAppear:]
Setting a breakpoint at -[UIViewController viewDidAppear:] with condition (void*)object_getClass((id)$rdi) == 0x000000010e2f4d28
Breakpoint 1: where = UIKit`-[UIViewController viewDidAppear:], address = 0x000000010e11533c
LLDB 和 Python
command和expr的組合

建立一個(gè)breakPoint.
使用expr表達(dá)式
用command添加到br上面朦肘。

br com add 1
>expr ...
>continue
>DONE

Thread

thread until (line number)
thread select (thread number)
thread return (value)
frame variable 查看線程相關(guān)變量
bt (thread backtrace) backtrace

Watchpoint

Watchpoint

watchpoint set v (變量名)
跟蹤變量的值的變化托嚣,如果變量地址變成0x0000000000000000就說(shuō)明變量被釋放,指向了nil

image

Chisel

Chisel Tutorial
Chisel

border 標(biāo)記view
mask 標(biāo)記view
pca layer tree
presponder responder chain
pclass class hierachy
vs vs view, change the view hierachy
caflush refresh screen
visualize previews views

pviews Print the recursive view description for the key window.
pvc Print the recursive view controller description for the key window.
fv Find a view in the hierarchy whose class name matches the provided regex.
fvc Find a view controller in the hierarchy whose class name matches the provided regex.
bmessage Set a symbolic breakpoint on the method of a class or the method of an instance without worrying which class in the hierarchy actually implements the method.
wivar Set a watchpoint on an instance variable of an object.

Xcode Debugging Hotkeys

Here is a listing of Xcode hotkeys (related to debugging) we mentioned in this course. Let us know if we missed any!

Show Navigator (?+0)
Show Debug Navigator (?+6)
Show Breakpoint Navigator (?+7)
Show Debug Area (?+Shift+Y)
Open Documentation (?+Shift+0)
Step Over (F6)
Step Into (F7)
Step Out (F8)
Continue (?+Ctrl+Y)
Build (?+B)
Run (?+R)
Activate/Deactivate Breakpoint (?+Y)
Quick Search (?+Shift+O)

Xcode Debugging Hotkeys

Icon Injection Plugin for Xcode

Icon Injection Plugin for Xcode

[圖片上傳失敗...(image-a4381f-1523691381635)]

一個(gè)Xcode的插件厚骗,讓你在改完代碼后無(wú)需重新運(yùn)行Xcode就可以看到效果示启。

將需要調(diào)試的代碼寫到injected這個(gè)方法中,然后在和這個(gè)方法中設(shè)置一個(gè)斷言领舰,使用Ctr + =,即會(huì)停在這個(gè)斷言里夫嗓,每次修改迟螺,使用一下Ctr + =就會(huì)重新注入,釋放斷言就可以看到效果舍咖。

- (void)injected
{
    NSLog(@"I've been injected: %@", self);
}

The plugin can be removed either via Alcatraz, or by running:
rm -rf ~/Library/Application\ Support/Developer/Shared/Xcode/Plug-ins/InjectionPlugin.xcplugin

注意

- (void)injected as an instance method, which gives you the chance to re-update an object with new contexts.
+ (void)injected as a class method, making it possible to update globals with new information
Listening for INJECTION_BUNDLE_NOTIFICATION, allowing other classes to listen out for injection calls, this is useful for providing app level changes.

原理

它通過(guò)解析應(yīng)用程序的生成日志來(lái)確定源文件是如何最后編譯的矩父。用這個(gè)包將重新編譯成一個(gè)bundle,該bundle使用動(dòng)態(tài)加載程序注入應(yīng)用程序∨琶梗現(xiàn)在在bundle中就有兩個(gè)版本窍株,原版本和新的修改版本。修改后的版本是“調(diào)和”在原版本發(fā)生變化攻柠。

LLDB cheatsheet

A cheatsheet for commands and ideas on how to use LLDB.

Getting help

(lldb) help
List all commands and aliases.

(lldb) help po
Get help documentation for po (expression) command.

(lldb) help break set
Get help documentation for breakpoint set.

(lldb) apropos step-in
Search through help documentation containing step-in.

Finding code

(lldb) image lookup -rn UIAlertController
Look up all code containing UIAlertController that's compiled or loaded into an executable.

(lldb) image lookup -rn (?i)hosturl
Case insensitive search for any code that contains "hosturl".

(lldb) image lookup -rn 'UIViewController\ set\w+:\]'
Look up all setter property methods UIViewController implements or overrides.

(lldb) image lookup -rn . Security
Look up all code located within the Security module.

(lldb) image lookup -a 0x10518a720
Look up code based upon address 0x10518a720.

(lldb) image lookup -s mmap
Look up code for the symbol named mmap.

Breakpoints

(lldb) b viewDidLoad
Creates a breakpoint on all methods named viewDidLoad for both Swift and Objective-C.

(lldb) b setAlpha:
Creates a breakpoint on either the setAlpha: Objective-C method or the setter of the Objective-C alpha property.

(lldb) b -[CustomViewControllerSubclass viewDidLoad]
Creates a breakpoint on the Objective-C method [CustomViewControllerSubclass viewDidLoad].

(lldb) rbreak CustomViewControllerSubclass.viewDidLoad
Creates a regex breakpoint to match either an Objective-C or Swift class CustomViewControllerSubclass which contains viewDidLoad. Could be Objective-C - [CustomViewControllerSubclass viewDidLoad] or could be Swift ModuleName.CustomViewControllerSubclass.viewDidLoad () -> ().

(lldb) breakpoint delete
Deletes all breakpoints.

(lldb) breakpoint delete 2
Deletes breakpoint ID 2.

(lldb) breakpoint list
List all breakpoints and their IDs.

(lldb) rbreak viewDid
Creates a regex breakpoint on .viewDid..

(lldb) rbreak viewDid -s SwiftRadio
Creates a breakpoint on .viewDid., but restricts the breakpoint(s) to the SwiftRadio module.

(lldb) rbreak viewDid(Appear|Disappear) -s SwiftHN
Creates a breakpoint on viewDidAppear or viewDidDisappear inside the SwiftHN module.

(lldb) rb "\-\[UIViewController\ set" -s UIKit
Creates a breakpoint on any Objective-C style breakpoints containing - [UIViewController set within the UIKit module.

(lldb) rb . -s SwiftHN -o
Create a breakpoint on every function in the SwiftHN module, but remove all breakpoints once the breakpoint is hit.

(lldb) rb . -f ViewController.m
Create a breakpoint on every function found in ViewController.m.

Expressions

(lldb) po "hello, debugger"
Prints "hello, debugger" regardless of the debugging context.

(lldb) expression -lobjc -O -- [UIApplication sharedApplication]
Print the shared UIApplication instance in an Objective-C context.

(lldb) expression -lswift -O -- UIApplication.shared
Print the shared UIApplication instance in a Swift context.

Creates a breakpoint on getenv, executes the getenv function, and stops at the beginning of the getenv function.
(lldb) b getenv
(lldb) expression -i0 -- getenv("HOME")
raywenderlich.com 361
Advanced Apple Debugging & Reverse Engineering Appendix A: LLDB Cheatsheet (lldb) expression -u0 -O -- [UIApplication test]
Don't let LLDB unwind the stack if you’re executing a method that will cause the program to crash.
Declares a global NSString* called globalString. (lldb) expression -g -O -lobjc -- [NSObject new]
Debug the debugger that's parsing the [NSObject new] Objective-C expression.
Stepping
(lldb) thread return false
Return early from code with false.
Step in.
Step over.
Step out of a function.
Step in if about to execute a function. Step an assembly instruction otherwise.
GDB formatting
(lldb) p/x 128
Print value in hexadecimal.
(lldb) expression -p -- NSString *globalString = [NSString
stringWithUTF8String: "Hello, Debugger"];
(lldb) po globalString
Hello, Debugger
(lldb) thread step-in
(lldb) s
(lldb) thread step-over
(lldb) n
(lldb) thread step-out
(lldb) finish
(lldb) thread step-inst
(lldb) ni
raywenderlich.com 362
Advanced Apple Debugging & Reverse Engineering
Appendix A: LLDB Cheatsheet
(lldb) p/d 128
Print value in decimal.
(lldb) p/t 128
Print value in binary.
(lldb) p/a 128
Print value as address.
(lldb) x/gx 0x000000010fff6c40
Get the value pointed at by 0x000000010fff6c40 and display in 8 bytes. (lldb) x/wx 0x000000010fff6c40
Get the value pointed at by 0x000000010fff6c40 and display in 4 bytes.
Memory
(lldb) memory read 0x000000010fff6c40
Read memory at address 0x000000010fff6c40.
Grab an instance of a remote file and write it to /tmp/file on your computer.
Registers & assembly
(lldb) register read -a
Display all registers on the system.
(lldb) register read rdi rsi
Read the RSI and the RDI register in x64 assembly. (lldb) register write rsi 0x0
Set the RSI register to 0x0 in x64 assembly. (lldb) register write rflags $rflags ^ 64
(lldb) po id $d = [NSData dataWithContentsOfFile:@"..."]
(lldb) mem read (uintptr_t)[$d bytes] (uintptr_t)[$d bytes] + (uintptr_t)[$d length] -r -b -o /tmp/file
raywenderlich.com 363
Advanced Apple Debugging & Reverse Engineering Appendix A: LLDB Cheatsheet
Toggle the zero flag in x64 assembly (augment if condition logic).
(lldb) register write rflags $rflags | 64
Set the zero flag (set to 1) in x64 assembly (augment if condition logic).
(lldb) register write rflags $rflags & ~64
Clear the zero flag (set to 0) in x64 assembly (augment if condition logic).
(lldb) register write pc $pc+4
Increments the program counter by 4.
(lldb) disassemble
Display assembly for function in which you’re currently stopped.
(lldb) disassemble -p
Disassemble around current location; useful if in the middle of a function.
(lldb) disassemble -b
Disassemble function while showing opcodes; useful for learning what is responsible for what.
(lldb) disassemble -n '-[UIViewController setTitle:]'
Disassemble the Objective-C -[UIViewController setTitle:] method. (lldb) disassemble -a 0x000000010b8d972d
Disassemble the function that contains the address 0x000000010b8d972d.
Modules
(lldb) image list
List all modules loaded into the executable's process space.
(lldb) image list -b
Get the names of all the modules loaded into the executable's process space.
(lldb) process load /Path/To/Module.framework/Module
Load the module located at path into the executable's process space.

我的debug速查表(入門級(jí))My debug cheatsheet

我的debug速查表(入門級(jí))My debug cheatsheet

debug cheetsheet
common
查找進(jìn)程:

ps aux | grep /App
ps -e | grep /Applications
查找文件:

grep -r ToBeFind /System/Library/
分離fat binary

lipo -thin armv7 WeChat.decrypted -output WeChat_armv7.decrypted
lipo -thin armv64 xxx.decrypted -output xxx_arm64.decrypted
class dump

class-dump --list-arches AlipayWallet.decrypted

class-dump -S -s -H WeChat_armv7.decrypted -o dumparmv7
class-dump -s -S -H --arch armv7 AlipayWallet.decrypted -o dumpAlipay
lldb
參考 
- https://github.com/iosre/iOSAppReverseEngineering43
- http://objccn.io/issue-19-2/27

幫助

help frame
打印UI結(jié)構(gòu)

po [[[UIWindow keyWindow] rootViewController] _printHierarchy]    (iOS 8)
po [[UIWindow keyWindow] recursiveDescription]
棧信息

bt (backtrace)
bt all (all threads)
objc_msgSend 參數(shù)打印

po $r0
p (char*)$r1
p (SEL)$r1
返回地址

p/x $lr
斷點(diǎn)

br s -a 0x0023234f 
breakpoint set -F "-[NSArray objectAtIndex:]"

br s -a 0x02107730+0x000ab000 -c '(BOOL)[(NSString *)$r2 isEqualToString:@"snakeninny"]'

b ptrace
列舉模塊

image -o -f
lldb基礎(chǔ)命令

c
n
s
frame info
expr

thread return
breakpoint command add 1
遠(yuǎn)程調(diào)試

debugserver *:1234 -a AlipayWallet
debugserver -x backboard *:1234 /var/mobile/Containers/Bundle/Application/9DB7CE45-3B4C-42A3-9D4D-49A3A5122903/AlipayWallet.app/AlipayWallet
lldb連接遠(yuǎn)程調(diào)試

(lldb) process connect connect://192.168.199.164:1234
lldb expr例子

(lldb) expr char *$str = (char *)malloc(8)
(lldb) expr (void)strcpy($str, "munkeys")
(lldb) expr $str[1] = 'o'
(char) $0 = 'o'
(lldb) p $str
(char *) $str = 0x00007fd04a900040 "monkeys"

(lldb) x/4c $str
(lldb) x/1w `$str + 3`
(lldb) expr (void)free($str)

(lldb) expr id $myView = (id)0x7f82b1d01fd0
(lldb) expr (void)[$myView setBackgroundColor:[UIColor blueColor]]
(lldb) expr (void)[CATransaction flush]

(lldb) po [$myButton allTargets]

(lldb) p (ptrdiff_t)ivar_getOffset((struct Ivar *)class_getInstanceVariable([MyView class], "_layer"))
觀察點(diǎn)

(lldb) watchpoint set expression -- (int *)$myView + 8
arm64

param1 $x0
param2 $x1

po $x0
p (char*)$x1
cycript
參考: http://www.cycript.org/manual/17

開始

cycript -p BinaryName
打印UI結(jié)構(gòu)

[[UIWindow keyWindow] recursiveDescription].toString()
[[[UIWindow keyWindow] rootViewController] _printHierarchy].toString()
打印沙盒Documents路徑

[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask]
基本使用

cy# [#0xb226710 url]
@"ww4fd1rfRDShBo_4K6rqfwAAACMAAQED"

cy# c = #0x1752d8c0
cy#"<FavAudioPlayerController: 0x1752d8c0; frame = (0 0; 290 60); autoresize = W; layer = <CALayer: 0x172dc2b0>>"
cy# c->m_audioInfo
cy#"<FavAudioInfo: 0x172b2a30>"
cy# c->m_audioInfo.m_nsAudioPath
linker
-Wl,-sectcreate,__RESTRICT,__restrict,/dev/null
into Other link flag
Anti
iHex replace RESTRICT , restrict
ldid -S AppName
AppSync
Info.plist
輸出bundle id

/var/mobile/Containers/Bundle/Application/9DB7CE45-3B4C-42A3-9D4D-49A3A5122903/AlipayWallet.app root# cat Info.plist | grep com.
    <string>com.alipay.iphoneclient</string>
dumpdecrypted
https://github.com/stefanesser/dumpdecrypted

例子

scp -P 2222 Security/dumpdecrypted-master/dumpdecrypted.dylib root@localhost:/var/mobile/Containers/Data/Application/BA2644DB-450F-4DB0-A71F-A38F65488A48/Documents/

scp ~/sec/dumpdecrypted-master/dumpdecrypted.dylib root@192.168.199.164:/var/mobile/Containers/Data/Application/72AB36DD-2E9B-47C0-9695-099235E40C3C/Documents/
dumpdecrypted.dylib

everettjfs-iPhone:/var/mobile/Containers/Data/Application/72AB36DD-2E9B-47C0-9695-099235E40C3C/Documents root# DYLD_INSERT_LIBRARIES=dumpdecrypted.dylib /var/mobile/Containers/Bundle/Application/2DAD493D-6275-4CED-8242-BDEF27F36740/AlipayWallet.app/AlipayWallet
theos
https://github.com/theos/theos3

開始

everettjf@e WeChatVoiceSaver (master)]$ ~/sec/theos/bin/nic.pl
chisel
參考:https://github.com/facebook/chisel

usbmuxd
https://cgit.sukimashita.com/usbmuxd.git/snapshot/usbmuxd-1.0.8.tar.gz2
https://cgit.sukimashita.com/usbmuxd.git/3
First:

cd python-client 
python tcprelay.py -t 22:2222
Then:

ssh root@localhost -p 2222

參考

The Debugging Process

Advanced Apple Debugging & Reverse Engineering

Debugging in Xcode2012

What's New in LLDB 2015

LLDB

小笨狼與LLDB的故事

lldb.llvm.org

Chisel

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末球订,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子瑰钮,更是在濱河造成了極大的恐慌冒滩,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,602評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件浪谴,死亡現(xiàn)場(chǎng)離奇詭異开睡,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)苟耻,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門篇恒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人凶杖,你說(shuō)我怎么就攤上這事婚度。” “怎么了官卡?”我有些...
    開封第一講書人閱讀 152,878評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)醋虏。 經(jīng)常有香客問我寻咒,道長(zhǎng),這世上最難降的妖魔是什么颈嚼? 我笑而不...
    開封第一講書人閱讀 55,306評(píng)論 1 279
  • 正文 為了忘掉前任毛秘,我火速辦了婚禮,結(jié)果婚禮上阻课,老公的妹妹穿的比我還像新娘叫挟。我一直安慰自己,他們只是感情好限煞,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,330評(píng)論 5 373
  • 文/花漫 我一把揭開白布抹恳。 她就那樣靜靜地躺著,像睡著了一般署驻。 火紅的嫁衣襯著肌膚如雪奋献。 梳的紋絲不亂的頭發(fā)上健霹,一...
    開封第一講書人閱讀 49,071評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音瓶蚂,去河邊找鬼糖埋。 笑死,一個(gè)胖子當(dāng)著我的面吹牛窃这,可吹牛的內(nèi)容都是我干的瞳别。 我是一名探鬼主播,決...
    沈念sama閱讀 38,382評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼杭攻,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼祟敛!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起朴上,我...
    開封第一講書人閱讀 37,006評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤垒棋,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后痪宰,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體叼架,經(jīng)...
    沈念sama閱讀 43,512評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,965評(píng)論 2 325
  • 正文 我和宋清朗相戀三年衣撬,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了乖订。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,094評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡具练,死狀恐怖乍构,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情扛点,我是刑警寧澤哥遮,帶...
    沈念sama閱讀 33,732評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站陵究,受9級(jí)特大地震影響眠饮,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜铜邮,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,283評(píng)論 3 307
  • 文/蒙蒙 一仪召、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧松蒜,春花似錦扔茅、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至惊楼,卻和暖如春萤晴,著一層夾襖步出監(jiān)牢的瞬間吐句,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工店读, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留嗦枢,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,536評(píng)論 2 354
  • 正文 我出身青樓屯断,卻偏偏與公主長(zhǎng)得像文虏,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子殖演,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,828評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • LLDB的Xcode默認(rèn)的調(diào)試器氧秘,它與LLVM編譯器一起,帶給我們更豐富的流程控制和數(shù)據(jù)檢測(cè)的調(diào)試功能趴久。平時(shí)用Xc...
    CoderSC閱讀 1,346評(píng)論 0 2
  • iOS調(diào)試之LLDB Xcode內(nèi)嵌了LLDB控制臺(tái)丸相,在Xcode代碼編輯區(qū)的下方。shift + cmd + y...
    comst閱讀 1,457評(píng)論 0 3
  • LLDB的Xcode默認(rèn)的調(diào)試器彼棍,它與LLVM編譯器一起灭忠,帶給我們更豐富的流程控制和數(shù)據(jù)檢測(cè)的調(diào)試功能。平時(shí)用Xc...
    小笨狼閱讀 20,432評(píng)論 31 187
  • [轉(zhuǎn)]淺談LLDB調(diào)試器文章來(lái)源于:http://www.cocoachina.com/ios/20150126/...
    loveobjc閱讀 2,484評(píng)論 2 6
  • 文/Joy_Winslet 藍(lán)天座硕,白云 烈日弛作,狂風(fēng) 遠(yuǎn)山樓宇 清清眼眸中 不覺匆匆 卻道歲月不與那時(shí)同
    Joy_Winslet閱讀 274評(píng)論 1 5