在上篇文章從fishhook看runtime,hook系統C函數中已經提到了利用LLDB的部分命令。在咱們玩逆向的時候在大多數時候實際上是拿不到源碼的。因此瞭解一些LLDB來輔助我對別人APP的學(破)習(壞),是很是有必要的。html
自從開始玩逆向,老是會有一些大佬給我發一些轉帳信息(爲何不是發紅包?紅包金額有限制,拿不出手),金額還挺大。 都是相似於這樣的。
python
那麼道友們想不想都收到這樣的紅包呢?看完這篇文章,你就能夠。若是沒有人轉給你,評論區告訴我,我給你轉,說到作到!git
廢話很少說,這篇文章內容很簡單,很是容易理解,可是須要記的東西比較多,理財師強烈推薦點個當心心,以備不時之需 O(∩_∩)O哈哈~。github
今天的DEMO也比較簡單,能夠在點擊這裏下載到: LLDB正則表達式
本文將介紹的內容以下:express
默認內置於Xcode中的動態調試工具。標準的 LLDB 提供了一組普遍的命令,旨在與老版本的 GDB 命令兼容。 除了使用標準配置外,還能夠很容易地自定義 LLDB 以知足實際須要。bash
命令格式以下微信
<command> [<subcommand> [<subcommand>...]] + <action> + [-options [option-value]] + [argument [argument...]]
複製代碼
[]
表示命令是可選的,能夠有也能夠沒有<command>
(命令)和<subcommand>
(子命令):LLDB
調試命令的名稱。命令和子命令按層級結構來排列:一個命令對象爲跟隨其的子命令對象建立一個上下文,子命令又爲其子命令建立一個上下文,依此類推。<action>
:咱們想在前面的命令序列的上下文中執行的一些操做。<options>
:行爲修改器(action modifiers)。一般帶有一些值。<argument>
:根據使用的命令的上下文來表示各類不一樣的東西。The full lldb command names are often long, but any unique short form can be used. Instead of "breakpoint set", "br se" is also acceptable. 通常lldb的命令會很長,可是隻要可以想出足夠斷,而且又能表明惟一性的縮寫,那麼縮寫命令也是同一輩子效的如:
breakpoint set
==br se
app
LLDB的全部命令在 LLVM官網或者Apple官網 均可以查詢到。筆者會在這篇文章中列舉一些比較經常使用的命令。ide
命令名稱 | 命令參樣例 |
---|---|
使用名稱設置斷點 | breakpoint set --name main |
使用內存地址設置斷點 | breakpoint -a 0xXXXXXXXX |
刪除斷點 | breakpoint delete 1 |
使斷點失效/生效 | breakpoint disable/enable 2 |
查看全部斷點 | breakpoint list |
OC中全部命名中包含爲Test4的方法設置斷點 | breakpoint set -r Test4 |
隨意上兩張樣式圖:
附帶一張官網截圖,這些命令均可以在 這 找到
命令名稱 | 命令參樣例 |
---|---|
給某一個斷點增長命令 | breakpoint command add 1 |
查看全部斷點命令 | breakpoint command list |
刪除斷點命令 | breakpoint command delete 1 |
使某個斷點命令生效/失效 | breakpoint command enable/disable |
給某一個斷點增長命令 | breakpoint command delete |
給某一處斷點加上一段代碼,使其每次被斷住的時候均可以自動執行終端代碼,以下圖:
expression
就是執行代碼的命令,也就是經常使用的p
,按照官網所說的縮寫惟一性原則e
、expr
,也是能夠的。 如圖:
命令名稱 | 命令參樣例 |
---|---|
查看當前全部堆棧 | bt |
返回上一步堆棧 | up |
查看某一條堆棧 | frame select 1 |
查看當前堆棧的參數 | frame variable |
堆棧回滾到上一條 | thread return |
程序繼續執行 | c |
單步下一步 | n |
進入下一個函數(方法) | s |
彙編級別的單步下一步 | ni |
彙編級別的進入下一個函數(方法) | si |
一樣是一張樣式圖:
某個屬性地址只要有改變,就觸發斷點。至關於對某個屬性設置了KVO。
命令名稱 | 命令參樣例 |
---|---|
直接觀察一個變量 | watchpoint set variable global_var |
直接觀察一個變量的地址 | watchpoint set expression -- 0xxxxxx |
刪除斷點 | watchpoint delete 1 |
使斷點失效/生效 | watchpoint disable/enable 2 |
查看全部斷點 | watchpoint list |
命令名稱 | 命令參樣例 |
---|---|
查看工程中使用的庫(包括MachO本身) | image list |
查找可執行文件或共享庫的原始地址 | image lookup --address 0x0000000100000de0 |
輸出NSURL的成員變量及屬性信息。 | image lookup --type NSURL |
導出可執行文件和共享庫的全部符號表 | image dump symtab |
給每一個斷點,都執行一段代碼。
命令名稱 | 命令參樣例 |
---|---|
增長一個HOOK | target stop-hook add -o "frame variable" |
直接全部HOOK | target stop-hook list |
刪除HOOK | target stop-hook disable 1 |
使HOOK失效/生效 | target stop-hook disable/enable 2 |
命令名稱 | 命令參樣例 |
---|---|
顯示當前線程全部寄存器的值 | register read --all |
將0x01寫入x2寄存器 | register write x2 0x01 |
讀取內存0x0002A8A2D中的的值 | memory read 0x0002A8A2D (縮寫x 0x0002A8A2D ) |
例如:
script print "Here is some text"
複製代碼
LLDB本質上就跟一個程序(或者說進程)同樣,每次啓動LLDB的時候都會主動加載一個初始化文件,這個文件就是.lldbinit
,他的地址位於根目錄下:
~/
複製代碼
若是你的根目錄沒有這個文件,那就只用touch
建立一個吧
// 建立.lldbinit
touch ~/.lldbinit
// 寫入
vi ~/.lldbinit
// 查看
cat ~/.lldbinit
複製代碼
在.lldbinit
中寫入以下代碼
target stop-hook add -o "frame variable"
複製代碼
重啓Xcode,運行工程,在任意一個地方加上斷點。
會發現當斷點斷住的時候,自動執行了frame variable
讀到這就有一個頗有意思的事情了:
.lldbinit
能夠幫咱們預加載部分命令,LLDB
又支持Python語法,那麼是否是能夠將部分Python的代碼封裝起來,再利用.lldbinit
的機制,進而就能夠實現用咱們本身的封裝好的代碼,讓咱們更方便的使用LLDB
?
說幹就幹。
以前咱們使用過命令image list
命令查看,查看App運行後再內存中的首地址(ASLR
),這個地址實際上是加上了pagezero
的值,其實使用命令image list -o
能夠直接查看ASLR
,如圖:
import lldb
import re
# 獲取ASLR偏移地址
def fy_get_ASLR(debugger, command, result, internal_dict):
# 獲取'image list -o'命令的返回結果
interpreter = lldb.debugger.GetCommandInterpreter()
returnObject = lldb.SBCommandReturnObject()
interpreter.HandleCommand('image list -o', returnObject)
output = returnObject.GetOutput();
# 正則匹配出第一個0x開頭的16進制地址
match = re.match(r'.+(0x[0-9a-fA-F]+)', output)
if match:
print match.group(1)
else:
return None
# And the initialization code to add your commands
def __lldb_init_module(debugger, internal_dict):
# 'command script add fy_get_ASLR' : 給lldb增長一個'fy_get_ASLR'命令
# '-f lldbPyDemo.fy_get_ASLR' : 該命令調用了lldbPyDemo文件的fy_get_ASLR函數
debugger.HandleCommand('command script add fy_get_ASLR -f lldbPyDemo.fy_get_ASLR')
print 'The "fy_get_ASLR" python command has been installed and is ready for use.'
複製代碼
一樣的,每次都主動加載lldbPyDemo.py
也有點煩,將其路徑加入.lldbinit
中,便可實現每次自動加載。
LLDB全部開放出來的接口均可以在官方網站中找到,有興趣的同窗能夠研究研究。
Chisel is a collection of LLDB commands to assist in the debugging of iOS apps. Chisel是一個用戶Debug iOS Apps 的LLDB命令集合
以上介紹來自chisel官網。
因爲其支持brew
,安裝使用的方法很簡單:
brew update
brew install chisel
複製代碼
若是本地沒有.lldbinit
文件,先在根目錄建立再打開,不然直接打開
// 建立.lldbinit文件
touch .lldbinit
// 打開.lldbinit文件
open .lldbinit
複製代碼
而後在.lldbinit
文件中追加以下命令
command script import /path/to/fblldb.py
複製代碼
重啓Xcode
便可使用。
如下挑了一些實用的命令:
命令名稱 | 命令描述 | iOS | OS X |
---|---|---|---|
pviews | 打印當前KeyWindow的全部View | Yes | Yes |
pvc | 打印當前KeyWindow的全部VC | Yes | No |
fv | 根據正則表達式打印查找並打印View | Yes | No |
fvc | 根據正則表達式打印查找並打印VC | Yes | No |
show/hide | 在不須要continue的狀況下顯示/隱藏View或者Layer | Yes | Yes |
bmessage | 在類的方法或實例的方法上設置符號斷點,就算沒有實現顯示的實現該剛發,也會觸發。如viewWillAppear這個方法,在當前控制器中沒有實現它,可是又想在調用它的時機觸發中斷。 | Yes | Yes |
wivar | 至關於watchpoint | Yes | Yes |
下圖是pviews和pvc的用例圖:
DerekSelander-LLDB
同chisel
同樣是一個LLDB的腳本集合,大部分功能一致,但DerekSelander-LLDB
有一個很是好用的功能:
sbt
:查看當前堆棧,而且儘量的恢復符號表!
這就很牛逼了,要知道在咱們逆向的過程當中,大部分研究的APP都是已經去符號的!
[站外圖片上傳中...(image-57c79-1554654483282)]
具體使用一樣也能夠參照官網: DerekSelander-LLDB
DerekSelander-LLDB
的安裝過程沒有chisel
那麼花哨,不須要用到brew,安裝過程以下(官網複製的,我就不翻譯了):
一、 To Install, copy the lldb_commands folder to a dir of your choosing.
二、 Open up (or create) ~/.lldbinit
三、 Add the following command to your ~/.lldbinit file: command script import /path/to/lldb_commands/dslldb.py
複製代碼
LLDB既然這麼好用,那麼咱們就利用LLDB來繼續分析一下咱們可愛的微信,O(∩_∩)O哈哈~。
利用以前文章iOS逆向(4)-代碼注入,竊取微信密碼講到的方法,直接利用Xcode將微信運行在手機上。
隨意讓一個小夥伴本身的微信號發一個最大的紅包(0.01元),進入聊天頁面以下圖:
在這個地方斷住程序,進入LLDB的調試頁面。
pviews
,會發現終端打印出了很是多的視圖結構。直接搜索紅包金額
0.01
,找到對應的
Label
,以下圖:
從上圖能夠發現顯示金額的控件是MMUILabel
,很像一個UILabel,並且地址爲0x10e6c7d00
。 在根據LLDB的p
命令執行更改文本的代碼,以下:
p ((UILabel *)0x10e6c7d00).text = @"¥88888.88"
複製代碼
此時的金額只是一個靜態被改變的字符串而已,實際上並不會讓咱們多一分錢或者少一分錢。
在普通的生活中,逆向實際上是一件很是有意思的事情,在增長本身的知識面的同時,也能給予咱們不少的歡樂,想一想看這樣一張截圖往朋友圈一放是否是賊有面子。哈哈,也許你的朋友圈中各類紅包轉帳截圖也是這樣來的呢?尤爲是常常發這樣的轉帳信息的代購們。
這片文章的內容其實很是簡單,首先介紹了一下LLDB的一下基本用法,從而得知其能夠支持Python語法,又有.lldbinit
文件能夠幫咱們自動加載腳本,全部就有了一個簡單的LLDB腳本案例,以後又引出facebook出品的Chiesl
和DerekSelander-LLDB
兩個腳本集合。最後就是利用LLDB進行一些簡單的UI分析和執行簡單的代碼了。
可是,每次使用LLDB都須要斷住程序,體驗不是很好。那是否是有一種能力,可讓程序在正常運行的時候,咱們也能夠對APP進行實時的動態分析呢?
答案是確定的,神器Cycript
就是這麼一個存在,在下一篇文章中,將會圍繞Cycript
講解一些逆向工程中很是很是重要的內容!