iOS逆向工程實戰篇

1. 備忘錄增長字數統計功能

實現的功能:

在導航欄上實時顯示備忘錄的字數.數組

功能分析:

  • 編輯界面是一個View, 能夠經過nextResponder找到它的Controller, 再經過Controller訪問備忘錄數據, 能夠在初始化編輯界面的時候初始化標題字數.xcode

  • 咱們要作到標題字數隨着內容的編輯而改變. 因此咱們要實時注意protocol中的方法有沒有這類方法.服務器

  • 最後經過Controller的title屬性設置標題.app

功能實現:

  1. 首先定位備忘錄的可執行文件

關閉無用App, 打開備忘錄, ssh到iOS, 利用ps命令看看當前的進程. 由於是系統App, 因此在/Applications/路徑下查詢, 以便咱們查找.ssh

ps -e | grep /Applications/
複製代碼

能夠看到MobileNotes這個App貌似是咱們的備忘錄. 咱們驗證一下, 經過killall掉它, 看看打開的備忘錄會不會關閉. 經過驗證MobileNotes果真關閉了.工具

咱們把MobileNotes的可執行文件/Applications/MobileNotes.app/MobileNotes 拷貝到電腦中.測試

  1. 導出MobileNotes的頭文件

由於MobileNotes不是從App Store下載的App, 沒有加殼, 因此能夠直接使用 class-dumpspa

  1. 此次咱們用可視化工具FLEXLoader找到咱們備忘錄界面的Controller;

而後咱們經過cycript驗證ICTextViewController是否是咱們的目標Controller. 這裏咱們能夠經過設置Controller的Title屬性來觀察變化.3d

執行後並無發現界面的標題有任何變化.代理

咱們經過FLEXLoader的views功能查看UI層級, 選擇當前控件的上一層控件的小圖標點進去.

能夠看到當前選中控件的Controller是ICNoteEditorViewController, 我想咱們應該試試它. 一樣執行上面設置title代碼, 觀察標題.

能夠看到當前的標題發生了改變. 因此當前的Controller是 ICNoteEditorViewController.

既然找到了咱們要hook的類, 那麼咱們就能夠打開ICNoteEditorViewController這個.h文件.

觀察.h文件, 尋找咱們的目標信息.

發現了咱們的目標控件 textView. 而後經過textView便可以獲取當前輸入內容的長度. 而後設置到title上.

咱們在繼續看發現了textView的代理方法.

這個方法咱們很熟悉, 就是當textView的內容改變的時候會走到這裏, 而後咱們在這個方法內根據textView的長度去設置title便可. 這裏驗證當輸入內容的時候走不走這個方法能夠經過不少方式驗證, 這裏我是經過簡單的hook方法並打印, 而後經過xcode查看打印的值確認的. 還有經過lldb和IDA打斷點到目標方法上, 而後觸發斷點也是能夠判斷的.不事後一種方法稍微要求高一些.這裏咱們沒有用.

以上是我分析後的結果.

編寫Tweak:

這個例子很簡單, 全部操做都在一個類中完成.

上面的111是我手速快輸入錯了, 因此從新輸入便可.

tweak的代碼

這個.h文件的目的僅僅是爲了讓tweak經過編譯不報錯. 存放在工程裏便可.

這個是Makefile 的內容:

圖中和建立工程的名字不同是由於時間緣由, 我沒有把以前的圖換掉, 直接用的老圖. 不過不影響流程.

安裝使用:

接下來咱們安裝這個tweak

而後打開備忘錄

能夠看到咱們的tweak生效了. title隨着咱們的內容增減而變化.

因爲時間問題分析過程可能少了不少, 我的感受作逆向開發, 最重要的就是分析過程, 因此後面有時間會補上分析過程.

若是不想用這個tweak, 能夠到這裏把它幹掉!


2. 將目標電子郵件標記爲已讀

實現的功能:

在Mail界面上增長編輯白名單的按鈕.

每次當Mail的收件箱收到新郵件時, 就會自動把白名單外的郵件標記爲已讀.

功能分析:

功能實現:

首先定位到Mail的可執行文件並class-dump它.

仍是老樣子經過ps命令很簡單的就定位到了Mail的可執行文件

而後導出它的頭文件:

接下來就是尋找到咱們安放編輯按鈕的位置:

咱們把這個編輯白名單的按鈕加到上圖的位置.

此次咱們經過Reveal查找上圖的Controller.

首先定位到最好找到的TableView, 而後查看右側 MailboxPickerController便是咱們要找的Controller, 爲了保險起見, 咱們經過cycript測試一下.

首先注入到 MobileMail 進程. 而後經過Reveal上提供的Controller地址設置rightBarButtonItems. 設置成功後出現如咱們上圖的那樣:

接下來咱們用相同的方法尋找收件箱列表的Controller.

MailboxContentViewController

而後用一樣的方法測試下MailboxContentViewController 是否是咱們的目標Controller.

而後咱們去MailboxContentViewController這個頭文件查找咱們須要的信息.

和以前同樣, 首先查看協議中有沒有蛛絲馬跡. 很快我發現了MessageMiniMallObserver 這個協議有咱們須要的東西.

從方法名字上看LoadMessages FinishedFetch MessageCountDidChanged 方法可能會在刷新完成先後調用.

爲何選擇這三個方法呢?

由於咱們作開發的時候通常獲取的頁面數據, 在刷新中是能夠獲取到的. 因此咱們重點測試下這個三個方法, 有沒有咱們想要的東西.

而後咱們利用LLDB在這個三個方法上打斷點.

經過IDA查看三個方法的基地址, 而後加上ASLR, 過程以前作過, 這裏就不一一寫出來了.

打完斷點以後, 咱們下拉刷新來觸發斷點:

能夠看到觸發的斷點地址正是 FinishedFetch方法ASLR偏移後的地址, 並且每次都是隻走這個方法.

而後我刪除一封郵件立刻就觸發了斷點, 正是方法MessageCountDidChanged:

經過測試發現 :

  • FinishedFetch方法每次刷新完成的時候都會走. 也就是在服務器成功取得郵件後獲得調用.

  • MessageCountDidChanged方法每次有刪除郵件或者有新郵件的時候纔會觸發.

  • 這裏咱們選擇MessageCountDidChanged方法做爲尋找全部郵件的方法.

設置斷點到MessageCountDidChanged方法, 刪除已有的一封郵件觸發斷點:

而後咱們看看它的參數:

能夠發現參數的類型的NSConcreteNotification 自定義的抽象通知類, 繼承自Notification.

而name是MiniMallMessageCountDidChange, object是MessageMiniMall對象. userInfo是一些改動的信息.

而後咱們尋找MessageMiniMall的頭文件繼續尋找咱們須要的信息.

這裏文件內容有些多, 就不所有截取了. 能夠發現MessageMiniMall類繼承自NSObject, 而後結合名字很容易就猜出來當前類是負責處理數據的M.

通過查找發現 - (id)copyAllMessages; 方法頗有多是獲取所有郵件的方法.

這裏咱們測試下:

能夠看到執行了copyAllMessages方法的返回值是一個集合類型而且集合中的元素是MFLibraryMessage類型的對象.

能夠看到集合中有4個元素, 正是咱們郵箱中的四封郵件. 所以copyAllMessages就是拿到全部郵件的方法.

同時咱們在頭文件中發現方法 - (void)markMessagesAsViewed:(id)arg1; 經過語義可知道應該是設置消息爲已讀的方法. 而參數也應該是含有MFLibraryMessage類型對象的數組.

到目前爲止咱們知道一封郵件就是一個MFLibraryMessage對象. 咱們在頭文件中沒有找到這個類文件. 因此它應該來自一個外部的dylib.(Message.framework)

經過MFLibraryMessage.h頭文件並無發現發件人地址等信息. 不過發現了- (id)copyMessageInfo; 這個方法. 試一下看看他返回什麼.

一個MFMessageInfo對象. 咱們感受去這個頭文件中看看. 可是通過查找發現並無咱們想要的信息. 咱們繼續查看MFLibraryMessage.h發現它繼承自MFMailMessage這個類, 咱們趕忙打開看看這個類.

經過觀察發現這個類中有咱們郵件中經常使用的詞彙.summary subject sender cc bcc 等. 不過有的屬性確沒見到getter. 咱們繼續查找它的父類MFMessage文件看看, MFMessage是MIME.framework的類.

能夠看到這裏有咱們須要的信息, 而後咱們經過LLDB查看一下具體的值.

能夠肯定這個類裏面有咱們須要的信息.

而後驗證一下以前尋找的 markMessagesAsViewed 是否是咱們要找的標記郵件爲已讀的方法.

經過IDA查找markMessagesAsViewed的地址.而後打斷點.在把郵箱中的郵件設置爲已讀試試這個斷點有沒有觸發.

能夠看到確實觸發了斷點, 說明這個方法就是咱們要找的.而後咱們看看這個方法的參數:

沒錯就是MFLibraryMessage對象組成的NSSet.

下面就能夠開始編寫咱們的Tweak了.

編寫Tweak:

安裝使用:

設置白名單, 使得除了白名單外的全部郵件都設置爲已讀. 這裏隨便寫一個.

而後刪除一封郵件看看效果:

能夠看到當郵件數量改變時, 收件箱中不在白名單中郵件已變成了已讀.

相關文章
相關標籤/搜索