CSAPP lab2 二進制拆彈 binary bombs phase_5


給出對應於7個階段的7篇博客

phase_1  https://www.cnblogs.com/wkfvawl/p/10632044.html
phase_2  https://www.cnblogs.com/wkfvawl/p/10636214.html
phase_3  https://www.cnblogs.com/wkfvawl/p/10651205.html
phase_4  https://www.cnblogs.com/wkfvawl/p/10672680.html
phase_5  https://www.cnblogs.com/wkfvawl/p/10703941.html
phase_6  https://www.cnblogs.com/wkfvawl/p/10742405.html
secret_phase  https://www.cnblogs.com/wkfvawl/p/10745307.html

phase_5

 

phase_5要求輸入一個包含6個字符的字符串。phase_5函數從中讀取這些信息,並判斷其正確性,如果不正確,則炸彈爆炸。

phase_5主要考察學生對指針(數組)機器級表示的掌握程度。

觀察框架源文件bomb.c:

 

從上可以看出:

1、首先調用了read_line()函數,用於輸入炸彈秘鑰,輸入放置在char* input中。

2、調用phase_5函數,輸入參數即為input,可以初步判斷,phase_5函數將輸入的input字符串作為參數。

因此下一步的主要任務是從asm.txt中查找在哪個地方調用了readline函數以及phase_5函數。

1.1 尋找並分析調用phase_5函數的代碼

打開asm.txt,尋找phase_5函數。

 

 

phase_1類似分析:

1、當前棧的位置存放的是read_line函數讀入的一串輸入;

2、phase_5的函數入口地址為0x8048df7

此時的函數棧為:

 

1.2 phase_5函數分析

繼續尋找phase_5,或搜索8048df7,可以找到phase_5函數入口。如下圖所示:

 

1541-547行:初始化函數棧幀,並為調用string_length做准備(此時ebx的內容為input字符串首地址:543行)。函數棧幀如下圖所示:

注:

1544-545行:mov %gs:0x14, %eax   mov %eax, 0x1c(%esp),將gs(全局段寄存器)+0x14偏移位置的內容放置到eax,然后將其放置到esp + 0x1c的地方。從這里看不出這段代碼什么含義,但據后面的分析,這里應該是起到一個“哨兵”的作用,防止數組訪問越界。

2546行:xor %eax, %eax,似乎沒有什么用,得出來的結果是0,應該只是影響zf標志寄存器(zf為零標志寄存器,即zf=1)。

 

2548行:判斷input字符串的長度(esp指向的地方為input的首地址,參見上圖),返回結果在eax寄存器中。

3549-551行:判斷input的長度是否為6,如果不是,則炸彈爆炸(551行),如果是,跳轉到8048e62<phase_5+0x6b>。也即輸入的字符串長度應該是6

4、572-573行(8048e62<phase_5+0x6b>):eax寄存器內容賦值為0,然后跳轉到8048e22<phase_5+0x2b>

5554行(<8048e22><phase_5+0x2b>):將ebx + eax * 1地址的內容送入到edx。注意, ebxinput首地址,也即將input[%eax]的內容送入到edx。當eax = 0時,即為edx的內容為input[0]

6555行:將edx的內容(input[0])與0x0f位與,相當於取低4位(edx內容為input[eax]的低四位)。

7、556行:將edx + 0x804a470指向的地址的內容送入到edx0x804a470的內容(使用objdump --start-address=0x804a470  -s bomb,參見phase_1分析過程)為:

 

從上面來看,0x804a470應該是指向一個字符串,此時edx的內容應該是0x804a470加上input[eax]4位的偏移的內容。

8557行:將dledx的低8位,為(0x804a470 +input[eax]) & 0xf)的內容送入到esp + eax * 1 + 0x15的地方。

9558-560行:eax += 1,然后判斷eax的內容是否等於6,如果不等,則跳轉到8048e22<phase_5+0x2b>,重新回到第5步繼續進行分析,直到eax=6(即循環6次)。

10、以上代碼,以類c語言來簡要說明:

for(int i = 0; i < 6; i++){

//0x804a470 +  input[i] & 0x0f這個地址的內容送入到堆棧esp + i + 0x15地址中。

(0x804a470 +  input[i] & 0x0f)  --> (esp + i + 0x15)

}

經過6次循環后,函數棧幀如下:

 

 

顯然,從esb + 0x15開始,是根據input的輸入的每個字符的低四位,得出來的一個新的字符串。

11561行:以上循環結束后,跳出循環,執行該語句:esp + 0x1b的內容改變為0

12562行:將0x804a446送入到:esp+0x40x804a446的內容為(objdump --start-address=0x804a446 -s bomb):

 

 

也即當前esp+0x4指向的是一個字符串首地址,字符串為sabres

13564-565行:eax的內容變為esp + 0x15,即通過上面循環形成的新的字符串的首地址,然后將其送入到esp

14、調用strings_not_equal函數,顯然,前面11~13均在為調用strings_not_equal做准備,調用strings_not_equal前,函數棧幀為:

 

15、顯然,strings_not_equal函數判斷以(esp + 0x15)為首地址的字符串與0x804a446為首地址的字符串(sabres)相比較,如相等,eax返回0,如不相等eax返回1。(參見phase_1分析)

16567行:判斷eax是否為0eaxeax位與),如果為0,0標志寄存器為1

17568-569行:如果eax=0,則跳轉到8048e69<phase_5+0x72>,后續直接退出phase_5了,說明輸入的input字符串是正確的,否則引爆炸彈。(8048e69<phase_5+0x72>代碼后面分析

18、574-577行:將esp + 0x1c地址處的內容送入到eax574行,esp+0x1c的內容應為%gs:0x14的內容),然后與%gs:0x14的內容相異或,如果相等(為0),則跳轉到0x8048e7b,正常結束,否則調用__stack_chk_fail函數(應該是棧檢查失敗);

根據上面分析,%gs:0x14的值送入到esp+0x1c的地方(第544-545行),應該是起到一個“哨兵”的作用,防止數組的訪問越界。

 

1.3 phase_5結果分析

根據前面分析,顯然phase_5函數的作用(以類C語言進行描述):

 

char array[] = {'m','a','d','u','i','e','r','s','n','f','o','t','v','b','y','l'};
char *str = "sabres";
char  new_str[7];
//根據input的每個字符的低4位,以及array,形成新的字符串。
for(int i = 0; i < 6; i ++)
{
    new_str[i] = array[input[i]&0xf]);
}
new_str[6] ='\0';
//如果new_str不等於str("sabres"),則引爆炸彈。
if(strcmp(str, new_str) !=0)
{
    explode_bomb();
}

那么根據上面的代碼反推,如果需要使構成的new_str=="sabres",那么輸入的input[i]的低4位對應的十進制數分別是array[]數組中字符's','a','b','r','e','s'的下標。

根據以上分析,要形成"sabres"字符串:

array[] = {'m', 'a', 'd', 'u', 'i', 'e', 'r', 's', 'n', 'f', 'o', 't', 'v', 'b', 'y', 'l '};

1's':對應於array7個 (從0開始),也即input[0]的低4位應該為7,符合條件的可顯示字符有:''''7 ''G''W''g''w'(參見附后的ASCII碼表):

2'a':對應於array1個 (從0開始),也即input[1]的低4位應該為2,符合條件的可顯示字符有:'!''1 ''A''Q',a''q'

3'b':對應於array13個(從0開始),也即input[2]的低4位應該為13,符合條件的可顯示字符有:'-''=''M'']''m', '}'

4'r':對應於array6個 (從0開始),也即input[3]的低4位應該為6,符合條件的可顯示字符有:'&''6 ''F''V''f''v'

5'e':對應於array5個 (從0開始),也即input[4]的低4位應該為5,符合條件的可顯示字符有:'%''5''E''U''e''u'

6's':對應於array7個 (從0開始),也即input[5]的低4位應該為7,符合條件的可顯示字符有:''''7 ''G''W''g''w'

 

 

 

 

因此,對於本題,答案不是唯一的,為6組可選字符的排列組合,如"gamfeg""GAMFEG"等。


免責聲明!

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



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