使用IDA的调试器
一個小bug程序
這個小程序只是簡單的計算了一下一組數據(1,2,3,4,5)的平均值。這組數據被保存在兩個數組里,一個是8bit的數值,一個是32bit數值表示。
#include?<stdio.h>
charchar_average(char?array[],int?count)
{
int?i;
char?average;
average =?0;
for?(i =?0; i < count; i++)
average += array[i];
average /= count;
return?average;
}
?
int?int_average(int?array[],?int?count)
{
int?i,average;
average =?0;
for?(i =?0; i < count; i++)
average += array[i];
average /= count;
return?average;
}
?
voidmain(void)
{
char?chars[]= {?1,?2,?3,?4,?5?};
int?integers[]= {?1,?2,?3,?4,?5?};
printf("chars[] - average =?%d\n",
char_average(chars,?sizeof(chars)));
printf("integers[] - average =?%d\n",
int_average(integers,?sizeof(integers)));
}
運行它,我們得到如下結果:
chars[]- average = 3
integers[]- average =?1054228
可以看出在整數方式下計算的結果是錯誤的,我們用IDA的調試器來分析一下吧。
裝入文件
調試器被完美的集成在IDA中,首先我們使用IDA裝入文件,來生成數據庫,用戶可以使用反匯編功能,所有反匯編的信息,均可以在調試器中使用。如果反匯編的文件被調試器正確識別,調試器的菜單將自動出現在IDA的主窗口中。
指令斷點
首先我們在反匯編窗口中找到int_average()這個函數,我們在程序前導部分(指程序開始的一些初始化等)的后面下斷點,可以使用右鍵菜單中的AddBreakpoint的命令,或使用快捷鍵F2。
程序運行
現在我們開始執行這個程序。首先使用相應的圖標打開調試器窗口,然后運行這個文件直到它到達斷點,我們可以使用快捷鍵F9,或使用調試工具條上的Start按鈕。
堆棧
IDA-ESP窗口現在列出了我們感興趣的函數的堆棧結構,我們很容易就找到了函數int_average()的整數數組參數,它指向了在main()的整數數組integers[]。
?
監視
我們可以添加監視,通過監視觀察在程序執行過程中數據的變化
地址分析
通過分析匯編代碼,我們可以知道計算累加和的循環所在,它將計算結果保存在EBX中,[EBX+EAX*4]明顯的指明EBX是數組的開始地址,EAX是數組的索引,這樣它就可以定位到數組中的每一項。
單步跟蹤
讓我們繼續一步一步的跟蹤這個循環。通過使用調試工具條上的按鈕或用快捷鍵F8,有時,IDA會用綠箭頭指示調轉命令的調轉方向和位置
?
找到Bug
現在讓我們看一下ESI值,每輪循環時,EAX都要與ESI比較,我們可以判別ESI是循環總輪數,但我們也注意到ESI中有一個奇怪的數據14h(=20),而我們的數組只有5個成員。我們已經找到問題所在了……
硬件斷點
為了確認這個問題,我們使用硬件斷點,就設在我們intergers這個數組最后一個成員的后面(事實上,就是在chars這個數組的第一個成員上)。如果我們在實行intergers的循環斷到了這里,說明我們的循環讀取了intergers這個數組之外的數據。我們在這里下硬件的4字節(一個整數的大小)訪問斷點。
正如我們猜測的,當我們繼續運行,它確實執行了對chars數組的訪問操作。注意,此時EIP執行導致硬件中斷的后一條指令上。
堆棧跟蹤
讓我們看一下ESI來自有調用int_average()時傳遞來的參數,為什么調用的程序會傳遞過來這么奇怪的一個參數?我們看一下,所有調用函數的堆棧。我們單擊一下main(),來到調用程序這里。通過IDA的PIT(參數識別技術),我們看到push 20這條指令,是它將這個錯誤的參數傳遞到int_average()。
我們回過來看看我們的C代碼,我們就明白了問題的所在,我們使用了sizeof這個函數,它返回了數組的字節數,而不是數組的成員數!
其它功能
IDA可以幫助你進入你所調試的進程內存空間的所有區段,在這些段內,你可以使用調試器的所有功能:可以在DLL中設置斷點,可以繪制流程圖,可以應用結構的數據類型等等。
對異常的處理也完全可以由使用者來決定。
有了調試器功能的IDA更加完美,你可以使用它的反匯編和調試器功能隨時隨地的進行靜態分析和動態調試。
總結
- 上一篇: socket connec连接超时处理
- 下一篇: IDA Plugin 编写基础