逆向分析之路-從運算碼開始-03


15.3 mov指令與暫存器

由於Intel的運算碼編碼很複雜,不是三言兩語就可以說完的,而且本書只是提供一個入門法,讓學習的路更輕鬆點,也看懂怎麼去查更複雜的運算碼文件罷了。因為在反組譯的過程當中,我們到處可見mov的蹤跡,所以我們會花多點時間把這個給分析詳細點,在逆向分析之路,不求快,但求懂。

15.3.1 與立即值的搭配

上圖大致整理了x86 CPU中央處理器的內部暫存器,越高階的CPU提供越多位元特性的暫存器。其中A、C、D、B開頭的暫存器都算一般用途,只是當有特殊情況時,其會扮演特殊功能參與運作,當然還有一些旗標暫存器之類的東西。請特別留意一下,這些8位元、16位元暫存器,都是屬於16位元暫存器,只是一般用途的暫存器如AX、CX、DX、BX,可以拆成兩個8位元暫存器來使用罷了

不過大家先有個概念即可,整理出來只是為了方便我們接下來的逆向分析而已,甚至有些我們根本在寫程式碼時不會去直接使用到,請各位不用太緊張執著在這個地方。

 

  1. 首先,先新增一個專案:

 

  1. 選擇Win32主控台應用程式並自行命名,然後一路到底按照預設即可,畫面如下:

 

在本書中常以RevOP命名此種方式,作為內嵌組合語言寫法,重複修改執行

 

  1. 寫入我們想由組合語言碼來正向驗證運算碼,先來個看mov al會產生什麼,寫完後先設定中斷點,然後按下F5功能鍵執行偵錯,或選擇上方本機Windows偵錯工具鈕。

 

  1. 偵錯工具會停在中斷點處,這時我們觀察右邊的反組譯碼視窗。這裡告訴我們正向推論,也就是原始碼會得到什麼樣的運算碼。

 

  1. 原來,mov al 被翻譯成 B0,我們這裡故意停在這畫面讓大家看到0xB0的表示法,這我們後面反向驗證時會用到。

  1. 執行完畢後,回到主程式,我們把原來的內嵌組合語言程式先註解掉,或者留著比對也沒關係。接下來的寫法是驗證直接寫入B0 05運算碼,會逆向得到相同的組合語言碼,當然,運算碼也會一樣。

這裡我們會用到一個 _emit 虛擬指令,他有點類似MASM組合語言裡面的 DB這個資料標名,他會在目前文字區段的目前位置,定義一個位元組。看下面寫法,會將位元組 0xB0、0x05放入程式碼:

 

輸入運算碼得到完全相同的反組譯碼:

  1. 因此我們可以很確認下圖關係:

如何?是不是不難!各位可以根據這個框架,除了16位元的AX、CX、DX、BX與 8位元的SP、BP、SI、DI比較特殊之外,能把下面表格8位元及32位元的部份給補齊運算碼嗎?其中的000~111是一種二進制對暫存器的編碼。

以下是CL的範例:先跑一次mov cl, 5的結果看到運算碼是B1 05後,再回原始程式去修改opcode2asm的定義,就可以得出下面結果。

本小節最後我們用一張畫面來告訴各位在32位元的暫存器裡,不論放上任何16位元或32位元的立即值,他最大就只能存32位元,所編譯出來的運算碼都相同,只有運算子不同而已。

 

發表留言

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料