譯文出處 : http://www.pediy.com/practise/IDA.htm
索引
1? 第一節:C語言的小程序
2? 第二節:基本類型的識別
3? 第三節:操作數格式
4? 第四節:字符和字符串的操作
5? 第五節:數組
6? 第六節:枚舉類型
7? 第七節:Bit-fields(位域)
8? 第八節:結構體
9? 第九節:結構變量和結構數組
10 第十節:聯合體和結構體中的結構體
11 第十一節:可變的結構體
12 第十二節:結構體偏移
13 第十三節:聯合體偏移量
14 第十四節:地址偏移量
15 第十五節:最終逆向結果
附錄
第一節:C語言的小程序
為了演示
IDA
的功能先寫一段小程序。(代碼在附錄)程序在此源代碼
程序執行結果:
CUSTOMERS:
CUSTOMER 0001: Peter (m)
CUSTOMER 0002: John (m)
CUSTOMER 0003: Mary (f)
PRODUCTS:
PRODUCT 0001: BOOK: IDA QuickStart Guide
PRODUCT 0002: SOFTWARE: IDA Pro: PC; WINDOWS DOS; DISASSEMBLY
PRODUCT 0003: SOFTWARE: PhotoRescue: PC MAC; WINDOWS OS-X; RECOVERY
PRODUCT 0004: SOFTWARE: aCrypt: PC; WINDOWS; CRYPTOGRAPHY
?????????????????????????????????????????????????????????????? TOP
----------------------------------------------------------------------
第二節:基本類型的識別
用IDA分析我們前面的程序,我們會發現下圖的類型
只要按"D"我們就可以任意轉換這些不確定的類型.可以變成byte,word,dword(db,dw,dd)。
當然你也可以設置更多的數據轉換類型:
選擇“Options”菜單的“Setup data types”命令就可以設置了
值得注意的是:你在數據轉換的時候,它是依據數據自身的結構來轉換的。我們按“D”的時候,
如果下一個字節已經被你轉換過,你的本次轉換,IDA將會提示讓你確認。
注:如果你想改變這種默認設置可以在“Options”菜單“Convert already defined bytes”命令里設置
撤銷你的所有轉換按“U”鍵。
??????????????????????????????????????????????????????????? TOP
-------------------------------------------------------------------------------------
第三節:操作數格式
數據類型自定義轉換后,被操作過的數據(就是你按過“D”的)的進制IDA也是可以自定義轉變的,
通過在“Operands”工具欄的“Number”命令我們可以隨意轉換數字的進制
最下面的“Toggle leading point”就是填補數據前的空位為0(就是說如果當前數據未占滿數據格式的所有位高位用0來填補)
IDA還可以轉換數據的標志位(就是正負)具體操作如下圖:
最后呢~~如果這些轉換你還不滿意(夠BT)當然你還可以自定義數據進制如圖:
??????????????????????????????????????????????????????????????? TOP
-----------------------------------------------------------------------------------------
第四節:字符和字符串的操作
作者又說話了:很多程序都是包含字符串的,一些被操作過的數據(就是你按過“D”的)可以轉化為
字符,使用的命令就在“Operands”工具欄上
由于編程語言的不同造成字符串也有不同的格式,當然IDA就支持所有的格式了。
IDA在轉化后會在地址添加一個名字。因為我們的程序是c的所以就找到c的字符串。具體操作如圖:
如果不是C寫的程序怎么辦呢?我們可以在“Options”菜單“ASCII string style”命令中設置。
允許你修改其它類型為默認設置,使用默認設置的快捷鍵是“A”,或者自定義一種類型可以使用不常用的終止字符。
??????????????????????????????????????????????????????????????????? TOP
--------------------------------------------------------------------------
第五節:數組
在c中,ASCII字符串被認為是字符數組,IDA是如何處理數組的呢?
我們用最常用命令來定義數組中的第一個元素,設置第一個元素類型為byte,格式為char,然后點擊“*”號鍵(或者“Edition ”工具欄的“Array”命令)來創建數組。這時彈出一個對話框,可以設置很多變量。
你可以定義數組一行的顯示個數,還可以使用“Element width”來設置他們之間的寬度。
使用“Use dup construct ”選項可以合并連貫的相似字節,“ Display index ”選項可以像注釋一樣顯示數組的下標。
例如我們設置一個有64個元素的數組,一行有8個元素,每個元素之間的寬度為4,不選取“dup constructs”,選取“Display index ”,我們就可以得到下面的數組。
當IDA遇到未被識別的字節他會用紅色的高亮顯示。
當然你也可以選擇一個范圍來創建數組,IDA會自適應的設定。
??????????????????????????????????????????????????????????????????????????? TOP
------------------------------------------------------------------------------------
第六節:枚舉類型
還記得我們在C程序中定義的product_category_t 類型嗎?
讓我們用IDA的“Enumerations”來定義一下。
首先,我們打開“Enumerations”窗口來創建一個新的枚舉類型
我們輸入我們的枚舉類型值
在check_product()函數,我們可以用枚舉類型重新定義一些操作數。
右鍵點擊在數值上,就會彈出一個菜單,選擇“Symbolic constant”。
IDA就會自動列舉枚舉值,用以匹配當前的數值。
操作完成,我們就會得到下面的結果:
??????????????????????????????????????????????????????????????????????????????????????????????? TOP
-----------------------------------------------------------------------------------------------------
第七節:Bit-fields(位域)
BTW:Bit-fields,我的理解就是在結構體中的位標志。太菜!希望高手指正!
現在,我們來定義一下在software_info_t 結構中的bitfields。
IDA的觀點就是,bitefields是一種特殊的枚舉類型。
我們可以選擇在枚舉類型創造窗口中的“Bitfield”選項。
還記得我們曾經在我們的程序中建立了兩種不同類型的bitfields ,
plateform和os包含了一種隱藏的模式:用來包含組合模式(用邏輯或來操作) 。因為一種產品可以同時在幾種plateforms和OS的組合。另一方面,category bitfield 中每一個數字表示一種類別:一種產品每次只能屬于一種類別。
在IDA中一種指定的模式,bitfield只能包含一個值。所以在描述plateform 和category bitfields時為了顯示組合模式,我們必須創建一個小的bitfields,每個值的一個bit.
現在我們開始創建category bitfield。mask值為0x3 (2 bits).我們指定一個名字、一個值、還有bitfield mask。我們還需要定義mask的名字:這個我們不用IDA自動生成的,IDA有一個內存助手可以幫助生成。
當所有的bitfields被輸入,我們就會得到下面的結果:
用Operands 工具欄上的Enum member命令就可以定義我們程序中的Enum member數據
??????????????????????????????????????????????????????????????????????????????????????????????????? TOP
---------------------------------------------------------------------------------------------------------
第八節:結構體
我們的程序當中包含了很多結構體。現在讓我們來在IDA中描述一下結構體,
看看是怎么提高匯編代碼的可讀性。
第一步,我們必須打開Structures 窗口,來創建一個新的結構體類型。
結構體的成員是一匯編的模式定義的。讓我們來定義software_t 結構中的第一個成員。
一直按“D”知道它變成“dd”意思就是這個成員的值為 dword類型。
把它的格式定義為我們以前定義好的software_info_t 枚舉類型,然后我們用Rename命令輸入一個適當的名字:info
開始定義第二個成員,這次使用ASCII命令(按“A”),在這個環節
IDA會彈出一個專用對話框用來設定字符串的大小
我們還可以從已經分析好的數據中來建立結構體。
舉個例子:假設我們選擇了一塊數據正好是和我們的customer_t結構體的數據格式一樣,我們就可以用IDA的“Create struct from data ”命令來創建結構體
一旦使用了這個命令,IDA就會在Structures窗口創建一個相對應的結構體
我們使用“A”鍵來修改name成員的長度為32bytes(和我們源代碼中定義的一樣),然后再給結構體一個好聽的名字。
我們拿這些結構體有什么用呢?IDA提供給我們兩種方法:
·Apply structure types to initialized data in the program.?
·Convert operands as offsets inside structures.
我們將在下面的教程當中來介紹這兩種方法
??????????????????????????????????????????????????????????????????????????????????????????? TOP
---------------------------------------------------------------------------------------------------------------------
第九節:結構變量和結構數組
現在讓我們用來customer_t結構體整理另外一個客戶信息John。
把鼠標指針放在我們定義的結構體的第一個自己上面,然后使用Struct var命令。
這樣我們就得到了一個新的結構體變量。IDA會自動在結構體成員的后面加上變量名的。
通過我們的源碼,我們知道有一個包含個4元素的customers數組,我們先前把
Peter和John都定義為 customer_t 結構體了。現在取消對Join結構變量的定義,然后在Peter結構上按“*”鍵創建我們的customer數組,這樣IDA就彈出一個數組設置框他會自動檢測出來我們要創建的數組最大數是4。
下來我們就看到創建好的數組了,剩下的就是改一下數組的名字。
??????????????????????????????????????????????????????????????????????????????????????????????? TOP
-------------------------------------------------------------------------------------------------------
第十節:聯合體和結構體中的結構體
IDA中可以像定義標準結構體那樣來定義聯合體。
讓我們來試著定義product_u 這個聯合體吧。
book_t和software_t這兩個結構體我們已經定義過了。
IDA認為聯合體就是一種特別的結構體:因此我們打開Structures窗口,運行Add struct type命令,在對話框中我們選擇創建Create union 選項。
我們可以使用IDA常用的命令來創建聯合體成員,分別添加一個book_t 結構體類型的book和一個software_t 結構體的software聯合體成員
當然結構體也可以嵌套一個結構體。事實上,我們剛才做的例子就實現了。
記住IDA認為聯合體只不過是一種特殊的結構體
??????????????????????????????????????????????????????????????????????????????????????? TOP
----------------------------------------------------------------------------------------------
第十一節:可變的結構體
我們還記得有一個softwares_t 結構體。結構體softs 的長度是不確定的。
在匯編中,我們必須創建一個大小可變的結構體~。這種結構體創建的時候和普通的一樣,僅僅最后一個元素定義的數組元素個數為0。
既然IDA不能計算出這種結構體的大小,我們就必須通過選擇結構體的區域,來定義大小。
我們可以看到所有的類型IDA用注釋模式來顯示成員名稱
??????????????????????????????????????????????????????????????????????????????????????????? TOP
----------------------------------------------------------------------------------------------------
第十二節:結構體偏移
現在我們知道如何定義聯合體和結構體了。現在我們來將一些操作數指向他們原本指向的結構體。
在print_customer() 函數中,我們知道他只有一個指向customer_t結構體的參數。EAX寄存器初始化這個指針的值,使他指向customer_t 結構體。因此我們推斷所有的[EAX+....]都是指向customer_t結構體成員的偏移。?
我們開始重新定義這些結構體變量的偏移,你右擊在他們上面IDA會自動給你提供偏移的信息。
當我們把所有的偏移量都整理一下的話,匯編代碼馬上就變得清晰易懂了。
print_software()函數呢就是另外一個例子:EBX在初始化的時候指向了software_t 及構體。注意EBX寄存器在整個函數中都有應用(一個一個替換會累死的)。不要緊張,IDA會使用一次操作就能替換全部。
做法如下:
選擇整個函數的代碼,然后選在Operands工具欄上的Offset (struct) 命令。
彈出Structure offsets窗口。然我們在列表中選擇EBX寄存器。
左邊樹形視圖顯示了在IDA中定義的所有結構。
右邊就顯示與EBX有關系的所有操作。如果我們選擇了左邊的一個結構,
IDA就會自動改變被選擇代碼中與結構體有關的偏移量。
樹視圖前面不同的符號表示經過計算后的狀態。對號就表示完全匹配,相反就是不完全匹配。在我們的操作中正好完全匹配。
確定以后,我們就得到了下面的結果:
????????????????????????????????????????????????????????????????????????????????????????????????????? TOP
--------------------------------------------------------------------------------------------------------------
第十三節:聯合體偏移量
依靠產品種類,我們可以調用適當的函數來打印產品信息。
但是這一次的結構體偏移量跟以前不一樣了,它是product_u聯合體中的一個成員,它是一個數,這時我們就選擇Edit struct 菜單中Select union member命令來處理
結果就是這樣:
Structure offset對話框顯示如何表明一個聯合體成員。在你選擇的區域中打開了這個窗口,IDA就會用“?”來顯示聯合體類型。
如果展開樹視圖中適當的分支,我們可以選擇被描述為聯合體成員的偏移量。
一旦選中,IDA會用在一種綠色的符號來表示偏移量指向的記錄中的聯合體。
??????????????????????????????????????????????????????????????????????????????????????? TOP
--------------------------------------------------------------------------------------------------------
第十四節:地址偏移量
IDA也可以重新定義操作數。在下面的例子中,桔黃色的部分顯示一個可能存在的參考~
使用Operands 工具欄上的Offset 按鈕就可以進行轉換。
??????????????????????????????????????????????????????????????????????????????????????????? TOP