1. 程式人生 > >一步一步用debugserver + lldb代替gdb進行動態除錯(整理與補充)

一步一步用debugserver + lldb代替gdb進行動態除錯(整理與補充)

原文章出處:http://bbs.iosre.com/t/debugserver-lldb-gdb/65/12

*** 以下部分內容摘自《iOS應用逆向工程》第二版,以iOS 8為環境編寫,應該也支援iOS 7,請大家注意。 ***

因為Apple已經棄gdb投lldb,所以隨著我動態除錯的次數越來越頻繁,gdb上一個接一個的bug經常會讓人很惱火。既然蘋果打算建立自己的偵錯程式王國,也投入了財力精力,那我們乾脆也上手lldb玩玩,看看lldb是不是比gdb要更好用:lol:(以下操作在iPhone 5,iOS 8.1上測試,方法同樣適用於arm64。更多內容請參照iphonedevwiki24

一、配置debugserver與

ARMDisassembler.framework

1. 在iOS中安裝debugserver
debugserver執行在iOS上,顧名思義,它作為服務端,實際執行LLDB(作為客戶端)傳過來的命令,再把執行結果反饋給LLDB,顯示給使用者,即所謂的“遠端除錯”。在預設情況下,iOS上並沒有安裝debugserver,只有在裝置連線過一次Xcode,並在Window→Devices選單中新增此裝置後,debugserver才會被Xcode安裝到iOS的“/Developer/usr/bin/”目錄下。

補充 :
首先來配置下裝置上的除錯環境,從xcode的/Developer/Platforms/iPhoneOS.platform/DeviceSupport/

3.2目錄下找到DeveloperDiskImage.dmg檔案,而3.2則是對應的ios裝置上的系統版本,在DeviceSupport目錄下通常會包含如如2所示的版本列表:


圖02
在實際的除錯過程中只需要選擇相應的版本就可以了。在每個目錄下都存在一個DeveloperDiskImage.dmg檔案,用ultraiso開啟這個檔案可以看到如圖3的檔案目錄列表:


圖3
在除錯的過程中需要將整個dmg檔案下的所有目錄和檔案拷貝到裝置上的/Developer目錄下,如圖4所示。這一步可以使用ios的檔案管理工具,或者使用winscp上傳檔案,不建議使用後者,太卡了~,如果使用過xcode開發除錯過程式那麼這個目錄下的所有東西應該都是存在的,可以無需手工複製。



圖4
  1. 幫debugserver減肥
    對照下表,記下裝置的ARM資訊。
    Screen-Shot-2015-03-24-at-6.53.01-PM.png667x645 11.9 KB
    我的iPhone 5對應的ARM是armv7s。將未經處理的debugserver從iOS拷貝到OSX中的“/Users/snakeninny/”目錄下:
snakeninnysiMac:~ snakeninny$ scp root@iOSIP:/Developer/usr/bin/debugserver ~/debugserver

然後幫它減肥:

snakeninnysiMac:~ snakeninny$ lipo -thin armv7s ~/debugserver -output ~/debugserver

注意把這裡的“armv7s”換成你的裝置所對應的ARM。

  1. 給debugserver新增task_for_pid許可權
    下載ent.xml (381 Bytes) 到OSX的“/Users/snakeninny/”目錄,然後執行:
snakeninnysiMac:~ snakeninny$ /opt/theos/bin/ldid -Sent.xml debugserver

注意,此處的ldid27來自joedj,且“-S”選項與“ent.xml”之間是沒有空格的。

補充:ent.xml檔案內容

<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>com.apple.springboard.debugapplications</key>
        <true/>
        <key>get-task-allow</key>
        <true/>
        <key>task_for_pid-allow</key>
        <true/>
        <key>run-unsigned-code</key>
        <true/>
</dict>
</plist>

正常情況下,上面這條命令會在5秒內執行完畢。如果ldid卡住了,執行超時,就換一種方案:下載ent.plist (366 Bytes) 到“/Users/snakeninny/”,然後執行:

snakeninnysiMac:~ snakeninny$ codesign -s - --entitlements ent.plist -f debugserver


補充:實際測試ldid就卡住了,採用第二種方案:codesign通用.ent.plist檔案內容

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/ PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>com.apple.springboard.debugapplications</key>
    <true/>
    <key>run-unsigned-code</key>
    <true/>
    <key>get-task-allow</key>
    <true/>
    <key>task_for_pid-allow</key>
    <true/>
</dict>
</plist>


  1. 將經過處理的debugserver拷回iOS
    將經過處理的debugserver拷回iOS,並新增執行許可權,命令如下:
snakeninnysiMac:~ snakeninny$ scp ~/debugserver [email protected]:/usr/bin/debugserver
snakeninnysiMac:~ snakeninny$ ssh root@iOSIP
FunMaker-5:~ root# chmod +x /usr/bin/debugserver

這裡之所以把處理過的debugserver存放在iOS的“/usr/bin/”下,而沒有覆蓋“/Developer/usr/bin/”下的原版debugserver,一是因為原版debugserver是不可寫的,無法覆蓋;二是因為“/usr/bin/”下的命令無須輸入全路徑就可以執行,即在任意目錄下執行“debugserver”都可啟動處理過的debugserver。

拷貝ARMDisassembler.framework

將DeveloperDiskImage.dmg中的/Library/PrivateFrameworks/ARMDisassembler.framework拷貝到手機上/System/Library/PrivateFrameworks 目錄下。


二、在iOS上用debugserver來attach程序
debugserver + lldb除錯方法跟gdb最大的不同,在於前者是用OSX中的lldb遠端連線debugserver,由debugserver作為lldb和iOS的中轉,在執行命令和返回結果;而後者是gdb直接執行在iOS上。但對於一般的開發者來說,這個區別跟我們沒關係,瞭解一下就好~
在iOS上執行下面的命令來attach程序,其中1234是我們指定的埠號:

debugserver *:1234 -a "SpringBoard"

成功後會顯示:


三、在OSX上用lldb遠端除錯
首先在Terminal中執行lldb,然後輸入以下命令:

process connect connect://iOSIP:1234

注意,這條命令執行耗時比較長,很多讀者可能會以為iOS/OSX死掉了,其實沒有,耐心等一會,看看@iOS應用逆向工程6有沒有重新整理微博,或在論壇裡逛逛吧~
執行成功後會顯示:

Screen Shot 2014-03-19 at 9.54.47 PM.png729x231 19.1 KB

四、獲取ASLR的offset
首先在lldb裡輸入"c"並回車,讓程序繼續執行;lldb有一個gdb沒有的優點,就是可以在程序執行的過程中執行一些命令,這樣就可以有效避免SpringBoard這樣的程序在暫停過久後被WatchDog給kill掉。在lldb裡輸入
image list -o -f

顯示如下圖片:

Screen Shot 2014-03-19 at 10.01.42 PM.png1094x247 35.1 KB

其中第一列[X]是image的序號,不用管;第二列是ASLR的offset(也就是對應image的虛擬記憶體slide);第三列是image的全路徑和slide之後的基地址,也不用管~所以第二列就是我們需要的資訊。

五、在記憶體地址上下斷點





假如我們在SpringBoard這個image的0xb446(在_menuButtonDown:中)處下斷點,則此地址在記憶體中的實際位置是0xb446 + 0x9a000 = 0xa5446,在lldb中對應的命令是:

br s -a 0xA5446

執行成功後顯示:

Screen Shot 2014-03-19 at 10.12.33 PM.png926x39 9.62 KB
值得注意的是,lldb命令裡如果涉及到加法操作,必須要加上單引號,即
br s -a '0x0009a000 + 0xb446'

六、更改暫存器的值
按下home鍵,觸發斷點,顯示如圖:

Screen Shot 2014-03-19 at 10.15.36 PM.png1276x195 20 KB

可以看到,lldb把包括斷點在內的4條指令顯示了出來,方便我們除錯。這裡,我們將r0的值設為0,讓其跳轉到0xa5470(0xb470 + 0x9a000)處。更改r0值的lldb命令是:

register write r0 0

接著”ni“兩次,我們就可以看到程式執行到了0xa5470處,如圖:

Screen Shot 2014-03-19 at 10.22.37 PM.png1277x400 33.3 KB

七、用lldb啟動一個App

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

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

此命令會啟動記事本,並斷在dyld的第一條指令上,如圖所示:

Screen Shot 2014-07-06 at 12.03.50 AM.png728x267 21.3 KB

接下來,在lldb中持續輸入“ni”,直到出現“error: invalid thread”的字樣,如圖所示:

稍等片刻,lldb即會停在程式的第一條指令上,如圖所示:

Screen Shot 2014-07-06 at 12.06.13 AM.png728x252 19 KB

此時我們即已處在程序內部,可以開始一窺究竟啦~
相較attach的半路出家,這種方式更有助於我們從頭除錯一個程式,可以觀察到一些變數的初始化過程。

八、更多lldb命令
經過上面的操作,我們可以看到,lldb還是比較方便的,用慣了gdb而對它不熟悉的朋友可以通過lldb與gdb命令對照表46來熟悉lldb的命令。其實有了上面的幾個操作,我們就可以開始簡單動態分析程式了,相信能把上面六步走通的朋友,已經具備了舉一反三的能力,其他需要用到的功能都可以Google到,當然更歡迎你到論壇裡發帖提問或分享。好了,debugserver + lldb的簡單介紹到此結束,接下來趕緊開啟Terminal,hack起來吧~!

補充:

USB除錯方法

通過wifi除錯很慢,有時候"process connect"命令甚至會失敗。如果你也遇到這樣的情況,你可以通過USB而不是Wifi進行除錯。

1. 首先在你的Mac上下載usbmuxd解壓,並執行:

1 2 3 4 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

2. 這樣所有試圖連結到localhost:1234的連線都會通過USB被重定向到你的iOS裝置的1234埠

  這樣,上面第8步中的process connect命令就可以更改如下:

1 process connect connect://localhost:1234

然後你就可以像在Xcode中一樣用lldb除錯了。

Ref:  

http://iphonedevwiki.net/index.php/Debugserver

相關推薦

debugserver + lldb代替gdb進行動態除錯(整理補充)

原文章出處:http://bbs.iosre.com/t/debugserver-lldb-gdb/65/12 *** 以下部分內容摘自《iOS應用逆向工程》第二版,以iOS 8為環境編寫,應該也支援iOS 7,請大家注意。 *** 因為Apple已經棄gdb投lldb,所以隨著我動態除錯的次數越來越頻繁,

分鐘瞭解“matlab矩陣寫法代替for迴圈”

K>> [xx,yy]=meshgrid(-3:3,-3:3); K>> [email protected](x,y) x^2+y^2; K>> arrayfun(f,xx,yy) ans =     18    13    1

搭建客服系統 (4) 客戶列表 - JS($.ajax)調WCF 遇到的各種坑

clu web operation script ont javascrip -1 mod ima 閱讀目錄 1 創建WCF服務 2 調用WCF 3 配置 4 遇到的各種坑 本文以一個生成、獲取“客戶列表”的demo來介紹如何用js調用wcf,以及遇到的各種問題。

Html5/CSS3做Winform,教你搭建CefSharp開發環境(附JavaScript異步調C#例子,及全部源代碼)上

轉載 界面設計 右鍵 異步 一個 由於 編寫 scrip 調用 本文為雞毛巾原創,原文地址:http://www.cnblogs.com/jimaojin/p/7077131.html,轉載請註明 CefSharp說白了就是Chromium瀏覽器的嵌入式核心,我們用此開發W

【Python實戰】Scrapyd把Scrapy爬蟲部署到騰訊雲

將我們的爬蟲部署到騰訊雲伺服器上面。廢話不多說,我們就來實戰操作吧。 這裡選擇什麼雲服務都是可以的,阿里雲,AWS,騰訊雲,其他雲都是沒有問題的。部署方法基本一樣,這裡為了方便,所以筆者選擇了騰訊雲來做講解。 既然我們選擇了騰訊雲,首先去騰訊雲的官網,註冊登入一下。 點選複製https:

Tensorflow構建卷積神經網路

摘要: 本文主要和大家分享如何使用Tensorflow從頭開始構建和訓練卷積神經網路。這樣就可以將這個知識作為一個構建塊來創造有趣的深度學習應用程式了。 0. 簡介 在過去,我寫的主要都是“傳統類”的機器學習文章,如樸素貝葉斯分類、邏輯迴歸和Perceptron演算法。在過去的

Django寫自己的blog系統 --教你建立屬於你的部落格-1

專案的文章導航: 一:連線 1:新建blog專案 2:配置 3:新建一個首頁 二: 1.準備環境,在win7 64位下進行開發 軟體 pycharm 這些能夠使你的開發更專注, 2,python3.6 pip django1.11.16 pymysql mysql5.6 3,開始

arduinoProcessing實現雷達掃描(1)

平時,我們在軍事題材的電影中看到雷達掃描的畫面,感覺很酷很炫,實際,對於今天的我們來說這個效果要實現並不是很難,只不過步驟較多而已。所以我們需要一步一步來實現,也就有了我這篇(或者要用幾篇的篇幅來實現)《一步一步用arduino與Processing實現雷達掃描》。 首先把我們要實現

教你 Vue.js + Vuex 製作專門收藏微信公眾號的 app

寫於 2016.06.30 只看不讚,或者只收藏不讚的都是耍流氓,放學別走,我找我哥收拾你們。 專案地址:github.com/jrainlau/we… 下載&執行 git clone [email protected]:jra

Canvas寫一個貪吃蛇

之前在慕課網看了幾集Canvas的視訊,一直想著寫點東西練練手。感覺貪吃蛇算是比較簡單的了,當年大學的時候還寫過C語言字元版的,沒想到還是遇到了很多問題。 最終效果如下(圖太大的話 時間太長 錄製gif的軟體有時限…) 首先定義遊戲區域。貪吃蛇的螢幕上只有蛇身和蘋果兩種元素,而這兩個都可以用正方形格子

【Visual C++】遊戲開發筆記二十九 教你優雅的Direct3D11程式碼畫一個三角形

                本系列文章由zhmxy555(毛星雲)編寫,轉載請註明出處。這個demo演示的效果是用Direct3D11在螢幕上渲染一個三角形,當然是通過這個demo進一步鞏固和學習Direct3D11,而不是單單為了畫一個三角形這麼簡單。正如之前所說,這個demo是建立在筆記二十八中講解的

arduinoProcessing實現雷達掃描(3)

前面我們已經比較完整的實現了processing的雷達掃描效果,軟體部分只剩下目標掃描點的類封裝、掃描線的拖影效果及硬體部分的實現。 其中類的封裝,在我的博文《Processing摸索前行(4)》中有過比較詳細的介紹。但我們這裡具體處理掃描點的方法有必要詳細介紹一下。 我們首先明確一

教你PHP+MySql搭建網站 No.0 準備工作

新開一個系列教程吧,這次是講如何用PHP+MySQL搭建網站。 之前一直有想過搭建自己的個人網站,然後上週通過阿里雲申請的域名和空間都通過稽核了,於是就開始研究如何用PHP+MYSQL搭建網站,研究了差不多兩週,總算搞定了一個小型的blog類的網站。當然,整個過程是通過學習

vue-cli vuex搭建一個筆記應用()

寫這篇文章是因為想學習一下vuex,說實話,一直在用vue,但是它核心的vuex卻還沒有用過。 https://segmentfault.com/a/1190000005015164 這篇文章寫得很好,就是有點舊了,那個時候是1年前寫的吧。 現在我將用vu

九之再續:教你c語言實現sift演算法、下

                      教你一步一步用c語言實現sift演算法、下作者:July、二零一一年三月十二日出處:http://blog.csdn.net/v_JULY_v。參考:Rob Hess維護的sift 庫環境:windows xp+vc6.0條件:c語

如何DDD設計一個電商網站()—— 先理解核心概念

文章內容 一、前言 DDD(領域驅動設計)的一些介紹網上資料很多,這裡就不繼續描述了。自己使用領域驅動設計摸滾打爬也有2年多的時間,出於對知識的總結和分享,也是對自我理解的一個公開檢驗,介於部落格園這個平臺也算是對DDD的推廣盡了一份綿薄之力。一開始接觸這個東西是在2014年,真的覺得像

教你OpenGL寫遊戲——前言

關於這套教程 這是一個系列的教程。在這套教程裡,我將會把之前用OpenGL+Qt做過的一款遊戲和大家分享,並且從頭到尾一步步分析整個遊戲的實現過程和架構設計。 關於寫這些東西的目的,我想大概有三點吧:其一是想把自己寫過的這個遊戲重新梳理一遍,認真重構重構,真

教你PHP+MySql搭建網站 No.1 主頁&資料庫連線

這一章節我們來看使用者輸入網頁後的主介面。 一般來說,預設主頁都是index點xxx,比如 index.php, index.html , index.jsp等等。我們來看一下我們的index.php吧 index.php 提醒: 在<?php?>的兩端,不要

騰訊雲伺服器搭建一個tomcat專案,並用外網通過ip訪問專案

搭建了一天的專案,陸陸續續也遇到一些小問題不過最後還是成功解決了,接下來把這個過程記錄下來。首先呢,是因為騰訊雲伺服器的一波廣告一個月才10塊錢,所以毫不猶豫買下來了也就是這樣的伺服器,還不錯接下來呢就是配置這個伺服器1.安裝java JDK並配置環境參考:http://bl

教你將java程式碼打成jar包bat批處理命令執行

1.背景 前不久接到一個朋友的請求,讓我幫他做個小程式處理一些工作上的事情,好歹作為java開發工程師,這點忙還是要幫的.不過馬上遇到了一個問題,平時我們都是用IDEA或者eclipse執行的程式碼, 或者是web專案用tomcat執行的, 他現在這種小白肯定