CMU-CSAPP-Lab2拆解二進制炸彈


一、 實驗目的

1.理解C語言程序的機器級表示。
2.初步掌握GDB調試器的用法。
3.閱讀C編譯器生成的x86-64機器代碼,理解不同控制結構生成的基本指令模式,過程的實現。

二、實驗工具

  1. SecureCRT
  2. Linux
  3. Objdump命令反匯編
  4. GDB調試工具

三、實驗內容

登錄bupt1服務器,在home目錄下可以找到Evil博士專門為你量身定制的一個bomb,當運行時,它會要求你輸入一個字符串,如果正確,則進入下一關,繼續要求你輸入下一個字符串;否則,炸彈就會爆炸,輸出一行提示信息並向計分服務器提交扣分信息。因此,本實驗要求你必須通過反匯編和逆向工程對bomb執行文件進行分析,找到正確的字符串來解除這個的炸彈。

本實驗通過要求使用課程所學知識拆除一個“binary bombs”來增強對程序的機器級表示、匯編語言、調試器和逆向工程等方面原理與技能的掌握。 “binary bombs”是一個Linux可執行程序,包含了5個階段(或關卡)。炸彈運行的每個階段要求你輸入一個特定字符串,你的輸入符合程序預期的輸入,該階段的炸彈就被拆除引信;否則炸彈“爆炸”,打印輸出 “BOOM!!!”。炸彈的每個階段考察了機器級程序語言的一個不同方面,難度逐級遞增。 

為完成二進制炸彈拆除任務,需要使用gdb調試器和objdump來反匯編bomb文件,可以單步跟蹤調試每一階段的機器代碼,也可以閱讀反匯編代碼,從中理解每一匯編語言代碼的行為或作用,進而設法推斷拆除炸彈所需的目標字符串。實驗2的具體內容見實驗2說明。

四、實驗步驟及實驗分析

1、反匯編並利用SSH Secure Shell Client工具下載反匯編代碼

通過ls指令顯示當前目錄下的文件,找到壓縮包bomb115.tar,即目標炸彈。通過tar xvf bomb115.tar解壓此壓縮包,然后再通過ls顯示解壓出的文件:bomb、bomb.c和README。

通過objdump –d bomb > bomb.txt將炸彈程序反匯編並重定向到bomb.txt,通過ls顯示反匯編出的代碼文件bomb.txt。

打開SSH Secure Shell Client工具,登錄到遠程主機,將遠程主機上的文件下載到本機上,便於查看。

 

2、查看目標文件並做好調試准備

文件介紹:

bomb.txt:反匯編得到的代碼文件,也是主要研究的目標文件。

bomb.c:主函數,通過調用每一關的函數實現,未顯示每關的具體代碼。

bomb:炸彈程序,當調試得出每一關的密碼后打開程序運行來拆炸彈。

通過gdb bomb指令進入gdb調試環境。

大致瀏覽反匯編代碼,可以觀察到整個程序一共有六關,分別為phase_1到phase_6,並有一關隱藏關secret_phase,每次輸入錯誤時會調用引爆函數explode_bomb,因此為避免調試時引爆炸彈,需要首先在引爆函數前設置斷點,即b explode_bomb。

 

3、拆除炸彈 

1、 第一個炸彈

 

 

程序流程:

  1. 取內存地址0x4024b0處的內容;
  2. 取用戶輸入的內容(即密碼);
  3. 比較兩者的值,相等則%eax置為0,進入下一關,不相等則調用引爆程序引爆炸彈。

破解思路:

通過x/s 0x4024b0指令取出該地址的字符串,得到:Only you can give me that feeling.

則密碼為:Only you can give me that feeling.

通過 !

 

 

 

 

 

2、 第二個炸彈

 

程序流程:

  1. 讀取用戶輸入內容(為6個數字);
  2. 判斷輸入的第一個值是否為1,不是則引爆炸彈;
  3. 做一個6次循環,判斷后一個數是否等於前一個數加上之前循環變量,不是則引爆炸彈;
  4. 六個數字判斷相等結束后,進入下一關

破解思路:

設輸入內容為一個數組Key[6],則可知Key[0]=1,Key[i+1]=Key[i]+i。

因此第二關的密碼是:1 2 6 24 120 720

 

3、 第三個炸彈

程序流程:

  1. 讀取輸入參數1和參數2,調用scanf函數傳入兩個參數;
  2. 比較參數1與7的大小,小於等於7繼續,大於7引爆;
  3. 根據參數1的值來搜索跳轉地址,計算得到最終的%eax;
  4. 比較參數1與5的大小,小於等於5繼續,大於5引爆;
  5. 比較參數2與計算得到的%eax是否相等,相等則進入下一關,不相等則引爆。

 

重點在於參數1的選擇決定了switch的跳轉,該實驗地址為(設參數1為x):

0x402510+x*8

其中存在一個Switch函數表,這個炸彈我選擇參數1為2,則跳轉地址為0x00400f33

Switch跳轉到改地址開始計算eax%,最終結果為0x328-0xf7=0x231=561。

輸入 2 561。

成功 !

 

4、 第四個炸彈

 

主程序流程:

  1. 讀取2個參數,調用scanf函數傳入參數;
  2. 比較輸入參數與2的大小,小於則引爆;比較輸入參數與4的大小,大於則引爆。
  3. 把輸入參數傳入函數func4,並調用函數func4;
  4. 若函數func4返回值等於%rsp+0x8,則返回,進入下一關,否則引爆炸彈。

 

func4函數流程:

1.  比較傳入參數是否大於1,大於1則繼續,小於1則返回0,等於1則返回%rax;

2.  循環%edi=%edi-1,並遞歸調用函數func4,直到參數小於等於1;

3.  循環變量%edi=edi-2,並傳入%esp繼續遞歸調用函數func4;

4.  函數返回的所得值加到%eax;

 

設b=%edi,a=%esi,則f(a,b)=f(a,b-1)+f(a,b-2)+a;

第二個參數小於1則返回0,等於1則返回%rax(即a)。

炸彈中默認b=8,我們輸入a=2,經過上述式子計算得f(8)=561.

輸入108 2 或者162 3。

成功 !

 

5、 第五個炸彈

 

程序流程:

  1. 輸入字符串
  2. 調用string_length的字符串長度函數,測得的長度若不為6則引爆;
  3. 做一個6次的循環,循環變量%eax從1到6,;
  4. 我們要使得 string_not_equal返回值為0 ,也就是%ebp處的值和0x4024fe處的值相等,查看0x4024fe處的值,發現為bruins
  5. 循環賦giant了, 依次改變以%ebp為開始位置的char的數組的值 那么b,r,u,I,n,s就存在於該字符串,尋找改變字符串值的語句。
  6. 取得 (0x8[%ebp]+0xc(%ebp)) &0xf的值,作為下標取得0x402550中的值,查看 0x402550處的內存為 maduiersnfotvbylSo you think you can stop the bomb with ctrl-c, do you?
  7. bruins分別對應 13 6 3 4 8 7 所以要取得13 6 3 4 8 7
  8. 我們輸入的內容寫成 ASCII碼應該是xd x6 x3 x4 x8 x7。x表示任取,隨便取得 3d 36 33 34 38 37,對應ASCII碼為=63487。輸入
  9. 成功 !


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM