我也要學iOS逆向工程--函數

  你們好,這篇我開始學習函數了.先學 C 函數,而後再 OC 的吧.OC 應該複雜點的吧.算法

而後看看彙編狀況哦!xcode

學習函數呢,確定要弄清楚幾個事情.sass

1.跳轉地址.函數

2.返回地址學習

3.參數spa

4.函數獲取參數3d

5.返回值和如何返回指針

6.掃尾調試

咱們開始了哦!1個個的突破!唉,這個學習筆記是一邊學一邊寫,不知道到底能不能邊寫邊突破呢.小馬過河,試試吧.呵呵.code

1.跳轉地址.由於xcode默認反彙編的時候,並無顯示出機器碼,因此這裏,咱們要用一個命令去顯示:disassemble -fmb

咱們發現這樣子呢就能夠看到機器碼了.而後,bl就是call了哦.bl後面的0x18dc4就是具體的函數代碼地址了.這裏,咱們要從機器碼中學習下跳轉地址是如何計算的.咱們知道在x86中是這樣計算的:

call指令的地址 +call指令的長度- 偏移量 = 跳轉地址.課是這裏我卡住了.

   0x18dfe:  0xf7ffffe1   bl     0x18dc4                   ; Add at main.m:13

我剛纔忙乎了會,實在是沒想出來算法.這裏,我先作個記號.咱們先學習下面的內容.

2.返回地址

咱們從代碼中能夠看到bl(call)指令後的返回地址是 0x18e02 .咱們腦子裏首先浮現是x86平臺,返回地址是存放在ESP寄存器中的.經過 ESP 寄存器的地址取內容就是返回地址.可是咱們如今在 IOS 中.IOS 中我尚未發現 ESP 寄存器.那麼只有一個辦法.咱們把進入函數前和進入函數後的寄存器都打印出來對比下.

進入函數前                                  進入函數後

 

 

咱們看到進入函數後有一個寄存器叫lr或者叫r14的值與咱們的0x18e02最接近.可是爲何會多1個1呢.哈哈,目前還未知啊!不過咱們再看看函數的反彙編

在最後有bx lr ,既然這樣,這條指令又在最後面,一個函數結束了確定要返回的.因此說咱們就能夠認定lr寄存器就是放入的函數返回值. 

3.參數

咱們再看看這個圖

咱們程序傳入的參數是1和2.咱們從反彙編看到,1和2 被傳入了r2和r3.只是咱們目前在調試版下進行的實驗,因此編譯器作了些無用功.

可是最後咱們發現,r2,r3是給了r0和r1.而後立刻就跳轉到函數了.那麼說明,r0,r1作爲傳遞參數的可能性最大.可是數據量大的時候怎麼辦的呢

等下回再分析了,呵呵.

4.函數獲取參數

咱們再看看這個截圖呢

暈!調試版的程序就是比較麻煩啊.咱們看到

0x18dc6:  str    r0, [sp, #0x8]

0x18dc8:  str    r1, [sp, #0x4]

0x18dca:  ldr    r0, [sp, #0x8]

0x18dcc:  ldr    r1, [sp, #0x4]

這笨蛋編譯器把r0和r1中的參數又放到了棧裏,又從棧裏取回到原處.

這裏的緣由是由於調試版,,爲何ro和r1寄存器中的值剛剛保存,立刻又將其加載回來.

可是至少咱們知道.取函數,就是直接從寄存器裏面取的了.

5.返回值和如何返回

從上面的截圖咱們知道

0x18dce:  add    r0, r1

返回值放入了r0中了.

而後呢

0x18dd4:  add    sp, #0xc

由於以前呢 

0x18dc4:  sub    sp, #0xc

因此如今必須把12加回去.由於必須確保棧指針的正確性,否則棧指針會指向錯誤的地方了哦.!

咱們以前要減12呢.其實目前來看,就是預留了12個字節的空間.

6.掃尾了哦!

0x18dd6:  bx     lr

最後,執行bx指令會回到調用函數的地方.還記得lr嗎,放的是函數的返回地址哦. 

至此函數就分析完了,可是我忘記了一個事情,就是沒有在函數裏放置局部變量.等下次我再加入局部變量分析了哦!學習過x86肯定對看 IOS arm也有幫助.其實關鍵是分析思路哦!要根據蛛絲馬跡重現犯罪現場哦!

固然後面會繼續分析 OC 的方法,但願不要太難了哦!

相關文章
相關標籤/搜索