LLDB全稱是Low Level Debugger,並非low的調試器,而是輕量級的高性能調試器,xcode默認內置了它,所以咱們不須要再本身安裝。筆者最近也是系統的學習了LLDB的用法,在此以前就用過p和po
,哈哈😄。本篇文章主要爲了將最近學習的LLDB記錄並總結,加深記憶並方便之後查找。git
另外,本篇文章主要有兩部分,一個是LLDB的基礎用法,另外一個就是對基礎LLDB使用插件進行擴展。express
首先就來介紹一下這幾個經常使用命令之間的關係吧。 先看看expression
指令。 xcode
expression
指令主要有如下做用:
expression a = 100
,一樣這裏你能夠試試expression self.view.backgroundColor = [UIColor redColor]
,也是能修改背景顏色的。$
符號定義和使用lldb變量,如:expression int $b = 99
。多是p太容易讓人聯想到print
了,不少人都會認爲p是print的縮寫,po是print object的縮寫
,事實上並非這樣。
p 和 print
其實都是expression --
的縮寫,可使用help
指令查看。 bash
po
也並非print object(本來也就沒這個寫法)
的縮寫,而是expression -O --
的縮寫,一樣可使用help
指令查看。 服務器
help expression
看看
expression -O --
是什麼意思,以下,能夠看到
-O
表明的是對象的
description(描述)
,即打印出變量的描述。
斷點調試在平常開發中都常常用到,而且在xcode中咱們也可以很輕易的設置、禁用、刪除斷點。下面就來看看如何使用LLDB達到而且超越界面化斷點。微信
經常使用設置斷點的參數及表明的意義。app
縮寫 | 全稱 | 意義 |
---|---|---|
-f | --file | 文件名稱 |
-l | --line | 行數 |
-n | --name | 方法名 |
-S | --selector | SEL |
-r | --func-regex | 方法正則 |
// 舉例
breakpoint set -f ViewController.m -l 28
複製代碼
click1:
的方法設置斷點。breakpoint set -n click1:
複製代碼
click2:
的方法設置斷點。breakpoint set -S click2:
複製代碼
click
的地方設置斷點。breakpoint set -r click
複製代碼
效果以下: curl
能夠看到一次性設置了103個地方,顯然想要的不是這樣。條件拼接,和第一個例子那樣。ViewController.m
文件中包含click
的地方設置斷點。breakpoint set -f ViewController.m -r click
複製代碼
breakpoint set
雖然在拼寫時lldb會提示,但感受仍是太長了,怎麼辦?
直接使用b
便可。 函數
// 縮寫:br list
breakpoint list
複製代碼
這裏須要注意如下,因爲這三個斷點是使用一條語句設置的,所以它們三個會被分到同一個斷點組裏面。 oop
這一步就至關於界面操做中,讓斷點顏色變半透明。
代碼設置以下:// 設置斷點14.1無效
br disable 14.1
// 一樣,將無效斷點設置爲有效
br enable 14.1
複製代碼
br delete 14.3
複製代碼
能夠看到,14.3並無被刪除,而只是被設置爲了無效。緣由就是14.3屬於14這個組,不能只刪除一個,要刪必須將所有都刪掉。
是否是感受很666?
其實這些東西基本上用不到,哈哈哈。
正向開發中可使用xcode提供的界面操做設置和刪除斷點。
而在逆向中,根本就獲取不到這些符號(類名,文件名,方法名等)。
不信?看看下圖:
上面說了,在逆向中,因爲沒法獲取到符號,是沒法直接經過符號設置斷點的,而咱們還須要使用斷點怎麼辦?下內存斷點。
這裏在24行的斷點處,獲取了_name
指針的地址,而後經過
watchpoint set expression 0x000000014b80b880
複製代碼
給_name
變量設置了一個內存斷點,接下來c--->continue
過掉斷點,點擊按鈕1,在_name = @"abc";
語句調用時,因_name
指向的空間變化了,就會打印出old value
和new value
。
variable
,效果是同樣的,入下:
這裏是有點取巧了,變量的內存地址也是直接經過符號獲取的,而且這裏也只是演示了給變量打內存斷點,那麼如何給方法打內存斷點呢?
假設我如今要給click2:
方法打個斷點,那麼就須要這樣計算:
上面咱們查看MachO
文件的ASLR
時使用了這個命令。這裏的image不是圖片的意思,而是鏡像。
能夠理解爲每個MachO
都是一個image
,主程序是一個image
,主程序連接的每個動態庫也各自是一個image
。
image list
就是打印出App
中所有的image
信息,每一個image
信息的那個地址就是這個image
在內存中的首地址,也即這個image
的ASLR
。
bt命令是用來查看函數調用棧的,以下,我在click1:
中調了click2:
,click2:
中又調用了click3:
,再在click3:
中設置一個斷點,點擊按鈕1
,輸入bt
命令,以下:
frame select [調用棧的編號]
複製代碼
查看該調用棧的詳細信息,包括調用者的內存地址,調用的方法,參數的內存地址等。
在此基礎上,還可以使用up
和
down
命令查看臨近的調用棧信息。
這個就簡單了,以下圖:
上面記錄的都是xcode自帶的lldb所具備的功能,接下來要說的是使用插件對lldb進行擴展,使得lldb更簡單,更強大。
對於chisel
的安裝,最方便的仍是使用Homebrew
安裝了,使用mac電腦,安裝一個Homebrew
是很是有用的,不過這個玩意由於是國外的服務器,因此安裝更新都特別慢,甚至很是容易出錯,一旦出錯就要重來。對此,咱們可使用國內的源。
這裏提供一種使用國內源進行安裝的方法,終端執行下面的語句便可。若是使用的不是zsh,那麼能夠嘗試將zsh改爲bash。
/bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)"
複製代碼
安裝完Homebrew
以後,直接終端下面的命令便可安裝chisel。
brew install chisel
複製代碼
完成後在/Users/[username]/.lldbinit
文件裏面添加一句(沒有就建立一個文件)。
command script import /usr/local/Cellar/chisel/2.0.0/libexec/fblldb.py
複製代碼
安裝完chisel以後,能夠來嘗試一下chisel對lldb的擴展。
遞歸獲取所有的視圖類對象,而且按照視圖的層級結構打印出來。
打印當前所有的控制器對象及層級關係。這裏代碼進行來一點修改,點擊屏幕空白時跳轉到NextViewController
。
ViewController
被
NextViewController
蓋住了,能夠看到控制器對象的
state
,
ViewController 的 state 是 disappeared
。
用來刷新UI,在動態調試時,咱們可能會修改UI控件的佈局,此時直接使用caflush
便可刷新視圖。
f-->find
,這兩個命令是用來查找view
和ViewController
的。
這個就比較厲害了,直接輸入taplog,而後你會發現程序正常運行了,此時點擊任意一個按鈕,那麼就會打印出點擊的這個按鈕的信息。
這個對於逆向調試是很是有幫助的,直接定位到點擊的那個控件的內存地址。有了內存地址,什麼都好辦了。打印出responder響應鏈。
打印對象所屬的類的繼承關係。
經過按鈕的內存地址,直接找到按鈕響應的actions。
打印對象所屬類的所有方法以及屬性。相似於class-dump
的功能。
讓內存地址對應的控件在手機上閃爍一下。
讓內存地址對應的控件變成半透明的紅色,而且進入一個編輯模式,使用
還有其餘的一些功能,使用help
命令能夠進行查看。
這篇文章主要記錄了