iOS應用安全7 -- LLDB動態調試

前言

LLDB全稱是Low Level Debugger,並非low的調試器,而是輕量級的高性能調試器,xcode默認內置了它,所以咱們不須要再本身安裝。筆者最近也是系統的學習了LLDB的用法,在此以前就用過p和po,哈哈😄。本篇文章主要爲了將最近學習的LLDB記錄並總結,加深記憶並方便之後查找。git

另外,本篇文章主要有兩部分,一個是LLDB的基礎用法,另外一個就是對基礎LLDB使用插件進行擴展。express

基礎LLDB用法

p、po、print、expression

首先就來介紹一下這幾個經常使用命令之間的關係吧。 先看看expression指令。 xcode

expression
從這裏能夠發現, expression指令主要有如下做用:

  1. 打印變量的信息
  2. 執行語句,如:expression a = 100,一樣這裏你能夠試試expression self.view.backgroundColor = [UIColor redColor],也是能修改背景顏色的。
  3. 經過$符號定義和使用lldb變量,如:expression int $b = 99

多是p太容易讓人聯想到print了,不少人都會認爲p是print的縮寫,po是print object的縮寫,事實上並非這樣。
p 和 print其實都是expression --的縮寫,可使用help指令查看。 bash

help

po也並非print object(本來也就沒這個寫法)的縮寫,而是expression -O --的縮寫,一樣可使用help指令查看。 服務器

po
接下來使用 help expression看看 expression -O --是什麼意思,以下,能夠看到 -O表明的是對象的 description(描述),即打印出變量的描述。
expression -O

breakpoint

斷點調試在平常開發中都常常用到,而且在xcode中咱們也可以很輕易的設置、禁用、刪除斷點。下面就來看看如何使用LLDB達到而且超越界面化斷點。微信

設置斷點

經常使用設置斷點的參數及表明的意義。app

縮寫 全稱 意義
-f --file 文件名稱
-l --line 行數
-n --name 方法名
-S --selector SEL
-r --func-regex 方法正則
  1. 在ViewController.m文件的第28行設置斷點。
// 舉例
breakpoint set -f ViewController.m -l 28
複製代碼
  1. 給方法名是click1:的方法設置斷點。
breakpoint set -n click1:
複製代碼
  1. 給SEL是click2:的方法設置斷點。
breakpoint set -S click2:
複製代碼
  1. 給包含click的地方設置斷點。
breakpoint set -r click
複製代碼

效果以下: curl

click
能夠看到一次性設置了103個地方,顯然想要的不是這樣。條件拼接,和第一個例子那樣。

  1. ViewController.m文件中包含click的地方設置斷點。
breakpoint set -f ViewController.m -r click
複製代碼

組合

breakpoint set雖然在拼寫時lldb會提示,但感受仍是太長了,怎麼辦?
直接使用b便可。 函數

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提供的界面操做設置和刪除斷點。
而在逆向中,根本就獲取不到這些符號(類名,文件名,方法名等)。
不信?看看下圖:

微信
由於在逆向中,是沒法獲取符號的,由於可以獲得的文件就只有一個,MachO文件。而在MachO文件中是沒有這些符號的,有的只是地址。

內存斷點

上面說了,在逆向中,因爲沒法獲取到符號,是沒法直接經過符號設置斷點的,而咱們還須要使用斷點怎麼辦?下內存斷點。

這裏在24行的斷點處,獲取了_name指針的地址,而後經過

watchpoint set expression 0x000000014b80b880
複製代碼

_name變量設置了一個內存斷點,接下來c--->continue過掉斷點,點擊按鈕1,在_name = @"abc";語句調用時,因_name指向的空間變化了,就會打印出old valuenew value

內存斷點
除了使用上面那種方法外,還可以使用 variable,效果是同樣的,入下:
variable

這裏是有點取巧了,變量的內存地址也是直接經過符號獲取的,而且這裏也只是演示了給變量打內存斷點,那麼如何給方法打內存斷點呢?
假設我如今要給click2:方法打個斷點,那麼就須要這樣計算:

  1. 先找到ASLR的值。
    ASLR
  2. 使用MachOView或者hooper打開App的MachO文件。
    hooper
    MachOView
  3. 使用ASLR+方法在MachO文件中的地址 = 方法在內存中的地址。
    內存地址
  4. 測試如下是否是真的斷住了click2:方法。點擊按鈕2,發現程序停到了這個方法。斷點設置成功。
    按鈕2

LLDB的其餘經常使用命令

image list

上面咱們查看MachO文件的ASLR時使用了這個命令。這裏的image不是圖片的意思,而是鏡像。
能夠理解爲每個MachO都是一個image,主程序是一個image,主程序連接的每個動態庫也各自是一個image
image list就是打印出App中所有的image信息,每一個image信息的那個地址就是這個image在內存中的首地址,也即這個imageASLR

bt

bt命令是用來查看函數調用棧的,以下,我在click1:中調了click2:,click2:中又調用了click3:,再在click3:中設置一個斷點,點擊按鈕1,輸入bt命令,以下:

bt
能夠看到函數之間的調用關係。而且還可使用

frame select [調用棧的編號]
複製代碼

查看該調用棧的詳細信息,包括調用者的內存地址,調用的方法,參數的內存地址等。

frame
在此基礎上,還可以使用 updown命令查看臨近的調用棧信息。
updown

c,n,s

這個就簡單了,以下圖:

cns

LLDB插件擴展

上面記錄的都是xcode自帶的lldb所具備的功能,接下來要說的是使用插件對lldb進行擴展,使得lldb更簡單,更強大。

chisel

對於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的擴展。

pviews

遞歸獲取所有的視圖類對象,而且按照視圖的層級結構打印出來。

pviews

pvc

打印當前所有的控制器對象及層級關係。這裏代碼進行來一點修改,點擊屏幕空白時跳轉到NextViewController

pvc
由於 ViewControllerNextViewController蓋住了,能夠看到控制器對象的 stateViewController 的 state 是 disappeared

caflush

用來刷新UI,在動態調試時,咱們可能會修改UI控件的佈局,此時直接使用caflush便可刷新視圖。

fv 和 fvc

f-->find,這兩個命令是用來查找viewViewController的。

fv

taplog

這個就比較厲害了,直接輸入taplog,而後你會發現程序正常運行了,此時點擊任意一個按鈕,那麼就會打印出點擊的這個按鈕的信息。

taplog
這個對於逆向調試是很是有幫助的,直接定位到點擊的那個控件的內存地址。有了內存地址,什麼都好辦了。

presponder

打印出responder響應鏈。

pclass

打印對象所屬的類的繼承關係。

pclass

pactions

經過按鈕的內存地址,直接找到按鈕響應的actions。

pactions

methods

打印對象所屬類的所有方法以及屬性。相似於class-dump的功能。

methods

flicker

讓內存地址對應的控件在手機上閃爍一下。

flicker

vs

讓內存地址對應的控件變成半透明的紅色,而且進入一個編輯模式,使用

  • w:定位到當前視圖的父視圖。
  • s:定位到當前視圖的第一個子視圖。
  • a:定位到當前視圖的兄弟視圖的前一個。
  • d:定位到當前視圖的兄弟視圖的後一個。
  • p:打印定位到的視圖的信息。
  • q:退出這個編輯模式。

vs

還有其餘的一些功能,使用help命令能夠進行查看。

總結

這篇文章主要記錄了

  1. xcode自帶的LLDB的使用方法。
  2. 逆向時如何設置斷點。
  3. 使用插件chisel對LLDB進行功能擴展(更利於逆向)。

本文地址

相關文章
相關標籤/搜索